feat(nfc): add phase-one card emulation mode
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user