Tool/software: Code Composer Studio
Hello again, guys. Digging the web I found a library to allow easy use of MFRC552, but it was written in C++, but I use C, so I tried to port to C, but there is an issue: I can't authenticate my cards/tags. The code below is able to retrieve card/tag ID, but every time I try to authenticate to read or write a block, it fails and I guess it is some problem with porting code from C++ to C. I tried several changes in MFRC552_Auth function but nothing worked.
main.c
#include <stdint.h> #include <stdbool.h> #include <string.h> #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "driverlib/gpio.h" #include "driverlib/pin_map.h" #include "driverlib/sysctl.h" #include "driverlib/uart.h" #include "driverlib/ssi.h" #include "driverlib/timer.h" #include "driverlib/rom_map.h" #include "driverlib/interrupt.h" #include "utils/uartstdio.h" #include "MFRC522.h" /*PIN Connections: * Used SSI2 (Module 2) * * To use another Module or Reset Pin, the variables... * ...NRSTPD and chipSelectPin should be changed to the Pin Mask. * * Also, in MFRC552_cpp, the definitions of CHIPSELECT_BASE,... * ...NRSTPD_BASE and SSI_BASE must be changed to the respective... * ...Port Base used. * * Finally, the respective chipSelectPin and NRSTPD... * ... GPIO Base and Pin should be enabled in InitSSI function. * * * Further versions should auto-change this values. * * * SDA / CS / FSS ------------ PB5 * SCK / CLK ------------ PB4 * MOSI / TX ------------ PB7 * MISO / RX ------------ PB6 * * RST ------------ PF0 * * */ #define redLED 0x00000002 #define blueLED 0x00000004 #define greenLED 0x00000008 void initLeds(); void dumpHex(unsigned char* buffer, int len); uint8_t Version; uint8_t AntennaGain; uint8_t status; uint32_t readTeste; unsigned char str[MAX_LEN]; unsigned char cardID[CARD_LENGTH]; unsigned char RxData[MAX_LEN]; unsigned char TxData[MAX_LEN]; void InitConsole(void) { SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); GPIOPinConfigure(GPIO_PA0_U0RX); GPIOPinConfigure(GPIO_PA1_U0TX); SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC); GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); UARTStdioConfig(0, 115200, 16000000); } void InitSSI(){ uint32_t junkAuxVar; SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI2); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); //SDA SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); //reset GPIOPinConfigure(GPIO_PB4_SSI2CLK); //GPIOPinConfigure(GPIO_PB5_SSI2FSS); GPIOPinConfigure(GPIO_PB6_SSI2RX); GPIOPinConfigure(GPIO_PB7_SSI2TX); GPIOPinTypeSSI(GPIO_PORTB_BASE, GPIO_PIN_4 | GPIO_PIN_6 | GPIO_PIN_7); GPIOPinTypeGPIOOutput(CHIP_SELECT_BASE, CHIP_SELECT_PIN); //chipSelectPin GPIOPinTypeGPIOOutput(NRSTPD_BASE, NRSTPD_PIN); //NRSTPD SSIConfigSetExpClk(SSI2_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 4000000, 8); SSIEnable(SSI2_BASE); while(SSIDataGetNonBlocking(SSI2_BASE, &junkAuxVar)); UARTprintf("SSI Enabled! SPI Mode! \nData: 8bits.\n\n"); } int main(void) { SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); //80MHz InitConsole(); initLeds(); InitSSI(); unsigned char key[6], i; for (i = 0; i < 6; i++) key[i] = 0xFF; GPIOPinWrite(CHIP_SELECT_BASE, CHIP_SELECT_PIN, 0); GPIOPinWrite(NRSTPD_BASE, NRSTPD_PIN, NRSTPD_PIN); MFRC552_Init(); Version = MFRC552_ReadReg(VersionReg); AntennaGain = MFRC552_ReadReg(PICC_REQIDL) & (0x70); UARTprintf("Version: 0x%x \n", Version); UARTprintf("Antenna Gain: 0x%x \n\n", AntennaGain); while(1) { status = MFRC552_Request(PICC_REQIDL, str); if(status == MI_OK) { UARTprintf("Cartao 0x%0X Detectado! \n", (str[0] << 8) + str[1]); //Card Detected status = MFRC552_Anticoll(str); if(status == MI_OK) { memcpy(cardID, str, CARD_LENGTH); UARTprintf("ID: "); dumpHex((unsigned char*)cardID, CARD_LENGTH); if(cardID[0] == 0x36 || cardID[1] == 0xE2 || cardID[2] == 0x45 || cardID[3] == 0x43 || cardID[0] == 0xD2) GPIOPinWrite(GPIO_PORTF_BASE, greenLED, greenLED); else GPIOPinWrite(GPIO_PORTF_BASE, blueLED, blueLED); strcpy(TxData, "1234567890"); status = MFRC552_Auth(0x60, 1, key, cardID); if(status == MI_ERR) { UARTprintf("FALHA NA AUTENTICACAO: 0x%X\n", MFRC552_ReadReg(ErrorReg)); GPIOPinWrite(GPIO_PORTF_BASE, redLED, redLED); } status = MFRC552_WriteBlock(1, TxData); if(status == MI_ERR) { UARTprintf("FALHA NA ESCRITA: 0x%X\n", MFRC552_ReadReg(ErrorReg)); GPIOPinWrite(GPIO_PORTF_BASE, redLED, redLED); } SysCtlDelay(SysCtlClockGet()/6); //Delay status = MFRC552_Auth(0x60, 1, key, cardID); if(status == MI_ERR) { UARTprintf("FALHA NA AUTENTICACAO: 0x%X\n", MFRC552_ReadReg(ErrorReg)); GPIOPinWrite(GPIO_PORTF_BASE, redLED, redLED); } status = MFRC552_ReadBlock(1, RxData); if(status == MI_ERR) { UARTprintf("FALHA NA LEITURA: 0x%X\n", MFRC552_ReadReg(ErrorReg)); GPIOPinWrite(GPIO_PORTF_BASE, redLED, redLED); } else if(status == MI_OK) dumpHex((unsigned char*)RxData, 10); } else if(status == MI_ERR) { UARTprintf("Colisao detectada!!!\n", MFRC552_ReadReg(ErrorReg)); GPIOPinWrite(GPIO_PORTF_BASE, redLED, redLED); } SysCtlDelay(SysCtlClockGet()/3); //Delay GPIOPinWrite(GPIO_PORTF_BASE, 0x0E, 0); UARTprintf("\n\nAproxime o cartao/tag\n"); } } } void initLeds(){ SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3); } void dumpHex(unsigned char* buffer, int len){ int i; for(i=0; i < len; i++) UARTprintf("0x%X ", buffer[i]); UARTprintf("\n\n"); }
MFRC552.h
/* File: MFRC522.h MFRC522 - Library for communicating with cheap MFRC522 based NFC Reader/Writers Created by Eelco Rouw - Mainly based on code from Grant Gibson (www.grantgibson.co.uk) and Dr.Leong ( WWW.B2CQSHOP.COM ) Ported to C by Stephen S. M. Released into the public domain */ /* MFRC522 and Card specific defines. For the role of each define, please consult the datasheet. */ #define MAX_LEN 16 #define CARD_LENGTH 5 #define CHIP_SELECT_BASE GPIO_PORTB_BASE #define CHIP_SELECT_PIN GPIO_PIN_5 #define NRSTPD_BASE GPIO_PORTF_BASE #define NRSTPD_PIN GPIO_PIN_0 #define SSI_BASE SSI2_BASE //MF522 - Commands #define PCD_IDLE 0x00 #define PCD_AUTHENT 0x0E #define PCD_RECEIVE 0x08 #define PCD_TRANSMIT 0x04 #define PCD_TRANSCEIVE 0x0C #define PCD_RESETPHASE 0x0F #define PCD_CALCCRC 0x03 //Mifare_One - Commands #define PICC_REQIDL 0x26 #define PICC_REQALL 0x52 #define PICC_ANTICOLL 0x93 #define PICC_SElECTTAG 0x93 #define PICC_AUTHENT1A 0x60 #define PICC_AUTHENT1B 0x61 #define PICC_READ 0x30 #define PICC_WRITE 0xA0 #define PICC_DECREMENT 0xC0 #define PICC_INCREMENT 0xC1 #define PICC_RESTORE 0xC2 #define PICC_TRANSFER 0xB0 #define PICC_HALT 0x50 //MF522 - Status #define MI_OK 0 #define MI_NOTAGERR 1 #define MI_ERR 2 //MF522 - Registers //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 void MFRC552_WriteReg(unsigned char addr, unsigned char val); unsigned char MFRC552_ReadReg(unsigned char addr); void MFRC552_SetBitMask(unsigned char reg, unsigned char mask); void MFRC552_ClearBitMask(unsigned char reg, unsigned char mask); void MFRC552_AntennaOn(void); void MFRC552_AntennaOff(void); void MFRC552_Reset(void); void MFRC552_Init(void); unsigned char MFRC552_Request(unsigned char reqMode, unsigned char *TagType); unsigned char MFRC552_ToCard(unsigned char command, unsigned char *sendData, unsigned char sendLen, unsigned char *backData, unsigned int *backLen); unsigned char MFRC552_Anticoll(unsigned char *serNum); void MFRC552_CalulateCRC(unsigned char *pIndata, unsigned char len, unsigned char *pOutData); unsigned char MFRC552_SelectTag(unsigned char *serNum); unsigned char MFRC552_Auth(unsigned char authMode, unsigned char BlockAddr, unsigned char *Sectorkey, unsigned char *serNum); unsigned char MFRC552_ReadBlock(unsigned char blockAddr, unsigned char *recvData); unsigned char MFRC552_WriteBlock(unsigned char blockAddr, unsigned char *writeData); void MFRC552_Halt(void);
MFRC552.c
#include <stdbool.h> #include <stdint.h> /* File: MFRC522.h MFRC522 - Library for communicating with cheap MFRC522 based NFC Reader/Writers Created by Eelco Rouw - Mainly based on code from Grant Gibson (www.grantgibson.co.uk) and Dr.Leong ( WWW.B2CQSHOP.COM ) Ported to C by Stephen S. M. Released into the public domain */ #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "driverlib/gpio.h" #include "driverlib/pin_map.h" #include "driverlib/sysctl.h" #include "driverlib/ssi.h" #include "MFRC522.h" /* * Function: WriteReg * Description: write a byte data into one register of MR RC522 * Input parameter: addr--register address;val--the value that need to write in * Return: Null */ uint8_t SPI_transfer(uint8_t data) { uint32_t rxtxData; rxtxData = data; SSIDataPut(SSI_BASE, (uint8_t) rxtxData); while(SSIBusy(SSI_BASE)); SSIDataGet(SSI_BASE, &rxtxData); return (uint8_t) rxtxData; } void MFRC552_WriteReg(unsigned char addr, unsigned char val) { GPIOPinWrite(CHIP_SELECT_BASE, CHIP_SELECT_PIN, 0); SPI_transfer((addr<<1)&0x7E); SPI_transfer(val); GPIOPinWrite(CHIP_SELECT_BASE, CHIP_SELECT_PIN, CHIP_SELECT_PIN); } /* * Function: ReadReg * Description: read a byte data into one register of MR RC522 * Input parameter: addr--register address * Return: return the read value */ unsigned char MFRC552_ReadReg(unsigned char addr) { unsigned char val; GPIOPinWrite(CHIP_SELECT_BASE, CHIP_SELECT_PIN, 0); SPI_transfer(((addr<<1)&0x7E) | 0x80); val = SPI_transfer(0x00); GPIOPinWrite(CHIP_SELECT_BASE, CHIP_SELECT_PIN, CHIP_SELECT_PIN); return val; } /* * Function: SetBitMask * Description: set RC522 register bit * Input parameter: reg--register address;mask--value * Return: null */ void MFRC552_SetBitMask(unsigned char reg, unsigned char mask) { unsigned char tmp; tmp = MFRC552_ReadReg(reg); MFRC552_WriteReg(reg, tmp | mask); // set bit mask } /* * Function: ClearBitMask * Description: clear RC522 register bit * Input parameter: reg--register address;mask--value * Return: null */ void MFRC552_ClearBitMask(unsigned char reg, unsigned char mask) { unsigned char tmp; tmp = MFRC552_ReadReg(reg); MFRC552_WriteReg(reg, tmp & (~mask)); // clear bit mask } /* * Function: AntennaOn * Description: Turn on antenna, every time turn on or shut down antenna need at least 1ms delay * Input parameter: null * Return: null */ void MFRC552_AntennaOn(void) { unsigned char temp; temp = MFRC552_ReadReg(TxControlReg); if (!(temp & 0x03)) { MFRC552_SetBitMask(TxControlReg, 0x03); } } /* * Function: AntennaOff * Description: Turn off antenna, every time turn on or shut down antenna need at least 1ms delay * Input parameter: null * Return: null */ void MFRC552_AntennaOff(void) { MFRC552_ClearBitMask(TxControlReg, 0x03); } /* * Function: Reset * Description: reset RC522 * Input parameter: null * Return: null */ void MFRC552_Reset(void) { MFRC552_WriteReg(CommandReg, PCD_RESETPHASE); } /* * Function: Init * Description: initilize RC522 * Input parameter: null * Return: null */ void MFRC552_Init(void) { GPIOPinWrite(NRSTPD_BASE, NRSTPD_PIN, NRSTPD_PIN); MFRC552_Reset(); //Timer: TPrescaler*TreloadVal/6.78MHz = 24ms MFRC552_WriteReg(TModeReg, 0x8D); //Tauto=1; f(Timer) = 6.78MHz/TPreScaler MFRC552_WriteReg(TPrescalerReg, 0x3E); //TModeReg[3..0] + TPrescalerReg MFRC552_WriteReg(TReloadRegL, 30); MFRC552_WriteReg(TReloadRegH, 0); MFRC552_WriteReg(TxAutoReg, 0x40); //100%ASK MFRC552_WriteReg(ModeReg, 0x3D); //ClearBitMask(Status2Reg, 0x08); //MFCrypto1On=0 //WriteReg(RxSelReg, 0x86); //RxWait = RxSelReg[5..0] //WriteReg(RFCfgReg, 0x7F); //RxGain = 48dB MFRC552_AntennaOn(); } /* * Function: Request * Description: Searching card, read card type * Input parameter: reqMode--search methods: * TagType--return card types * 0x4400 = Mifare_UltraLight * 0x0400 = Mifare_One(S50) * 0x0200 = Mifare_One(S70) * 0x0800 = Mifare_Pro(X) * 0x4403 = Mifare_DESFire * return: return MI_OK if successed */ unsigned char MFRC552_Request(unsigned char reqMode, unsigned char *TagType) { unsigned char status; unsigned int backBits; MFRC552_WriteReg(BitFramingReg, 0x07); //TxLastBists = BitFramingReg[2..0] ??? TagType[0] = reqMode; status = MFRC552_ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits); if ((status != MI_OK) || (backBits != 0x10)) { status = MI_ERR; } return status; } /* * Function: ToCard * Description: communicate between RC522 and ISO14443 * Input parameter: command--MF522 command bits * sendData--send data to card via rc522 * sendLen--send data length * backData--the return data from card * backLen--the length of return data * return: return MI_OK if successed */ unsigned char MFRC552_ToCard(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: { irqEn = 0x12; waitIRq = 0x10; break; } case PCD_TRANSCEIVE: { irqEn = 0x77; waitIRq = 0x30; break; } default: break; } MFRC552_WriteReg(CommIEnReg, irqEn|0x80); MFRC552_ClearBitMask(CommIrqReg, 0x80); MFRC552_SetBitMask(FIFOLevelReg, 0x80); MFRC552_WriteReg(CommandReg, PCD_IDLE); for (i=0; i < sendLen; i++) { MFRC552_WriteReg(FIFODataReg, sendData[i]); } MFRC552_WriteReg(CommandReg, command); if (command == PCD_TRANSCEIVE) { MFRC552_SetBitMask(BitFramingReg, 0x80); //StartSend=1,transmission of data starts } i = 10000; do { n = MFRC552_ReadReg(CommIrqReg); i--; } while ((i!=0) && !(n&0x01) && !(n&waitIRq)); MFRC552_ClearBitMask(BitFramingReg, 0x80); //StartSend=0 if (i != 0) { if(!(MFRC552_ReadReg(ErrorReg) & 0x1B)) //BufferOvfl Collerr CRCErr ProtecolErr { status = MI_OK; if (n & irqEn & 0x01) { status = MI_NOTAGERR; //?? } if (command == PCD_TRANSCEIVE) { n = MFRC552_ReadReg(FIFOLevelReg); lastBits = MFRC552_ReadReg(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; } for (i=0; i<n; i++) { backData[i] = MFRC552_ReadReg(FIFODataReg); } } } else { status = MI_ERR; } } //SetBitMask(ControlReg,0x80); //timer stops //WriteReg(CommandReg, PCD_IDLE); return status; } /* * Function: MFRC522_Anticoll * Description: Prevent conflict, read the card serial number * Input parameter: serNum--return the 4 bytes card serial number, the 5th byte is recheck byte * return: return MI_OK if successed */ unsigned char MFRC552_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 MFRC552_WriteReg(BitFramingReg, 0x00); //TxLastBists = BitFramingReg[2..0] serNum[0] = PICC_ANTICOLL; serNum[1] = 0x20; status = MFRC552_ToCard(PCD_TRANSCEIVE, serNum, 2, serNum, &unLen); if (status == MI_OK) { for (i=0; i<4; i++) { serNumCheck ^= serNum[i]; } if (serNumCheck != serNum[i]) { status = MI_ERR; } } //SetBitMask(CollReg, 0x80); //ValuesAfterColl=1 return status; } /* * Function: CalulateCRC * Description: Use MF522 to calculate CRC * Input parameter: pIndata--the CRC data need to be read,len--data length,pOutData-- the caculated result of CRC * return: Null */ void MFRC552_CalulateCRC(unsigned char *pIndata, unsigned char len, unsigned char *pOutData) { unsigned char i, n; MFRC552_ClearBitMask(DivIrqReg, 0x04); //CRCIrq = 0 MFRC552_SetBitMask(FIFOLevelReg, 0x80); //WriteReg(CommandReg, PCD_IDLE); for (i=0; i<len; i++) { MFRC552_WriteReg(FIFODataReg, *(pIndata+i)); } MFRC552_WriteReg(CommandReg, PCD_CALCCRC); i = 0xFF; do { n = MFRC552_ReadReg(DivIrqReg); i--; } while ((i!=0) && !(n&0x04)); //CRCIrq = 1 pOutData[0] = MFRC552_ReadReg(CRCResultRegL); pOutData[1] = MFRC552_ReadReg(CRCResultRegM); } /* * Function: SelectTag * Description: Select card, read card storage volume * Input parameter: serNum--Send card serial number * return: return the card storage volume */ unsigned char MFRC552_SelectTag(unsigned char *serNum) { unsigned char i; unsigned char status; unsigned char size; unsigned int recvBits; unsigned char buffer[9]; //ClearBitMask(Status2Reg, 0x08); //MFCrypto1On=0 buffer[0] = PICC_SElECTTAG; buffer[1] = 0x70; for (i=0; i<5; i++) { buffer[i+2] = *(serNum+i); } MFRC552_CalulateCRC(buffer, 7, &buffer[7]); //?? status = MFRC552_ToCard(PCD_TRANSCEIVE, buffer, 9, buffer, &recvBits); if ((status == MI_OK) && (recvBits == 0x18)) { size = buffer[0]; } else { size = 0; } return size; } /* * Function: Auth * Description: verify card password * Input parameters: authMode--password verify mode 0x60 = verify A password key 0x61 = verify B password key BlockAddr--Block address Sectorkey--Block password serNum--Card serial number ,4 bytes * return: return MI_OK if successed */ unsigned char MFRC552_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]; 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 = MFRC552_ToCard(PCD_AUTHENT, buff, 12, buff, &recvBits); if ((status != MI_OK) || (!(MFRC552_ReadReg(Status2Reg) & 0x08))) { status = MI_ERR; } return status; } /* * Function: ReadBlock * Description: Read data * Input parameters: blockAddr--block address;recvData--the block data which are read * return: return MI_OK if successed */ unsigned char MFRC552_ReadBlock(unsigned char blockAddr, unsigned char *recvData) { unsigned char status; unsigned int unLen; recvData[0] = PICC_READ; recvData[1] = blockAddr; MFRC552_CalulateCRC(recvData,2, &recvData[2]); status = MFRC552_ToCard(PCD_TRANSCEIVE, recvData, 4, recvData, &unLen); if ((status != MI_OK) || (unLen != 0x90)) { status = MI_ERR; } return status; } /* * Function: WriteBlock * Description: write block data * Input parameters: blockAddr--block address;writeData--Write 16 bytes data into block * return: return MI_OK if successed */ unsigned char MFRC552_WriteBlock(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; MFRC552_CalulateCRC(buff, 2, &buff[2]); status = MFRC552_ToCard(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++) { buff[i] = *(writeData+i); } MFRC552_CalulateCRC(buff, 16, &buff[16]); status = MFRC552_ToCard(PCD_TRANSCEIVE, buff, 18, buff, &recvBits); if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A)) { status = MI_ERR; } } return status; } /* * Function: Halt * Description: Command the cards into sleep mode * Input parameters: null * return: null */ void MFRC552_Halt(void) { unsigned char status; unsigned int unLen; unsigned char buff[4]; buff[0] = PICC_HALT; buff[1] = 0; MFRC552_CalulateCRC(buff, 2, &buff[2]); status = MFRC552_ToCard(PCD_TRANSCEIVE, buff, 4, buff, &unLen); }