138 lines
4.0 KiB
C
138 lines
4.0 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;
|
|||
|
|
|
|||
|
|
// 克隆的手环出厂物理 ID 地址
|
|||
|
|
#define CLONED_ADDR 0x55AAAA
|
|||
|
|
|
|||
|
|
// 本地私有变量
|
|||
|
|
static u8 sos_last_phase = 99; // 记录上一次发射的 500ms 半周期状态
|
|||
|
|
static u32 alarm_timer_ms = 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;
|
|||
|
|
alarm_timer_ms = 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 双灯珠以 50ms 频率进行高频左右交替红蓝爆闪 ======
|
|||
|
|
{
|
|||
|
|
u8 flash = (ms_tick / 50) % 2;
|
|||
|
|
if (flash) {
|
|||
|
|
RGB_Send(0, 200, 0, 0, 0, 200); // 灯 1 亮红 (GRB 中 R=200),灯 2 亮蓝 (B=200)
|
|||
|
|
} 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;
|
|||
|
|
|
|||
|
|
alarm_timer_ms += tick_diff;
|
|||
|
|
if (alarm_timer_ms >= 1200) {
|
|||
|
|
alarm_timer_ms = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (alarm_timer_ms < 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;
|
|||
|
|
}
|