497 lines
13 KiB
C
497 lines
13 KiB
C
|
|
#include "config.h"
|
|||
|
|
#include "appmgr.h"
|
|||
|
|
#include "../Drivers/lcd.h"
|
|||
|
|
#include "../Drivers/rf.h"
|
|||
|
|
|
|||
|
|
/* =========================================================================
|
|||
|
|
* 全局变量声明(从 main.c 迁移)
|
|||
|
|
* ========================================================================= */
|
|||
|
|
|
|||
|
|
extern volatile u16 ms_tick;
|
|||
|
|
extern volatile u32 pair_timeout_ms;
|
|||
|
|
extern volatile u16 alarm_timer_ms;
|
|||
|
|
extern volatile bit alarm_flash_flag;
|
|||
|
|
|
|||
|
|
extern SystemState current_state;
|
|||
|
|
extern u8 current_hour, current_min;
|
|||
|
|
extern u8 menu_select;
|
|||
|
|
extern u32 captured_addr;
|
|||
|
|
extern u8 captured_type;
|
|||
|
|
extern u8 alarm_sensor_slot;
|
|||
|
|
|
|||
|
|
extern Sensor_Slot xdata sensor_list[16];
|
|||
|
|
|
|||
|
|
extern sbit MOTOR;
|
|||
|
|
extern bit LED_R, LED_G, LED_B;
|
|||
|
|
extern bit rgb_test_mode;
|
|||
|
|
|
|||
|
|
extern char *code default_names[5];
|
|||
|
|
extern u8 code default_zones[5];
|
|||
|
|
extern char *code menu_items[5];
|
|||
|
|
|
|||
|
|
extern void Delay_ms(u16 ms);
|
|||
|
|
extern void Format_Sensor_Name(u8 slot, char *buf);
|
|||
|
|
extern void Uart_SendString(char *s);
|
|||
|
|
extern void Uart_SendHex8(u8 val);
|
|||
|
|
|
|||
|
|
/* =========================================================================
|
|||
|
|
* 应用私有状态变量
|
|||
|
|
* ========================================================================= */
|
|||
|
|
|
|||
|
|
// 时钟应用状态
|
|||
|
|
static bit clock_redraw_flag = 0;
|
|||
|
|
|
|||
|
|
// 配对应用状态
|
|||
|
|
static u8 pair_menu_select = 0;
|
|||
|
|
static u8 pair_state = 0; // 0: MENU, 1: WAIT, 2: CONFIRM, 3: SUCCESS, 4: FAIL
|
|||
|
|
|
|||
|
|
// 报警应用状态
|
|||
|
|
static u8 alarm_last_frame = 99;
|
|||
|
|
|
|||
|
|
// SOS应用状态
|
|||
|
|
static u8 sos_last_tx = 99;
|
|||
|
|
|
|||
|
|
/* =========================================================================
|
|||
|
|
* 时钟应用实现
|
|||
|
|
* ========================================================================= */
|
|||
|
|
|
|||
|
|
static void ClockApp_OnStart(void)
|
|||
|
|
{
|
|||
|
|
Uart_SendString("[APP] ClockApp Started\r\n");
|
|||
|
|
current_state = STATE_NORMAL;
|
|||
|
|
clock_redraw_flag = 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static void ClockApp_onRun(void)
|
|||
|
|
{
|
|||
|
|
// 分钟变化时重绘时钟
|
|||
|
|
if (clock_redraw_flag)
|
|||
|
|
{
|
|||
|
|
clock_redraw_flag = 0;
|
|||
|
|
UI_ShowClockPage(current_state, current_hour, current_min);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 监听射频信号(后台监测)
|
|||
|
|
{
|
|||
|
|
u32 rx_addr;
|
|||
|
|
u8 rx_data;
|
|||
|
|
if (EV1527_Decode(&rx_addr, &rx_data))
|
|||
|
|
{
|
|||
|
|
u8 slot;
|
|||
|
|
if (Check_Sensor_ID(rx_addr, &slot))
|
|||
|
|
{
|
|||
|
|
u32 slot_addr = ((u32)sensor_list[slot].addr[0] << 16) |
|
|||
|
|
((u32)sensor_list[slot].addr[1] << 8) |
|
|||
|
|
sensor_list[slot].addr[2];
|
|||
|
|
u8 sensor_type = slot_addr & 0x0F;
|
|||
|
|
|
|||
|
|
if (sensor_type < 5)
|
|||
|
|
{
|
|||
|
|
u8 zone = default_zones[sensor_type];
|
|||
|
|
if (zone == 0 || current_state == STATE_ARMED)
|
|||
|
|
{
|
|||
|
|
captured_addr = rx_addr;
|
|||
|
|
alarm_sensor_slot = slot;
|
|||
|
|
AppManager_StartApp(APP_ID_ALARM);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static void ClockApp_onClose(void)
|
|||
|
|
{
|
|||
|
|
Uart_SendString("[APP] ClockApp Closed\r\n");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static EventResult ClockApp_onEvent(SystemEvent evt)
|
|||
|
|
{
|
|||
|
|
// 处理定时器发送的时钟更新事件(priority为LOW,key_event为NONE)
|
|||
|
|
if (evt.key_event == KEY_EVENT_NONE && evt.priority == EVENT_PRIORITY_LOW)
|
|||
|
|
{
|
|||
|
|
// 从extra_data中提取时间信息
|
|||
|
|
u8 hour = (u8)(evt.extra_data >> 8);
|
|||
|
|
u8 min = (u8)(evt.extra_data & 0xFF);
|
|||
|
|
|
|||
|
|
// 更新时钟显示
|
|||
|
|
UI_ShowClockPage(current_state, hour, min);
|
|||
|
|
return EVENT_HANDLED;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
switch (evt.key_event)
|
|||
|
|
{
|
|||
|
|
case KEY_EVENT_UP_DOWN_COMB:
|
|||
|
|
// 组合键进入菜单
|
|||
|
|
AppManager_StartApp(APP_ID_MENU);
|
|||
|
|
return EVENT_HANDLED;
|
|||
|
|
|
|||
|
|
case KEY_EVENT_SOS_CLICK:
|
|||
|
|
// 短按SOS进入求救模式
|
|||
|
|
AppManager_StartApp(APP_ID_SOS);
|
|||
|
|
return EVENT_HANDLED;
|
|||
|
|
|
|||
|
|
case KEY_EVENT_SOS_LONG:
|
|||
|
|
// 长按SOS绑定IPC
|
|||
|
|
UI_ShowBindingPage();
|
|||
|
|
RF_SetMode(2);
|
|||
|
|
EV1527_Transmit(CLONED_ADDR, 0x01);
|
|||
|
|
RF_SetMode(0);
|
|||
|
|
Delay_ms(2000);
|
|||
|
|
AppManager_StartApp(APP_ID_CLOCK);
|
|||
|
|
return EVENT_HANDLED;
|
|||
|
|
|
|||
|
|
default:
|
|||
|
|
return EVENT_IGNORED;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* =========================================================================
|
|||
|
|
* 菜单应用实现
|
|||
|
|
* ========================================================================= */
|
|||
|
|
|
|||
|
|
static void MenuApp_OnStart(void)
|
|||
|
|
{
|
|||
|
|
Uart_SendString("[APP] MenuApp Started\r\n");
|
|||
|
|
pair_menu_select = 0;
|
|||
|
|
RF_SetMode(0);
|
|||
|
|
UI_ShowPairMenuPage(pair_menu_select);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static void MenuApp_onRun(void)
|
|||
|
|
{
|
|||
|
|
// 菜单应用无持续运行逻辑
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static void MenuApp_onClose(void)
|
|||
|
|
{
|
|||
|
|
Uart_SendString("[APP] MenuApp Closed\r\n");
|
|||
|
|
RF_SetMode(1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static EventResult MenuApp_onEvent(SystemEvent evt)
|
|||
|
|
{
|
|||
|
|
switch (evt.key_event)
|
|||
|
|
{
|
|||
|
|
case KEY_EVENT_UP_CLICK:
|
|||
|
|
if (pair_menu_select > 0)
|
|||
|
|
{
|
|||
|
|
pair_menu_select--;
|
|||
|
|
UI_ShowPairMenuPage(pair_menu_select);
|
|||
|
|
}
|
|||
|
|
return EVENT_HANDLED;
|
|||
|
|
|
|||
|
|
case KEY_EVENT_DOWN_CLICK:
|
|||
|
|
if (pair_menu_select < 4)
|
|||
|
|
{
|
|||
|
|
pair_menu_select++;
|
|||
|
|
UI_ShowPairMenuPage(pair_menu_select);
|
|||
|
|
}
|
|||
|
|
return EVENT_HANDLED;
|
|||
|
|
|
|||
|
|
case KEY_EVENT_SOS_CLICK:
|
|||
|
|
// 确认进入配对等待
|
|||
|
|
MOTOR = 1;
|
|||
|
|
Delay_ms(100);
|
|||
|
|
MOTOR = 0;
|
|||
|
|
|
|||
|
|
AppManager_StartApp(APP_ID_PAIR);
|
|||
|
|
return EVENT_HANDLED;
|
|||
|
|
|
|||
|
|
case KEY_EVENT_DOWN_LONG:
|
|||
|
|
// 长按返回时钟
|
|||
|
|
AppManager_CloseApp();
|
|||
|
|
return EVENT_HANDLED;
|
|||
|
|
|
|||
|
|
default:
|
|||
|
|
return EVENT_IGNORED;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* =========================================================================
|
|||
|
|
* 配对应用实现
|
|||
|
|
* ========================================================================= */
|
|||
|
|
|
|||
|
|
static void PairApp_OnStart(void)
|
|||
|
|
{
|
|||
|
|
Uart_SendString("[APP] PairApp Started\r\n");
|
|||
|
|
pair_state = 1; // 进入等待状态
|
|||
|
|
pair_timeout_ms = 0;
|
|||
|
|
captured_type = pair_menu_select;
|
|||
|
|
|
|||
|
|
RF_SetMode(1);
|
|||
|
|
LCD_Clear(COLOR_BLACK);
|
|||
|
|
LCD_ShowStringCentered(135, "RECHERCHE...", COLOR_WHITE, COLOR_BLACK);
|
|||
|
|
LCD_ShowStringCentered(160, "DECLENCH. CAPT", COLOR_CYAN, COLOR_BLACK);
|
|||
|
|
UI_ShowPairWaitPage(0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static void PairApp_onRun(void)
|
|||
|
|
{
|
|||
|
|
switch (pair_state)
|
|||
|
|
{
|
|||
|
|
case 1: // WAIT状态
|
|||
|
|
{
|
|||
|
|
// 雷达动画
|
|||
|
|
u8 frame = (u8)((ms_tick / 250) % 3);
|
|||
|
|
static u8 last_frame = 99;
|
|||
|
|
if (frame != last_frame)
|
|||
|
|
{
|
|||
|
|
last_frame = frame;
|
|||
|
|
UI_ShowPairWaitPage(frame);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 监听射频信号
|
|||
|
|
u32 rx_addr;
|
|||
|
|
u8 rx_data;
|
|||
|
|
if (EV1527_Decode(&rx_addr, &rx_data))
|
|||
|
|
{
|
|||
|
|
captured_addr = rx_addr;
|
|||
|
|
pair_state = 2; // 进入确认状态
|
|||
|
|
|
|||
|
|
RF_SetMode(0);
|
|||
|
|
UI_ShowPairConfirmPage(captured_addr);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 超时检测
|
|||
|
|
if (pair_timeout_ms >= 30000UL)
|
|||
|
|
{
|
|||
|
|
pair_timeout_ms = 0;
|
|||
|
|
UI_ShowPairFailPage(1);
|
|||
|
|
Delay_ms(2500);
|
|||
|
|
AppManager_CloseApp();
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 2: // CONFIRM状态
|
|||
|
|
// 等待用户操作
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
case 3: // SUCCESS状态
|
|||
|
|
// 成功动画已在事件处理中完成
|
|||
|
|
break;
|
|||
|
|
|
|||
|
|
default:
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static void PairApp_onClose(void)
|
|||
|
|
{
|
|||
|
|
Uart_SendString("[APP] PairApp Closed\r\n");
|
|||
|
|
RF_SetMode(1);
|
|||
|
|
pair_state = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static EventResult PairApp_onEvent(SystemEvent evt)
|
|||
|
|
{
|
|||
|
|
switch (pair_state)
|
|||
|
|
{
|
|||
|
|
case 1: // WAIT状态
|
|||
|
|
{
|
|||
|
|
if (evt.key_event == KEY_EVENT_DOWN_LONG)
|
|||
|
|
{
|
|||
|
|
AppManager_CloseApp();
|
|||
|
|
return EVENT_HANDLED;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
case 2: // CONFIRM状态
|
|||
|
|
{
|
|||
|
|
if (evt.key_event == KEY_EVENT_SOS_LONG)
|
|||
|
|
{
|
|||
|
|
// 保存对码
|
|||
|
|
Add_Sensor(captured_addr, captured_type);
|
|||
|
|
|
|||
|
|
pair_state = 3; // 进入成功状态
|
|||
|
|
UI_ShowPairSuccessPage(captured_addr);
|
|||
|
|
|
|||
|
|
// 物理反馈
|
|||
|
|
MOTOR = 1;
|
|||
|
|
LED_G = 0;
|
|||
|
|
LED_R = 1;
|
|||
|
|
LED_B = 1;
|
|||
|
|
Delay_ms(400);
|
|||
|
|
MOTOR = 0;
|
|||
|
|
|
|||
|
|
Delay_ms(1600);
|
|||
|
|
LED_G = 1;
|
|||
|
|
|
|||
|
|
Delay_ms(500);
|
|||
|
|
AppManager_CloseApp();
|
|||
|
|
return EVENT_HANDLED;
|
|||
|
|
}
|
|||
|
|
else if (evt.key_event == KEY_EVENT_DOWN_LONG)
|
|||
|
|
{
|
|||
|
|
AppManager_CloseApp();
|
|||
|
|
return EVENT_HANDLED;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
default:
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return EVENT_IGNORED;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* =========================================================================
|
|||
|
|
* 报警应用实现
|
|||
|
|
* ========================================================================= */
|
|||
|
|
|
|||
|
|
static void AlarmApp_OnStart(void)
|
|||
|
|
{
|
|||
|
|
Uart_SendString("[APP] AlarmApp Started\r\n");
|
|||
|
|
current_state = STATE_ALARM;
|
|||
|
|
|
|||
|
|
u8 slot = alarm_sensor_slot;
|
|||
|
|
static char alarm_name[24];
|
|||
|
|
char *name = "UNKNOWN SENSOR";
|
|||
|
|
|
|||
|
|
if (Check_Sensor_ID(captured_addr, &slot))
|
|||
|
|
{
|
|||
|
|
Format_Sensor_Name(slot, alarm_name);
|
|||
|
|
name = alarm_name;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
UI_ShowAlarmPage(name, 1);
|
|||
|
|
|
|||
|
|
// 重置报警定时器
|
|||
|
|
alarm_timer_ms = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static void AlarmApp_onRun(void)
|
|||
|
|
{
|
|||
|
|
// 警报边框闪烁效果
|
|||
|
|
if (alarm_flash_flag)
|
|||
|
|
{
|
|||
|
|
LCD_DrawRectBorder(4, 4, 112, 232, COLOR_RED);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
LCD_DrawRectBorder(4, 4, 112, 232, COLOR_BLACK);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static void AlarmApp_onClose(void)
|
|||
|
|
{
|
|||
|
|
Uart_SendString("[APP] AlarmApp Closed\r\n");
|
|||
|
|
current_state = STATE_NORMAL;
|
|||
|
|
|
|||
|
|
// 停止报警效果
|
|||
|
|
MOTOR = 0;
|
|||
|
|
LED_R = 1;
|
|||
|
|
LED_G = 1;
|
|||
|
|
LED_B = 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static EventResult AlarmApp_onEvent(SystemEvent evt)
|
|||
|
|
{
|
|||
|
|
// 任何按键都可以清除报警
|
|||
|
|
if (evt.key_event != KEY_EVENT_NONE)
|
|||
|
|
{
|
|||
|
|
AppManager_CloseApp();
|
|||
|
|
return EVENT_HANDLED;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return EVENT_IGNORED;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* =========================================================================
|
|||
|
|
* SOS应用实现
|
|||
|
|
* ========================================================================= */
|
|||
|
|
|
|||
|
|
static void SOSApp_OnStart(void)
|
|||
|
|
{
|
|||
|
|
Uart_SendString("[APP] SOSApp Started\r\n");
|
|||
|
|
current_state = STATE_SOS_EMITTED;
|
|||
|
|
UI_ShowSosPage();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static void SOSApp_onRun(void)
|
|||
|
|
{
|
|||
|
|
// 每500ms发射一次射频求救帧
|
|||
|
|
u8 sec_phase = (u8)((ms_tick / 500) % 2);
|
|||
|
|
if (sec_phase != sos_last_tx)
|
|||
|
|
{
|
|||
|
|
sos_last_tx = sec_phase;
|
|||
|
|
RF_SetMode(2);
|
|||
|
|
EV1527_Transmit(CLONED_ADDR, 0x08);
|
|||
|
|
RF_SetMode(0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 红色警告边框闪烁
|
|||
|
|
if (alarm_flash_flag)
|
|||
|
|
{
|
|||
|
|
LCD_DrawRectBorder(4, 4, 112, 232, COLOR_RED);
|
|||
|
|
LCD_DrawRectBorder(8, 8, 104, 224, COLOR_WHITE);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
LCD_DrawRectBorder(4, 4, 112, 232, COLOR_BLACK);
|
|||
|
|
LCD_DrawRectBorder(8, 8, 104, 224, COLOR_BLACK);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static void SOSApp_onClose(void)
|
|||
|
|
{
|
|||
|
|
Uart_SendString("[APP] SOSApp Closed\r\n");
|
|||
|
|
current_state = STATE_NORMAL;
|
|||
|
|
|
|||
|
|
// 停止求救效果
|
|||
|
|
MOTOR = 0;
|
|||
|
|
LED_R = 1;
|
|||
|
|
LED_G = 1;
|
|||
|
|
LED_B = 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static EventResult SOSApp_onEvent(SystemEvent evt)
|
|||
|
|
{
|
|||
|
|
// 长按任意键解除求救
|
|||
|
|
if (evt.key_event == KEY_EVENT_SOS_LONG ||
|
|||
|
|
evt.key_event == KEY_EVENT_UP_LONG ||
|
|||
|
|
evt.key_event == KEY_EVENT_DOWN_LONG)
|
|||
|
|
{
|
|||
|
|
AppManager_CloseApp();
|
|||
|
|
return EVENT_HANDLED;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return EVENT_IGNORED;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* =========================================================================
|
|||
|
|
* 应用注册函数
|
|||
|
|
* ========================================================================= */
|
|||
|
|
|
|||
|
|
void Apps_RegisterAll(void)
|
|||
|
|
{
|
|||
|
|
// 注册时钟应用(前台)
|
|||
|
|
AppManager_RegisterApp(APP_ID_CLOCK, APP_TYPE_FOREGROUND, "Clock",
|
|||
|
|
ClockApp_OnStart, ClockApp_onRun,
|
|||
|
|
ClockApp_onClose, ClockApp_onEvent);
|
|||
|
|
|
|||
|
|
// 注册菜单应用(前台)
|
|||
|
|
AppManager_RegisterApp(APP_ID_MENU, APP_TYPE_FOREGROUND, "Menu",
|
|||
|
|
MenuApp_OnStart, MenuApp_onRun,
|
|||
|
|
MenuApp_onClose, MenuApp_onEvent);
|
|||
|
|
|
|||
|
|
// 注册配对应用(前台)
|
|||
|
|
AppManager_RegisterApp(APP_ID_PAIR, APP_TYPE_FOREGROUND, "Pair",
|
|||
|
|
PairApp_OnStart, PairApp_onRun,
|
|||
|
|
PairApp_onClose, PairApp_onEvent);
|
|||
|
|
|
|||
|
|
// 注册报警应用(前台)
|
|||
|
|
AppManager_RegisterApp(APP_ID_ALARM, APP_TYPE_FOREGROUND, "Alarm",
|
|||
|
|
AlarmApp_OnStart, AlarmApp_onRun,
|
|||
|
|
AlarmApp_onClose, AlarmApp_onEvent);
|
|||
|
|
|
|||
|
|
// 注册SOS应用(前台)
|
|||
|
|
AppManager_RegisterApp(APP_ID_SOS, APP_TYPE_FOREGROUND, "SOS",
|
|||
|
|
SOSApp_OnStart, SOSApp_onRun,
|
|||
|
|
SOSApp_onClose, SOSApp_onEvent);
|
|||
|
|
|
|||
|
|
Uart_SendString("[APP] All applications registered\r\n");
|
|||
|
|
}
|