From c3e9731a7ff1ff43ac320d3ce15bcb05035c31af Mon Sep 17 00:00:00 2001 From: minimal2 Date: Tue, 21 May 2013 16:56:03 +0200 Subject: [PATCH] =?UTF-8?q?Zapomnia=C5=82em=20o=20nag=C5=82=C3=B3wkach...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- arduino/RFID.cpp | 485 +++++++++++++++++++++++++++++++++++++++++++++++ arduino/RFID.h | 151 +++++++++++++++ 2 files changed, 636 insertions(+) create mode 100644 arduino/RFID.cpp create mode 100644 arduino/RFID.h diff --git a/arduino/RFID.cpp b/arduino/RFID.cpp new file mode 100644 index 0000000..84d5e8c --- /dev/null +++ b/arduino/RFID.cpp @@ -0,0 +1,485 @@ +/* + * RFID.cpp - Library to use ARDUINO RFID MODULE KIT 13.56 MHZ WITH TAGS SPI W AND R BY COOQROBOT. + * Based on code Dr.Leong ( WWW.B2CQSHOP.COM ) + * Created by Miguel Balboa, Jan, 2012. + * Released into the public domain. + */ + +/****************************************************************************** + * Includes + ******************************************************************************/ +#include +#include + +/****************************************************************************** + * User API + ******************************************************************************/ + +/** + * Construct RFID + * int chipSelectPin RFID /ENABLE pin + */ +RFID::RFID(int chipSelectPin, int NRSTPD) +{ + _chipSelectPin = chipSelectPin; + + pinMode(_chipSelectPin,OUTPUT); // Set digital as OUTPUT to connect it to the RFID /ENABLE pin + digitalWrite(_chipSelectPin, LOW); + + + pinMode(NRSTPD,OUTPUT); // Set digital pin, Not Reset and Power-down + digitalWrite(NRSTPD, HIGH); + _NRSTPD = NRSTPD; +} +/****************************************************************************** + * User API + ******************************************************************************/ + + bool RFID::isCard() + { + unsigned char status; + unsigned char str[MAX_LEN]; + + status = MFRC522Request(PICC_REQIDL, str); + if (status == MI_OK) { + return true; + } else { + return false; + } + } + + bool RFID::readCardSerial(){ + + unsigned char status; + unsigned char str[MAX_LEN]; + + // Anti-colisión, devuelva el número de serie de tarjeta de 4 bytes + status = anticoll(str); + memcpy(serNum, str, 5); + + if (status == MI_OK) { + return true; + } else { + return false; + } + + } + +/****************************************************************************** + * Dr.Leong ( WWW.B2CQSHOP.COM ) + ******************************************************************************/ + +void RFID::init() +{ + digitalWrite(_NRSTPD,HIGH); + + 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 + + //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) +{ + digitalWrite(_chipSelectPin, LOW); + + //0XXXXXX0 formato de dirección + SPI.transfer((addr<<1)&0x7E); + SPI.transfer(val); + + digitalWrite(_chipSelectPin, HIGH); +} + +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; + digitalWrite(_chipSelectPin, LOW); + SPI.transfer(((addr<<1)&0x7E) | 0x80); + val =SPI.transfer(0x00); + digitalWrite(_chipSelectPin, HIGH); + 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 MAX_LEN) + { + n = MAX_LEN; + } + + //??FIFO??????? Lea los datos recibidos en el FIFO + for (i=0; i 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; +} + +/* + * MFRC522Auth -> auth + * Verificar la contraseña de la tarjeta + * Los parámetros de entrada: AuthMode - Modo de autenticación de contraseña + 0x60 = A 0x60 = validación KeyA + 0x61 = B 0x61 = validación KeyB + BlockAddr-- bloque de direcciones + Sectorkey-- sector contraseña + serNum--,4? Tarjeta de número de serie, 4 bytes + * MI_OK Valor de retorno: el retorno exitoso MI_OK + */ +unsigned char RFID::auth(unsigned char authMode, unsigned char BlockAddr, unsigned char *Sectorkey, unsigned char *serNum) +{ + unsigned char status; + unsigned int recvBits; + unsigned char i; + unsigned char buff[12]; + + //????+???+????+???? Verifique la dirección de comandos de bloques del sector + + contraseña + número de la tarjeta de serie + buff[0] = authMode; + buff[1] = BlockAddr; + for (i=0; i<6; i++) + { + buff[i+2] = *(Sectorkey+i); + } + for (i=0; i<4; i++) + { + buff[i+8] = *(serNum+i); + } + status = MFRC522ToCard(PCD_AUTHENT, buff, 12, buff, &recvBits); + + if ((status != MI_OK) || (!(readMFRC522(Status2Reg) & 0x08))) + { + status = MI_ERR; + } + + return status; +} + +/* + * MFRC522Read -> read + * Lectura de datos de bloque + * Los parámetros de entrada: blockAddr - dirección del bloque; recvData - leer un bloque de datos + * MI_OK Valor de retorno: el retorno exitoso MI_OK + */ +unsigned char RFID::read(unsigned char blockAddr, unsigned char *recvData) +{ + unsigned char status; + unsigned int unLen; + + recvData[0] = PICC_READ; + recvData[1] = blockAddr; + calculateCRC(recvData,2, &recvData[2]); + status = MFRC522ToCard(PCD_TRANSCEIVE, recvData, 4, recvData, &unLen); + + if ((status != MI_OK) || (unLen != 0x90)) + { + status = MI_ERR; + } + + return status; +} + +/* + * MFRC522Write -> write + * La escritura de datos de bloque + * blockAddr - dirección del bloque; WriteData - para escribir 16 bytes del bloque de datos + * Valor de retorno: el retorno exitoso MI_OK + */ +unsigned char RFID::write(unsigned char blockAddr, unsigned char *writeData) +{ + unsigned char status; + unsigned int recvBits; + unsigned char i; + unsigned char buff[18]; + + buff[0] = PICC_WRITE; + buff[1] = blockAddr; + calculateCRC(buff, 2, &buff[2]); + status = MFRC522ToCard(PCD_TRANSCEIVE, buff, 4, buff, &recvBits); + + if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A)) + { + status = MI_ERR; + } + + if (status == MI_OK) + { + for (i=0; i<16; i++) //?FIFO?16Byte?? Datos a la FIFO 16Byte escribir + { + buff[i] = *(writeData+i); + } + calculateCRC(buff, 16, &buff[16]); + status = MFRC522ToCard(PCD_TRANSCEIVE, buff, 18, buff, &recvBits); + + if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A)) + { + status = MI_ERR; + } + } + + return status; +} + + +/* + * MFRC522Halt -> halt + * Cartas de Mando para dormir + * Los parámetros de entrada: Ninguno + * Valor devuelto: Ninguno + */ +void RFID::halt() +{ + unsigned char status; + unsigned int unLen; + unsigned char buff[4]; + + buff[0] = PICC_HALT; + buff[1] = 0; + calculateCRC(buff, 2, &buff[2]); + + status = MFRC522ToCard(PCD_TRANSCEIVE, buff, 4, buff,&unLen); +} \ No newline at end of file diff --git a/arduino/RFID.h b/arduino/RFID.h new file mode 100644 index 0000000..a30ac32 --- /dev/null +++ b/arduino/RFID.h @@ -0,0 +1,151 @@ +/* RFID.h - Library to use ARDUINO RFID MODULE KIT 13.56 MHZ WITH TAGS SPI W AND R BY COOQROBOT. + * Based on code Dr.Leong ( WWW.B2CQSHOP.COM ) + * Created by Miguel Balboa (circuitito.com), Jan, 2012. + */ +#ifndef RFID_h +#define RFID_h + +#include +#include + + + +/****************************************************************************** + * Definitions + ******************************************************************************/ +#define MAX_LEN 16 // Largo máximo de la matriz + +//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(int chipSelectPin, int NRSTPD); + + bool isCard(); + bool readCardSerial(); + + 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); + unsigned char auth(unsigned char authMode, unsigned char BlockAddr, unsigned char *Sectorkey, unsigned char *serNum); + unsigned char read(unsigned char blockAddr, unsigned char *recvData); + unsigned char write(unsigned char blockAddr, unsigned char *writeData); + void halt(); + + 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: + int _chipSelectPin; + int _NRSTPD; + +}; + +#endif \ No newline at end of file