调用:
if (!MFRC522_Request(PICC_REQIDL, str) && !MFRC522_Anticoll(str))
{
//当卡片识别成功进入此IF
//打印识别到卡片的ID号
// for(i=0;i<MFRC522_MAX_LEN;i++)
// printf("%d,",str[i]);
// printf("\r\n");
//
}
驱动代码(.C和.H)
RC522.C
// Mifare RC522 RFID Card reader 13.56 MHz
// STM32F103 RFID RC522 SPI1 / UART / USB / Keil HAL / 2017 vk.com/zz555
// PA0 - (OUT) LED2
// PA1 - (IN) BTN1
// PA4 - (OUT) SPI1_NSS (Soft)
// PA5 - (OUT) SPI1_SCK
// PA6 - (IN) SPI1_MISO (Master In)
// PA7 - (OUT) SPI1_MOSI (Master Out)
// PA9 - (OUT) TX UART1 (RX-RS232)
// PA10 - (IN) RX UART1 (TX-RS232)
// PA11 - (OUT) USB_DM
// PA12 - (OUT) USB_DP
// PA13 - (IN) SWDIO
// PA14 - (IN) SWDCLK
// PC13 - (OUT) LED1
// MFRC522 STM32F103 DESCRIPTION
// CS (SDA) PA4 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 "stm32f1xx_hal.h"
#include "rc522.h"
uint8_t retstr[10];
uint8_t rxBuffer[8];
SPI_HandleTypeDef hspi1;
// RC522
extern uint8_t MFRC522_Check(uint8_t* id);
extern uint8_t MFRC522_Compare(uint8_t* CardID, uint8_t* CompareID);
extern void MFRC522_WriteRegister(uint8_t addr, uint8_t val);
extern uint8_t MFRC522_ReadRegister(uint8_t addr);
extern void MFRC522_SetBitMask(uint8_t reg, uint8_t mask);
extern void MFRC522_ClearBitMask(uint8_t reg, uint8_t mask);
extern uint8_t MFRC522_Request(uint8_t reqMode, uint8_t* TagType);
extern uint8_t MFRC522_ToCard(uint8_t command, uint8_t* sendData, uint8_t sendLen, uint8_t* backData, uint16_t* backLen);
extern uint8_t MFRC522_Anticoll(uint8_t* serNum);
extern void MFRC522_CalulateCRC(uint8_t* pIndata, uint8_t len, uint8_t* pOutData);
extern uint8_t MFRC522_SelectTag(uint8_t* serNum);
extern uint8_t MFRC522_Auth(uint8_t authMode, uint8_t BlockAddr, uint8_t* Sectorkey, uint8_t* serNum);
extern uint8_t MFRC522_Read(uint8_t blockAddr, uint8_t* recvData);
extern uint8_t MFRC522_Write(uint8_t blockAddr, uint8_t* writeData);
extern void MFRC522_Init(void);
extern void MFRC522_Reset(void);
extern void MFRC522_AntennaOn(void);
extern void MFRC522_AntennaOff(void);
extern void MFRC522_Halt(void);
uint8_t dui_bi_shu_zu(uint8_t num1[],uint8_t num2[][6],uint8_t card_num)
{
int i,k;
for(k=0;k<card_num;k++)
{
for(i=0;i<6;i++)
{
if(num1[i]!=num2[k][i])
break;
}
if(i==6)
return 1;
}
return 0;
}
void nfc_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE(); //why
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4, GPIO_PIN_RESET);
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(hspi->Instance==SPI1)
{
/* USER CODE BEGIN SPI1_MspInit 0 */
/* USER CODE END SPI1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_SPI1_CLK_ENABLE();
/**SPI1 GPIO Configuration
PA5 ------> SPI1_SCK
PA6 ------> SPI1_MISO
PA7 ------> SPI1_MOSI
*/
GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USER CODE BEGIN SPI1_MspInit 1 */
/* USER CODE END SPI1_MspInit 1 */
}
}
void MX_SPI1_Init(void)
{
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
}
}
uint8_t SPI1SendByte(uint8_t data) {
unsigned char writeCommand[1];
unsigned char readValue[1];
writeCommand[0] = data;
HAL_SPI_TransmitReceive(&hspi1, (uint8_t*)&writeCommand, (uint8_t*)&readValue, 1, 10);
return readValue[0];
//while (SPI1->SR & SPI_SR_BSY); // STM32F030 - ???? ????? ????????
//while (SPI1->SR & SPI_I2S_FLAG_BSY); // STM32F103 - ???? ????? ????????
//while (!(SPI1->SR & SPI_SR_TXE)); // ?????????, ??? ?????????? ???????? ????????? (STM32F103)
//SPI1->DR = data; // ????? ? SPI1
//while (!(SPI1->SR & SPI_SR_RXNE)); // ???? ????????? ?????? (STM32F103)
//for (uint8_t i=0; i<50; i++) {};
//data = SPI1->DR; // ?????? ???????? ??????
//return data;
}
void SPI1_WriteReg(uint8_t address, uint8_t value) {
cs_reset();
SPI1SendByte(address);
SPI1SendByte(value);
cs_set();
}
uint8_t SPI1_ReadReg(uint8_t address) {
uint8_t val;
cs_reset();
SPI1SendByte(address);
val = SPI1SendByte(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) {
nfc_GPIO_Init();
MX_SPI1_Init();
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, 0x7F); // 48dB gain
MFRC522_WriteRegister(MFRC522_REG_RX_THRESHOLD, 0x84);<<<<<<<<<<<<<<<<<<<<
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);
}
uint8_t hex_to_char(uint8_t data) {
uint8_t number;
if (rxBuffer[data] < 58) number = (rxBuffer[data]-48)*16; else number = (rxBuffer[data]-55)*16;
data++;
if (rxBuffer[data] < 58) number = number+(rxBuffer[data]-48); else number = number+(rxBuffer[data]-55);
return number;
}
// char number to string hex (FF) (Only big letters!)
void char_to_hex(uint8_t data) {
uint8_t digits[] = {'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)];
}
}
// Number to string (16 bit)
void StrTo() {
uint32_t number;
uint32_t ret;
number = 0;
ret = 0;
ret = retstr[0]-0x30;
number = ret*1000000;
ret = retstr[1]-0x30;
number = number+ret*100000;
ret = retstr[2]-0x30;
number = number+ret*10000;
ret = retstr[3]-0x30;
number = number+ret*1000;
ret = retstr[4]-0x30;
number = number+ret*100;
ret = retstr[5]-0x30;
number = number+ret*10;
ret = retstr[6]-0x30;
number = number+ret;
}
// String to number (32 bit)
void ToStr(uint32_t number) {
uint32_t i;
i = number/1000000000;
number = number-i*1000000000;
retstr[0] = i+0x30;
i=number/100000000;
number=number-i*100000000;
retstr[1] = i+0x30;
i = number/10000000;
number = number-i*10000000;
retstr[2] = i+0x30;
i = number/1000000;
number = number-i*1000000;
retstr[3] = i+0x30;
i = number/100000;
number = number-i*100000;
retstr[4] = i+0x30;
i = number/10000;
number = number-i*10000;
retstr[5] = i+0x30;
i = number/1000;
number = number-i*1000;
retstr[6] = i+0x30;
i = number/100;
number = number-i*100;
retstr[7] = i+0x30;
i = number/10;
number = number-i*10;
retstr[8] = i+0x30;
retstr[9] = number+0x30;
}
RC522.H
// Mifare RC522 RFID Card reader 13.56 MHz
// STM32F103 RFID RC522 SPI1 / UART / USB / Keil HAL
#include "stm32f1xx_hal.h"
extern uint8_t rxBuffer[8];
extern uint8_t retstr[10];
extern SPI_HandleTypeDef hspi1;
uint8_t dui_bi_shu_zu(uint8_t num1[],uint8_t num2[][6],uint8_t card_num);
void MX_SPI1_Init(void);
// RC522
void ToStr(uint32_t number) ;
void StrTo(void);
void char_to_hex(uint8_t data) ;
uint8_t hex_to_char(uint8_t data) ;
uint8_t MFRC522_Check(uint8_t* id);
uint8_t MFRC522_Compare(uint8_t* CardID, uint8_t* CompareID);
void MFRC522_WriteRegister(uint8_t addr, uint8_t val);
uint8_t MFRC522_ReadRegister(uint8_t addr);
void MFRC522_SetBitMask(uint8_t reg, uint8_t mask);
void MFRC522_ClearBitMask(uint8_t reg, uint8_t mask);
uint8_t MFRC522_Request(uint8_t reqMode, uint8_t* TagType);
uint8_t MFRC522_ToCard(uint8_t command, uint8_t* sendData, uint8_t sendLen, uint8_t* backData, uint16_t* backLen);
uint8_t MFRC522_Anticoll(uint8_t* serNum);
void MFRC522_CalulateCRC(uint8_t* pIndata, uint8_t len, uint8_t* pOutData);
uint8_t MFRC522_SelectTag(uint8_t* serNum);
uint8_t MFRC522_Auth(uint8_t authMode, uint8_t BlockAddr, uint8_t* Sectorkey, uint8_t* serNum);
uint8_t MFRC522_Read(uint8_t blockAddr, uint8_t* recvData);
uint8_t MFRC522_Write(uint8_t blockAddr, uint8_t* writeData);
void MFRC522_Init(void);
void MFRC522_Reset(void);
void MFRC522_AntennaOn(void);
void MFRC522_AntennaOff(void);
void MFRC522_Halt(void);
// SPI CS define
//#define SPI_I2S_FLAG_BSY ((uint16_t)0x0080)
#define cs_reset() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET)
#define cs_set() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET)
// Status enumeration, Used with most functions
#define MI_OK 0
#define MI_NOTAGERR 1
#define MI_ERR 2
// MFRC522 Commands
#define PCD_IDLE 0x00 // NO action; Cancel the current command
#define PCD_AUTHENT 0x0E // Authentication Key
#define PCD_RECEIVE 0x08 // Receive Data
#define PCD_TRANSMIT 0x04 // Transmit data
#define PCD_TRANSCEIVE 0x0C // Transmit and receive data,
#define PCD_RESETPHASE 0x0F // Reset
#define PCD_CALCCRC 0x03 // CRC Calculate
// Mifare_One card command word
#define PICC_REQIDL 0x26 // find the antenna area does not enter hibernation
#define PICC_REQALL 0x52 // find all the cards antenna area
#define PICC_ANTICOLL 0x93 // anti-collision
#define PICC_SElECTTAG 0x93 // election card
#define PICC_AUTHENT1A 0x60 // authentication key A
#define PICC_AUTHENT1B 0x61 // authentication key B
#define PICC_READ 0x30 // Read Block
#define PICC_WRITE 0xA0 // write block
#define PICC_DECREMENT 0xC0 // debit
#define PICC_INCREMENT 0xC1 // recharge
#define PICC_RESTORE 0xC2 // transfer block data to the buffer
#define PICC_TRANSFER 0xB0 // save the data in the buffer
#define PICC_HALT 0x50 // Sleep
// MFRC522 Registers
// Page 0: Command and Status
#define MFRC522_REG_RESERVED00 0x00
#define MFRC522_REG_COMMAND 0x01
#define MFRC522_REG_COMM_IE_N 0x02
#define MFRC522_REG_DIV1_EN 0x03
#define MFRC522_REG_COMM_IRQ 0x04
#define MFRC522_REG_DIV_IRQ 0x05
#define MFRC522_REG_ERROR 0x06
#define MFRC522_REG_STATUS1 0x07
#define MFRC522_REG_STATUS2 0x08
#define MFRC522_REG_FIFO_DATA 0x09
#define MFRC522_REG_FIFO_LEVEL 0x0A
#define MFRC522_REG_WATER_LEVEL 0x0B
#define MFRC522_REG_CONTROL 0x0C
#define MFRC522_REG_BIT_FRAMING 0x0D
#define MFRC522_REG_COLL 0x0E
#define MFRC522_REG_RESERVED01 0x0F
// Page 1: Command
#define MFRC522_REG_RESERVED10 0x10
#define MFRC522_REG_MODE 0x11
#define MFRC522_REG_TX_MODE 0x12
#define MFRC522_REG_RX_MODE 0x13
#define MFRC522_REG_TX_CONTROL 0x14
#define MFRC522_REG_TX_AUTO 0x15
#define MFRC522_REG_TX_SELL 0x16
#define MFRC522_REG_RX_SELL 0x17
#define MFRC522_REG_RX_THRESHOLD 0x18
#define MFRC522_REG_DEMOD 0x19
#define MFRC522_REG_RESERVED11 0x1A
#define MFRC522_REG_RESERVED12 0x1B
#define MFRC522_REG_MIFARE 0x1C
#define MFRC522_REG_RESERVED13 0x1D
#define MFRC522_REG_RESERVED14 0x1E
#define MFRC522_REG_SERIALSPEED 0x1F
// Page 2: CFG
#define MFRC522_REG_RESERVED20 0x20
#define MFRC522_REG_CRC_RESULT_M 0x21
#define MFRC522_REG_CRC_RESULT_L 0x22
#define MFRC522_REG_RESERVED21 0x23
#define MFRC522_REG_MOD_WIDTH 0x24
#define MFRC522_REG_RESERVED22 0x25
#define MFRC522_REG_RF_CFG 0x26
#define MFRC522_REG_GS_N 0x27
#define MFRC522_REG_CWGS_PREG 0x28
#define MFRC522_REG__MODGS_PREG 0x29
#define MFRC522_REG_T_MODE 0x2A
#define MFRC522_REG_T_PRESCALER 0x2B
#define MFRC522_REG_T_RELOAD_H 0x2C
#define MFRC522_REG_T_RELOAD_L 0x2D
#define MFRC522_REG_T_COUNTER_VALUE_H 0x2E
#define MFRC522_REG_T_COUNTER_VALUE_L 0x2F
// Page 3:TestRegister
#define MFRC522_REG_RESERVED30 0x30
#define MFRC522_REG_TEST_SEL1 0x31
#define MFRC522_REG_TEST_SEL2 0x32
#define MFRC522_REG_TEST_PIN_EN 0x33
#define MFRC522_REG_TEST_PIN_VALUE 0x34
#define MFRC522_REG_TEST_BUS 0x35
#define MFRC522_REG_AUTO_TEST 0x36
#define MFRC522_REG_VERSION 0x37
#define MFRC522_REG_ANALOG_TEST 0x38
#define MFRC522_REG_TEST_ADC1 0x39
#define MFRC522_REG_TEST_ADC2 0x3A
#define MFRC522_REG_TEST_ADC0 0x3B
#define MFRC522_REG_RESERVED31 0x3C
#define MFRC522_REG_RESERVED32 0x3D
#define MFRC522_REG_RESERVED33 0x3E
#define MFRC522_REG_RESERVED34 0x3F
#define MFRC522_DUMMY 0x00 // Dummy byte
#define MFRC522_MAX_LEN 16 // Buf len byte