599 lines
15 KiB
C
599 lines
15 KiB
C
#include "stm32f1xx_hal.h"
|
|
#include "rc522.h"
|
|
#include "stdio.h"
|
|
#include "usart.h"
|
|
#include <string.h>
|
|
|
|
extern SPI_HandleTypeDef hspi1;
|
|
|
|
void MFRC_Init(void)
|
|
{
|
|
RS522_NSS(1);
|
|
RS522_RST(1);
|
|
}
|
|
|
|
static uint8_t ret;
|
|
uint8_t SPI1_RW_Byte(uint8_t byte)
|
|
{
|
|
HAL_SPI_TransmitReceive(&hspi1, &byte, &ret, 1, 10);
|
|
return ret;
|
|
}
|
|
|
|
void MFRC_WriteReg(uint8_t addr, uint8_t data)
|
|
{
|
|
const uint8_t AddrByte = (addr << 1) & 0x7E;
|
|
RS522_NSS(0);
|
|
SPI1_RW_Byte(AddrByte);
|
|
SPI1_RW_Byte(data);
|
|
RS522_NSS(1);
|
|
}
|
|
|
|
uint8_t MFRC_ReadReg(uint8_t addr)
|
|
{
|
|
const uint8_t AddrByte = ((addr << 1) & 0x7E) | 0x80;
|
|
RS522_NSS(0);
|
|
SPI1_RW_Byte(AddrByte);
|
|
const uint8_t data = SPI1_RW_Byte(0x00);
|
|
RS522_NSS(1); //NSS拉高
|
|
return data;
|
|
}
|
|
|
|
void MFRC_SetBitMask(uint8_t addr, uint8_t mask)
|
|
{
|
|
uint8_t temp;
|
|
temp = MFRC_ReadReg(addr);
|
|
MFRC_WriteReg(addr, temp | mask);
|
|
}
|
|
|
|
void MFRC_ClrBitMask(uint8_t addr, uint8_t mask)
|
|
{
|
|
uint8_t temp;
|
|
temp = MFRC_ReadReg(addr);
|
|
MFRC_WriteReg(addr, temp & ~mask);
|
|
}
|
|
|
|
void MFRC_CalulateCRC(uint8_t* pInData, uint8_t len, uint8_t* pOutData)
|
|
{
|
|
//0xc1 1 2 pInData[2]
|
|
uint8_t temp;
|
|
uint32_t i;
|
|
MFRC_ClrBitMask(MFRC_DivIrqReg, 0x04); //使能CRC中断
|
|
MFRC_WriteReg(MFRC_CommandReg, MFRC_IDLE); //取消当前命令的执行
|
|
MFRC_SetBitMask(MFRC_FIFOLevelReg, 0x80); //清除FIFO及其标志位
|
|
for (i = 0; i < len; i++) //将待CRC计算的数据写入FIFO
|
|
{
|
|
MFRC_WriteReg(MFRC_FIFODataReg, *(pInData + i));
|
|
}
|
|
MFRC_WriteReg(MFRC_CommandReg, MFRC_CALCCRC); //执行CRC计算
|
|
i = 100000;
|
|
do
|
|
{
|
|
temp = MFRC_ReadReg(MFRC_DivIrqReg); //读取DivIrqReg寄存器的值
|
|
i--;
|
|
}
|
|
while ((i != 0) && !(temp & 0x04)); //等待CRC计算完成
|
|
pOutData[0] = MFRC_ReadReg(MFRC_CRCResultRegL); //读取CRC计算结果
|
|
pOutData[1] = MFRC_ReadReg(MFRC_CRCResultRegM);
|
|
}
|
|
|
|
char MFRC_CmdFrame(uint8_t cmd, uint8_t* pInData, uint8_t InLenByte, uint8_t* pOutData, uint16_t* pOutLenBit)
|
|
{
|
|
uint8_t lastBits;
|
|
uint8_t n;
|
|
uint32_t i;
|
|
char status = MFRC_ERR;
|
|
uint8_t irqEn = 0x00;
|
|
uint8_t waitFor = 0x00;
|
|
|
|
/*根据命令设置标志位*/
|
|
switch (cmd)
|
|
{
|
|
case MFRC_AUTHENT: //Mifare认证
|
|
irqEn = 0x12;
|
|
waitFor = 0x10; //idleIRq中断标志
|
|
break;
|
|
case MFRC_TRANSCEIVE: //发送并接收数据
|
|
irqEn = 0x77;
|
|
waitFor = 0x30; //RxIRq和idleIRq中断标志
|
|
break;
|
|
}
|
|
|
|
/*发送命令帧前准备*/
|
|
MFRC_WriteReg(MFRC_ComIEnReg, irqEn | 0x80); //开中断
|
|
MFRC_ClrBitMask(MFRC_ComIrqReg, 0x80); //清除中断标志位SET1
|
|
MFRC_WriteReg(MFRC_CommandReg, MFRC_IDLE); //取消当前命令的执行
|
|
MFRC_SetBitMask(MFRC_FIFOLevelReg, 0x80); //清除FIFO缓冲区及其标志位
|
|
|
|
/*发送命令帧*/
|
|
for (i = 0; i < InLenByte; i++) //写入命令参数
|
|
{
|
|
MFRC_WriteReg(MFRC_FIFODataReg, pInData[i]);
|
|
}
|
|
MFRC_WriteReg(MFRC_CommandReg, cmd); //执行命令
|
|
if (cmd == MFRC_TRANSCEIVE)
|
|
{
|
|
MFRC_SetBitMask(MFRC_BitFramingReg, 0x80); //启动发送
|
|
}
|
|
i = 300000; //根据时钟频率调整,操作M1卡最大等待时间25ms
|
|
do
|
|
{
|
|
n = MFRC_ReadReg(MFRC_ComIrqReg);
|
|
i--;
|
|
}
|
|
while ((i != 0) && !(n & 0x01) && !(n & waitFor)); //等待命令完成
|
|
MFRC_ClrBitMask(MFRC_BitFramingReg, 0x80); //停止发送
|
|
|
|
/*处理接收的数据*/
|
|
if (i != 0)
|
|
{
|
|
if (!(MFRC_ReadReg(MFRC_ErrorReg) & 0x1B))
|
|
{
|
|
status = MFRC_OK;
|
|
if (n & irqEn & 0x01)
|
|
{
|
|
status = MFRC_NOTAGERR;
|
|
}
|
|
if (cmd == MFRC_TRANSCEIVE)
|
|
{
|
|
n = MFRC_ReadReg(MFRC_FIFOLevelReg);
|
|
lastBits = MFRC_ReadReg(MFRC_ControlReg) & 0x07;
|
|
if (lastBits)
|
|
{
|
|
*pOutLenBit = (n - 1) * 8 + lastBits;
|
|
}
|
|
else
|
|
{
|
|
*pOutLenBit = n * 8;
|
|
}
|
|
if (n == 0)
|
|
{
|
|
n = 1;
|
|
}
|
|
if (n > MFRC_MAXRLEN)
|
|
{
|
|
n = MFRC_MAXRLEN;
|
|
}
|
|
for (i = 0; i < n; i++)
|
|
{
|
|
pOutData[i] = MFRC_ReadReg(MFRC_FIFODataReg);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
status = MFRC_ERR;
|
|
}
|
|
}
|
|
|
|
MFRC_SetBitMask(MFRC_ControlReg, 0x80); // 停止定时器运行
|
|
MFRC_WriteReg(MFRC_CommandReg, MFRC_IDLE); // 取消当前命令的执行
|
|
|
|
return status;
|
|
}
|
|
|
|
void PCD_Reset(void)
|
|
{
|
|
/* Hard reset */
|
|
RS522_RST(1); //用到复位引脚
|
|
osDelay(2);
|
|
RS522_RST(0);
|
|
osDelay(2);
|
|
RS522_RST(1);
|
|
osDelay(2);
|
|
|
|
/* Soft reset */
|
|
MFRC_WriteReg(MFRC_CommandReg, MFRC_RESETPHASE);
|
|
osDelay(2);
|
|
|
|
/* Init after reset */
|
|
MFRC_WriteReg(MFRC_ModeReg, 0x3D); // CRC初始值0x6363
|
|
MFRC_WriteReg(MFRC_TReloadRegL, 30); // 定时器重装值
|
|
MFRC_WriteReg(MFRC_TReloadRegH, 0);
|
|
MFRC_WriteReg(MFRC_TModeReg, 0x8D); // 定时器设置
|
|
MFRC_WriteReg(MFRC_TPrescalerReg, 0x3E); // 定时器预分频值
|
|
MFRC_WriteReg(MFRC_TxAutoReg, 0x40); // 100%ASK
|
|
|
|
PCD_AntennaOff(); // 关天线
|
|
osDelay(2);
|
|
PCD_AntennaOn(); // 开天线
|
|
}
|
|
|
|
void PCD_AntennaOn(void)
|
|
{
|
|
uint8_t temp;
|
|
temp = MFRC_ReadReg(MFRC_TxControlReg);
|
|
if (!(temp & 0x03))
|
|
{
|
|
MFRC_SetBitMask(MFRC_TxControlReg, 0x03);
|
|
}
|
|
}
|
|
|
|
void PCD_AntennaOff(void)
|
|
{
|
|
MFRC_ClrBitMask(MFRC_TxControlReg, 0x03);
|
|
}
|
|
|
|
void PCD_Init(void)
|
|
{
|
|
MFRC_Init(); //MFRC管脚配置
|
|
PCD_Reset(); //PCD复位 并初始化配置
|
|
PCD_AntennaOff(); //关闭天线
|
|
PCD_AntennaOn(); //开启天线
|
|
}
|
|
|
|
char PCD_Request(uint8_t RequestMode, uint8_t* pCardType)
|
|
{
|
|
int status;
|
|
uint16_t unLen;
|
|
uint8_t CmdFrameBuf[MFRC_MAXRLEN];
|
|
|
|
MFRC_ClrBitMask(MFRC_Status2Reg, 0x08); //关内部温度传感器
|
|
MFRC_WriteReg(MFRC_BitFramingReg, 0x07); //存储模式,发送模式,是否启动发送等
|
|
MFRC_SetBitMask(MFRC_TxControlReg, 0x03); //配置调制信号13.56MHZ
|
|
|
|
CmdFrameBuf[0] = RequestMode;
|
|
|
|
status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 1, CmdFrameBuf, &unLen);
|
|
|
|
if ((status == PCD_OK) && (unLen == 0x10))
|
|
{
|
|
*pCardType = CmdFrameBuf[0];
|
|
*(pCardType + 1) = CmdFrameBuf[1];
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
char PCD_AntiColl(uint8_t* pSnr)
|
|
{
|
|
char status;
|
|
uint8_t i, snr_check = 0;
|
|
uint16_t unLen;
|
|
uint8_t CmdFrameBuf[MFRC_MAXRLEN];
|
|
|
|
MFRC_ClrBitMask(MFRC_Status2Reg, 0x08);
|
|
MFRC_WriteReg(MFRC_BitFramingReg, 0x00);
|
|
MFRC_ClrBitMask(MFRC_CollReg, 0x80);
|
|
|
|
CmdFrameBuf[0] = PICC_ANTICOLL1;
|
|
CmdFrameBuf[1] = 0x20;
|
|
|
|
status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 2, CmdFrameBuf, &unLen);
|
|
|
|
if (status == PCD_OK)
|
|
{
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
*(pSnr + i) = CmdFrameBuf[i];
|
|
snr_check ^= CmdFrameBuf[i];
|
|
}
|
|
if (snr_check != CmdFrameBuf[i])
|
|
{
|
|
status = PCD_ERR;
|
|
}
|
|
}
|
|
|
|
MFRC_SetBitMask(MFRC_CollReg, 0x80);
|
|
return status;
|
|
}
|
|
|
|
char PCD_Select(uint8_t* pSnr)
|
|
{
|
|
char status;
|
|
uint8_t i;
|
|
uint16_t unLen;
|
|
uint8_t CmdFrameBuf[MFRC_MAXRLEN];
|
|
|
|
CmdFrameBuf[0] = PICC_ANTICOLL1;
|
|
CmdFrameBuf[1] = 0x70;
|
|
CmdFrameBuf[6] = 0;
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
CmdFrameBuf[i + 2] = *(pSnr + i);
|
|
CmdFrameBuf[6] ^= *(pSnr + i);
|
|
}
|
|
MFRC_CalulateCRC(CmdFrameBuf, 7, &CmdFrameBuf[7]);
|
|
|
|
MFRC_ClrBitMask(MFRC_Status2Reg, 0x08);
|
|
|
|
status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 9, CmdFrameBuf, &unLen);
|
|
|
|
if ((status == PCD_OK) && (unLen == 0x18))
|
|
{
|
|
status = PCD_OK;
|
|
}
|
|
else
|
|
{
|
|
status = PCD_ERR;
|
|
}
|
|
return status;
|
|
}
|
|
|
|
char PCD_AuthState(uint8_t AuthMode, uint8_t BlockAddr, uint8_t* pKey, uint8_t* pSnr)
|
|
{
|
|
char status;
|
|
uint16_t unLen;
|
|
uint8_t i, CmdFrameBuf[MFRC_MAXRLEN];
|
|
CmdFrameBuf[0] = AuthMode;
|
|
CmdFrameBuf[1] = BlockAddr;
|
|
for (i = 0; i < 6; i++)
|
|
{
|
|
CmdFrameBuf[i + 2] = *(pKey + i);
|
|
}
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
CmdFrameBuf[i + 8] = *(pSnr + i);
|
|
}
|
|
|
|
status = MFRC_CmdFrame(MFRC_AUTHENT, CmdFrameBuf, 12, CmdFrameBuf, &unLen);
|
|
if ((status != PCD_OK) || (!(MFRC_ReadReg(MFRC_Status2Reg) & 0x08)))
|
|
{
|
|
status = PCD_ERR;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
char PCD_WriteBlock(uint8_t BlockAddr, uint8_t* pData)
|
|
{
|
|
char status;
|
|
uint16_t unLen;
|
|
uint8_t i, CmdFrameBuf[MFRC_MAXRLEN];
|
|
|
|
CmdFrameBuf[0] = PICC_WRITE;
|
|
CmdFrameBuf[1] = BlockAddr;
|
|
MFRC_CalulateCRC(CmdFrameBuf, 2, &CmdFrameBuf[2]);
|
|
|
|
status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 4, CmdFrameBuf, &unLen);
|
|
|
|
if ((status != PCD_OK) || (unLen != 4) || ((CmdFrameBuf[0] & 0x0F) != 0x0A))
|
|
{
|
|
status = PCD_ERR;
|
|
}
|
|
|
|
if (status == PCD_OK)
|
|
{
|
|
for (i = 0; i < 16; i++)
|
|
{
|
|
CmdFrameBuf[i] = *(pData + i);
|
|
}
|
|
MFRC_CalulateCRC(CmdFrameBuf, 16, &CmdFrameBuf[16]);
|
|
|
|
status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 18, CmdFrameBuf, &unLen);
|
|
|
|
if ((status != PCD_OK) || (unLen != 4) || ((CmdFrameBuf[0] & 0x0F) != 0x0A))
|
|
{
|
|
status = PCD_ERR;
|
|
}
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
char PCD_ReadBlock(uint8_t BlockAddr, uint8_t* pData)
|
|
{
|
|
char status;
|
|
uint16_t unLen;
|
|
uint8_t i, CmdFrameBuf[MFRC_MAXRLEN];
|
|
|
|
CmdFrameBuf[0] = PICC_READ;
|
|
CmdFrameBuf[1] = BlockAddr;
|
|
MFRC_CalulateCRC(CmdFrameBuf, 2, &CmdFrameBuf[2]);
|
|
|
|
status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 4, CmdFrameBuf, &unLen);
|
|
if ((status == PCD_OK) && (unLen == 0x90))
|
|
{
|
|
for (i = 0; i < 16; i++)
|
|
{
|
|
*(pData + i) = CmdFrameBuf[i];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
status = PCD_ERR;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
char PCD_Value(uint8_t mode, uint8_t BlockAddr, uint8_t* pValue)
|
|
{
|
|
//0XC1 1 Increment[4]={0x03, 0x01, 0x01, 0x01};
|
|
char status;
|
|
uint16_t unLen;
|
|
uint8_t i, CmdFrameBuf[MFRC_MAXRLEN];
|
|
|
|
CmdFrameBuf[0] = mode;
|
|
CmdFrameBuf[1] = BlockAddr;
|
|
MFRC_CalulateCRC(CmdFrameBuf, 2, &CmdFrameBuf[2]);
|
|
|
|
status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 4, CmdFrameBuf, &unLen);
|
|
|
|
if ((status != PCD_OK) || (unLen != 4) || ((CmdFrameBuf[0] & 0x0F) != 0x0A))
|
|
{
|
|
status = PCD_ERR;
|
|
}
|
|
|
|
if (status == PCD_OK)
|
|
{
|
|
for (i = 0; i < 16; i++)
|
|
{
|
|
CmdFrameBuf[i] = *(pValue + i);
|
|
}
|
|
MFRC_CalulateCRC(CmdFrameBuf, 4, &CmdFrameBuf[4]);
|
|
unLen = 0;
|
|
status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 6, CmdFrameBuf, &unLen);
|
|
if (status != PCD_ERR)
|
|
{
|
|
status = PCD_OK;
|
|
}
|
|
}
|
|
|
|
if (status == PCD_OK)
|
|
{
|
|
CmdFrameBuf[0] = PICC_TRANSFER;
|
|
CmdFrameBuf[1] = BlockAddr;
|
|
MFRC_CalulateCRC(CmdFrameBuf, 2, &CmdFrameBuf[2]);
|
|
|
|
status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 4, CmdFrameBuf, &unLen);
|
|
|
|
if ((status != PCD_OK) || (unLen != 4) || ((CmdFrameBuf[0] & 0x0F) != 0x0A))
|
|
{
|
|
status = PCD_ERR;
|
|
}
|
|
}
|
|
return status;
|
|
}
|
|
|
|
char PCD_BakValue(uint8_t sourceBlockAddr, uint8_t goalBlockAddr)
|
|
{
|
|
char status;
|
|
uint16_t unLen;
|
|
uint8_t CmdFrameBuf[MFRC_MAXRLEN];
|
|
|
|
CmdFrameBuf[0] = PICC_RESTORE;
|
|
CmdFrameBuf[1] = sourceBlockAddr;
|
|
MFRC_CalulateCRC(CmdFrameBuf, 2, &CmdFrameBuf[2]);
|
|
status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 4, CmdFrameBuf, &unLen);
|
|
if ((status != PCD_OK) || (unLen != 4) || ((CmdFrameBuf[0] & 0x0F) != 0x0A))
|
|
{
|
|
status = PCD_ERR;
|
|
}
|
|
|
|
if (status == PCD_OK)
|
|
{
|
|
CmdFrameBuf[0] = 0;
|
|
CmdFrameBuf[1] = 0;
|
|
CmdFrameBuf[2] = 0;
|
|
CmdFrameBuf[3] = 0;
|
|
MFRC_CalulateCRC(CmdFrameBuf, 4, &CmdFrameBuf[4]);
|
|
status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 6, CmdFrameBuf, &unLen);
|
|
if (status != PCD_ERR)
|
|
{
|
|
status = PCD_OK;
|
|
}
|
|
}
|
|
|
|
if (status != PCD_OK)
|
|
{
|
|
return PCD_ERR;
|
|
}
|
|
|
|
CmdFrameBuf[0] = PICC_TRANSFER;
|
|
CmdFrameBuf[1] = goalBlockAddr;
|
|
MFRC_CalulateCRC(CmdFrameBuf, 2, &CmdFrameBuf[2]);
|
|
status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 4, CmdFrameBuf, &unLen);
|
|
if ((status != PCD_OK) || (unLen != 4) || ((CmdFrameBuf[0] & 0x0F) != 0x0A))
|
|
{
|
|
status = PCD_ERR;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
char PCD_Halt(void)
|
|
{
|
|
char status;
|
|
uint16_t unLen;
|
|
uint8_t CmdFrameBuf[MFRC_MAXRLEN];
|
|
|
|
CmdFrameBuf[0] = PICC_HALT;
|
|
CmdFrameBuf[1] = 0;
|
|
MFRC_CalulateCRC(CmdFrameBuf, 2, &CmdFrameBuf[2]);
|
|
|
|
status = MFRC_CmdFrame(MFRC_TRANSCEIVE, CmdFrameBuf, 4, CmdFrameBuf, &unLen);
|
|
|
|
return status;
|
|
}
|
|
|
|
void RC522_InitStateMachine(RC522_Handle* handle)
|
|
{
|
|
handle->state = RC522_STATE_IDLE;
|
|
memset(handle->cardType, 0, sizeof(handle->cardType));
|
|
memset(handle->cardID, 0, sizeof(handle->cardID));
|
|
memset(handle->blockData, 0, sizeof(handle->blockData));
|
|
handle->blockAddr = 0x01 * 4 + 0x03;
|
|
memset(handle->keyA, 0xFF, sizeof(handle->keyA));
|
|
memset(handle->keyB, 0xFF, sizeof(handle->keyB));
|
|
handle->status = PCD_OK;
|
|
}
|
|
|
|
void RC522_ProcessStateMachine(RC522_Handle* handle)
|
|
{
|
|
switch (handle->state)
|
|
{
|
|
case RC522_STATE_IDLE:
|
|
// 等待触发
|
|
break;
|
|
|
|
case RC522_STATE_REQUEST:
|
|
handle->status = PCD_Request(PICC_REQALL, handle->cardType);
|
|
if (handle->status == PCD_OK)
|
|
{
|
|
handle->state = RC522_STATE_ANTICOLL;
|
|
}
|
|
else
|
|
{
|
|
handle->state = RC522_STATE_IDLE;
|
|
}
|
|
break;
|
|
|
|
case RC522_STATE_ANTICOLL:
|
|
handle->status = PCD_AntiColl(handle->cardID);
|
|
if (handle->status == PCD_OK)
|
|
{
|
|
handle->state = RC522_STATE_SELECT;
|
|
}
|
|
else
|
|
{
|
|
handle->state = RC522_STATE_IDLE;
|
|
}
|
|
break;
|
|
|
|
case RC522_STATE_SELECT:
|
|
handle->status = PCD_Select(handle->cardID);
|
|
if (handle->status == PCD_OK)
|
|
{
|
|
handle->state = RC522_STATE_AUTH;
|
|
}
|
|
else
|
|
{
|
|
handle->state = RC522_STATE_IDLE;
|
|
}
|
|
break;
|
|
|
|
case RC522_STATE_AUTH:
|
|
handle->status = PCD_AuthState(PICC_AUTHENT1A, handle->blockAddr, handle->keyA, handle->cardID);
|
|
if (handle->status == PCD_OK)
|
|
{
|
|
handle->state = RC522_STATE_READ;
|
|
}
|
|
else
|
|
{
|
|
handle->state = RC522_STATE_IDLE;
|
|
}
|
|
break;
|
|
|
|
case RC522_STATE_READ:
|
|
handle->status = PCD_ReadBlock(handle->blockAddr, handle->blockData);
|
|
if (handle->status == PCD_OK)
|
|
{
|
|
handle->state = RC522_STATE_HALT;
|
|
}
|
|
else
|
|
{
|
|
handle->state = RC522_STATE_IDLE;
|
|
}
|
|
break;
|
|
|
|
case RC522_STATE_HALT:
|
|
PCD_Halt();
|
|
handle->state = RC522_STATE_IDLE;
|
|
break;
|
|
|
|
default:
|
|
handle->state = RC522_STATE_IDLE;
|
|
break;
|
|
}
|
|
}
|