Mindstorms 3rd Party ROBOTC Drivers RobotC
[Home] [Download] [Submit a bug/suggestion] [ROBOTC Forums] [Blog] [Support this project]

codatech-rfid.h

Go to the documentation of this file.
00001 /*!@addtogroup other
00002  * @{
00003  * @defgroup CTRFID Codatex RFID Sensor
00004  * Codatex RFID Sensor
00005  * @{
00006  */
00007 
00008 /*
00009  * $Id: codatech-rfid.h 133 2013-03-10 15:15:38Z xander $
00010  */
00011 
00012 #ifndef __CTRFID_driver_H__
00013 #define __CTRFID_driver_H__
00014 
00015 /** \file codatech-rfid.h
00016  * \brief Codatex RFID driver
00017  *
00018  * codatech-rfid.h provides an API for the Codatex RFID sensor.
00019  * Based on information given on http://www.codatex.com/picture/upload/en/RFID_I2C.pdf
00020  * and on Stephen Hall and Oliver Graff previous work on this sensor.
00021  *
00022  * Changelog:
00023  * - 0.1: Initial release
00024  * - 0.2: Partial rewrite by Xander Soldaat to simplify API
00025  * - 0.3: Uses new array typedefs instead of structs
00026  *
00027  * Credits:
00028  * - Big thanks to Xander Soldaat for giving his work on other sensors's drivers code for ROBOTC.<br>
00029  *   (Seriously, I'd have given up without you !)
00030  * - Thanks to Stephen Hall and Oliver Graff for their work which made me understand the initialisation need !
00031  *
00032  * License: You may use this code as you wish, provided you give credit where its due.
00033  *
00034  * THIS CODE WILL ONLY WORK WITH ROBOTC VERSION 3.59 AND HIGHER. 
00035 
00036  * \author Sylvain CACHEUX (sylcalego@cacheux.info)
00037  * \author Xander Soldaat (mightor@gmail.com), version 0.2 and up
00038  * \date 20 february 2011
00039  * \version 0.3
00040  * \example codatech-rfid-test1.c
00041  * \example codatech-rfid-test2.c
00042  */
00043 
00044 #pragma systemFile
00045 
00046 #ifndef __COMMON_H__
00047 #include "drivers/common.h"
00048 #endif
00049 
00050 // I2C ADDRESS
00051 #define CTRFID_I2C_ADDR         0x04      /*!< RFID I2C device address          */
00052 
00053 // REGISTER ADDRESSES
00054 #define CTRFID_FIRM_VER         0x00      /*!< RFID Firmware version            */
00055 #define CTRFID_MAN_NAME         0x08      /*!< RFID Manufacturer name (CODATEX) */
00056 #define CTRFID_SENS_TYP         0x10      /*!< RFID Sensor type (RFID)          */
00057 #define CTRFID_STATUS           0x32      /*!< Sensor status info (0/1)         */
00058 #define CTRFID_OFFSET           0x41      /*!< Offset for sensor's registers    */
00059 #define CTRFID_CMD              0x00      /*!< Command to the RFID sensor       */
00060 #define CTRFID_BYTE1            0x01      /*!< 1rst byte of transponder data    */
00061 #define CTRFID_BYTE2            0x02      /*!< 2nd  byte of transponder data    */
00062 #define CTRFID_BYTE3            0x03      /*!< 3rd  byte of transponder data    */
00063 #define CTRFID_BYTE4            0x04      /*!< 4th  byte of transponder data    */
00064 #define CTRFID_BYTE5            0x05      /*!< 5th  byte of transponder data    */
00065 #define CTRFID_SERIAL           0xA0      /*!< address of serial number         */
00066 
00067 // COMMANDS
00068 #define CTRFID_CMD_STOP         0x00      /*!< Stop RFID sensor, will stop reading and
00069                                                put RFID sensor into sleep mode  */
00070 #define CTRFID_CMD_SINGLESHOT   0x01      /*!< Will start a single read action, if any
00071                                                transponder is readable,
00072                                                the data will be read and stored in
00073                                                registers 42h to 46 h. Immediately
00074                                                after reading a transponder or after a
00075                                                max wait time of app. 0,5 seconds the sensor
00076                                                will enter the sleep mode */
00077 #define CTRFID_CMD_CONTINUOUS   0x02      /*!< Continuous read, the sensor will continuously
00078                                                read and store data in registers 42h to 46h!
00079                                                After app. 2 sec. of inactivity on the I2C bus
00080                                                the sensor will enter the sleep mode */
00081 #define CTRFID_CMD_BOOTLOADER   0x81      /*!< Start the bootloader */
00082 #define CTRFID_CMD_STARTAPPFIRM 0x83      /*!< Start the application firmware */
00083 
00084 // ---------------------------- Functions list -----------------------------------
00085 /*!< Functions definition */
00086 // Real RFID functions :
00087 bool CTRFIDinit(tSensors link);
00088 bool CTRFIDsetContinuous(tSensors link);
00089 bool CTRFIDsetSingleShot(tSensors link);
00090 bool CTRFIDreadTransponder (tSensors link, string &transponderID);
00091 
00092 // Internal functions
00093 bool _CTRFIDsendCommand(tSensors link, ubyte command);
00094 bool _CTRFIDsendDummy(tSensors link);
00095 bool _CTRFIDreadStatus(tSensors link, ubyte &_status);
00096 
00097 // ---------------------------- Global variables ---------------------------------
00098 /*!< Global variables */
00099 tByteArray CTRFID_I2CRequest;    /*!< Array to hold I2C command data */
00100 tByteArray CTRFID_I2CReply;      /*!< Array to hold I2C reply data   */
00101 
00102 bool CTRFIDreadContinuous[4] = {false, false, false, false};  /*!< Is the sensor configured for Continuous mode? */
00103 bool CTRFIDinitialised[4] = {false, false, false, false};     /*!< Has the sensor been initialised? */
00104 
00105 
00106 /**
00107  * Send a command to the RFID sensor.
00108  *
00109  * Note: this is an internal function and should not be called directly.
00110  * @param link the CTRFID port number,
00111  * @param command the CTRFID command to be sent to the sensor
00112  * @return true if no error occured, false if it did
00113  */
00114 bool _CTRFIDsendCommand(tSensors link, ubyte command) {
00115   memset(CTRFID_I2CRequest, 0, sizeof(tByteArray)); // init request
00116 
00117   if (!CTRFIDinitialised[link] && (command != CTRFID_CMD_STARTAPPFIRM))
00118     CTRFIDinit(link);
00119 
00120   CTRFID_I2CRequest[0] = 3;                          // Message size
00121   CTRFID_I2CRequest[1] = CTRFID_I2C_ADDR;            // I2C Address of RFID sensor
00122   CTRFID_I2CRequest[2] = CTRFID_OFFSET + CTRFID_CMD; // Address of cmd registry
00123   CTRFID_I2CRequest[3] = command;                    // Mode to set
00124 
00125   return writeI2C(link, CTRFID_I2CRequest);
00126 }
00127 
00128 
00129 /**
00130  * Send a dummy I2C packet to the sensor to wake it up
00131  *
00132  * Note: this is an internal function and should not be called directly.
00133  * @param link the CTRFID port number,
00134  * @return true if no error occured, false if it did
00135  */
00136 bool _CTRFIDsendDummy(tSensors link) {
00137   memset(CTRFID_I2CRequest, 0, sizeof(tByteArray)); // init request
00138 
00139   CTRFID_I2CRequest[0] = 1;                          // Message size
00140   CTRFID_I2CRequest[1] = CTRFID_I2C_ADDR;            // I2C Address of RFID sensor
00141 
00142   return writeI2C(link, CTRFID_I2CRequest);
00143   memset(CTRFID_I2CRequest, 0, sizeof(tByteArray));
00144 }
00145 
00146 /**
00147  * Check if the sensor is in continuous mode.
00148  *
00149  * Note: this is an internal function and should not be called directly.
00150  * @param link the CTRFID port number,
00151  * @param _status the sensor's status (continuous mode : 1, idle : 0),
00152  * @return true if no error occured, false if it did
00153  */
00154 bool _CTRFIDreadStatus(tSensors link, ubyte &_status) {
00155   memset(CTRFID_I2CRequest, 0, sizeof(tByteArray)); // init request
00156 
00157   if(!_CTRFIDsendDummy(link))
00158     return false;
00159 
00160   if (!CTRFIDinitialised[link])
00161     CTRFIDinit(link);
00162 
00163   if (CTRFIDreadContinuous[link])
00164     return true;
00165 
00166   CTRFID_I2CRequest[0] = 2;               // Message size
00167   CTRFID_I2CRequest[1] = CTRFID_I2C_ADDR; // I2C Address
00168   CTRFID_I2CRequest[2] = CTRFID_STATUS;   // Address for sensor's status
00169 
00170   if (!writeI2C(link, CTRFID_I2CRequest, CTRFID_I2CReply, 1))
00171     return false;
00172 
00173   _status = CTRFID_I2CReply[0];
00174 
00175   return true;
00176 }
00177 
00178 
00179 /**
00180  * Configure the sensor for reading transponders
00181  * @param link the CTRFID port number,
00182  * @return true if no error occured, false if it did
00183  */
00184 bool CTRFIDinit(tSensors link) {
00185   if (_CTRFIDsendCommand(link, CTRFID_CMD_STARTAPPFIRM)) {
00186     CTRFIDinitialised[link] = true;
00187     return true;
00188   } else {
00189     return false;
00190   }
00191 }
00192 
00193 
00194 /**
00195  * Configure the sensor for reading transponders
00196  * in continuous mode
00197  * @param link the CTRFID port number,
00198  * @return true if no error occured, false if it did
00199  */
00200 bool CTRFIDsetContinuous(tSensors link) {
00201   if(!_CTRFIDsendDummy(link))
00202     return false;
00203 
00204   if (_CTRFIDsendCommand(link, CTRFID_CMD_CONTINUOUS)) {
00205     CTRFIDreadContinuous[link] = true;
00206     return true;
00207   } else {
00208     return false;
00209   }
00210 }
00211 
00212 
00213 /**
00214  * Configure the sensor for reading transponders
00215  * in single shot mode
00216  * @return true if no error occured, false if it did
00217  */
00218 bool CTRFIDsetSingleShot(tSensors link) {
00219   if(!_CTRFIDsendDummy(link))
00220     return false;
00221 
00222   if (_CTRFIDsendCommand(link, CTRFID_CMD_SINGLESHOT)) {
00223     CTRFIDreadContinuous[link] = false;
00224     return true;
00225   } else {
00226     return false;
00227   }
00228 }
00229 
00230 
00231 /**
00232  * Read transponder ID's bytes. This function needs that a reading mode to be selected before using it.
00233  * @param link the CTRFID port number,
00234  * @param transponderID the read transponder ID,
00235  * @return true if no error occured, false if it did
00236  */
00237 bool CTRFIDreadTransponder(tSensors link, string &transponderID) {
00238   ubyte _status;
00239 
00240   // Always send a dummy packet to make sure the sensor is awake
00241   if(!_CTRFIDsendDummy(link)) {
00242     return false;
00243   }
00244 
00245   if (!CTRFIDinitialised[link]) {
00246     CTRFIDinit(link);
00247     // Wait for the initialisation to be done
00248     wait1Msec(100);
00249   }
00250 
00251   if(CTRFIDreadContinuous[link] == false) {
00252     // the mode has not been set, so set to single shot mode
00253     CTRFIDsetSingleShot(link);
00254 
00255     // Wait for RF setup time.
00256     wait1Msec(250);
00257   } else {
00258     _CTRFIDreadStatus(link, _status);
00259     if (_status == 0) {
00260       CTRFIDsetContinuous(link);
00261       // Wait for RF setup time.
00262       wait1Msec(250);
00263     }
00264   }
00265 
00266   // Retrieve the transponder's address
00267   memset(CTRFID_I2CRequest, 0, sizeof(tByteArray));
00268   CTRFID_I2CRequest[0] = 2;                                        // Message size
00269   CTRFID_I2CRequest[1] = CTRFID_I2C_ADDR;                     // I2C Address of RFID sensor
00270   CTRFID_I2CRequest[2] = CTRFID_OFFSET + CTRFID_BYTE1;   // Address byte1 registry
00271   if (!writeI2C(link, CTRFID_I2CRequest, CTRFID_I2CReply, 5))
00272     return false;
00273 
00274   // formating the value read into a string of 10 chars
00275   // first : clear the current value of TransponderID
00276   // (if not, the next instructions will concatenate as much IDs as read !)
00277   strcpy(transponderID, "");
00278   for (int i=0;i<5;i++) {
00279     // "%02x"  will pad the hex number with a zero to make it two digits long at all times.
00280     StringFormat(transponderID, "%s%02x", transponderID, CTRFID_I2CReply[i]);
00281   }
00282   return true;
00283 }
00284 
00285 #endif // __CODATEX_RFID_driver_H__
00286 
00287 /*
00288  * $Id: codatech-rfid.h 133 2013-03-10 15:15:38Z xander $
00289  */
00290 /* @} */
00291 /* @} */