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

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