Files
99_7018_lmx/apps/earphone/remote_control/RFID/reader/MIFARE.c

456 lines
14 KiB
C
Raw Normal View History

2025-12-01 10:01:10 +08:00
#include "../include/MIFARE.h"
#include "../include/READER.h"
#include "../include/READER_REG.h"
#include "../include/rfid_main.h"
#include "../rfid_hal.h"
#define FUN_ENABLE_XLOG 1
#ifdef xlog
#undef xlog
#endif
#if FUN_ENABLE_XLOG
#define xlog(format, ...) printf("[XT:%s] " format, __func__, ##__VA_ARGS__)
#else
#define xlog(format, ...) ((void)0)
#endif
unsigned char SECTOR,BLOCK,BLOCK_NUM;
unsigned char BLOCK_DATA[16];
unsigned char KEY_A[16][6]=
{{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//0
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//1
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//2
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//3
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//4
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//5
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//6
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//7
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//8
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//9
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//10
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//11
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//12
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//13
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//14
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}};//15
unsigned char KEY_B[16][6]=
{{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//0
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//1
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//2
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//3
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//4
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//5
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//6
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//7
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//8
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//9
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//10
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//11
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//12
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//13
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},//14
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}};//15
/**
* @brief Mifare卡加密认证标志
* @details
* Mifare卡进行认证AuthenticationBIT_CRYPTO1ON
* 便
* @return
*/
void Mifare_Clear_Crypto(void)
{
ModifyReg(REG_STATUS,BIT_CRYPTO1ON,RESET);
return;
}
/**
* @brief Mifare卡事件处理函数
* @details
* Mifare Classic卡进行读写操作的完整流程
* 1.
* 2. 1使A进行认证
* 3. 02
* 4. 160xFF
* 5.
* @return SUCCESS表示成功FAIL表示失败
*/
unsigned char MIFARE_CARD_EVENT(void)
{
unsigned char result;
int i;
Mifare_Clear_Crypto();
SECTOR = 1;
//for(SECTOR = 0;SECTOR < 16; SECTOR++)
{
BLOCK_NUM = (SECTOR * 4) + BLOCK;
result = Mifare_Auth(KEY_A_M1,SECTOR,KEY_A[SECTOR],PICC_A.UID);
if(result != SUCCESS)
{
SetCW(FUN_DISABLE);
xlog("-> AUTH ERROR!\r\n");
return result;
}
xlog("-> AUTH SUCCESS!\r\n");
for(BLOCK = 0;BLOCK < 3;BLOCK++)
{
BLOCK_NUM = (SECTOR * 4) + BLOCK;
if(BLOCK_NUM == 0)
BLOCK_NUM = 1;
xlog("-> SECTOR = %02X\r\n",SECTOR);;
xlog("-> BLOCK = %02X\r\n",BLOCK);
xlog("-> BLOCK_NUM = %02X\r\n",BLOCK_NUM);
memcpy(BLOCK_DATA,"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF",16);
result = Mifare_Blockwrite(BLOCK_NUM,BLOCK_DATA);
if(result != SUCCESS)
{
SetCW(FUN_DISABLE);
xlog("-> WRITE BLOCK ERROR!\r\n");
return result;
}
xlog("-> WRITE BLOCK SUCCESS!\r\n");
result = Mifare_Blockread(BLOCK_NUM,BLOCK_DATA);
if(result != SUCCESS)
{
SetCW(FUN_DISABLE);
xlog("-> READ BLOCK ERROR!\r\n");
return result;
}
xlog("-> READ BLOCK = ");
for(i=0; i<16; i++) xlog("%02X", BLOCK_DATA[i]);
xlog("\r\n");
}
}
SetCW(FUN_DISABLE);
return result;
}
/**
* @brief 6Mifare密钥加载到芯片的密钥缓冲区
* @param mifare_key [in] 6
* @return SUCCESS表示成功FAIL表示失败
* @details
* Mifare_Auth使
*/
unsigned char Mifare_LoadKey(unsigned char *mifare_key)
{
unsigned char reg_data;
SetCommand(CMD_IDLE);
ModifyReg(REG_FIFOCONTROL,BIT_FIFOFLUSH,FUN_ENABLE); //Clear FIFO
SetReg(REG_FIFODATA,mifare_key[0]);
SetReg(REG_FIFODATA,mifare_key[1]);
SetReg(REG_FIFODATA,mifare_key[2]);
SetReg(REG_FIFODATA,mifare_key[3]);
SetReg(REG_FIFODATA,mifare_key[4]);
SetReg(REG_FIFODATA,mifare_key[5]);
SetCommand(CMD_LOADKEY);
rfid_delay_ms(1);
GetReg(REG_COMMAND,&reg_data);
if((reg_data & CMD_MASK) == CMD_IDLE)
return SUCCESS;
else
return FAIL;
}
/**
* @brief Mifare Classic卡片的指定扇区进行认证
* @param key_mode [in] `KEY_A_M1` (0) 使A`KEY_B_M1` (1) 使B
* @param sector [in] (0-15)
* @param mifare_key [in] 6
* @param card_uid [in] 4UID的指针
* @return SUCCESS表示认证成功FAIL表示失败
* @details
* 访Mifare卡数据块之前的必要步骤
*/
unsigned char Mifare_Auth(unsigned char key_mode,unsigned char sector,unsigned char *mifare_key,unsigned char *card_uid)
{
unsigned char result,reg_data;
result = Mifare_LoadKey(mifare_key);
if (result != SUCCESS)
return result;
SetCommand(CMD_IDLE);
ModifyReg(REG_FIFOCONTROL,BIT_FIFOFLUSH,FUN_ENABLE); //Clear FIFO
if(key_mode == KEY_A_M1)
{
SetReg(REG_FIFODATA,0x60);// 0x60: Key A认证指令
ModifyReg(REG_RXTXCON,BIT_SHMODE,FUN_DISABLE);
}
if(key_mode == KEY_B_M1)
{
SetReg(REG_FIFODATA,0x61);// 0x61: Key B认证指令
ModifyReg(REG_RXTXCON,BIT_SHMODE,FUN_DISABLE);
}
SetReg(REG_FIFODATA,sector * 4);// 认证扇区的块0地址
SetReg(REG_FIFODATA,card_uid[0]);
SetReg(REG_FIFODATA,card_uid[1]);
SetReg(REG_FIFODATA,card_uid[2]);
SetReg(REG_FIFODATA,card_uid[3]);
ModifyReg(REG_TXCRCCON, BIT_CRCEN,FUN_ENABLE);
ModifyReg(REG_RXCRCCON, BIT_CRCEN,FUN_ENABLE);
SetCommand(CMD_AUTHENT);
rfid_delay_ms(5);
GetReg(REG_COMMAND,&reg_data);
if((reg_data & CMD_MASK) == CMD_IDLE)
{
GetReg(REG_STATUS,&reg_data);
if(reg_data & BIT_CRYPTO1ON)// 检查加密标志位以确认认证成功
return SUCCESS;
}
return FAIL;
}
/**
* @brief 4Mifare值块格式并写入指定块
* @param block [in]
* @param data_buff [in] 4
* @return SUCCESS表示成功FAIL表示失败
* @details
* Mifare值块有特定的数据格式
*/
unsigned char Mifare_Blockset(unsigned char block,unsigned char *data_buff)
{
unsigned char block_data[16],result;
// 格式化为值块
block_data[0] = data_buff[3];
block_data[1] = data_buff[2];
block_data[2] = data_buff[1];
block_data[3] = data_buff[0];
block_data[4] = ~data_buff[3];
block_data[5] = ~data_buff[2];
block_data[6] = ~data_buff[1];
block_data[7] = ~data_buff[0];
block_data[8] = data_buff[3];
block_data[9] = data_buff[2];
block_data[10] = data_buff[1];
block_data[11] = data_buff[0];
block_data[12] = block;
block_data[13] = ~block;
block_data[14] = block;
block_data[15] = ~block;
result = Mifare_Blockwrite(block,block_data);
return result;
}
/**
* @brief Mifare卡读取一个16字节的数据块
* @param block [in] (0x00 - 0x3F)
* @param data_buff [out] 16
* @return SUCCESS表示成功FAIL表示失败
*/
unsigned char Mifare_Blockread(unsigned char block,unsigned char *data_buff)
{
unsigned char reg_data,i;
SetCommand(CMD_IDLE);
SetReg(REG_TXDATANUM,0x08);
SetReg(REG_FIFODATA,0x30);// 0x30: 读块指令
SetReg(REG_FIFODATA,block);// 块地址
ModifyReg(REG_TXCRCCON, BIT_CRCEN,FUN_ENABLE);
ModifyReg(REG_RXCRCCON, BIT_CRCEN,FUN_ENABLE);
SetCommand(CMD_TRANSCEIVE);
rfid_delay_ms(2);
GetReg(REG_FIFOLENGTH,&reg_data);
if (reg_data != 16) // 成功时应返回16字节数据
return FAIL;
GetReg(REG_ERROR,&reg_data);
if(reg_data & 0x07)
return FAIL;
for(i=0;i<16;i++)
{
GetReg (REG_FIFODATA,&data_buff[i]);
}
return SUCCESS;
}
/**
* @brief Mifare卡写入一个16字节的数据块
* @param block [in] (0x00 - 0x3F)
* @param data_buff [in] 16
* @return SUCCESS表示成功FAIL表示失败
*/
unsigned char Mifare_Blockwrite(unsigned char block,unsigned char *data_buff)
{
unsigned char reg_data,i;
SetCommand(CMD_IDLE);
SetReg(REG_TXDATANUM,0x08);
SetReg(REG_FIFODATA,0xA0);// 0xA0: 写块指令
SetReg(REG_FIFODATA,block);// 块地址
ModifyReg(REG_TXCRCCON, BIT_CRCEN,FUN_ENABLE);
ModifyReg(REG_RXCRCCON, BIT_CRCEN,FUN_DISABLE);
SetCommand(CMD_TRANSCEIVE);
rfid_delay_ms(5);
GetReg(REG_FIFOLENGTH,&reg_data);
if (reg_data != 1) // 接收到ACK (0x0A)
return FAIL;
GetReg (REG_FIFODATA,&reg_data);
if(reg_data != 0x0A)
return FAIL;
for(i=0;i<16;i++)
{
SetReg(REG_FIFODATA,data_buff[i]);
}
SetCommand(CMD_TRANSCEIVE);
rfid_delay_ms(5);
GetReg(REG_FIFOLENGTH,&reg_data);
if (reg_data != 1) // 接收到ACK (0x0A)
return FAIL;
GetReg (REG_FIFODATA,&reg_data);
if(reg_data != 0x0A)
return FAIL;
return SUCCESS;
}
/**
* @brief Mifare卡的指定值块执行增值操作
* @param block [in]
* @param data_buff [in] 4
* @return SUCCESS表示成功FAIL表示失败
*/
unsigned char Mifare_Blockinc(unsigned char block,unsigned char *data_buff)
{
unsigned char reg_data,i;
SetCommand(CMD_IDLE);
SetReg(REG_TXDATANUM,0x08);
SetReg(REG_FIFODATA,0xC1);// 0xC1: 增值指令
SetReg(REG_FIFODATA,block);// 块地址
ModifyReg(REG_TXCRCCON, BIT_CRCEN,FUN_ENABLE);
ModifyReg(REG_RXCRCCON, BIT_CRCEN,FUN_DISABLE);
SetCommand(CMD_TRANSCEIVE);
rfid_delay_ms(5);
GetReg(REG_FIFOLENGTH,&reg_data);
if (reg_data != 1)
return FAIL;
GetReg (REG_FIFODATA,&reg_data);
if(reg_data != 0x0A)
return FAIL;
for(i=0;i<4;i++)
{
SetReg(REG_FIFODATA,data_buff[i]);
}
SetCommand(CMD_TRANSCEIVE);
rfid_delay_ms(5);
GetReg(REG_FIFOLENGTH,&reg_data);
if (reg_data != 1)
return FAIL;
GetReg (REG_FIFODATA,&reg_data);
if(reg_data != 0x0A)
return FAIL;
return SUCCESS;
}
/**
* @brief Mifare卡的指定值块执行减值操作
* @param block [in]
* @param data_buff [in] 4
* @return SUCCESS表示成功FAIL表示失败
*/
unsigned char Mifare_Blockdec(unsigned char block,unsigned char *data_buff)
{
unsigned char reg_data,i;
SetCommand(CMD_IDLE);
SetReg(REG_TXDATANUM,0x08);
SetReg(REG_FIFODATA,0xC0);// 0xC0: 减值指令
SetReg(REG_FIFODATA,block);// 块地址
ModifyReg(REG_TXCRCCON, BIT_CRCEN,FUN_ENABLE);
ModifyReg(REG_RXCRCCON, BIT_CRCEN,FUN_DISABLE);
SetCommand(CMD_TRANSCEIVE);
rfid_delay_ms(5);
GetReg(REG_FIFOLENGTH,&reg_data);
if (reg_data != 1)
return FAIL;
GetReg (REG_FIFODATA,&reg_data);
if(reg_data != 0x0A)
return FAIL;
for(i=0;i<4;i++)
{
SetReg(REG_FIFODATA,data_buff[i]);
}
SetCommand(CMD_TRANSCEIVE);
rfid_delay_ms(5);
GetReg(REG_FIFOLENGTH,&reg_data);
if (reg_data != 1)
return FAIL;
GetReg (REG_FIFODATA,&reg_data);
if(reg_data != 0x0A)
return FAIL;
return SUCCESS;
}
/**
* @brief Mifare卡的传输Transfer
* @param block [in]
* @return SUCCESS表示成功FAIL表示失败
* @details
* /
*/
unsigned char Mifare_Transfer(unsigned char block)
{
unsigned char reg_data;
SetCommand(CMD_IDLE);
SetReg(REG_TXDATANUM,0x08);
SetReg(REG_FIFODATA,0xB0);// 0xB0: Transfer指令
SetReg(REG_FIFODATA,block);// 块地址
ModifyReg(REG_TXCRCCON, BIT_CRCEN,FUN_ENABLE);
ModifyReg(REG_RXCRCCON, BIT_CRCEN,FUN_DISABLE);
SetCommand(CMD_TRANSCEIVE);
rfid_delay_ms(5);
GetReg(REG_FIFOLENGTH,&reg_data);
if (reg_data != 1)
return FAIL;
GetReg (REG_FIFODATA,&reg_data);
if(reg_data != 0x0A)
return FAIL;
return SUCCESS;
}
/**
* @brief Mifare卡的恢复Restore
* @param block [in]
* @return SUCCESS表示成功FAIL表示失败
* @details
*
*/
unsigned char Mifare_Restore(unsigned char block)
{
unsigned char reg_data,i;
SetCommand(CMD_IDLE);
SetReg(REG_TXDATANUM,0x08);
SetReg(REG_FIFODATA,0xC2);// 0xC2: Restore指令
SetReg(REG_FIFODATA,block);// 块地址
ModifyReg(REG_TXCRCCON, BIT_CRCEN,FUN_ENABLE);
ModifyReg(REG_RXCRCCON, BIT_CRCEN,FUN_DISABLE);
SetCommand(CMD_TRANSCEIVE);
rfid_delay_ms(5);
GetReg(REG_FIFOLENGTH,&reg_data);
if (reg_data != 1)
return FAIL;
GetReg (REG_FIFODATA,&reg_data);
if(reg_data != 0x0A)
return FAIL;
for(i=0;i<4;i++)
{
SetReg(REG_FIFODATA,0);
}
SetCommand(CMD_TRANSCEIVE);
rfid_delay_ms(5);
GetReg(REG_FIFOLENGTH,&reg_data);
if (reg_data != 1)
return FAIL;
GetReg (REG_FIFODATA,&reg_data);
if(reg_data != 0x0A)
return FAIL;
return SUCCESS;
}