RFID
Dependents: RoboticHackathon2 RoboticHackathonFINAL
Rfid.cpp
- Committer:
- iLyngklip
- Date:
- 2014-04-07
- Revision:
- 0:051708395e3c
File content as of revision 0:051708395e3c:
/****************************************************************************** * 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; }