diff --git a/ql-application/threadx/interface/custom_app/nfc.c b/ql-application/threadx/interface/custom_app/nfc.c index 22cb038..6539d90 100644 --- a/ql-application/threadx/interface/custom_app/nfc.c +++ b/ql-application/threadx/interface/custom_app/nfc.c @@ -5,47 +5,126 @@ #include "ql_audio.h" #include "ql_iic.h" #include "ql_gpio.h" -#include "app_inc.h" -#include "ql_fs.h" - -extern int fota_start; -extern int audio_packet_type; -extern volatile int tts_playing; -extern int g_testmode; - -static ql_sem_t nfc_irq_sem = NULL; -#define DP1312EA_PIN_IRQ GPIO_PIN_NO_85 - -// NFC 任务状态 +#include "app_inc.h" +#include "ql_fs.h" +#include "DP1312EA.h" +#include "TypeA.h" +#include "LPCD.h" + +#define NFC_WORK_MODE_READER 0 +#define NFC_WORK_MODE_CARD_EMULATION 1 + +/* + * Phase-1 validation switch. + * Set to NFC_WORK_MODE_READER to restore the original NTAG213 reader flow. + */ +#ifndef NFC_WORK_MODE +#define NFC_WORK_MODE NFC_WORK_MODE_CARD_EMULATION +#endif + +#define DP1312EA_PIN_IRQ GPIO_PIN_NO_85 + +#if (NFC_WORK_MODE == NFC_WORK_MODE_READER) +extern int fota_start; +extern int audio_packet_type; +extern volatile int tts_playing; +extern int g_testmode; + +static ql_sem_t nfc_irq_sem = NULL; + +// NFC 任务状态 typedef enum { NFC_STATE_LPCD_WAIT, // 低功耗等待中断 NFC_STATE_POLLING, // 500ms 轮询读卡中 } nfc_state_t; -static volatile nfc_state_t g_nfc_state = NFC_STATE_LPCD_WAIT; -static volatile int g_poll_fail_count = 0; -static volatile int g_nfc_irq_trigger = 0; - -static void nfc_irq_wake(void *args) -{ - unsigned char level = 0; - - ql_eint_disable_wakeup(DP1312EA_PIN_IRQ); - ql_gpio_get_level(DP1312EA_PIN_IRQ, &level); - printf("DP1312EA_PIN_IRQ level:%d\n", level); - - ql_eint_enable_wakeup(DP1312EA_PIN_IRQ, PIN_RISING_EDGE); - - if(g_nfc_irq_trigger==0){ - g_nfc_irq_trigger = 1; - ql_rtos_semaphore_release(nfc_irq_sem); - } -} - - -void ql_nfc_task_thread(void *arvg) -{ - s8 read_status; +static volatile nfc_state_t g_nfc_state = NFC_STATE_LPCD_WAIT; +static volatile int g_poll_fail_count = 0; +static volatile int g_nfc_irq_trigger = 0; +#endif + +#if (NFC_WORK_MODE == NFC_WORK_MODE_CARD_EMULATION) +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", + reason, + DP1312EA_ReadRawRC(CommandReg), + DP1312EA_ReadRawRC(ComIrqReg), + DP1312EA_ReadRawRC(ErrorReg), + DP1312EA_ReadRawRC(Status1Reg), + DP1312EA_ReadRawRC(Status2Reg), + DP1312EA_ReadRawRC(FIFOLevelReg)); +} + +static void nfc_card_emulation_start(void) +{ + DP1312EA_WriteRawRC(CommandReg, DP1312EA_IDLE); + DP1312EA_WriteRawRC(ComIrqReg, 0x7F); + DP1312EA_WriteRawRC(DivIrqReg, 0x7F); + DP1312EA_SetBitMask(FIFOLevelReg, 0x80); + + DP1312EA_Simulate_Card(); + nfc_card_emulation_log_status("started"); + printf("NFC phase-1 target: ATQA=44 00, UID=08 AA BB CC, SAK=00\r\n"); +} + +static void nfc_card_emulation_task(void) +{ + u8 last_command = 0xFF; + u8 command; + + nfc_card_emulation_start(); + + while (1) { + command = DP1312EA_ReadRawRC(CommandReg) & 0x0F; + + if (command != last_command) { + nfc_card_emulation_log_status("state changed"); + last_command = command; + } + + if (command != DP1312EA_AUTOCOLL) { + /* + * AutoColl normally exits after selection or on an RF/error event. + * Phase 1 has no ISO14443-4 handler yet, so allow the phone time to + * finish its probe, then arm AutoColl again for the next tap. + */ + ql_rtos_task_sleep_ms(500); + nfc_card_emulation_start(); + last_command = DP1312EA_AUTOCOLL; + } + + ql_rtos_task_sleep_ms(20); + } +} +#endif + +#if (NFC_WORK_MODE == NFC_WORK_MODE_READER) +static void nfc_irq_wake(void *args) +{ + unsigned char level = 0; + + ql_eint_disable_wakeup(DP1312EA_PIN_IRQ); + ql_gpio_get_level(DP1312EA_PIN_IRQ, &level); + printf("DP1312EA_PIN_IRQ level:%d\n", level); + + ql_eint_enable_wakeup(DP1312EA_PIN_IRQ, PIN_RISING_EDGE); + + if(g_nfc_irq_trigger==0){ + g_nfc_irq_trigger = 1; + ql_rtos_semaphore_release(nfc_irq_sem); + } +} +#endif + + +void ql_nfc_task_thread(void *arvg) +{ +#if (NFC_WORK_MODE == NFC_WORK_MODE_CARD_EMULATION) + printf("NFC work mode: CARD_EMULATION (phase 1)\r\n"); + nfc_card_emulation_task(); +#else + s8 read_status; while(1) { @@ -136,28 +215,36 @@ void ql_nfc_task_thread(void *arvg) ql_rtos_task_sleep_ms(300); } } - } - } + } + } +#endif } -void DP1312EA_Init(void) -{ - // 创建信号量 - ql_rtos_semaphore_create(&nfc_irq_sem, 0); - - // 配置中断引脚 - ql_gpio_init(DP1312EA_PIN_IRQ, PIN_DIRECTION_IN, PIN_PULL_PD, PIN_LEVEL_LOW); - ql_eint_register(DP1312EA_PIN_IRQ, PIN_RISING_EDGE, PIN_PULL_PD, NULL, nfc_irq_wake); - ql_eint_enable_wakeup(DP1312EA_PIN_IRQ, PIN_RISING_EDGE); - - // I2C 和芯片初始化 - DP1312EA_Reset(); - Check_Chip(); - - // 初始状态为低功耗等待 - g_nfc_state = NFC_STATE_LPCD_WAIT; - g_poll_fail_count = 0; +void DP1312EA_Init(void) +{ +#if (NFC_WORK_MODE == NFC_WORK_MODE_READER) + // 创建信号量 + ql_rtos_semaphore_create(&nfc_irq_sem, 0); + + // 配置中断引脚 + ql_gpio_init(DP1312EA_PIN_IRQ, PIN_DIRECTION_IN, PIN_PULL_PD, PIN_LEVEL_LOW); + ql_eint_register(DP1312EA_PIN_IRQ, PIN_RISING_EDGE, PIN_PULL_PD, NULL, nfc_irq_wake); + ql_eint_enable_wakeup(DP1312EA_PIN_IRQ, PIN_RISING_EDGE); +#else + /* Poll IRQ/status registers during the phase-1 card-emulation test. */ + ql_gpio_init(DP1312EA_PIN_IRQ, PIN_DIRECTION_IN, PIN_PULL_PD, PIN_LEVEL_LOW); +#endif + + // I2C 和芯片初始化 + DP1312EA_Reset(); + Check_Chip(); + + // Reader mode starts in low-power card detection. +#if (NFC_WORK_MODE == NFC_WORK_MODE_READER) + g_nfc_state = NFC_STATE_LPCD_WAIT; + g_poll_fail_count = 0; +#endif // 创建任务 ql_task_t nfcTaskRef = NULL;