Files
stc32g128k/App/event.c

310 lines
9.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}
}
}
}