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

774 lines
25 KiB
C
Raw Normal View History

2025-11-24 16:33:33 +08:00
/********************************************************************************************************
* @file READER.c
* @brief RFID
* @details
* FM176XX系列RFID芯片的底层通信协议
* - Type A, B, V, F
* -
* - FIFORF场
* `rfid_hal.h`
********************************************************************************************************/
#include "../include/READER.h"
#include "../include/READER_REG.h"
#include "../include/rfid_main.h"
#include "../rfid_hal.h" // 引入硬件抽象层
2025-11-24 18:58:32 +08:00
#define FUN_ENABLE_XLOG 1
2025-11-24 16:33:33 +08:00
#ifdef xlog
#undef xlog
#endif
2025-11-24 18:58:32 +08:00
#if FUN_ENABLE_XLOG
2025-11-24 16:33:33 +08:00
#define xlog(format, ...) printf("[XT:%s] " format, __func__, ##__VA_ARGS__)
#else
#define xlog(format, ...) ((void)0)
#endif
// 定义全局变量以存储不同类型卡片的信息
struct picc_a_struct PICC_A;
struct picc_b_struct PICC_B;
struct picc_v_struct PICC_V;
struct picc_f_struct PICC_F;
/********************************************************************************************************
*
********************************************************************************************************/
/**
* @brief
* @param reg_address [in]
* @param mask [in]
* @param set [in] 010
* @return
* @details
* --`set`
*
*/
void ModifyReg(unsigned char reg_address, unsigned char mask, unsigned char set)
{
unsigned char reg_data;
GetReg(reg_address, &reg_data);
if (set)
{
reg_data |= mask;
}
else
{
reg_data &= ~mask;
}
SetReg(reg_address, reg_data);
}
/**
* @brief
* @param command [in] CMD_IDLE, CMD_TRANSCEIVE等
* @return SUCCESS表示成功
*/
unsigned char SetCommand(unsigned char command)
{
return SetReg(REG_COMMAND, CMD_MASK & command);
}
/**
* @brief
* @param timeout [in] (ms)
* @return
* @details
* T0和T1定时器
*
*/
void SetTimer(unsigned int timeout)
{
unsigned long prescale = 1;
unsigned long t, fc;
fc = timeout * 13560; // 13.56MHz时钟频率
t = fc;
while (fc > 65535)
{
prescale *= 2;
fc = t / prescale;
if (fc * prescale != t)
fc++;
}
if (prescale > 1)
{
SetReg(REG_T0CONTROL, BIT_TSTOP_RX | BIT_TSTART_TX | BIT_TAUTORESTARTED | VALUE_TCLK_1356_MHZ);
SetReg(REG_T0RELOADHI, (unsigned char)(fc >> 8));
SetReg(REG_T0RELOADLO, (unsigned char)fc);
SetReg(REG_T1CONTROL, BIT_TSTOP_RX | BIT_TSTART_TX | VALUE_TCLK_T0);
SetReg(REG_T1RELOADHI, (unsigned char)(prescale >> 8));
SetReg(REG_T1RELOADLO, (unsigned char)prescale);
}
else
{
SetReg(REG_T1CONTROL, BIT_TSTOP_RX | BIT_TSTART_TX | VALUE_TCLK_1356_MHZ);
SetReg(REG_T1RELOADHI, (unsigned char)(fc >> 8));
SetReg(REG_T1RELOADLO, (unsigned char)fc);
}
}
/**
* @brief RF场
2025-11-24 18:58:32 +08:00
* @param mode [in] FUN_ENABLE表示打开FUN_DISABLE表示关闭
2025-11-24 16:33:33 +08:00
* @return SUCCESS表示成功
*/
unsigned char SetCW(unsigned char mode)
{
2025-11-24 18:58:32 +08:00
if (mode == FUN_ENABLE)
2025-11-24 16:33:33 +08:00
{
2025-11-24 18:58:32 +08:00
ModifyReg(REG_COMMAND, BIT_MODEMOFF, FUN_DISABLE);
ModifyReg(REG_TXMODE, BIT_TPUSHON | BIT_TPULLON, FUN_ENABLE);
2025-11-24 16:33:33 +08:00
}
else
{
2025-11-24 18:58:32 +08:00
ModifyReg(REG_COMMAND, BIT_MODEMOFF, FUN_ENABLE);
ModifyReg(REG_TXMODE, BIT_TPUSHON | BIT_TPULLON, FUN_DISABLE);
2025-11-24 16:33:33 +08:00
}
rfid_delay_ms(5);
return SUCCESS;
}
/**
* @brief FIFO缓冲区
* @return
*/
void Clear_FIFO(void)
{
unsigned char fifolength;
GetReg(REG_FIFOLENGTH, &fifolength);
if (fifolength != 0)
{
2025-11-24 18:58:32 +08:00
ModifyReg(REG_FIFOCONTROL, BIT_FIFOFLUSH, FUN_ENABLE);
2025-11-24 16:33:33 +08:00
}
}
/**
* @brief
* @param p_rx [in]
* @param p_tx [in]
* @return SUCCESS表示成功FAIL表示失败
* @details
* A, B, V, F使
*
*/
unsigned char LoadProtocol(unsigned char p_rx, unsigned char p_tx)
{
unsigned char reg_data = 0;
SetCommand(CMD_IDLE);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_FIFOCONTROL, BIT_FIFOFLUSH, FUN_ENABLE); // 清空FIFO
2025-11-24 16:33:33 +08:00
SetReg(REG_FIFODATA, p_rx); // 写入接收协议
SetReg(REG_FIFODATA, p_tx); // 写入发送协议
SetCommand(CMD_LOADPROTOCOL);
rfid_delay_ms(2);
GetReg(REG_COMMAND, &reg_data);
if (reg_data != CMD_IDLE)
return FAIL;
return SUCCESS;
}
/**
* @brief 使
2025-11-24 18:58:32 +08:00
* @param state [in] FUN_ENABLE或FUN_DISABLE
2025-11-24 16:33:33 +08:00
* @return
*/
void SetParity(unsigned char state)
{
ModifyReg(REG_FRAMECON, BIT_TXPARITYEN | BIT_RXPARITYEN, state);
}
/**
* @brief Type A卡片
* @return SUCCESS表示成功
*/
unsigned char ReaderA_Initial(void)
{
LoadProtocol(RX_TYPEA_106, TX_TYPEA_106);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_TXMODE, BIT_RFON, FUN_ENABLE); // FORCE 100ask FUN_ENABLE
2025-11-24 16:33:33 +08:00
SetReg(REG_TXAMP, AMPLITUDE_A);
SetReg(REG_TXCON, 0x00);
SetReg(REG_RXANA, (HPCF_A << 3) | GAIN_A);
SetReg(0x5F, 0x08);
SetReg(REG_THNSET, 0xFF);
SetReg(REG_THNMIN, 0xC0);
SetReg(REG_RXTXCON, 0x80);
2025-11-24 18:58:32 +08:00
SetParity(FUN_ENABLE);
2025-11-24 16:33:33 +08:00
SetReg(REG_STATUS, 0); // 清除Crypto1On位
return SUCCESS;
}
/**
* @brief Type B卡片
* @return SUCCESS表示成功
*/
unsigned char ReaderB_Initial(void)
{
LoadProtocol(RX_TYPEB_106, TX_TYPEB_106);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_TXMODE, BIT_RFON, FUN_DISABLE); // FORCE 100ask FUN_DISABLE
2025-11-24 16:33:33 +08:00
SetReg(REG_TXAMP, AMPLITUDE_B);
SetReg(REG_TXCON, MODULATION_B);
SetReg(REG_RXANA, (HPCF_B << 3) | GAIN_B);
SetReg(0x5F, 0x08);
SetReg(REG_THNSET, 0xFF);
SetReg(REG_THNMIN, 0xC0);
SetReg(REG_RXTXCON, 0x80);
return SUCCESS;
}
/**
* @brief Type V (ISO15693)
* @return SUCCESS表示成功
*/
unsigned char ReaderV_Initial(void)
{
LoadProtocol(RX_TYPEV_26, RX_TYPEV_26);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_RXANA, MASK_RCV_GAIN | MASK_RCV_HPCF, FUN_DISABLE);
ModifyReg(REG_RXANA, (HPCF_V << 3) | GAIN_V, FUN_ENABLE);
SetParity(FUN_DISABLE);
2025-11-24 16:33:33 +08:00
SetReg(REG_TXAMP, AMPLITUDE_V);
SetReg(REG_TXCON, MODULATION_V);
SetReg(REG_TXI, 0x06);
SetReg(REG_THNSET, 0xFF);
SetReg(REG_THNMIN, 0x80);
SetReg(REG_THNADJ, 0x08);
SetReg(REG_RXTXCON, 0);
return SUCCESS;
}
/**
* @brief Type F (FeliCa)
* @return SUCCESS表示成功
*/
unsigned char ReaderF_Initial(void)
{
2025-11-24 18:58:32 +08:00
ModifyReg(REG_MISC, 0x04, FUN_ENABLE);
2025-11-24 16:33:33 +08:00
LoadProtocol(RX_FELICA_212, TX_FELICA_212);
SetReg(REG_TXAMP, AMPLITUDE_F);
SetReg(REG_TXCON, MODULATION_F);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_RXANA, MASK_RCV_GAIN | MASK_RCV_HPCF, FUN_DISABLE);
ModifyReg(REG_RXANA, (HPCF_F << 3) | GAIN_F, FUN_ENABLE);
SetParity(FUN_DISABLE);
2025-11-24 16:33:33 +08:00
SetReg(REG_THNSET, 0xFF);
SetReg(REG_THNMIN, 0x80);
SetReg(REG_THNADJ, 0x08);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_MISC, 0x04, FUN_DISABLE);
2025-11-24 16:33:33 +08:00
return SUCCESS;
}
/**
* @brief Type A卡片发送WUPAWake-Up A
* @param picc_a [out]
* @return SUCCESS表示成功FAIL表示失败
*/
unsigned char ReaderA_Wakeeup(struct picc_a_struct *picc_a)
{
unsigned char reg_data;
SetCommand(CMD_IDLE);
SetReg(REG_TXDATANUM, 0x0F);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_FIFOCONTROL, BIT_FIFOFLUSH, FUN_ENABLE);
2025-11-24 16:33:33 +08:00
SetReg(REG_FIFODATA, RF_CMD_WUPA);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_TXCRCCON, BIT_CRCEN, FUN_DISABLE);
ModifyReg(REG_RXCRCCON, BIT_CRCEN, FUN_DISABLE);
2025-11-24 16:33:33 +08:00
SetCommand(CMD_TRANSCEIVE);
rfid_delay_ms(2);
GetReg(REG_FIFOLENGTH, &reg_data);
if (reg_data != 2)
return FAIL;
GetReg(REG_FIFODATA, &picc_a->ATQA[0]);
GetReg(REG_FIFODATA, &picc_a->ATQA[1]);
return SUCCESS;
}
/**
* @brief Type A卡片发送REQARequest A
* @param picc_a [out]
* @return SUCCESS表示成功FAIL表示失败
*/
unsigned char ReaderA_Request(struct picc_a_struct *picc_a)
{
unsigned char reg_data;
SetCommand(CMD_IDLE);
SetReg(REG_TXDATANUM, 0x0F);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_FIFOCONTROL, BIT_FIFOFLUSH, FUN_ENABLE);
2025-11-24 16:33:33 +08:00
SetReg(REG_FIFODATA, RF_CMD_REQA);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_TXCRCCON, BIT_CRCEN, FUN_DISABLE);
ModifyReg(REG_RXCRCCON, BIT_CRCEN, FUN_DISABLE);
2025-11-24 16:33:33 +08:00
SetCommand(CMD_TRANSCEIVE);
rfid_delay_ms(2);
GetReg(REG_FIFOLENGTH, &reg_data);
if (reg_data != 2)
return FAIL;
GetReg(REG_FIFODATA, &picc_a->ATQA[0]);
GetReg(REG_FIFODATA, &picc_a->ATQA[1]);
return SUCCESS;
}
/**
* @brief Type A卡片的防冲突流程
* @param picc_a [in, out]
* @return SUCCESS表示成功FAIL表示失败
*/
unsigned char ReaderA_Anticoll(struct picc_a_struct *picc_a)
{
unsigned char reg_data;
SetCommand(CMD_IDLE);
SetReg(REG_TXDATANUM, 0x08);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_FIFOCONTROL, BIT_FIFOFLUSH, FUN_ENABLE);
2025-11-24 16:33:33 +08:00
SetReg(REG_FIFODATA, RF_CMD_ANTICOLL[picc_a->CASCADE_LEVEL]);
SetReg(REG_FIFODATA, 0x20);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_TXCRCCON, BIT_CRCEN, FUN_DISABLE);
ModifyReg(REG_RXCRCCON, BIT_CRCEN, FUN_DISABLE);
2025-11-24 16:33:33 +08:00
SetCommand(CMD_TRANSCEIVE);
rfid_delay_ms(2);
GetReg(REG_FIFOLENGTH, &reg_data);
if (reg_data != 5)
return FAIL;
GetReg(REG_FIFODATA, &picc_a->UID[picc_a->CASCADE_LEVEL * 4]);
GetReg(REG_FIFODATA, &picc_a->UID[picc_a->CASCADE_LEVEL * 4 + 1]);
GetReg(REG_FIFODATA, &picc_a->UID[picc_a->CASCADE_LEVEL * 4 + 2]);
GetReg(REG_FIFODATA, &picc_a->UID[picc_a->CASCADE_LEVEL * 4 + 3]);
GetReg(REG_FIFODATA, &picc_a->BCC[picc_a->CASCADE_LEVEL]);
if ((picc_a->UID[picc_a->CASCADE_LEVEL * 4] ^ picc_a->UID[picc_a->CASCADE_LEVEL * 4 + 1] ^ picc_a->UID[picc_a->CASCADE_LEVEL * 4 + 2] ^ picc_a->UID[picc_a->CASCADE_LEVEL * 4 + 3]) == picc_a->BCC[picc_a->CASCADE_LEVEL])
return SUCCESS;
return FAIL;
}
/**
* @brief Type A卡片
* @param picc_a [in, out]
* @return SUCCESS表示成功FAIL表示失败
*/
unsigned char ReaderA_Select(struct picc_a_struct *picc_a)
{
unsigned char reg_data;
SetCommand(CMD_IDLE);
SetReg(REG_TXDATANUM, 0x08);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_FIFOCONTROL, BIT_FIFOFLUSH, FUN_ENABLE);
2025-11-24 16:33:33 +08:00
SetReg(REG_FIFODATA, RF_CMD_ANTICOLL[picc_a->CASCADE_LEVEL]);
SetReg(REG_FIFODATA, 0x70);
SetReg(REG_FIFODATA, picc_a->UID[picc_a->CASCADE_LEVEL * 4]);
SetReg(REG_FIFODATA, picc_a->UID[picc_a->CASCADE_LEVEL * 4 + 1]);
SetReg(REG_FIFODATA, picc_a->UID[picc_a->CASCADE_LEVEL * 4 + 2]);
SetReg(REG_FIFODATA, picc_a->UID[picc_a->CASCADE_LEVEL * 4 + 3]);
SetReg(REG_FIFODATA, picc_a->BCC[picc_a->CASCADE_LEVEL]);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_TXCRCCON, BIT_CRCEN, FUN_ENABLE);
ModifyReg(REG_RXCRCCON, BIT_CRCEN, FUN_ENABLE);
2025-11-24 16:33:33 +08:00
SetCommand(CMD_TRANSCEIVE);
rfid_delay_ms(2);
GetReg(REG_ERROR, &reg_data);
if ((reg_data & 0x0F) != 0)
return FAIL;
GetReg(REG_FIFOLENGTH, &reg_data);
if (reg_data != 1)
return FAIL;
GetReg(REG_FIFODATA, &picc_a->SAK[picc_a->CASCADE_LEVEL]);
return SUCCESS;
}
/**
* @brief Type A卡片REQA, Anticoll, Select全过程
* @param picc_a [out]
* @return SUCCESS表示成功FAIL表示失败
*/
unsigned char ReaderA_CardActivate(struct picc_a_struct *picc_a)
{
unsigned char result, cascade_level;
result = ReaderA_Request(picc_a);
if (result != SUCCESS)
return result;
if ((picc_a->ATQA[0] & 0xC0) == 0x00) // 单倍UID
{
cascade_level = 1;
picc_a->UID_Length = 4;
}
else if ((picc_a->ATQA[0] & 0xC0) == 0x40) // 双倍UID
{
cascade_level = 2;
picc_a->UID_Length = 7; // 实际是7字节
}
else if ((picc_a->ATQA[0] & 0xC0) == 0x80) // 三倍UID
{
cascade_level = 3;
picc_a->UID_Length = 10; // 实际是10字节
}
else
{
return FAIL; // 未知UID长度
}
for (picc_a->CASCADE_LEVEL = 0; picc_a->CASCADE_LEVEL < cascade_level; picc_a->CASCADE_LEVEL++)
{
result = ReaderA_Anticoll(picc_a);
if (result != SUCCESS)
return result;
result = ReaderA_Select(picc_a);
if (result != SUCCESS)
return result;
}
picc_a->CASCADE_LEVEL--;
return result;
}
/**
* @brief Type B卡片发送WUPBWake-Up B
* @param picc_b [out]
* @return SUCCESS表示成功FAIL表示失败
*/
unsigned char ReaderB_Wakeup(struct picc_b_struct *picc_b)
{
unsigned char reg_data, i;
SetCommand(CMD_IDLE);
SetReg(REG_TXDATANUM, 0x08);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_FIFOCONTROL, BIT_FIFOFLUSH, FUN_ENABLE);
2025-11-24 16:33:33 +08:00
SetReg(REG_FIFODATA, 0x05); // APf
SetReg(REG_FIFODATA, 0x00); // AFI (00:for all cards)
SetReg(REG_FIFODATA, 0x08); // PARAM(WUPB, Number of slots = 0)
2025-11-24 18:58:32 +08:00
ModifyReg(REG_TXCRCCON, BIT_CRCEN, FUN_ENABLE);
ModifyReg(REG_RXCRCCON, BIT_CRCEN, FUN_ENABLE);
2025-11-24 16:33:33 +08:00
SetCommand(CMD_TRANSCEIVE);
rfid_delay_ms(10);
GetReg(REG_ERROR, &reg_data);
if ((reg_data & 0x0F) != 0)
return FAIL;
GetReg(REG_FIFOLENGTH, &reg_data);
if (reg_data != 12)
return FAIL;
for (i = 0; i < 12; i++)
GetReg(REG_FIFODATA, &picc_b->ATQB[i]);
memcpy(picc_b->PUPI, picc_b->ATQB + 1, 4);
memcpy(picc_b->APPLICATION_DATA, picc_b->ATQB + 6, 4);
memcpy(picc_b->PROTOCOL_INF, picc_b->ATQB + 10, 3);
return SUCCESS;
}
/**
* @brief Type B卡片发送REQBRequest B
* @param picc_b [out]
* @return SUCCESS表示成功FAIL表示失败
*/
unsigned char ReaderB_Request(struct picc_b_struct *picc_b)
{
unsigned char reg_data, i;
SetCommand(CMD_IDLE);
SetReg(REG_TXDATANUM, 0x08);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_FIFOCONTROL, BIT_FIFOFLUSH, FUN_ENABLE);
2025-11-24 16:33:33 +08:00
SetReg(REG_FIFODATA, 0x05); // APf
SetReg(REG_FIFODATA, 0x00); // AFI (00:for all cards)
SetReg(REG_FIFODATA, 0x00); // PARAM(REQB, Number of slots = 0)
2025-11-24 18:58:32 +08:00
ModifyReg(REG_TXCRCCON, BIT_CRCEN, FUN_ENABLE);
ModifyReg(REG_RXCRCCON, BIT_CRCEN, FUN_ENABLE);
2025-11-24 16:33:33 +08:00
SetCommand(CMD_TRANSCEIVE);
rfid_delay_ms(10);
GetReg(REG_ERROR, &reg_data);
if ((reg_data & 0x0F) != 0)
return FAIL;
GetReg(REG_FIFOLENGTH, &reg_data);
if (reg_data != 12)
return FAIL;
for (i = 0; i < 12; i++)
GetReg(REG_FIFODATA, &picc_b->ATQB[i]);
memcpy(picc_b->PUPI, picc_b->ATQB + 1, 4);
memcpy(picc_b->APPLICATION_DATA, picc_b->ATQB + 6, 4);
memcpy(picc_b->PROTOCOL_INF, picc_b->ATQB + 10, 3);
return SUCCESS;
}
/**
* @brief Type B卡片发送ATTRIB命令
* @param picc_b [in, out]
* @return SUCCESS表示成功FAIL表示失败
*/
unsigned char ReaderB_Attrib(struct picc_b_struct *picc_b)
{
unsigned char reg_data;
SetCommand(CMD_IDLE);
SetReg(REG_TXDATANUM, 0x08);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_FIFOCONTROL, BIT_FIFOFLUSH, FUN_ENABLE);
2025-11-24 16:33:33 +08:00
SetReg(REG_FIFODATA, 0x1D);
SetReg(REG_FIFODATA, picc_b->PUPI[0]);
SetReg(REG_FIFODATA, picc_b->PUPI[1]);
SetReg(REG_FIFODATA, picc_b->PUPI[2]);
SetReg(REG_FIFODATA, picc_b->PUPI[3]);
SetReg(REG_FIFODATA, 0x00); // Param1
SetReg(REG_FIFODATA, 0x08); // Param2
SetReg(REG_FIFODATA, 0x01); // COMPATIBLE WITH 14443-4
SetReg(REG_FIFODATA, 0x01); // CID:01
2025-11-24 18:58:32 +08:00
ModifyReg(REG_TXCRCCON, BIT_CRCEN, FUN_ENABLE);
ModifyReg(REG_RXCRCCON, BIT_CRCEN, FUN_ENABLE);
2025-11-24 16:33:33 +08:00
SetCommand(CMD_TRANSCEIVE);
rfid_delay_ms(10);
GetReg(REG_ERROR, &reg_data);
if ((reg_data & 0x0F) != 0)
return FAIL;
GetReg(REG_FIFOLENGTH, &reg_data);
if (reg_data != 1)
return FAIL;
GetReg(REG_FIFODATA, &reg_data);
picc_b->CID = reg_data & 0x0F;
return SUCCESS;
}
/**
* @brief Type B卡片发送HALT命令使
* @param picc_b [in, out]
* @return SUCCESS表示成功FAIL表示失败
*/
unsigned char ReaderB_Halt(struct picc_b_struct *picc_b)
{
unsigned char reg_data;
SetCommand(CMD_IDLE);
SetReg(REG_TXDATANUM, 0x08);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_FIFOCONTROL, BIT_FIFOFLUSH, FUN_ENABLE);
2025-11-24 16:33:33 +08:00
SetReg(REG_FIFODATA, 0x50);
SetReg(REG_FIFODATA, picc_b->PUPI[0]);
SetReg(REG_FIFODATA, picc_b->PUPI[1]);
SetReg(REG_FIFODATA, picc_b->PUPI[2]);
SetReg(REG_FIFODATA, picc_b->PUPI[3]);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_TXCRCCON, BIT_CRCEN, FUN_ENABLE);
ModifyReg(REG_RXCRCCON, BIT_CRCEN, FUN_ENABLE);
2025-11-24 16:33:33 +08:00
SetCommand(CMD_TRANSCEIVE);
rfid_delay_ms(10);
GetReg(REG_ERROR, &reg_data);
if ((reg_data & 0x0F) != 0)
return FAIL;
GetReg(REG_FIFOLENGTH, &reg_data);
if (reg_data != 1)
return FAIL;
GetReg(REG_FIFODATA, &reg_data);
*picc_b->Answer_to_HALT = reg_data & 0x0F;
return SUCCESS;
}
/**
* @brief Type B卡片的序列号
* @param picc_b [out]
* @return SUCCESS表示成功FAIL表示失败
*/
unsigned char ReaderB_Get_SN(struct picc_b_struct *picc_b)
{
unsigned char reg_data, i;
SetCommand(CMD_IDLE);
SetReg(REG_TXDATANUM, 0x08);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_FIFOCONTROL, BIT_FIFOFLUSH, FUN_ENABLE);
2025-11-24 16:33:33 +08:00
SetReg(REG_FIFODATA, 0x00);
SetReg(REG_FIFODATA, 0x36);
SetReg(REG_FIFODATA, 0x00);
SetReg(REG_FIFODATA, 0x00);
SetReg(REG_FIFODATA, 0x08);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_TXCRCCON, BIT_CRCEN, FUN_ENABLE);
ModifyReg(REG_RXCRCCON, BIT_CRCEN, FUN_ENABLE);
2025-11-24 16:33:33 +08:00
SetCommand(CMD_TRANSCEIVE);
rfid_delay_ms(10);
GetReg(REG_ERROR, &reg_data);
if ((reg_data & 0x0F) != 0)
return FAIL;
GetReg(REG_FIFOLENGTH, &reg_data);
if (reg_data != 10)
return FAIL;
for (i = 0; i < 8; i++)
GetReg(REG_FIFODATA, &picc_b->SN[i]);
return SUCCESS;
}
/**
* @brief Type V (ISO15693) Inventory命令
* @param picc_v [out]
* @return SUCCESS表示成功FAIL表示失败
*/
unsigned char ReaderV_Inventory(struct picc_v_struct *picc_v)
{
unsigned char reg_data, i;
SetCommand(CMD_IDLE);
SetReg(REG_TXDATANUM, 0x08);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_FIFOCONTROL, BIT_FIFOFLUSH, FUN_ENABLE);
2025-11-24 16:33:33 +08:00
SetReg(REG_FIFODATA, 0x26);
SetReg(REG_FIFODATA, 0x01);
SetReg(REG_FIFODATA, 0x00);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_TXCRCCON, BIT_CRCEN, FUN_ENABLE);
ModifyReg(REG_RXCRCCON, BIT_CRCEN, FUN_ENABLE);
2025-11-24 16:33:33 +08:00
SetCommand(CMD_TRANSCEIVE);
rfid_delay_ms(10);
GetReg(REG_ERROR, &reg_data);
if ((reg_data & 0x0F) != 0)
return FAIL;
GetReg(REG_FIFOLENGTH, &reg_data);
if (reg_data != 10)
return FAIL;
GetReg(REG_FIFODATA, &picc_v->RESPONSE);
GetReg(REG_FIFODATA, &reg_data); // DSFID
for (i = 0; i < 8; i++)
{
GetReg(REG_FIFODATA, &picc_v->UID[i]);
}
return SUCCESS;
}
/**
* @brief UID的Type V卡片
* @param picc_v [in, out]
* @return SUCCESS表示成功FAIL表示失败
*/
unsigned char ReaderV_Select(struct picc_v_struct *picc_v)
{
unsigned char reg_data;
SetCommand(CMD_IDLE);
SetReg(REG_TXDATANUM, 0x08);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_FIFOCONTROL, BIT_FIFOFLUSH, FUN_ENABLE);
2025-11-24 16:33:33 +08:00
SetReg(REG_FIFODATA, 0x22); // Addressed flag
SetReg(REG_FIFODATA, 0x25); // Select command
SetReg(REG_FIFODATA, picc_v->UID[0]);
SetReg(REG_FIFODATA, picc_v->UID[1]);
SetReg(REG_FIFODATA, picc_v->UID[2]);
SetReg(REG_FIFODATA, picc_v->UID[3]);
SetReg(REG_FIFODATA, picc_v->UID[4]);
SetReg(REG_FIFODATA, picc_v->UID[5]);
SetReg(REG_FIFODATA, picc_v->UID[6]);
SetReg(REG_FIFODATA, picc_v->UID[7]);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_TXCRCCON, BIT_CRCEN, FUN_ENABLE);
ModifyReg(REG_RXCRCCON, BIT_CRCEN, FUN_ENABLE);
2025-11-24 16:33:33 +08:00
SetCommand(CMD_TRANSCEIVE);
rfid_delay_ms(10);
GetReg(REG_ERROR, &reg_data);
if ((reg_data & 0x0F) != 0)
return FAIL;
GetReg(REG_FIFOLENGTH, &reg_data);
if (reg_data != 1)
return FAIL;
GetReg(REG_FIFODATA, &picc_v->RESPONSE);
return SUCCESS;
}
/**
* @brief Type V卡片的单个数据块
* @param block_num [in]
* @param picc_v [out] `BLOCK_DATA`
* @return SUCCESS表示成功FAIL表示失败
*/
unsigned char ReaderV_ReadSingleBlock(unsigned char block_num, struct picc_v_struct *picc_v)
{
unsigned char reg_data, i;
SetCommand(CMD_IDLE);
SetReg(REG_TXDATANUM, 0x08);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_FIFOCONTROL, BIT_FIFOFLUSH, FUN_ENABLE);
2025-11-24 16:33:33 +08:00
SetReg(REG_FIFODATA, 0x02); // Addressed flag
SetReg(REG_FIFODATA, 0x20); // Read Single Block command
SetReg(REG_FIFODATA, block_num);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_TXCRCCON, BIT_CRCEN, FUN_ENABLE);
ModifyReg(REG_RXCRCCON, BIT_CRCEN, FUN_ENABLE);
2025-11-24 16:33:33 +08:00
SetCommand(CMD_TRANSCEIVE);
rfid_delay_ms(10);
GetReg(REG_ERROR, &reg_data);
if ((reg_data & 0x0F) != 0)
return FAIL;
GetReg(REG_FIFOLENGTH, &reg_data);
if (reg_data != 5) // 1 byte response flag + 4 bytes data
return FAIL;
GetReg(REG_FIFODATA, &picc_v->RESPONSE);
for (i = 0; i < 4; i++)
{
GetReg(REG_FIFODATA, &picc_v->BLOCK_DATA[i]);
}
return SUCCESS;
}
/**
* @brief Type V卡片的单个数据块写入数据
* @param block_num [in]
* @param picc_v [in] `BLOCK_DATA`
* @return SUCCESS表示成功FAIL表示失败
*/
unsigned char ReaderV_WriteSingleBlock(unsigned char block_num, struct picc_v_struct *picc_v)
{
unsigned char reg_data;
SetCommand(CMD_IDLE);
SetReg(REG_TXDATANUM, 0x08);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_FIFOCONTROL, BIT_FIFOFLUSH, FUN_ENABLE);
2025-11-24 16:33:33 +08:00
SetReg(REG_FIFODATA, 0x02); // Addressed flag
SetReg(REG_FIFODATA, 0x21); // Write Single Block command
SetReg(REG_FIFODATA, block_num);
SetReg(REG_FIFODATA, picc_v->BLOCK_DATA[0]);
SetReg(REG_FIFODATA, picc_v->BLOCK_DATA[1]);
SetReg(REG_FIFODATA, picc_v->BLOCK_DATA[2]);
SetReg(REG_FIFODATA, picc_v->BLOCK_DATA[3]);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_TXCRCCON, BIT_CRCEN, FUN_ENABLE);
ModifyReg(REG_RXCRCCON, BIT_CRCEN, FUN_ENABLE);
2025-11-24 16:33:33 +08:00
SetCommand(CMD_TRANSCEIVE);
rfid_delay_ms(10);
GetReg(REG_ERROR, &reg_data);
if ((reg_data & 0x0F) != 0)
return FAIL;
GetReg(REG_FIFOLENGTH, &reg_data);
if (reg_data != 1)
return FAIL;
GetReg(REG_FIFODATA, &picc_v->RESPONSE);
return SUCCESS;
}
/**
* @brief Type F (FeliCa) Inventory命令
* @param picc_f [out]
* @return SUCCESS表示成功FAIL表示失败
*/
unsigned char ReaderF_Inventory(struct picc_f_struct *picc_f)
{
unsigned char reg_data, i;
SetCommand(CMD_IDLE);
SetReg(REG_TXDATANUM, 0x08);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_FIFOCONTROL, BIT_FIFOFLUSH, FUN_ENABLE);
2025-11-24 16:33:33 +08:00
SetReg(REG_FIFODATA, 0x06);
SetReg(REG_FIFODATA, 0x00);
SetReg(REG_FIFODATA, 0xFF);
SetReg(REG_FIFODATA, 0xFF);
SetReg(REG_FIFODATA, 0x10);
SetReg(REG_FIFODATA, 0x00);
2025-11-24 18:58:32 +08:00
ModifyReg(REG_TXCRCCON, BIT_CRCEN, FUN_ENABLE);
ModifyReg(REG_RXCRCCON, BIT_CRCEN, FUN_ENABLE);
2025-11-24 16:33:33 +08:00
SetCommand(CMD_TRANSCEIVE);
rfid_delay_ms(10);
GetReg(REG_ERROR, &reg_data);
if ((reg_data & 0x0F) != 0)
return FAIL;
GetReg(REG_FIFOLENGTH, &reg_data);
if (reg_data != 18)
return FAIL;
GetReg(REG_FIFODATA, &reg_data); // Length
GetReg(REG_FIFODATA, &reg_data); // Response code
for (i = 0; i < 8; i++)
{
GetReg(REG_FIFODATA, &picc_f->UID[i]);
}
return SUCCESS;
}