4 changed files with 617 additions and 189 deletions
+1 -3
View File
@@ -1,8 +1,6 @@
@echo off
set CURDIR=%~dp0
set time0=%time: =0%
set hour=%time0:~0,2%
set appbuildtime=%date:~0,4%%date:~5,2%%date:~8,2%%hour%%time:~3,2%%time:~6,2%
for /f %%i in ('powershell -NoProfile -Command "Get-Date -Format yyyyMMddHHmmss"') do set appbuildtime=%%i
set appbuildrev=NULL
set appbuildmodel=EG800AKCN_11LG
set appbuildver=beta1
@@ -30,9 +30,40 @@ extern int fota_start;
#define KEY_LONG_PRESS_1_5S 1500/5
#define KEY_LONG_PRESS_3S 3000/5
#define KEY_LONG_PRESS_5S 5000/5
#define KEY_LONG_PRESS_10S 10000/5
static unsigned char key_down_event = 0;
#define KEY_LONG_PRESS_10S 10000/5
#define NFC_TX_CLICK_GAP 2000/5
#define NFC_TX_CLICK_COUNT 5
static unsigned char key_down_event = 0;
static unsigned char nfc_tx_click_count = 0;
static u32 nfc_tx_last_click_time = 0;
extern void app_nfc_tx_mode_start(void);
static int key_mic_register_short_click(void)
{
u32 now = ql_rtos_get_systicks();
if (nfc_tx_click_count == 0 ||
(u32)(now - nfc_tx_last_click_time) > NFC_TX_CLICK_GAP) {
nfc_tx_click_count = 1;
} else {
nfc_tx_click_count++;
}
nfc_tx_last_click_time = now;
printf("NFC TX key clicks:%u/%u\r\n",
nfc_tx_click_count, NFC_TX_CLICK_COUNT);
if (nfc_tx_click_count >= NFC_TX_CLICK_COUNT) {
nfc_tx_click_count = NFC_TX_CLICK_COUNT;
app_nfc_tx_mode_start();
return 1;
}
/* Keep the first click's existing voice action. Suppress clicks 2-4 so
* a rapid NFC gesture does not repeatedly start/interrupt voice work. */
return nfc_tx_click_count > 1;
}
static void key_press_mic(void *args)
{
@@ -114,31 +145,36 @@ static void key_thread_entry(void *parameter)
if(level!=0){ //up
key_press_mic_status = 0;
if(ql_rtos_get_systicks() - key_press_mic_time > KEY_LONG_PRESS_3S){
//app_play_tips_file(10);
if(ql_rtos_get_systicks() - key_press_mic_time > KEY_LONG_PRESS_3S){
nfc_tx_click_count = 0;
//app_play_tips_file(10);
// power_down_status = 1;
ql_rtos_task_sleep_s(3);
ql_power_down(1);
}
else if(ql_rtos_get_systicks() - key_press_mic_time > KEY_WAIT_TIME){
//休眠唤醒其它线程
if(app_get_app_sleep_flag()==0){
app_set_app_operation(1);
}
int mic_pdp = app_get_data_call_net_status();
int mic_mqtt = get_mqtt_connect_status();
printf("[NET-GATE] mic pdp=%d mqtt=%d action=%s\r\n",
mic_pdp, mic_mqtt,
!mic_pdp ? "blocked_no_pdp" : (mic_mqtt != 1 ? "blocked_mqtt_offline" : "start_voice"));
if(mic_pdp && mic_mqtt == 1){
if(tts_play_interrupt_func()==-2){
app_play_tips_file(2);
}
}else{
app_play_tips_file(2);
}
}
else if(ql_rtos_get_systicks() - key_press_mic_time > KEY_WAIT_TIME){
int nfc_click_handled = key_mic_register_short_click();
//休眠唤醒其它线程
if(app_get_app_sleep_flag()==0){
app_set_app_operation(1);
}
if (!nfc_click_handled) {
int mic_pdp = app_get_data_call_net_status();
int mic_mqtt = get_mqtt_connect_status();
printf("[NET-GATE] mic pdp=%d mqtt=%d action=%s\r\n",
mic_pdp, mic_mqtt,
!mic_pdp ? "blocked_no_pdp" : (mic_mqtt != 1 ? "blocked_mqtt_offline" : "start_voice"));
if(mic_pdp && mic_mqtt == 1){
if(tts_play_interrupt_func()==-2){
app_play_tips_file(2);
}
}else{
app_play_tips_file(2);
}
}
}
key_press_mic_time = ql_rtos_get_systicks();
key_press_mic_counter = 0;
@@ -148,8 +184,9 @@ static void key_thread_entry(void *parameter)
key_press_mic_status = 1;//表示已经按下了
}
if(ql_rtos_get_systicks() - key_press_mic_time > KEY_LONG_PRESS_3S && power_down_status==0){
power_down_status = 1;
if(ql_rtos_get_systicks() - key_press_mic_time > KEY_LONG_PRESS_3S && power_down_status==0){
nfc_tx_click_count = 0;
power_down_status = 1;
app_play_tips_file(10);
power_down_status = 2;
//ql_rtos_task_sleep_s(3);
+474 -152
View File
@@ -1,166 +1,488 @@
#if 1
#include <stdio.h>
#include "ql_rtos.h"
#if 1
#include <stdio.h>
#include <string.h>
#include "ql_rtos.h"
#include "ql_application.h"
#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"
#include "hal_api.h"
#define DP1312EA_PIN_IRQ GPIO_PIN_NO_85
#define NFC_TX_MODE_DURATION_MS 30000U
#define NFC_TICKS_PER_MS_DIVISOR 5U
extern int fota_start;
extern int audio_packet_type;
extern volatile int tts_playing;
extern int g_testmode;
extern uint8_t get_sleep_mode(void);
extern int get_mqtt_connect_status(void);
extern bool vad_audio_is_recording(void);
extern int xiaoice_get_play_counter(void);
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);
}
}
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 volatile u8 g_nfc_tx_mode_requested = 0;
static volatile u32 g_nfc_tx_mode_deadline = 0;
#define NFC_CARD_FRAME_MAX 64
#define NFC_CARD_TX_POLLS 20
#define NFC_CARD_RX_POLLS 200
#define NFC_CARD_SESSION_POLL_MS 1
#define NFC_TYPE2_PAGE_SIZE 4
#define NFC_TYPE2_READ_SIZE 16
#define NFC_TYPE2_MEMORY_SIZE 160
#define NFC_TYPE2_NDEF_OFFSET 16
#define NFC_IRQ_TX 0x40
#define NFC_IRQ_RX 0x20
#define NFC_IRQ_ERR 0x02
extern int hal_os_get_device_sn(char *pdevice_sn);
extern s8 Test_NTAG213(void);
static u8 nfc_type2_memory[NFC_TYPE2_MEMORY_SIZE];
static u8 nfc_tx_mode_is_active(void)
{
u32 now;
if (!g_nfc_tx_mode_requested) {
return 0;
}
now = ql_rtos_get_systicks();
if ((s32)(now - g_nfc_tx_mode_deadline) >= 0) {
g_nfc_tx_mode_requested = 0;
return 0;
}
return 1;
}
void app_nfc_tx_mode_start(void)
{
g_nfc_tx_mode_deadline = ql_rtos_get_systicks() +
(NFC_TX_MODE_DURATION_MS / NFC_TICKS_PER_MS_DIVISOR);
g_nfc_tx_mode_requested = 1;
if (nfc_irq_sem != NULL) {
ql_rtos_semaphore_release(nfc_irq_sem);
}
printf("NFC TX mode requested for 30 seconds\r\n");
}
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 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(TxModeReg),
DP1312EA_ReadRawRC(RxModeReg),
DP1312EA_ReadRawRC(BitFramingReg));
}
static u8 nfc_card_emulation_read_frame(u8 *frame, u8 capacity)
{
u8 fifo_len = DP1312EA_ReadRawRC(FIFOLevelReg) & 0x7F;
u8 read_len = fifo_len;
if (read_len > capacity) {
read_len = capacity;
}
if (read_len > 0) {
DP1312EA_ReadFIFO(frame, read_len);
}
while (read_len < fifo_len) {
(void)DP1312EA_ReadRawRC(FIFODataReg);
read_len++;
}
return fifo_len > capacity ? capacity : fifo_len;
}
static void nfc_card_emulation_log_frame(const char *prefix,
const u8 *frame,
u8 length)
{
u8 i;
printf("NFC %s (%u):", prefix, length);
for (i = 0; i < length; i++) {
printf(" %02X", frame[i]);
}
printf("\r\n");
}
static u8 nfc_card_emulation_send_frame(const u8 *frame, u8 length)
{
u16 poll_count;
u8 irq;
/* AutoColl has activated target mode and changed to Transceive. Keep it
* active: writing Idle here clears TargetActivated in Status2Reg. */
DP1312EA_WriteRawRC(ComIrqReg, 0x7F);
DP1312EA_SetBitMask(FIFOLevelReg, 0x80);
DP1312EA_SetBitMask(TxModeReg, 0x80);
DP1312EA_SetBitMask(RxModeReg, 0x80);
DP1312EA_WriteRawRC(BitFramingReg, 0x00);
DP1312EA_WriteFIFO((u8 *)frame, length);
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("frame transmit failed");
return 0;
}
static void nfc_type2_build_ndef(void)
{
char device_id[32] = {0};
char serial_number[32] = {0};
char json[128];
int json_len;
u8 *ndef;
u8 record_len;
if (hal_os_get_device_id(device_id) != 0) {
strcpy(device_id, "unknown");
}
if (hal_os_get_device_sn(serial_number) != 0) {
strcpy(serial_number, "unknown");
}
json_len = snprintf(json, sizeof(json),
"{\"device_id\":\"%s\",\"serial_number\":\"%s\"}",
device_id, serial_number);
if (json_len < 0) {
json_len = 0;
} else if (json_len >= (int)sizeof(json)) {
json_len = sizeof(json) - 1;
}
memset(nfc_type2_memory, 0, sizeof(nfc_type2_memory));
/* Static UID/manufacturer pages followed by a read-only Type 2 CC. */
nfc_type2_memory[0] = 0x08;
nfc_type2_memory[1] = 0xAA;
nfc_type2_memory[2] = 0xBB;
nfc_type2_memory[3] = 0xCC;
nfc_type2_memory[12] = 0xE1;
nfc_type2_memory[13] = 0x10;
nfc_type2_memory[14] = 0x12; /* 144 data bytes (18 x 8). */
nfc_type2_memory[15] = 0x0F; /* Read-only access. */
ndef = &nfc_type2_memory[NFC_TYPE2_NDEF_OFFSET];
record_len = (u8)(7 + json_len);
ndef[0] = 0x03; /* NDEF Message TLV. */
ndef[1] = record_len;
ndef[2] = 0xD1; /* MB, ME, SR, TNF well-known. */
ndef[3] = 0x01; /* Type length. */
ndef[4] = (u8)(3 + json_len); /* Text status/lang plus JSON. */
ndef[5] = 'T';
ndef[6] = 0x02; /* UTF-8, language length 2. */
ndef[7] = 'e';
ndef[8] = 'n';
memcpy(&ndef[9], json, json_len);
ndef[9 + json_len] = 0xFE; /* Terminator TLV. */
printf("NFC Type 2 NDEF: %s\r\n", json);
}
static void nfc_type2_read_pages(u8 start_page, u8 *response)
{
u16 start = (u16)start_page * NFC_TYPE2_PAGE_SIZE;
u8 i;
for (i = 0; i < NFC_TYPE2_READ_SIZE; i++) {
u16 offset = start + i;
response[i] = offset < NFC_TYPE2_MEMORY_SIZE
? nfc_type2_memory[offset]
: 0x00;
}
}
static void nfc_card_emulation_configure_type2(void)
{
static const u8 card_config[] = {
0x04, 0x00, /* ATQA: single-size (4-byte) UID */
0xAA, 0xBB, 0xCC, /* NFCID1; first byte 08 is added by PN512 */
0x00, /* SEL_RES / SAK: Type 2, no ISO-DEP */
0x01, 0xFE, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
0x07, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0xFF, 0xFF,
0x88
};
DP1312EA_PcdConfigISOType('K');
ql_rtos_task_sleep_ms(2);
DP1312EA_WriteFIFO((u8 *)card_config, sizeof(card_config));
ql_rtos_task_sleep_ms(2);
DP1312EA_WriteRawRC(CommandReg, DP1312EA_MEM);
DP1312EA_WriteRawRC(CommandReg, DP1312EA_AUTOCOLL);
}
static void nfc_card_emulation_start(void)
{
DP1312EA_WriteRawRC(CommandReg, DP1312EA_IDLE);
DP1312EA_WriteRawRC(ComIrqReg, 0x7F);
DP1312EA_WriteRawRC(DivIrqReg, 0x7F);
DP1312EA_SetBitMask(FIFOLevelReg, 0x80);
nfc_type2_build_ndef();
nfc_card_emulation_configure_type2();
nfc_card_emulation_log_status("started");
printf("NFC Type 2 tag: ATQA=04 00, UID=08 AA BB CC, SAK=00\r\n");
}
static void nfc_card_emulation_task(void)
{
u8 frame[NFC_CARD_FRAME_MAX];
u8 response[NFC_TYPE2_READ_SIZE];
u8 frame_len;
u16 poll_count;
u8 last_command = 0xFF;
u8 command;
nfc_card_emulation_start();
while (nfc_tx_mode_is_active()) {
command = DP1312EA_ReadRawRC(CommandReg) & 0x0F;
if (command != last_command) {
nfc_card_emulation_log_status("state changed");
last_command = command;
}
if (command == DP1312EA_TRANSCEIVE) {
frame_len = nfc_card_emulation_read_frame(frame, sizeof(frame));
while (nfc_tx_mode_is_active() &&
frame_len >= 2 && frame[0] == 0x30) {
nfc_card_emulation_log_frame("Type 2 READ RX", frame,
frame_len);
nfc_type2_read_pages(frame[1], response);
if (!nfc_card_emulation_send_frame(response,
sizeof(response))) {
break;
}
printf("NFC Type 2 READ page %u TX complete\r\n", frame[1]);
nfc_card_emulation_log_frame("Type 2 READ TX", response,
sizeof(response));
DP1312EA_WriteRawRC(ComIrqReg, NFC_IRQ_TX);
for (poll_count = 0;
poll_count < NFC_CARD_RX_POLLS &&
nfc_tx_mode_is_active();
poll_count++) {
u8 irq = DP1312EA_ReadRawRC(ComIrqReg);
if ((irq & NFC_IRQ_ERR) != 0) {
nfc_card_emulation_log_status("Type 2 receive error");
break;
}
if ((irq & NFC_IRQ_RX) != 0 &&
(DP1312EA_ReadRawRC(FIFOLevelReg) & 0x7F) != 0) {
frame_len = nfc_card_emulation_read_frame(
frame, sizeof(frame));
break;
}
ql_rtos_task_sleep_ms(NFC_CARD_SESSION_POLL_MS);
}
if (poll_count == NFC_CARD_RX_POLLS) {
nfc_card_emulation_log_status("Type 2 receive timeout");
break;
}
if ((DP1312EA_ReadRawRC(ComIrqReg) & NFC_IRQ_ERR) != 0) {
break;
}
}
if (frame_len > 0 && !(frame_len >= 2 && frame[0] == 0x30)) {
nfc_card_emulation_log_frame("Type 2 session end RX", frame,
frame_len);
}
nfc_card_emulation_log_status("session complete");
nfc_card_emulation_start();
last_command = DP1312EA_AUTOCOLL;
} else if (command != DP1312EA_AUTOCOLL) {
nfc_card_emulation_log_status("unexpected command");
nfc_card_emulation_start();
last_command = DP1312EA_AUTOCOLL;
}
ql_rtos_task_sleep_ms(1);
}
DP1312EA_WriteRawRC(CommandReg, DP1312EA_IDLE);
DP1312EA_WriteRawRC(ComIrqReg, 0x7F);
DP1312EA_SetBitMask(FIFOLevelReg, 0x80);
printf("NFC TX mode expired, restoring reader mode\r\n");
}
static void nfc_irq_wake(void *args)
{
PIN_LEVEL_E level = PIN_LEVEL_LOW;
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_tx_mode_requested) {
return;
}
if(g_nfc_irq_trigger==0){
g_nfc_irq_trigger = 1;
ql_rtos_semaphore_release(nfc_irq_sem);
}
}
static void nfc_reader_prepare(void)
{
DP1312EA_Reset();
Check_Chip();
g_nfc_state = NFC_STATE_LPCD_WAIT;
g_poll_fail_count = 0;
g_nfc_irq_trigger = 0;
}
static void nfc_reader_task_step(void)
{
s8 read_status;
int can_read = 0;
if (g_nfc_state == NFC_STATE_LPCD_WAIT) {
DP1312EA_LPCD_Start();
printf("NFC enter LPCD mode, waiting for IRQ...\r\n");
ql_rtos_semaphore_wait(nfc_irq_sem, 0xFFFFFFFF);
if (g_nfc_tx_mode_requested) {
return;
}
DP1312EA_CLEAR_IRQ();
ql_rtos_task_sleep_ms(10);
printf("NFC IRQ wake up, switch to polling mode\r\n");
g_nfc_state = NFC_STATE_POLLING;
g_poll_fail_count = 0;
return;
}
if (fota_start == 0 &&
get_sleep_mode() != 1 &&
get_mqtt_connect_status() == 1) {
if ((vad_audio_is_recording() != 1 &&
audio_packet_type == 0 &&
tts_playing == 0 &&
xiaoice_get_play_counter() == 0) ||
g_testmode == 1) {
can_read = 1;
}
}
if (!can_read) {
ql_rtos_task_sleep_ms(300);
return;
}
read_status = Test_NTAG213();
if (read_status == 0) {
printf("NFC read OK, back to LPCD\r\n");
g_nfc_state = NFC_STATE_LPCD_WAIT;
g_poll_fail_count = 0;
g_nfc_irq_trigger = 0;
ql_rtos_task_sleep_ms(10);
return;
}
g_poll_fail_count++;
printf("NFC read failed, fail_count=%d\r\n", g_poll_fail_count);
if (g_poll_fail_count >= 3) {
printf("NFC fail 3 times, card removed, back to LPCD\r\n");
g_nfc_state = NFC_STATE_LPCD_WAIT;
g_poll_fail_count = 0;
g_nfc_irq_trigger = 0;
ql_rtos_task_sleep_ms(10);
} else {
ql_rtos_task_sleep_ms(300);
}
}
void ql_nfc_task_thread(void *arvg)
{
printf("NFC work mode: READER (5 clicks enable Type 2 TX)\r\n");
while (1) {
if (nfc_tx_mode_is_active()) {
printf("NFC TX mode enabled\r\n");
DP1312EA_Reset();
Check_Chip();
nfc_card_emulation_task();
nfc_reader_prepare();
continue;
}
nfc_reader_task_step();
}
}
void ql_nfc_task_thread(void *arvg)
{
s8 read_status;
while(1)
{
// ========== 状态1: 低功耗等待中断 ==========
if (g_nfc_state == NFC_STATE_LPCD_WAIT) {
DP1312EA_LPCD_Start(); // 进入低功耗检卡,等待中断
printf("NFC enter LPCD mode, waiting for IRQ...\r\n");
// 阻塞等待中断唤醒
ql_rtos_semaphore_wait(nfc_irq_sem, 0xFFFFFFFF);
DP1312EA_CLEAR_IRQ();
ql_rtos_task_sleep_ms(10); // 防抖延迟
printf("NFC IRQ wake up, switch to polling mode\r\n");
// 切换到轮询模式,重置失败计数
g_nfc_state = NFC_STATE_POLLING;
g_poll_fail_count = 0;
// 立即执行第一次读卡(不等待200ms)
continue;
}
// ========== 状态2: 200ms 轮询读卡 ==========
if (g_nfc_state == NFC_STATE_POLLING) {
// 检查是否允许读卡(业务条件)
int can_read = 0;
if (fota_start == 0 &&
get_sleep_mode() != 1 &&
get_mqtt_connect_status() == 1) {
if ((get_mqtt_connect_status() == 1 &&
vad_audio_is_recording() != 1 &&
audio_packet_type == 0 &&
tts_playing == 0 &&
xiaoice_get_play_counter() == 0) ||
g_testmode == 1) {
can_read = 1;
}
}
if (!can_read) {
// 当前业务状态不允许读卡,继续等待下次轮询
// printf("NFC business condition not met, keep polling\r\n");
ql_rtos_task_sleep_ms(300);
continue;
}
// 执行读卡
// printf("NFC polling read, fail_count=%d\r\n", g_poll_fail_count);
read_status = Test_NTAG213();
if (read_status == 0) {
// ===== 读卡成功 =====
printf("NFC read OK, continue polling\r\n");
// 直接回到 LPCD,不再轮询
g_nfc_state = NFC_STATE_LPCD_WAIT;
g_poll_fail_count = 0;
g_nfc_irq_trigger = 0;
ql_rtos_task_sleep_ms(10);
continue; // 回到 LPCD 等待
} else {
// ===== 读卡失败 =====
g_poll_fail_count++;
printf("NFC read failed, fail_count=%d\r\n", g_poll_fail_count);
if (g_poll_fail_count >= 3) {
// 连续失败 3 次,认为卡已离开
printf("NFC fail 3 times, card removed, back to LPCD\r\n");
// 清理状态,回到低功耗
g_nfc_state = NFC_STATE_LPCD_WAIT;
g_poll_fail_count = 0;
g_nfc_irq_trigger = 0;
// 短暂延迟确保硬件稳定
ql_rtos_task_sleep_ms(10);
} else {
// 继续轮询,可能卡只是位置偏移
ql_rtos_task_sleep_ms(300);
}
}
}
}
}
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;
// 创建任务
ql_task_t nfcTaskRef = NULL;
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);
DP1312EA_Reset();
Check_Chip();
g_nfc_state = NFC_STATE_LPCD_WAIT;
g_poll_fail_count = 0;
ql_task_t nfcTaskRef = NULL;
ql_rtos_task_create(&nfcTaskRef, 1024*6, 100, "nfc_Task_Ref", ql_nfc_task_thread, NULL);
}
#endif
@@ -21,6 +21,7 @@
#include "ql_ping.h"
#include "ql_nw.h"
#include "ql_atcmd.h"
#include "ql_platform.h"
#include "layer3.h"
#include "ql_uart.h"
#include "hal_api.h"
@@ -29,6 +30,8 @@
#define PCM_FRAME_LENGTH 1152
#define CLOUD_TTS_ERROR_URL_FORMAT \
"http://101.35.224.118:8080/assets/roles/banban/tts_error/tts_error%02u.mp3"
static int g_sim_ready = 0;
@@ -192,6 +195,56 @@ static void remove_underscores(char *str) {
*dst = '\0'; // 添加字符串结束符
}
/*
* 将后台下发的任意角色对话超时音频 URL 改为 banban 角色的 HTTP 地址,
* 并在 tts_error00~tts_error09 中随机选择一条。
*/
static int randomize_tts_error_url(char *url, size_t url_size)
{
static uint32_t random_sequence = 0;
static unsigned int last_random_index = 10;
char *file_name;
uint32_t random_value;
unsigned int random_index;
int written;
if(url == NULL || url_size == 0){
return 0;
}
file_name = strrchr(url, '/');
file_name = (file_name == NULL) ? url : file_name + 1;
if(strncmp(file_name, "tts_error", strlen("tts_error")) != 0 &&
strncmp(file_name, "tts_err", strlen("tts_err")) != 0){
return 0;
}
/*
* 某些设备上硬件随机接口可能持续返回 0,因此混合伪随机数、系统 tick
* 和递增序列;若仍与上一次相同,则向后偏移,避免连续重复播放。
*/
random_sequence++;
random_value = hal_os_get_rand();
random_value ^= ql_pseudo_random_number();
random_value ^= ql_rtos_get_systicks();
random_value ^= random_sequence * 0x9E3779B9U;
random_index = random_value % 10;
if(random_index == last_random_index){
random_index = (random_index + 1 + (random_sequence % 9)) % 10;
}
last_random_index = random_index;
written = snprintf(url, url_size, CLOUD_TTS_ERROR_URL_FORMAT, random_index);
if(written < 0 || (size_t)written >= url_size){
printf("random tts error url buffer too small\n");
return -1;
}
printf("random cloud tts error index:%02u, url:%s\n", random_index, url);
return 1;
}
void add_file_to_play_player_queue(char *path, int type)
{
ice_work_item *item = NULL;
@@ -266,14 +319,32 @@ static void onmessage_text(rws_socket socket, const char *text, const unsigned i
}else{//TTS_URL:audio_url
wss_connect_start = 0;
char *ret_str1= strstr(text, "http:");
char *ret_str2= strstr(text, ".mp3");
int len = 0;
char *ret_str1 = strstr(text, "https://");
char *ret_str2 = NULL;
size_t url_len = 0;
int is_tts_error_url = 0;
if(ret_str1 == NULL){
ret_str1 = strstr(text, "http://");
}
if(ret_str1 != NULL){
ret_str2 = strstr(ret_str1, ".mp3");
}
if(ret_str1!=NULL && ret_str2!=NULL){
len = strlen(ret_str1)-strlen(ret_str2);
strncpy(url_buff, ret_str1, len);
sprintf(url_buff+len, "%s", ".mp3");
/* 提取完整的 HTTP/HTTPS MP3 URL,结尾额外包含“.mp3”四个字符 */
url_len = (size_t)(ret_str2 - ret_str1) + strlen(".mp3");
if(url_len >= sizeof(url_buff)){
printf("audio url too long:%d\n", (int)url_len);
return;
}
memcpy(url_buff, ret_str1, url_len);
url_buff[url_len] = '\0';
/* 两个角色统一使用 banban 的 HTTP 随机超时提示音 */
is_tts_error_url = randomize_tts_error_url(url_buff, sizeof(url_buff));
if(is_tts_error_url < 0){
return;
}
memcpy(url_buff_bak, url_buff, strlen(url_buff)+1);
@@ -292,7 +363,7 @@ static void onmessage_text(rws_socket socket, const char *text, const unsigned i
tts_play_status = 2;
}
if(strstr(url_buff, "tts_error")!=NULL || strstr(url_buff, "message_ok")!=NULL){
if(is_tts_error_url == 1 || strstr(url_buff, "message_ok")!=NULL){
printf("tts_error or message_ok\n");
vad_set_speech_timeout_flag(1);
}