fix(nfc): separate ATS transmit and receive

This commit is contained in:
chenjintao
2026-09-22 15:53:06 +08:00
parent 768ad0e47f
commit 14c0065bb1
@@ -45,19 +45,27 @@ static volatile int g_nfc_irq_trigger = 0;
#if (NFC_WORK_MODE == NFC_WORK_MODE_CARD_EMULATION)
#define NFC_CARD_FRAME_MAX 64
#define NFC_CARD_SESSION_POLLS 200
#define NFC_CARD_TX_POLLS 20
#define NFC_CARD_RX_POLLS 200
#define NFC_CARD_SESSION_POLL_MS 1
#define NFC_IRQ_TX 0x40
#define NFC_IRQ_RX 0x20
#define NFC_IRQ_ERR 0x02
static void nfc_card_emulation_log_status(const char *reason)
{
printf("NFC card emulation %s: cmd=%02X irq=%02X err=%02X status1=%02X status2=%02X fifo=%02X\r\n",
printf("NFC card emulation %s: cmd=%02X irq=%02X err=%02X status1=%02X status2=%02X fifo=%02X txm=%02X rxm=%02X framing=%02X\r\n",
reason,
DP1312EA_ReadRawRC(CommandReg),
DP1312EA_ReadRawRC(ComIrqReg),
DP1312EA_ReadRawRC(ErrorReg),
DP1312EA_ReadRawRC(Status1Reg),
DP1312EA_ReadRawRC(Status2Reg),
DP1312EA_ReadRawRC(FIFOLevelReg));
DP1312EA_ReadRawRC(FIFOLevelReg),
DP1312EA_ReadRawRC(TxModeReg),
DP1312EA_ReadRawRC(RxModeReg),
DP1312EA_ReadRawRC(BitFramingReg));
}
static u8 nfc_card_emulation_read_frame(u8 *frame, u8 capacity)
@@ -94,16 +102,46 @@ static void nfc_card_emulation_log_frame(const char *prefix,
printf("\r\n");
}
static void nfc_card_emulation_send_frame(const u8 *frame, u8 length)
static u8 nfc_card_emulation_send_frame(const u8 *frame, u8 length)
{
u16 poll_count;
u8 irq;
/* Stop the AutoColl-created Transceive before starting a clean TX. */
DP1312EA_WriteRawRC(CommandReg, DP1312EA_IDLE);
DP1312EA_WriteRawRC(ComIrqReg, 0x7F);
DP1312EA_SetBitMask(FIFOLevelReg, 0x80);
DP1312EA_WriteFIFO((u8 *)frame, length);
/* AutoColl leaves Transceive active and waiting for StartSend. */
DP1312EA_SetBitMask(TxModeReg, 0x80);
DP1312EA_SetBitMask(RxModeReg, 0x80);
DP1312EA_WriteRawRC(BitFramingReg, 0x80);
DP1312EA_WriteRawRC(BitFramingReg, 0x00);
DP1312EA_WriteFIFO((u8 *)frame, length);
DP1312EA_WriteRawRC(CommandReg, DP1312EA_TRANSMIT);
DP1312EA_SetBitMask(BitFramingReg, 0x80);
for (poll_count = 0; poll_count < NFC_CARD_TX_POLLS; poll_count++) {
irq = DP1312EA_ReadRawRC(ComIrqReg);
if ((irq & NFC_IRQ_TX) != 0) {
DP1312EA_WriteRawRC(BitFramingReg, 0x00);
return 1;
}
if ((irq & NFC_IRQ_ERR) != 0) {
break;
}
ql_rtos_task_sleep_ms(NFC_CARD_SESSION_POLL_MS);
}
DP1312EA_WriteRawRC(BitFramingReg, 0x00);
nfc_card_emulation_log_status("ATS transmit failed");
return 0;
}
static void nfc_card_emulation_start_receive(void)
{
DP1312EA_WriteRawRC(CommandReg, DP1312EA_IDLE);
DP1312EA_WriteRawRC(ComIrqReg, 0x7F);
DP1312EA_SetBitMask(FIFOLevelReg, 0x80);
DP1312EA_WriteRawRC(BitFramingReg, 0x00);
DP1312EA_WriteRawRC(CommandReg, DP1312EA_RECEIVE);
}
static void nfc_card_emulation_configure_iso_dep(void)
@@ -166,21 +204,28 @@ static void nfc_card_emulation_task(void)
nfc_card_emulation_log_frame("activation RX", frame, frame_len);
if (frame_len == 2 && frame[0] == 0xE0) {
nfc_card_emulation_send_frame(ats, sizeof(ats));
nfc_card_emulation_log_frame("ATS TX", ats, sizeof(ats));
if (!nfc_card_emulation_send_frame(ats, sizeof(ats))) {
nfc_card_emulation_log_status("session complete");
nfc_card_emulation_start();
last_command = DP1312EA_AUTOCOLL;
ql_rtos_task_sleep_ms(1);
continue;
}
nfc_card_emulation_log_frame("ATS TX complete", ats,
sizeof(ats));
nfc_card_emulation_start_receive();
for (poll_count = 0;
poll_count < NFC_CARD_SESSION_POLLS;
poll_count < NFC_CARD_RX_POLLS;
poll_count++) {
u8 irq = DP1312EA_ReadRawRC(ComIrqReg);
u8 error = DP1312EA_ReadRawRC(ErrorReg);
if (error != 0) {
nfc_card_emulation_log_status("ISO-DEP error");
if ((irq & NFC_IRQ_ERR) != 0) {
nfc_card_emulation_log_status("ISO-DEP receive error");
break;
}
if ((irq & 0x20) != 0 &&
if ((irq & NFC_IRQ_RX) != 0 &&
(DP1312EA_ReadRawRC(FIFOLevelReg) & 0x7F) != 0) {
frame_len = nfc_card_emulation_read_frame(
frame, sizeof(frame));
@@ -191,6 +236,10 @@ static void nfc_card_emulation_task(void)
ql_rtos_task_sleep_ms(NFC_CARD_SESSION_POLL_MS);
}
if (poll_count == NFC_CARD_RX_POLLS) {
nfc_card_emulation_log_status("ISO-DEP receive timeout");
}
} else {
printf("NFC activation frame is not RATS\r\n");
}