RFID
Dependents: RoboticHackathon2 RoboticHackathonFINAL
Revision 0:051708395e3c, committed 2014-04-07
- 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