#include "app_manager.h" #include "xtell.h" #include "ui.h" #include "rgb.h" #include "event.h" #include "system.h" #include "../Drivers/rf.h" // 二级传感器对码菜单中,各类传感器的法语显示名称定义 char *code menu_items[5] = { "DETEC. PORTE", // 0: 门磁探测器 (法语: 门) "DETEC. PIR", // 1: 红外探测器 "DETEC. FUMEE", // 2: 烟雾传感器 "DETEC. GAZ", // 3: 燃气探测器 "DETEC. EAU" // 4: 水浸探测器 }; // 外部全局变量引用 extern SystemState current_state; extern u8 menu_select; extern u8 captured_type; extern volatile u16 ms_tick; // 菜单应用私有变量 static u8 menu_level = 0; // 0-主菜单, 1-二级传感器选择菜单, 2-IPC绑定一键发射 static u16 last_bind_tx_ms = 0; // 记录上一次绑定发射的时间戳 // 引入外部时钟调节接口 extern void Start_Time_Edit(void); // 声明本应用的生命周期回调函数 static void MenuApp_OnStart(void); static void MenuApp_onRun(void); static void MenuApp_onClose(void); static EventResult MenuApp_onEvent(SystemEvent *evt); // 实体化定义菜单应用控制块 WristbandApp menu_app = { APP_ID_MENU, "Menu", MenuApp_OnStart, MenuApp_onRun, MenuApp_onClose, MenuApp_onEvent }; /** * @brief MenuApp 启动回调 */ static void MenuApp_OnStart(void) { menu_level = 0; menu_select = 0; current_state = STATE_PAIR_MENU; // 系统运行状态设为对码配置菜单 RF_SetMode(0); // 关闭射频接收芯片,防止接收杂波干扰屏幕绘制 UI_ShowMainMenu(menu_select); // 初始化绘制一级主菜单 RGB_Send(0, 0, 0, 0, 0, 0); // 熄灭所有灯条 XTELL_LOG("[MenuApp] Started\r\n"); } /** * @brief MenuApp 轮询主回调 */ static void MenuApp_onRun(void) { if (menu_level == 2) { // ====== 控制青色双灯珠同步呼吸效果 (呼吸周期 1000ms) ====== u16 breath = ms_tick % 1000; u8 val = (breath < 500) ? (breath * 2 / 5) : ((1000 - breath) * 2 / 5); // 亮度映射 0~200 RGB_Send(0, val, val, 0, val, val); // 渲染青色 (G+B) // ====== 控制无线发射,每 500ms 广播一次配对数据 ====== if (ms_tick - last_bind_tx_ms >= 500 || ms_tick < last_bind_tx_ms) { last_bind_tx_ms = ms_tick; // 备份当前时间戳 RF_SetMode(2); // 暂时切换射频芯片为发射调制模式 EV1527_Transmit(CLONED_ADDR, 0x01); // 调制发射手环克隆 ID + 绑定数据码 0x01 RF_SetMode(0); // 切回关闭状态,避免产生噪声 XTELL_LOG("[MenuApp] IPC Binding frame emitted\r\n"); } } } /** * @brief MenuApp 退出清理回调 */ static void MenuApp_onClose(void) { menu_level = 0; RGB_Send(0, 0, 0, 0, 0, 0); // 熄灭 RGB RF_SetMode(1); // 重新开启无线接收模式 XTELL_LOG("[MenuApp] Closed\r\n"); } /** * @brief MenuApp 接收按键与控制事件回调 */ static EventResult MenuApp_onEvent(SystemEvent *evt) { if (menu_level == 0) { // ====== 处于一级主菜单层 (0-HORLOGE, 1-APPAIRAGE, 2-LIAISON) ====== if (evt->key_event == KEY_EVENT_UP_CLICK) { // 短按 ▲ 键向上移动焦点 if (menu_select > 0) { menu_select--; UI_ShowMainMenu(menu_select); } return EVENT_HANDLED; } if (evt->key_event == KEY_EVENT_DOWN_CLICK) { // 短按 ▼ 键向下移动焦点 if (menu_select < 2) { menu_select++; UI_ShowMainMenu(menu_select); } return EVENT_HANDLED; } if (evt->key_event == KEY_EVENT_CONFIRM_CLICK) { // 短按 ■ 确认键,进入选定功能的子页面 if (menu_select == 0) { // 功能 1:设置时间。启动待机时钟应用,并调用微调编辑入口 AppManager_SwitchToForeground(&clock_app); Start_Time_Edit(); } else if (menu_select == 1) { // 功能 2:传感器学习。进入二级传感器类别选择菜单 menu_level = 1; menu_select = 0; UI_ShowPairMenuPage(menu_select); // 绘制二级设备分类页 } else if (menu_select == 2) { // 功能 3:相机配对。进入摄像机一键绑定发射状态 menu_level = 2; last_bind_tx_ms = ms_tick; // 记录初始发射时间 current_state = STATE_IPC_BIND; // 系统设为 IPC 绑定状态 UI_ShowBindingPage(CLONED_ADDR); // 绘制相机绑定信息页 } return EVENT_HANDLED; } if (evt->key_event == KEY_EVENT_CONFIRM_LONG) { // 长按 ■ 确认键,退出设置菜单直接返回待机时钟 AppManager_SwitchToForeground(&clock_app); return EVENT_HANDLED; } } else if (menu_level == 1) { // ====== 处于二级传感器对码类型菜单层 (0-门磁, 1-PIR, 2-烟感, 3-气感, 4-水浸) ====== if (evt->key_event == KEY_EVENT_UP_CLICK) { // 上移焦点 if (menu_select > 0) { menu_select--; UI_ShowPairMenuPage(menu_select); } return EVENT_HANDLED; } if (evt->key_event == KEY_EVENT_DOWN_CLICK) { // 下移焦点 if (menu_select < 4) { menu_select++; UI_ShowPairMenuPage(menu_select); } return EVENT_HANDLED; } if (evt->key_event == KEY_EVENT_CONFIRM_CLICK) { // 确认选择:缓存用户选好的传感器类别,短震反馈并加载对码应用 (PairApp) captured_type = menu_select; MOTOR = 1; Delay_ms(100); MOTOR = 0; AppManager_SwitchToForeground(&pair_app); // 切换至 PairApp 对码 return EVENT_HANDLED; } if (evt->key_event == KEY_EVENT_DOWN_LONG) { // 长按 ▼ 键,从二级菜单退回到一级主菜单 menu_level = 0; menu_select = 1; // 回到 APPAIRAGE 选项上 UI_ShowMainMenu(menu_select); return EVENT_HANDLED; } } else if (menu_level == 2) { // ====== 处于摄像机配对一键绑定发送层 ====== // 长按 ■ 确认键 或 长按 ▼ 键,均表示取消绑定,退出发射并返回一级主菜单 if (evt->key_event == KEY_EVENT_CONFIRM_LONG || evt->key_event == KEY_EVENT_DOWN_LONG) { menu_level = 0; menu_select = 2; // 回到 LIAISON 选项上 current_state = STATE_PAIR_MENU; RGB_Send(0, 0, 0, 0, 0, 0); // 关闭呼吸灯 UI_ShowMainMenu(menu_select); return EVENT_HANDLED; } } return EVENT_IGNORED; }