Part Number: EK-TM4C123GXL
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);
}