310 lines
9.7 KiB
C
310 lines
9.7 KiB
C
#include "event.h"
|
||
#include "app_manager.h"
|
||
#include "database.h"
|
||
#include "system.h"
|
||
|
||
#define EVENT_QUEUE_DEPTH 8
|
||
|
||
static SystemEvent idata event_queue[EVENT_QUEUE_DEPTH];
|
||
static u8 queue_head = 0;
|
||
static u8 queue_tail = 0;
|
||
static u8 queue_count = 0;
|
||
|
||
void EventQueue_Init(void)
|
||
{
|
||
queue_head = 0;
|
||
queue_tail = 0;
|
||
queue_count = 0;
|
||
}
|
||
|
||
bit EventQueue_Push(SystemEvent evt)
|
||
{
|
||
if (queue_count >= EVENT_QUEUE_DEPTH) return 0;
|
||
EA = 0;
|
||
event_queue[queue_tail] = evt;
|
||
queue_tail = (queue_tail + 1) % EVENT_QUEUE_DEPTH;
|
||
queue_count++;
|
||
EA = 1;
|
||
return 1;
|
||
}
|
||
|
||
bit EventQueue_InsertFront(SystemEvent evt)
|
||
{
|
||
if (queue_count >= EVENT_QUEUE_DEPTH) return 0;
|
||
EA = 0;
|
||
queue_head = (queue_head - 1 + EVENT_QUEUE_DEPTH) % EVENT_QUEUE_DEPTH;
|
||
event_queue[queue_head] = evt;
|
||
queue_count++;
|
||
EA = 1;
|
||
return 1;
|
||
}
|
||
|
||
SystemEvent EventQueue_Pop(void)
|
||
{
|
||
SystemEvent evt;
|
||
evt.key_event = KEY_EVENT_NONE;
|
||
evt.priority = EVENT_PRIORITY_LOW;
|
||
evt.extra_data = 0;
|
||
evt.extra_size = 0;
|
||
if (queue_count == 0) return evt;
|
||
EA = 0;
|
||
evt = event_queue[queue_head];
|
||
queue_head = (queue_head + 1) % EVENT_QUEUE_DEPTH;
|
||
queue_count--;
|
||
EA = 1;
|
||
return evt;
|
||
}
|
||
|
||
bit EventQueue_IsEmpty(void)
|
||
{
|
||
return (queue_count == 0) ? 1 : 0;
|
||
}
|
||
|
||
bit EventQueue_IsFull(void)
|
||
{
|
||
return (queue_count >= EVENT_QUEUE_DEPTH) ? 1 : 0;
|
||
}
|
||
|
||
u8 EventQueue_GetCount(void)
|
||
{
|
||
return queue_count;
|
||
}
|
||
|
||
void Event_Dispatcher_Loop(void)
|
||
{
|
||
SystemEvent evt = EventQueue_Pop();
|
||
if (evt.key_event == KEY_EVENT_NONE && evt.extra_size == 0) {
|
||
return;
|
||
}
|
||
inactivity_timer = 0; // 收到有效按键或无线事件,重置闲置计时器
|
||
Uart_SendString("[EVENT] key=");
|
||
Uart_SendHex8((u8)evt.key_event);
|
||
Uart_SendString(", pri=");
|
||
Uart_SendHex8((u8)evt.priority);
|
||
Uart_SendString("\r\n");
|
||
|
||
// SOS 按键:仅在当前不处于 SOS 求求模式时触发进入 SOS 状态,否则作为普通按键进行事件分发
|
||
if ((evt.key_event == KEY_EVENT_SOS_CLICK || evt.key_event == KEY_EVENT_SOS_LONG) &&
|
||
AppManager_GetActiveAppID() != APP_ID_SOS) {
|
||
AppManager_StartApp(APP_ID_SOS);
|
||
return;
|
||
}
|
||
|
||
// 传感器入侵警报:当前不处于 SOS 求救状态时方可跳转到报警界面
|
||
if (evt.priority == EVENT_PRIORITY_HIGH && evt.extra_size >= 4) {
|
||
u8 slot;
|
||
if (Check_Sensor_ID(evt.extra_data, &slot)) {
|
||
if (AppManager_GetActiveAppID() != APP_ID_SOS) {
|
||
captured_addr = evt.extra_data;
|
||
alarm_sensor_slot = slot;
|
||
AppManager_StartApp(APP_ID_ALARM);
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 无线对码捕获:处于 PAIR 模式下时,将射频事件分发给 PairApp 处理并退出分发
|
||
if (evt.priority == EVENT_PRIORITY_NORMAL && evt.extra_size >= 4) {
|
||
captured_addr = evt.extra_data;
|
||
captured_type = menu_select;
|
||
if (AppManager_GetActiveAppID() == APP_ID_PAIR) {
|
||
AppManager_DispatchEvent(evt);
|
||
return;
|
||
}
|
||
}
|
||
|
||
AppManager_DispatchEvent(evt);
|
||
}
|
||
|
||
void Timer1_Init(void)
|
||
{
|
||
AUXR |= 0x40;
|
||
TMOD &= 0x0F;
|
||
{
|
||
u16 reload = (u16)(65536UL - (MAIN_Fosc / 1000UL));
|
||
TL1 = (u8)reload;
|
||
TH1 = (u8)(reload >> 8);
|
||
}
|
||
ET1 = 1;
|
||
TR1 = 1;
|
||
EA = 1;
|
||
}
|
||
|
||
void Timer1_Isr(void) interrupt 3
|
||
{
|
||
SystemEvent evt;
|
||
|
||
ms_tick++;
|
||
if (ms_tick >= 1000) {
|
||
ms_tick = 0;
|
||
current_sec++;
|
||
if (current_sec >= 60) {
|
||
current_sec = 0;
|
||
current_min++;
|
||
if (current_min >= 60) {
|
||
current_min = 0;
|
||
current_hour++;
|
||
if (current_hour >= 24) current_hour = 0;
|
||
}
|
||
clock_updated = 1;
|
||
}
|
||
}
|
||
|
||
if (current_state == STATE_PAIR_WAIT) {
|
||
pair_timeout_ms++;
|
||
}
|
||
|
||
/* 振动马达定时状态机(仅控制马达,不再控制已被挪用/废弃的 LED) */
|
||
if (current_state == STATE_SOS_EMITTED) {
|
||
alarm_timer_ms++;
|
||
if (alarm_timer_ms >= 1200) alarm_timer_ms = 0;
|
||
if (alarm_timer_ms < 1000) MOTOR = 1; else MOTOR = 0;
|
||
} else if (current_state == STATE_ALARM) {
|
||
u8 stype = sensor_list[alarm_sensor_slot].type;
|
||
alarm_timer_ms++;
|
||
if (alarm_timer_ms >= 5000) alarm_timer_ms = 0;
|
||
if (stype == 0) {
|
||
// 门磁警报振动波形
|
||
if (alarm_timer_ms < 300) MOTOR = 1; else MOTOR = 0;
|
||
} else if (stype == 1) {
|
||
// PIR 警报振动波形
|
||
if (alarm_timer_ms < 300) MOTOR = 1;
|
||
else if (alarm_timer_ms >= 300 && alarm_timer_ms < 500) MOTOR = 0;
|
||
else if (alarm_timer_ms >= 500 && alarm_timer_ms < 800) MOTOR = 1;
|
||
else MOTOR = 0;
|
||
} else if (stype == 2) {
|
||
// 烟感警报振动波形
|
||
if (alarm_timer_ms < 200) MOTOR = 1;
|
||
else if (alarm_timer_ms >= 200 && alarm_timer_ms < 350) MOTOR = 0;
|
||
else if (alarm_timer_ms >= 350 && alarm_timer_ms < 550) MOTOR = 1;
|
||
else if (alarm_timer_ms >= 550 && alarm_timer_ms < 700) MOTOR = 0;
|
||
else if (alarm_timer_ms >= 700 && alarm_timer_ms < 900) MOTOR = 1;
|
||
else MOTOR = 0;
|
||
} else if (stype == 3) {
|
||
// 气感警报振动波形
|
||
if (alarm_timer_ms < 200) MOTOR = 1;
|
||
else if (alarm_timer_ms >= 200 && alarm_timer_ms < 300) MOTOR = 0;
|
||
else if (alarm_timer_ms >= 300 && alarm_timer_ms < 500) MOTOR = 1;
|
||
else if (alarm_timer_ms >= 500 && alarm_timer_ms < 600) MOTOR = 0;
|
||
else if (alarm_timer_ms >= 600 && alarm_timer_ms < 800) MOTOR = 1;
|
||
else if (alarm_timer_ms >= 800 && alarm_timer_ms < 900) MOTOR = 0;
|
||
else if (alarm_timer_ms >= 900 && alarm_timer_ms < 1100) MOTOR = 1;
|
||
else MOTOR = 0;
|
||
} else if (stype == 4) {
|
||
// 水浸警报振动波形
|
||
if (alarm_timer_ms < 600) MOTOR = 1;
|
||
else if (alarm_timer_ms >= 600 && alarm_timer_ms < 900) MOTOR = 0;
|
||
else if (alarm_timer_ms >= 900 && alarm_timer_ms < 1500) MOTOR = 1;
|
||
else MOTOR = 0;
|
||
} else {
|
||
if (alarm_timer_ms < 300) MOTOR = 1; else MOTOR = 0;
|
||
}
|
||
} else {
|
||
MOTOR = 0;
|
||
alarm_timer_ms = 0;
|
||
motor_timer_ms = 0;
|
||
}
|
||
|
||
alarm_flash_flag = (ms_tick / 100) % 2;
|
||
|
||
/* 按键消抖扫描 (每10ms) */
|
||
key_scan_timer++;
|
||
if (key_scan_timer >= 10) {
|
||
u8 raw_up = !KEY_UP;
|
||
u8 raw_down = !KEY_DOWN;
|
||
u8 raw_confirm = !KEY_CONFIRM;
|
||
u8 raw_sos = !KEY_SOS;
|
||
key_scan_timer = 0;
|
||
|
||
// 如果检测到有任何按键按下,清零闲置计时器;否则在非休眠非警报下累加
|
||
if (raw_up || raw_down || raw_confirm || raw_sos) {
|
||
inactivity_timer = 0;
|
||
} else {
|
||
if (current_state != STATE_SLEEP && current_state != STATE_ALARM && current_state != STATE_SOS_EMITTED) {
|
||
inactivity_timer++;
|
||
}
|
||
}
|
||
|
||
evt.key_event = KEY_EVENT_NONE;
|
||
evt.extra_data = 0;
|
||
evt.extra_size = 0;
|
||
|
||
if (raw_up && raw_down) {
|
||
comb_hold++;
|
||
if (comb_hold == 300) {
|
||
evt.key_event = KEY_EVENT_UP_DOWN_COMB;
|
||
evt.priority = EVENT_PRIORITY_NORMAL;
|
||
EventQueue_Push(evt);
|
||
}
|
||
key_up_hold = 0;
|
||
key_down_hold = 0;
|
||
} else {
|
||
comb_hold = 0;
|
||
|
||
if (raw_up) {
|
||
key_up_hold++;
|
||
if (key_up_hold == 300) {
|
||
evt.key_event = KEY_EVENT_UP_LONG;
|
||
evt.priority = EVENT_PRIORITY_NORMAL;
|
||
EventQueue_Push(evt);
|
||
}
|
||
} else {
|
||
if (key_up_hold >= 2 && key_up_hold < 300) {
|
||
evt.key_event = KEY_EVENT_UP_CLICK;
|
||
evt.priority = EVENT_PRIORITY_NORMAL;
|
||
EventQueue_Push(evt);
|
||
}
|
||
key_up_hold = 0;
|
||
}
|
||
|
||
if (raw_down) {
|
||
key_down_hold++;
|
||
if (key_down_hold == 300) {
|
||
evt.key_event = KEY_EVENT_DOWN_LONG;
|
||
evt.priority = EVENT_PRIORITY_NORMAL;
|
||
EventQueue_Push(evt);
|
||
}
|
||
} else {
|
||
if (key_down_hold >= 2 && key_down_hold < 300) {
|
||
evt.key_event = KEY_EVENT_DOWN_CLICK;
|
||
evt.priority = EVENT_PRIORITY_NORMAL;
|
||
EventQueue_Push(evt);
|
||
}
|
||
key_down_hold = 0;
|
||
}
|
||
|
||
if (raw_confirm) {
|
||
key_confirm_hold++;
|
||
if (key_confirm_hold == 300) {
|
||
evt.key_event = KEY_EVENT_CONFIRM_LONG;
|
||
evt.priority = EVENT_PRIORITY_NORMAL;
|
||
EventQueue_Push(evt);
|
||
}
|
||
} else {
|
||
if (key_confirm_hold >= 2 && key_confirm_hold < 300) {
|
||
evt.key_event = KEY_EVENT_CONFIRM_CLICK;
|
||
evt.priority = EVENT_PRIORITY_NORMAL;
|
||
EventQueue_Push(evt);
|
||
}
|
||
key_confirm_hold = 0;
|
||
}
|
||
|
||
if (raw_sos) {
|
||
key_sos_hold++;
|
||
if (key_sos_hold == 300) {
|
||
evt.key_event = KEY_EVENT_SOS_LONG;
|
||
evt.priority = EVENT_PRIORITY_URGENT;
|
||
EventQueue_InsertFront(evt);
|
||
}
|
||
} else {
|
||
if (key_sos_hold >= 2 && key_sos_hold < 300) {
|
||
evt.key_event = KEY_EVENT_SOS_CLICK;
|
||
evt.priority = EVENT_PRIORITY_URGENT;
|
||
EventQueue_InsertFront(evt);
|
||
}
|
||
key_sos_hold = 0;
|
||
}
|
||
}
|
||
}
|
||
}
|