135 lines
3.9 KiB
C
135 lines
3.9 KiB
C
#include "app_manager.h"
|
||
#include "xtell.h"
|
||
#include "ui.h"
|
||
#include "rgb.h"
|
||
#include "event.h"
|
||
#include "system.h"
|
||
#include "../Drivers/rf.h"
|
||
#include "../Drivers/lcd.h"
|
||
|
||
// 外部全局变量引用
|
||
extern SystemState current_state;
|
||
extern volatile u16 ms_tick;
|
||
extern volatile bit alarm_flash_flag;
|
||
|
||
// 本地私有变量
|
||
static u8 sos_last_phase = 99; // 记录上一次发射的 500ms 半周期状态
|
||
static u32 sos_pulse_timer = 0; // SOS 马达震动波形计数器
|
||
static u16 last_run_tick = 0; // 记录上一次轮询的 ticks
|
||
|
||
// 声明本应用的生命周期回调函数
|
||
static void SOSApp_OnStart(void);
|
||
static void SOSApp_onRun(void);
|
||
static void SOSApp_onClose(void);
|
||
static EventResult SOSApp_onEvent(SystemEvent *evt);
|
||
|
||
// 实体化定义 SOS 呼救应用控制块
|
||
WristbandApp sos_app = {
|
||
APP_ID_SOS,
|
||
"SOS",
|
||
SOSApp_OnStart,
|
||
SOSApp_onRun,
|
||
SOSApp_onClose,
|
||
SOSApp_onEvent
|
||
};
|
||
|
||
/**
|
||
* @brief SOSApp 启动回调
|
||
*/
|
||
static void SOSApp_OnStart(void)
|
||
{
|
||
current_state = STATE_SOS_EMITTED; // 进入 SOS 紧急求救状态
|
||
sos_last_phase = 99;
|
||
sos_pulse_timer = 0; // 马达震动计数器清零
|
||
last_run_tick = ms_tick;
|
||
UI_ShowSosPage(); // 初始化渲染 SOS 警示主页
|
||
|
||
// 立即点亮左侧灯为红色,右侧熄灭,准备开启双色红灯交替爆闪
|
||
RGB_Send(0, 200, 0, 0, 0, 0);
|
||
|
||
XTELL_LOG("[SOSApp] Started\r\n");
|
||
}
|
||
|
||
/**
|
||
* @brief SOSApp 轮询主回调
|
||
* @details 包含 500ms 周期的高频射频 SOS 码发射、红蓝交替爆闪以及
|
||
* 马达 (1000ms震动 / 200ms静音) 规律震动控制。
|
||
*/
|
||
static void SOSApp_onRun(void)
|
||
{
|
||
u16 tick_diff;
|
||
|
||
// ====== 1. 控制无线射频,每 500ms 发射一次 SOS 无线数据帧 (0x08) ======
|
||
u8 sec_phase = (u8)((ms_tick / 500) % 2);
|
||
if (sec_phase != sos_last_phase) {
|
||
sos_last_phase = sec_phase;
|
||
RF_SetMode(2); // 切换发射
|
||
EV1527_Transmit(CLONED_ADDR, 0x08); // 发射克隆 ID 及其 SOS (0x08) 命令字
|
||
RF_SetMode(0); // 释放接收
|
||
XTELL_LOG("[SOSApp] SOS Radio packet emitted\r\n");
|
||
}
|
||
|
||
// ====== 2. 控制 RGB 双灯珠以 300ms 周期进行特定的交替闪烁 ======
|
||
{
|
||
u8 flash = (ms_tick / 300) % 2;
|
||
if (flash) {
|
||
RGB_Send(0, 200, 0, 0, 0, 0); // 灯1先亮红,灯2灭
|
||
} else {
|
||
RGB_Send(0, 0, 200, 0, 200, 0); // 灯1变蓝,灯2亮红
|
||
}
|
||
}
|
||
|
||
// ====== 3. 控制屏幕绘制多层爆闪红白框 ======
|
||
if (alarm_flash_flag) {
|
||
LCD_DrawRectBorder(4, 4, 112, 232, COLOR_RED);
|
||
LCD_DrawRectBorder(5, 5, 110, 230, COLOR_RED);
|
||
LCD_DrawRectBorder(8, 8, 104, 224, COLOR_WHITE);
|
||
} else {
|
||
LCD_DrawRectBorder(4, 4, 112, 232, COLOR_BLACK);
|
||
LCD_DrawRectBorder(5, 5, 110, 230, COLOR_BLACK);
|
||
LCD_DrawRectBorder(8, 8, 104, 224, COLOR_BLACK);
|
||
}
|
||
|
||
// ====== 4. 马达 SOS 震动节拍自处理 (1000ms 震动,200ms 静音) ======
|
||
if (ms_tick >= last_run_tick) {
|
||
tick_diff = ms_tick - last_run_tick;
|
||
} else {
|
||
tick_diff = 1000 + ms_tick - last_run_tick;
|
||
}
|
||
last_run_tick = ms_tick;
|
||
|
||
sos_pulse_timer += tick_diff;
|
||
if (sos_pulse_timer >= 1200) {
|
||
sos_pulse_timer = 0;
|
||
}
|
||
|
||
if (sos_pulse_timer < 1000) {
|
||
MOTOR = 1;
|
||
} else {
|
||
MOTOR = 0;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief SOSApp 退出清理
|
||
*/
|
||
static void SOSApp_onClose(void)
|
||
{
|
||
RGB_Send(0, 0, 0, 0, 0, 0); // 关闭 RGB
|
||
MOTOR = 0; // 停震
|
||
current_state = STATE_NORMAL;
|
||
XTELL_LOG("[SOSApp] Closed\r\n");
|
||
}
|
||
|
||
/**
|
||
* @brief SOSApp 事件拦截处理回调 (按任意键退出 SOS)
|
||
*/
|
||
static EventResult SOSApp_onEvent(SystemEvent *evt)
|
||
{
|
||
if (evt->key_event != KEY_EVENT_NONE) {
|
||
AppManager_SwitchToForeground(&clock_app); // 退出 SOS,返回时钟
|
||
return EVENT_HANDLED;
|
||
}
|
||
return EVENT_IGNORED;
|
||
}
|