RFID

Dependents:   RoboticHackathon2 RoboticHackathonFINAL

Files at this revision

API Documentation at this revision

Comitter:
iLyngklip
Date:
Mon Apr 07 06:23:00 2014 +0000
Commit message:
RFID

Changed in this revision

Rfid.cpp Show annotated file Show diff for this revision Revisions of this file
Rfid.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Rfid.cpp	Mon Apr 07 06:23:00 2014 +0000
@@ -0,0 +1,342 @@
+
+/******************************************************************************
+ * Includes
+ ******************************************************************************/
+#include "mbed.h"
+#include "Rfid.h"
+
+/******************************************************************************
+ * User API
+ ******************************************************************************/
+
+#define uchar unsigned char
+/**
+ * Construct RFID
+ * int chipSelectPin RFID /ENABLE pin
+ */
+RFID::RFID() : _rfid(PTD2, PTD3, PTD1), _chipSelectPin(PTD0), _NRSTPD(PTD5) 
+{
+    
+}
+/******************************************************************************
+ * User API
+ ******************************************************************************/
+
+void RFID::check()
+    {
+        
+        uchar status;
+        uchar str[MAX_LEN];
+        status = MFRC522Request(PICC_REQIDL, str); 
+        if (status == MI_OK)
+        {
+            //Prevent conflict, return the 4 bytes Serial number of the card
+            status = anticoll(str);
+            memcpy(serNum, str, 5);
+            if (status == MI_OK){
+            card = (serNum[0]+serNum[1]);
+            }
+            
+        }
+        else {card=0;}
+    }
+        
+/******************************************************************************
+ * Dr.Leong   ( WWW.B2CQSHOP.COM )
+ ******************************************************************************/
+
+void RFID::init()
+{
+    _NRSTPD =1;
+
+    reset();
+        
+    //Timer: TPrescaler*TreloadVal/6.78MHz = 24ms
+    writeMFRC522(TModeReg, 0x8D);       //Tauto=1; f(Timer) = 6.78MHz/TPreScaler
+    writeMFRC522(TPrescalerReg, 0x3E);  //TModeReg[3..0] + TPrescalerReg
+    writeMFRC522(TReloadRegL, 30);           
+    writeMFRC522(TReloadRegH, 0);
+    
+    writeMFRC522(TxAutoReg, 0x40);      //100%ASK
+    writeMFRC522(ModeReg, 0x3D);        // CRC valor inicial de 0x6363
+    writeMFRC522(CommIEnReg, 0x00);     //Enable Rx interupt
+    writeMFRC522(DivlEnReg, 0x08);      //IRQ is standar CMOS output
+    writeMFRC522(CommIrqReg, 0x20);     //IRQ on end of valid data stream
+    writeMFRC522(DivIrqReg, 0x08);
+    //ClearBitMask(Status2Reg, 0x08);   //MFCrypto1On=0
+    //writeMFRC522(RxSelReg, 0x86);     //RxWait = RxSelReg[5..0]
+    //writeMFRC522(RFCfgReg, 0x7F);     //RxGain = 48dB
+
+    antennaOn();        //Abre  la antena
+    
+    
+}
+void RFID::reset()
+{
+    writeMFRC522(CommandReg, PCD_RESETPHASE);
+}
+
+void RFID::writeMFRC522(unsigned char addr, unsigned char val)
+{
+    _chipSelectPin =0;
+
+    //0XXXXXX0 formato de dirección
+    _rfid.write((addr<<1)&0x7E);   
+    _rfid.write(val);
+    
+    _chipSelectPin = 1;
+}
+
+void RFID::antennaOn(void)
+{
+    unsigned char temp;
+
+    temp = readMFRC522(TxControlReg);
+    if (!(temp & 0x03))
+    {
+        setBitMask(TxControlReg, 0x03);
+    }
+}
+
+/*
+ *  Read_MFRC522 Nombre de la función: Read_MFRC522
+ *  Descripción: Desde el MFRC522 leer un byte de un registro de datos
+ *  Los parámetros de entrada: addr - la dirección de registro
+ *  Valor de retorno: Devuelve un byte de datos de lectura
+ */
+unsigned char RFID::readMFRC522(unsigned char addr)
+{
+    unsigned char val;
+    _chipSelectPin =0;
+    _rfid.write(((addr<<1)&0x7E) | 0x80);  
+    val =_rfid.write(0x00);
+    _chipSelectPin =1;
+    return val; 
+}
+
+void RFID::setBitMask(unsigned char reg, unsigned char mask)  
+{ 
+    unsigned char tmp;
+    tmp = readMFRC522(reg);
+    writeMFRC522(reg, tmp | mask);  // set bit mask
+}
+
+void RFID::clearBitMask(unsigned char reg, unsigned char mask)  
+{
+    unsigned char tmp;
+    tmp = readMFRC522(reg);
+    writeMFRC522(reg, tmp & (~mask));  // clear bit mask
+} 
+
+void RFID::calculateCRC(unsigned char *pIndata, unsigned char len, unsigned char *pOutData)
+{
+    unsigned char i, n;
+
+    clearBitMask(DivIrqReg, 0x04);          //CRCIrq = 0
+    setBitMask(FIFOLevelReg, 0x80);         //Claro puntero FIFO
+    //Write_MFRC522(CommandReg, PCD_IDLE);
+
+    //Escribir datos en el FIFO 
+    for (i=0; i<len; i++)
+    {   
+        writeMFRC522(FIFODataReg, *(pIndata+i));   
+    }
+    writeMFRC522(CommandReg, PCD_CALCCRC);
+
+    // Esperar a la finalización de cálculo del CRC
+    i = 0xFF;
+    do 
+    {
+        n = readMFRC522(DivIrqReg);
+        i--;
+    }
+    while ((i!=0) && !(n&0x04));            //CRCIrq = 1
+
+    //Lea el cálculo de CRC
+    pOutData[0] = readMFRC522(CRCResultRegL);
+    pOutData[1] = readMFRC522(CRCResultRegM);
+}
+
+unsigned char RFID::MFRC522ToCard(unsigned char command, unsigned char *sendData, unsigned char sendLen, unsigned char *backData, unsigned int *backLen)
+{
+    unsigned char status = MI_ERR;
+    unsigned char irqEn = 0x00;
+    unsigned char waitIRq = 0x00;
+    unsigned char lastBits;
+    unsigned char n;
+    unsigned int i;
+
+    switch (command)
+    {
+        case PCD_AUTHENT:       // Tarjetas de certificación cerca
+        {
+            irqEn = 0x12;
+            waitIRq = 0x10;
+            break;
+        }
+        case PCD_TRANSCEIVE:    //La transmisión de datos FIFO
+        {
+            irqEn = 0x77;
+            waitIRq = 0x30;
+            break;
+        }
+        default:
+            break;
+    }
+   
+    writeMFRC522(CommIEnReg, irqEn|0x80);   //De solicitud de interrupción
+    clearBitMask(CommIrqReg, 0x80);         // Borrar todos los bits de petición de interrupción
+    setBitMask(FIFOLevelReg, 0x80);         //FlushBuffer=1, FIFO de inicialización
+    
+    writeMFRC522(CommandReg, PCD_IDLE); //NO action;Y cancelar el comando
+
+    //Escribir datos en el FIFO
+    for (i=0; i<sendLen; i++)
+    {   
+        writeMFRC522(FIFODataReg, sendData[i]);    
+    }
+
+    //???? ejecutar el comando
+    writeMFRC522(CommandReg, command);
+    if (command == PCD_TRANSCEIVE)
+    {    
+        setBitMask(BitFramingReg, 0x80);        //StartSend=1,transmission of data starts  
+    }   
+    
+    // A la espera de recibir datos para completar
+    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??
+    do 
+    {
+        //CommIrqReg[7..0]
+        //Set1 TxIRq RxIRq IdleIRq HiAlerIRq LoAlertIRq ErrIRq TimerIRq
+        n = readMFRC522(CommIrqReg);
+        i--;
+    }
+    while ((i!=0) && !(n&0x01) && !(n&waitIRq));
+
+    clearBitMask(BitFramingReg, 0x80);          //StartSend=0
+    
+    if (i != 0)
+    {    
+        if(!(readMFRC522(ErrorReg) & 0x1B)) //BufferOvfl Collerr CRCErr ProtecolErr
+        {
+            status = MI_OK;
+            if (n & irqEn & 0x01)
+            {   
+                status = MI_NOTAGERR;           //??   
+            }
+
+            if (command == PCD_TRANSCEIVE)
+            {
+                n = readMFRC522(FIFOLevelReg);
+                lastBits = readMFRC522(ControlReg) & 0x07;
+                if (lastBits)
+                {   
+                    *backLen = (n-1)*8 + lastBits;   
+                }
+                else
+                {   
+                    *backLen = n*8;   
+                }
+
+                if (n == 0)
+                {   
+                    n = 1;    
+                }
+                if (n > MAX_LEN)
+                {   
+                    n = MAX_LEN;   
+                }
+                
+                //??FIFO??????? Lea los datos recibidos en el FIFO
+                for (i=0; i<n; i++)
+                {   
+                    backData[i] = readMFRC522(FIFODataReg);    
+                }
+            }
+        }
+        else
+        {   
+            status = MI_ERR;  
+        }
+        
+    }
+    
+    //SetBitMask(ControlReg,0x80);           //timer stops
+    //Write_MFRC522(CommandReg, PCD_IDLE); 
+
+    return status;
+}
+
+
+/*
+ *  Nombre de la función: MFRC522_Request
+ *  Descripción: Buscar las cartas, leer el número de tipo de tarjeta
+ *  Los parámetros de entrada: reqMode - encontrar el modo de tarjeta,
+ *             Tagtype - Devuelve el tipo de tarjeta
+ *              0x4400 = Mifare_UltraLight
+ *              0x0400 = Mifare_One(S50)
+ *              0x0200 = Mifare_One(S70)
+ *              0x0800 = Mifare_Pro(X)
+ *              0x4403 = Mifare_DESFire
+ *  Valor de retorno: el retorno exitoso MI_OK
+ */
+unsigned char  RFID::MFRC522Request(unsigned char reqMode, unsigned char *TagType)
+{
+    unsigned char status;  
+    unsigned int backBits;          //   Recibió bits de datos
+
+    writeMFRC522(BitFramingReg, 0x07);      //TxLastBists = BitFramingReg[2..0] ???
+    
+    TagType[0] = reqMode;
+    status = MFRC522ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits);
+
+    if ((status != MI_OK) || (backBits != 0x10))
+    {    
+        status = MI_ERR;
+    }
+   
+    return status;
+}
+
+/**
+ *  MFRC522Anticoll -> anticoll
+ *  Anti-detección de colisiones, la lectura del número de serie de la tarjeta de tarjeta
+ *  @param serNum - devuelve el número de tarjeta 4 bytes de serie, los primeros 5 bytes de bytes de paridad
+ *  @return retorno exitoso MI_OK
+ */
+unsigned char RFID::anticoll(unsigned char *serNum)
+{
+    unsigned char status;
+    unsigned char i;
+    unsigned char serNumCheck=0;
+    unsigned int unLen;
+    
+
+    //ClearBitMask(Status2Reg, 0x08);       //TempSensclear
+    //ClearBitMask(CollReg,0x80);           //ValuesAfterColl
+    writeMFRC522(BitFramingReg, 0x00);      //TxLastBists = BitFramingReg[2..0]
+ 
+    serNum[0] = PICC_ANTICOLL;
+    serNum[1] = 0x20;
+    status = MFRC522ToCard(PCD_TRANSCEIVE, serNum, 2, serNum, &unLen);
+
+    if (status == MI_OK)
+    {
+        //?????? Compruebe el número de serie de la tarjeta
+        for (i=0; i<4; i++)
+        {   
+            serNumCheck ^= serNum[i];
+        }
+        if (serNumCheck != serNum[i])
+        {   
+            status = MI_ERR;    
+        }
+    }
+
+    //SetBitMask(CollReg, 0x80);        //ValuesAfterColl=1
+
+    return status;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Rfid.h	Mon Apr 07 06:23:00 2014 +0000
@@ -0,0 +1,144 @@
+#ifndef RFID_h
+#define RFID_h
+
+#include "mbed.h"
+
+
+
+
+/******************************************************************************
+ * Definitions
+ ******************************************************************************/
+#define MAX_LEN 16   // Largo máximo de la matriz
+#define uchar unsigned char
+//MF522 comando palabra
+#define PCD_IDLE              0x00               // NO action; Y cancelar el comando
+#define PCD_AUTHENT           0x0E               // autenticación de clave
+#define PCD_RECEIVE           0x08               // recepción de datos
+#define PCD_TRANSMIT          0x04               // Enviar datos
+#define PCD_TRANSCEIVE        0x0C               // Enviar y recibir datos
+#define PCD_RESETPHASE        0x0F               // reajustar
+#define PCD_CALCCRC           0x03               // CRC calcular
+
+//Mifare_One  Tarjeta Mifare_One comando palabra
+#define PICC_REQIDL           0x26               // Área de la antena no está tratando de entrar en el estado de reposo
+#define PICC_REQALL           0x52               // Todas las cartas para encontrar el área de la antena
+#define PICC_ANTICOLL         0x93               // anti-colisión
+#define PICC_SElECTTAG        0x93               // elección de tarjeta
+#define PICC_AUTHENT1A        0x60               // verificación key A
+#define PICC_AUTHENT1B        0x61               // verificación Key B
+#define PICC_READ             0x30               // leer bloque
+#define PICC_WRITE            0xA0               // Escribir en el bloque 
+#define PICC_DECREMENT        0xC0               // cargo
+#define PICC_INCREMENT        0xC1               // recargar
+#define PICC_RESTORE          0xC2               // Transferencia de datos de bloque de buffer
+#define PICC_TRANSFER         0xB0               // Guardar los datos en el búfer
+#define PICC_HALT             0x50               // inactividad
+
+//MF522 Código de error de comunicación cuando regresó
+#define MI_OK                 0
+#define MI_NOTAGERR           1
+#define MI_ERR                2
+
+//------------------ MFRC522 registro---------------
+//Page 0:Command and Status
+#define     Reserved00            0x00    
+#define     CommandReg            0x01    
+#define     CommIEnReg            0x02    
+#define     DivlEnReg             0x03    
+#define     CommIrqReg            0x04    
+#define     DivIrqReg             0x05
+#define     ErrorReg              0x06    
+#define     Status1Reg            0x07    
+#define     Status2Reg            0x08    
+#define     FIFODataReg           0x09
+#define     FIFOLevelReg          0x0A
+#define     WaterLevelReg         0x0B
+#define     ControlReg            0x0C
+#define     BitFramingReg         0x0D
+#define     CollReg               0x0E
+#define     Reserved01            0x0F
+//Page 1:Command     
+#define     Reserved10            0x10
+#define     ModeReg               0x11
+#define     TxModeReg             0x12
+#define     RxModeReg             0x13
+#define     TxControlReg          0x14
+#define     TxAutoReg             0x15
+#define     TxSelReg              0x16
+#define     RxSelReg              0x17
+#define     RxThresholdReg        0x18
+#define     DemodReg              0x19
+#define     Reserved11            0x1A
+#define     Reserved12            0x1B
+#define     MifareReg             0x1C
+#define     Reserved13            0x1D
+#define     Reserved14            0x1E
+#define     SerialSpeedReg        0x1F
+//Page 2:CFG    
+#define     Reserved20            0x20  
+#define     CRCResultRegM         0x21
+#define     CRCResultRegL         0x22
+#define     Reserved21            0x23
+#define     ModWidthReg           0x24
+#define     Reserved22            0x25
+#define     RFCfgReg              0x26
+#define     GsNReg                0x27
+#define     CWGsPReg              0x28
+#define     ModGsPReg             0x29
+#define     TModeReg              0x2A
+#define     TPrescalerReg         0x2B
+#define     TReloadRegH           0x2C
+#define     TReloadRegL           0x2D
+#define     TCounterValueRegH     0x2E
+#define     TCounterValueRegL     0x2F
+//Page 3:TestRegister     
+#define     Reserved30            0x30
+#define     TestSel1Reg           0x31
+#define     TestSel2Reg           0x32
+#define     TestPinEnReg          0x33
+#define     TestPinValueReg       0x34
+#define     TestBusReg            0x35
+#define     AutoTestReg           0x36
+#define     VersionReg            0x37
+#define     AnalogTestReg         0x38
+#define     TestDAC1Reg           0x39  
+#define     TestDAC2Reg           0x3A   
+#define     TestADCReg            0x3B   
+#define     Reserved31            0x3C   
+#define     Reserved32            0x3D   
+#define     Reserved33            0x3E   
+#define     Reserved34            0x3F
+//-----------------------------------------------
+
+class RFID
+{
+  public:
+    RFID();
+    
+    
+    void check();
+    void init();
+    void reset();
+    void writeMFRC522(unsigned char addr, unsigned char val);
+    void antennaOn(void);
+    unsigned char readMFRC522(unsigned char addr);
+    void setBitMask(unsigned char reg, unsigned char mask);
+    void clearBitMask(unsigned char reg, unsigned char mask);
+    void calculateCRC(unsigned char *pIndata, unsigned char len, unsigned char *pOutData);
+    unsigned char MFRC522Request(unsigned char reqMode, unsigned char *TagType);
+    unsigned char MFRC522ToCard(unsigned char command, unsigned char *sendData, unsigned char sendLen, unsigned char *backData, unsigned int *backLen);
+    unsigned char anticoll(unsigned char *serNum);
+    
+    
+    int card;
+    unsigned char serNum[5];       // Constante para guardar el numero de serie leido.
+    unsigned char AserNum[5];      // Constante para guardar el numero d serie de la secion actual.
+    
+  private:
+    DigitalOut _chipSelectPin;
+    DigitalOut _NRSTPD;
+    SPI _rfid;
+};
+
+#endif
\ No newline at end of file