Mathias Lyngklip / Rfid

Dependents:   RoboticHackathon2 RoboticHackathonFINAL

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Rfid.cpp Source File

Rfid.cpp

00001 
00002 /******************************************************************************
00003  * Includes
00004  ******************************************************************************/
00005 #include "mbed.h"
00006 #include "Rfid.h"
00007 
00008 /******************************************************************************
00009  * User API
00010  ******************************************************************************/
00011 
00012 #define uchar unsigned char
00013 /**
00014  * Construct RFID
00015  * int chipSelectPin RFID /ENABLE pin
00016  */
00017 RFID::RFID() : _rfid(PTD2, PTD3, PTD1), _chipSelectPin(PTD0), _NRSTPD(PTD5) 
00018 {
00019     
00020 }
00021 /******************************************************************************
00022  * User API
00023  ******************************************************************************/
00024 
00025 void RFID::check()
00026     {
00027         
00028         uchar status;
00029         uchar str[MAX_LEN];
00030         status = MFRC522Request(PICC_REQIDL, str); 
00031         if (status == MI_OK)
00032         {
00033             //Prevent conflict, return the 4 bytes Serial number of the card
00034             status = anticoll(str);
00035             memcpy(serNum, str, 5);
00036             if (status == MI_OK){
00037             card = (serNum[0]+serNum[1]);
00038             }
00039             
00040         }
00041         else {card=0;}
00042     }
00043         
00044 /******************************************************************************
00045  * Dr.Leong   ( WWW.B2CQSHOP.COM )
00046  ******************************************************************************/
00047 
00048 void RFID::init()
00049 {
00050     _NRSTPD =1;
00051 
00052     reset();
00053         
00054     //Timer: TPrescaler*TreloadVal/6.78MHz = 24ms
00055     writeMFRC522(TModeReg, 0x8D);       //Tauto=1; f(Timer) = 6.78MHz/TPreScaler
00056     writeMFRC522(TPrescalerReg, 0x3E);  //TModeReg[3..0] + TPrescalerReg
00057     writeMFRC522(TReloadRegL, 30);           
00058     writeMFRC522(TReloadRegH, 0);
00059     
00060     writeMFRC522(TxAutoReg, 0x40);      //100%ASK
00061     writeMFRC522(ModeReg, 0x3D);        // CRC valor inicial de 0x6363
00062     writeMFRC522(CommIEnReg, 0x00);     //Enable Rx interupt
00063     writeMFRC522(DivlEnReg, 0x08);      //IRQ is standar CMOS output
00064     writeMFRC522(CommIrqReg, 0x20);     //IRQ on end of valid data stream
00065     writeMFRC522(DivIrqReg, 0x08);
00066     //ClearBitMask(Status2Reg, 0x08);   //MFCrypto1On=0
00067     //writeMFRC522(RxSelReg, 0x86);     //RxWait = RxSelReg[5..0]
00068     //writeMFRC522(RFCfgReg, 0x7F);     //RxGain = 48dB
00069 
00070     antennaOn();        //Abre  la antena
00071     
00072     
00073 }
00074 void RFID::reset()
00075 {
00076     writeMFRC522(CommandReg, PCD_RESETPHASE);
00077 }
00078 
00079 void RFID::writeMFRC522(unsigned char addr, unsigned char val)
00080 {
00081     _chipSelectPin =0;
00082 
00083     //0XXXXXX0 formato de dirección
00084     _rfid.write((addr<<1)&0x7E);   
00085     _rfid.write(val);
00086     
00087     _chipSelectPin = 1;
00088 }
00089 
00090 void RFID::antennaOn(void)
00091 {
00092     unsigned char temp;
00093 
00094     temp = readMFRC522(TxControlReg);
00095     if (!(temp & 0x03))
00096     {
00097         setBitMask(TxControlReg, 0x03);
00098     }
00099 }
00100 
00101 /*
00102  *  Read_MFRC522 Nombre de la función: Read_MFRC522
00103  *  Descripción: Desde el MFRC522 leer un byte de un registro de datos
00104  *  Los parámetros de entrada: addr - la dirección de registro
00105  *  Valor de retorno: Devuelve un byte de datos de lectura
00106  */
00107 unsigned char RFID::readMFRC522(unsigned char addr)
00108 {
00109     unsigned char val;
00110     _chipSelectPin =0;
00111     _rfid.write(((addr<<1)&0x7E) | 0x80);  
00112     val =_rfid.write(0x00);
00113     _chipSelectPin =1;
00114     return val; 
00115 }
00116 
00117 void RFID::setBitMask(unsigned char reg, unsigned char mask)  
00118 { 
00119     unsigned char tmp;
00120     tmp = readMFRC522(reg);
00121     writeMFRC522(reg, tmp | mask);  // set bit mask
00122 }
00123 
00124 void RFID::clearBitMask(unsigned char reg, unsigned char mask)  
00125 {
00126     unsigned char tmp;
00127     tmp = readMFRC522(reg);
00128     writeMFRC522(reg, tmp & (~mask));  // clear bit mask
00129 } 
00130 
00131 void RFID::calculateCRC(unsigned char *pIndata, unsigned char len, unsigned char *pOutData)
00132 {
00133     unsigned char i, n;
00134 
00135     clearBitMask(DivIrqReg, 0x04);          //CRCIrq = 0
00136     setBitMask(FIFOLevelReg, 0x80);         //Claro puntero FIFO
00137     //Write_MFRC522(CommandReg, PCD_IDLE);
00138 
00139     //Escribir datos en el FIFO 
00140     for (i=0; i<len; i++)
00141     {   
00142         writeMFRC522(FIFODataReg, *(pIndata+i));   
00143     }
00144     writeMFRC522(CommandReg, PCD_CALCCRC);
00145 
00146     // Esperar a la finalización de cálculo del CRC
00147     i = 0xFF;
00148     do 
00149     {
00150         n = readMFRC522(DivIrqReg);
00151         i--;
00152     }
00153     while ((i!=0) && !(n&0x04));            //CRCIrq = 1
00154 
00155     //Lea el cálculo de CRC
00156     pOutData[0] = readMFRC522(CRCResultRegL);
00157     pOutData[1] = readMFRC522(CRCResultRegM);
00158 }
00159 
00160 unsigned char RFID::MFRC522ToCard(unsigned char command, unsigned char *sendData, unsigned char sendLen, unsigned char *backData, unsigned int *backLen)
00161 {
00162     unsigned char status = MI_ERR;
00163     unsigned char irqEn = 0x00;
00164     unsigned char waitIRq = 0x00;
00165     unsigned char lastBits;
00166     unsigned char n;
00167     unsigned int i;
00168 
00169     switch (command)
00170     {
00171         case PCD_AUTHENT:       // Tarjetas de certificación cerca
00172         {
00173             irqEn = 0x12;
00174             waitIRq = 0x10;
00175             break;
00176         }
00177         case PCD_TRANSCEIVE:    //La transmisión de datos FIFO
00178         {
00179             irqEn = 0x77;
00180             waitIRq = 0x30;
00181             break;
00182         }
00183         default:
00184             break;
00185     }
00186    
00187     writeMFRC522(CommIEnReg, irqEn|0x80);   //De solicitud de interrupción
00188     clearBitMask(CommIrqReg, 0x80);         // Borrar todos los bits de petición de interrupción
00189     setBitMask(FIFOLevelReg, 0x80);         //FlushBuffer=1, FIFO de inicialización
00190     
00191     writeMFRC522(CommandReg, PCD_IDLE); //NO action;Y cancelar el comando
00192 
00193     //Escribir datos en el FIFO
00194     for (i=0; i<sendLen; i++)
00195     {   
00196         writeMFRC522(FIFODataReg, sendData[i]);    
00197     }
00198 
00199     //???? ejecutar el comando
00200     writeMFRC522(CommandReg, command);
00201     if (command == PCD_TRANSCEIVE)
00202     {    
00203         setBitMask(BitFramingReg, 0x80);        //StartSend=1,transmission of data starts  
00204     }   
00205     
00206     // A la espera de recibir datos para completar
00207     i = 2000;   //i????????,??M1???????25ms ??? i De acuerdo con el ajuste de frecuencia de reloj, el tiempo máximo de espera operación M1 25ms tarjeta??
00208     do 
00209     {
00210         //CommIrqReg[7..0]
00211         //Set1 TxIRq RxIRq IdleIRq HiAlerIRq LoAlertIRq ErrIRq TimerIRq
00212         n = readMFRC522(CommIrqReg);
00213         i--;
00214     }
00215     while ((i!=0) && !(n&0x01) && !(n&waitIRq));
00216 
00217     clearBitMask(BitFramingReg, 0x80);          //StartSend=0
00218     
00219     if (i != 0)
00220     {    
00221         if(!(readMFRC522(ErrorReg) & 0x1B)) //BufferOvfl Collerr CRCErr ProtecolErr
00222         {
00223             status = MI_OK;
00224             if (n & irqEn & 0x01)
00225             {   
00226                 status = MI_NOTAGERR;           //??   
00227             }
00228 
00229             if (command == PCD_TRANSCEIVE)
00230             {
00231                 n = readMFRC522(FIFOLevelReg);
00232                 lastBits = readMFRC522(ControlReg) & 0x07;
00233                 if (lastBits)
00234                 {   
00235                     *backLen = (n-1)*8 + lastBits;   
00236                 }
00237                 else
00238                 {   
00239                     *backLen = n*8;   
00240                 }
00241 
00242                 if (n == 0)
00243                 {   
00244                     n = 1;    
00245                 }
00246                 if (n > MAX_LEN)
00247                 {   
00248                     n = MAX_LEN;   
00249                 }
00250                 
00251                 //??FIFO??????? Lea los datos recibidos en el FIFO
00252                 for (i=0; i<n; i++)
00253                 {   
00254                     backData[i] = readMFRC522(FIFODataReg);    
00255                 }
00256             }
00257         }
00258         else
00259         {   
00260             status = MI_ERR;  
00261         }
00262         
00263     }
00264     
00265     //SetBitMask(ControlReg,0x80);           //timer stops
00266     //Write_MFRC522(CommandReg, PCD_IDLE); 
00267 
00268     return status;
00269 }
00270 
00271 
00272 /*
00273  *  Nombre de la función: MFRC522_Request
00274  *  Descripción: Buscar las cartas, leer el número de tipo de tarjeta
00275  *  Los parámetros de entrada: reqMode - encontrar el modo de tarjeta,
00276  *             Tagtype - Devuelve el tipo de tarjeta
00277  *              0x4400 = Mifare_UltraLight
00278  *              0x0400 = Mifare_One(S50)
00279  *              0x0200 = Mifare_One(S70)
00280  *              0x0800 = Mifare_Pro(X)
00281  *              0x4403 = Mifare_DESFire
00282  *  Valor de retorno: el retorno exitoso MI_OK
00283  */
00284 unsigned char  RFID::MFRC522Request(unsigned char reqMode, unsigned char *TagType)
00285 {
00286     unsigned char status;  
00287     unsigned int backBits;          //   Recibió bits de datos
00288 
00289     writeMFRC522(BitFramingReg, 0x07);      //TxLastBists = BitFramingReg[2..0] ???
00290     
00291     TagType[0] = reqMode;
00292     status = MFRC522ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits);
00293 
00294     if ((status != MI_OK) || (backBits != 0x10))
00295     {    
00296         status = MI_ERR;
00297     }
00298    
00299     return status;
00300 }
00301 
00302 /**
00303  *  MFRC522Anticoll -> anticoll
00304  *  Anti-detección de colisiones, la lectura del número de serie de la tarjeta de tarjeta
00305  *  @param serNum - devuelve el número de tarjeta 4 bytes de serie, los primeros 5 bytes de bytes de paridad
00306  *  @return retorno exitoso MI_OK
00307  */
00308 unsigned char RFID::anticoll(unsigned char *serNum)
00309 {
00310     unsigned char status;
00311     unsigned char i;
00312     unsigned char serNumCheck=0;
00313     unsigned int unLen;
00314     
00315 
00316     //ClearBitMask(Status2Reg, 0x08);       //TempSensclear
00317     //ClearBitMask(CollReg,0x80);           //ValuesAfterColl
00318     writeMFRC522(BitFramingReg, 0x00);      //TxLastBists = BitFramingReg[2..0]
00319  
00320     serNum[0] = PICC_ANTICOLL;
00321     serNum[1] = 0x20;
00322     status = MFRC522ToCard(PCD_TRANSCEIVE, serNum, 2, serNum, &unLen);
00323 
00324     if (status == MI_OK)
00325     {
00326         //?????? Compruebe el número de serie de la tarjeta
00327         for (i=0; i<4; i++)
00328         {   
00329             serNumCheck ^= serNum[i];
00330         }
00331         if (serNumCheck != serNum[i])
00332         {   
00333             status = MI_ERR;    
00334         }
00335     }
00336 
00337     //SetBitMask(CollReg, 0x80);        //ValuesAfterColl=1
00338 
00339     return status;
00340 }
00341 
00342