123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- // Mifare RC522 RFID Card reader 13.56 MHz
- // MFRC522 STM32F103 DESCRIPTION
- // CS (SDA) PB0 SPI1_NSS Chip select for SPI
- // SCK PA5 SPI1_SCK Serial Clock for SPI
- // MOSI PA7 SPI1_MOSI Master In Slave Out for SPI
- // MISO PA6 SPI1_MISO Master Out Slave In for SPI
- // IRQ - Irq
- // GND GND Ground
- // RST 3.3V Reset pin (3.3V)
- // VCC 3.3V 3.3V power
- #include "RC522.h"
- /******template******/
- // 0-255数字转换为字符 0xFF--"FF"
- void char_to_hex(uint8_t data, uint8_t *retStr) {
- uint8_t digits[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
-
- if (data < 16) {
- retStr[0] = '0';
- retStr[1] = digits[data];
- } else {
- retStr[0] = digits[(data & 0xF0)>>4];
- retStr[1] = digits[(data & 0x0F)];
- }
- }
- /**
- * @brief 扫描RFID卡
- * @param cardID 四字节数组
- * @retval 0扫描到RFID卡
- */
- uint8_t RC522_cardScan(uint8_t *cardID)
- {
- if(!MFRC522_Request(PICC_REQIDL, cardID)) {
- if(!MFRC522_Anticoll(cardID)) {
-
- #ifdef DEBUG_printf
- uint8_t cardIDString[8] = {0};
- for(uint8_t i = 0; i < 4; i++) {
- char_to_hex(cardID[i], cardIDString+i*2);
- }
- printf("card id:%s\n", cardIDString);
- #endif
- return 0;
- }
- }
- return 1;
- }
- /********************/
- void SPI1_WriteReg(uint8_t address, uint8_t value) {
- cs_reset();
- SPISendByte(address);
- SPISendByte(value);
- cs_set();
- }
- uint8_t SPI1_ReadReg(uint8_t address) {
- uint8_t val;
- cs_reset();
- SPISendByte(address);
- val = SPISendByte(0x00);
- cs_set();
- return val;
- }
- void MFRC522_WriteRegister(uint8_t addr, uint8_t val) {
- addr = (addr << 1) & 0x7E; // Address format: 0XXXXXX0
- SPI1_WriteReg(addr, val);
- }
- uint8_t MFRC522_ReadRegister(uint8_t addr) {
- uint8_t val;
- addr = ((addr << 1) & 0x7E) | 0x80;
- val = SPI1_ReadReg(addr);
- return val;
- }
- uint8_t MFRC522_Check(uint8_t* id) {
- uint8_t status;
- status = MFRC522_Request(PICC_REQIDL, id); // Find cards, return card type
- if (status == MI_OK) status = MFRC522_Anticoll(id); // Card detected. Anti-collision, return card serial number 4 bytes
- MFRC522_Halt(); // Command card into hibernation
- return status;
- }
- uint8_t MFRC522_Compare(uint8_t* CardID, uint8_t* CompareID) {
- uint8_t i;
- for (i = 0; i < 5; i++) {
- if (CardID[i] != CompareID[i]) return MI_ERR;
- }
- return MI_OK;
- }
- void MFRC522_SetBitMask(uint8_t reg, uint8_t mask) {
- MFRC522_WriteRegister(reg, MFRC522_ReadRegister(reg) | mask);
- }
- void MFRC522_ClearBitMask(uint8_t reg, uint8_t mask){
- MFRC522_WriteRegister(reg, MFRC522_ReadRegister(reg) & (~mask));
- }
- uint8_t MFRC522_Request(uint8_t reqMode, uint8_t* TagType) {
- uint8_t status;
- uint16_t backBits; // The received data bits
- MFRC522_WriteRegister(MFRC522_REG_BIT_FRAMING, 0x07); // TxLastBists = BitFramingReg[2..0]
- TagType[0] = reqMode;
- status = MFRC522_ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits);
- if ((status != MI_OK) || (backBits != 0x10)) status = MI_ERR;
- return status;
- }
- uint8_t MFRC522_ToCard(uint8_t command, uint8_t* sendData, uint8_t sendLen, uint8_t* backData, uint16_t* backLen) {
- uint8_t status = MI_ERR;
- uint8_t irqEn = 0x00;
- uint8_t waitIRq = 0x00;
- uint8_t lastBits;
- uint8_t n;
- uint16_t i;
- switch (command) {
- case PCD_AUTHENT: {
- irqEn = 0x12;
- waitIRq = 0x10;
- break;
- }
- case PCD_TRANSCEIVE: {
- irqEn = 0x77;
- waitIRq = 0x30;
- break;
- }
- default:
- break;
- }
- MFRC522_WriteRegister(MFRC522_REG_COMM_IE_N, irqEn | 0x80);
- MFRC522_ClearBitMask(MFRC522_REG_COMM_IRQ, 0x80);
- MFRC522_SetBitMask(MFRC522_REG_FIFO_LEVEL, 0x80);
- MFRC522_WriteRegister(MFRC522_REG_COMMAND, PCD_IDLE);
- // Writing data to the FIFO
- for (i = 0; i < sendLen; i++) MFRC522_WriteRegister(MFRC522_REG_FIFO_DATA, sendData[i]);
- // Execute the command
- MFRC522_WriteRegister(MFRC522_REG_COMMAND, command);
- if (command == PCD_TRANSCEIVE) MFRC522_SetBitMask(MFRC522_REG_BIT_FRAMING, 0x80); // StartSend=1,transmission of data starts
- // Waiting to receive data to complete
- i = 2000; // i according to the clock frequency adjustment, the operator M1 card maximum waiting time 25ms
- do {
- // CommIrqReg[7..0]
- // Set1 TxIRq RxIRq IdleIRq HiAlerIRq LoAlertIRq ErrIRq TimerIRq
- n = MFRC522_ReadRegister(MFRC522_REG_COMM_IRQ);
- i--;
- } while ((i!=0) && !(n&0x01) && !(n&waitIRq));
- MFRC522_ClearBitMask(MFRC522_REG_BIT_FRAMING, 0x80); // StartSend=0
- if (i != 0) {
- if (!(MFRC522_ReadRegister(MFRC522_REG_ERROR) & 0x1B)) {
- status = MI_OK;
- if (n & irqEn & 0x01) status = MI_NOTAGERR;
- if (command == PCD_TRANSCEIVE) {
- n = MFRC522_ReadRegister(MFRC522_REG_FIFO_LEVEL);
- lastBits = MFRC522_ReadRegister(MFRC522_REG_CONTROL) & 0x07;
- if (lastBits) *backLen = (n-1)*8+lastBits; else *backLen = n*8;
- if (n == 0) n = 1;
- if (n > MFRC522_MAX_LEN) n = MFRC522_MAX_LEN;
- for (i = 0; i < n; i++) backData[i] = MFRC522_ReadRegister(MFRC522_REG_FIFO_DATA); // Reading the received data in FIFO
- }
- } else status = MI_ERR;
- }
- return status;
- }
- uint8_t MFRC522_Anticoll(uint8_t* serNum) {
- uint8_t status;
- uint8_t i;
- uint8_t serNumCheck = 0;
- uint16_t unLen;
- MFRC522_WriteRegister(MFRC522_REG_BIT_FRAMING, 0x00); // TxLastBists = BitFramingReg[2..0]
- serNum[0] = PICC_ANTICOLL;
- serNum[1] = 0x20;
- status = MFRC522_ToCard(PCD_TRANSCEIVE, serNum, 2, serNum, &unLen);
- if (status == MI_OK) {
- // Check card serial number
- for (i = 0; i < 4; i++) serNumCheck ^= serNum[i];
- if (serNumCheck != serNum[i]) status = MI_ERR;
- }
- return status;
- }
- void MFRC522_CalculateCRC(uint8_t* pIndata, uint8_t len, uint8_t* pOutData) {
- uint8_t i, n;
- MFRC522_ClearBitMask(MFRC522_REG_DIV_IRQ, 0x04); // CRCIrq = 0
- MFRC522_SetBitMask(MFRC522_REG_FIFO_LEVEL, 0x80); // Clear the FIFO pointer
- // Write_MFRC522(CommandReg, PCD_IDLE);
- // Writing data to the FIFO
- for (i = 0; i < len; i++) MFRC522_WriteRegister(MFRC522_REG_FIFO_DATA, *(pIndata+i));
- MFRC522_WriteRegister(MFRC522_REG_COMMAND, PCD_CALCCRC);
- // Wait CRC calculation is complete
- i = 0xFF;
- do {
- n = MFRC522_ReadRegister(MFRC522_REG_DIV_IRQ);
- i--;
- } while ((i!=0) && !(n&0x04)); // CRCIrq = 1
- // Read CRC calculation result
- pOutData[0] = MFRC522_ReadRegister(MFRC522_REG_CRC_RESULT_L);
- pOutData[1] = MFRC522_ReadRegister(MFRC522_REG_CRC_RESULT_M);
- }
- uint8_t MFRC522_SelectTag(uint8_t* serNum) {
- uint8_t i;
- uint8_t status;
- uint8_t size;
- uint16_t recvBits;
- uint8_t buffer[9];
- buffer[0] = PICC_SElECTTAG;
- buffer[1] = 0x70;
- for (i = 0; i < 5; i++) buffer[i+2] = *(serNum+i);
- MFRC522_CalculateCRC(buffer, 7, &buffer[7]); //??
- status = MFRC522_ToCard(PCD_TRANSCEIVE, buffer, 9, buffer, &recvBits);
- if ((status == MI_OK) && (recvBits == 0x18)) size = buffer[0]; else size = 0;
- return size;
- }
- uint8_t MFRC522_Auth(uint8_t authMode, uint8_t BlockAddr, uint8_t* Sectorkey, uint8_t* serNum) {
- uint8_t status;
- uint16_t recvBits;
- uint8_t i;
- uint8_t buff[12];
- // Verify the command block address + sector + password + card serial number
- 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 = MFRC522_ToCard(PCD_AUTHENT, buff, 12, buff, &recvBits);
- if ((status != MI_OK) || (!(MFRC522_ReadRegister(MFRC522_REG_STATUS2) & 0x08))) status = MI_ERR;
- return status;
- }
- uint8_t MFRC522_Read(uint8_t blockAddr, uint8_t* recvData) {
- uint8_t status;
- uint16_t unLen;
- recvData[0] = PICC_READ;
- recvData[1] = blockAddr;
- MFRC522_CalculateCRC(recvData,2, &recvData[2]);
- status = MFRC522_ToCard(PCD_TRANSCEIVE, recvData, 4, recvData, &unLen);
- if ((status != MI_OK) || (unLen != 0x90)) status = MI_ERR;
- return status;
- }
- uint8_t MFRC522_Write(uint8_t blockAddr, uint8_t* writeData) {
- uint8_t status;
- uint16_t recvBits;
- uint8_t i;
- uint8_t buff[18];
- buff[0] = PICC_WRITE;
- buff[1] = blockAddr;
- MFRC522_CalculateCRC(buff, 2, &buff[2]);
- status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 4, buff, &recvBits);
- if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A)) status = MI_ERR;
- if (status == MI_OK) {
- // Data to the FIFO write 16Byte
- for (i = 0; i < 16; i++) buff[i] = *(writeData+i);
- MFRC522_CalculateCRC(buff, 16, &buff[16]);
- status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 18, buff, &recvBits);
- if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A)) status = MI_ERR;
- }
- return status;
- }
- void MFRC522_Init(void) {
- MFRC522_Reset();
- MFRC522_WriteRegister(MFRC522_REG_T_MODE, 0x8D);
- MFRC522_WriteRegister(MFRC522_REG_T_PRESCALER, 0x3E);
- MFRC522_WriteRegister(MFRC522_REG_T_RELOAD_L, 30);
- MFRC522_WriteRegister(MFRC522_REG_T_RELOAD_H, 0);
- MFRC522_WriteRegister(MFRC522_REG_RF_CFG, 0x70); // 48dB gain
- MFRC522_WriteRegister(MFRC522_REG_TX_AUTO, 0x40);
- MFRC522_WriteRegister(MFRC522_REG_MODE, 0x3D);
- MFRC522_AntennaOn(); // Open the antenna
- }
- void MFRC522_Reset(void) {
- MFRC522_WriteRegister(MFRC522_REG_COMMAND, PCD_RESETPHASE);
- }
- void MFRC522_AntennaOn(void) {
- uint8_t temp;
- temp = MFRC522_ReadRegister(MFRC522_REG_TX_CONTROL);
- if (!(temp & 0x03)) MFRC522_SetBitMask(MFRC522_REG_TX_CONTROL, 0x03);
- }
- void MFRC522_AntennaOff(void) {
- MFRC522_ClearBitMask(MFRC522_REG_TX_CONTROL, 0x03);
- }
- void MFRC522_Halt(void) {
- uint16_t unLen;
- uint8_t buff[4];
- buff[0] = PICC_HALT;
- buff[1] = 0;
- MFRC522_CalculateCRC(buff, 2, &buff[2]);
- MFRC522_ToCard(PCD_TRANSCEIVE, buff, 4, buff, &unLen);
- }
|