diff --git a/ql-application/threadx/interface/custom_app/nfc.c b/ql-application/threadx/interface/custom_app/nfc.c index 2cac288..281c6f4 100644 --- a/ql-application/threadx/interface/custom_app/nfc.c +++ b/ql-application/threadx/interface/custom_app/nfc.c @@ -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"); }