Files
stc32g128k/App/event.c

321 lines
11 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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"
#include "clock.h"
#include "xtell.h"
#include "../Drivers/adc.h"
// 定义事件çŽå½¢é˜Ÿåˆ—çš„æœå¤§æ·±åº¦ä¸º 8
#define EVENT_QUEUE_DEPTH 8
// çŽå½¢é˜Ÿåˆ—å­˜å‚¨æ•°ç» (存放在å<C2A8>•片机 xdata 拓展 RAM区中)
static SystemEvent xdata event_queue[EVENT_QUEUE_DEPTH];
static u8 queue_head = 0; // 队é–è»æŒ‡é’
static u8 queue_tail = 0; // 队尾写指é’
static u8 queue_count = 0; // 当å‰<C3A5>队列内有效äºä»¶æ»æ•°
/**
* @brief åˆ<C3A5>ååŒ/清空事件队列
*/
void EventQueue_Init(void)
{
queue_head = 0;
queue_tail = 0;
queue_count = 0;
}
/**
* @brief 将普通事件压入队å°
* @param evt 输入的系统事ä»
* @return bit 1-æˆ<C3A6>功ï¼0-失败
*/
bit EventQueue_Push(SystemEvent evt)
{
if (queue_count >= EVENT_QUEUE_DEPTH) return 0; // 队列满,丢弃事件
EA = 0; // å…³é—­å…¨å±€ä¸æï¼Œä¿<C3A4>护临界区æ“<C3A6>作的原å­<C3A5>æ
event_queue[queue_tail] = evt; // 存入队尾
queue_tail = (queue_tail + 1) % EVENT_QUEUE_DEPTH; // 尾指éˆå<CB86>å<E28098>Žç§»åŠï¼ŒåžçŽ
queue_count++; // æœ‰æ•ˆè®¡æ•°åŠ 1
EA = 1; // æ<>¢å<C2A2>å…¨å±ä¸æ
return 1;
}
/**
* @brief 将高优先çº/ç´§æ¥äºä»¶å¼ºè¡Œæ<C592>到队é¦
* @param evt 输入的系统事ä»
* @return bit 1-æˆ<C3A6>功ï¼0-失败
*/
bit EventQueue_InsertFront(SystemEvent evt)
{
if (queue_count >= EVENT_QUEUE_DEPTH) return 0; // 队列满,æ<C592>队失败
EA = 0; // å±<C3A5>è”½ä¸æ
// 头指éˆå<CB86>å‰<C3A5>移动一ä½<C3A4>(带åžçŽé˜²æº¢å‡ºï¼‰
queue_head = (queue_head - 1 + EVENT_QUEUE_DEPTH) % EVENT_QUEUE_DEPTH;
event_queue[queue_head] = evt; // 存入腾出的队é¦ä½<C3A4>ç½
queue_count++; // è®¡æ•°åŠ 1
EA = 1; // æ<>¢å<C2A2>中æ
return 1;
}
/**
* @brief 从队首弹出一ä¸ç¼“冲事件
* @return SystemEvent 返回弹出的事件ã‚若空返回空闲事ä»
*/
SystemEvent EventQueue_Pop(void)
{
SystemEvent evt;
// 默è¤ç©ºäº‹ä»¶å±žæ
evt.key_event = KEY_EVENT_NONE;
evt.priority = EVENT_PRIORITY_NORMAL;
evt.extra_data = 0;
evt.extra_size = 0;
if (queue_count == 0) return evt; // 队空,直接返回空闲事ä»
EA = 0; // å±<C3A5>è”½ä¸æ
evt = event_queue[queue_head]; // 读å<C2BB>é˜Ÿéæ•°æ<C2B0>
queue_head = (queue_head + 1) % EVENT_QUEUE_DEPTH; // 头指éˆå<CB86>å<E28098>Žç§»åŠï¼ŒåžçŽ
queue_count--; // æœ‰æ•ˆè®¡æ•°å‡ 1
EA = 1; // æ<>¢å<C2A2>中æ
return evt;
}
/**
* @brief 判æ­é˜Ÿåˆ—æ˜å<CB9C>¦ä¸ºç©
*/
bit EventQueue_IsEmpty(void)
{
return (queue_count == 0) ? 1 : 0;
}
/**
* @brief 判æ­é˜Ÿåˆ—æ˜å<CB9C>¦å·²æ»
*/
bit EventQueue_IsFull(void)
{
return (queue_count >= EVENT_QUEUE_DEPTH) ? 1 : 0;
}
/**
* @brief 获å<C2B7>当å‰<C3A5>队列ä¸çš„äºä»¶æ»æ•°
*/
u8 EventQueue_GetCount(void)
{
return queue_count;
}
/**
* @brief äºä»¶åˆ†å<E280A0>器核心轮询é»è¾
* @details é€<C3A9>一处ç<E2809E>†é˜Ÿåˆ—ä¸çš„äºä»¶ï¼Œå¹¶æ ¹æ<C2B9>系统当å‰<C3A5>çš„è¿<C3A8>行模å¼<C3A5>è¿è¡Œæ¦æˆã€<C3A3>è·³è½æˆä¸å<E280B9>æ´¾å<C2BE>ã
*/
void Event_Dispatcher_Loop(void)
{
SystemEvent evt = EventQueue_Pop(); // 弹出ä¸ä¸äº‹ä»¶
// 妿žœæ˜æ— äºå<E280B9>生的空äºä»¶ï¼Œç´æŽ¥éå‡
if (evt.key_event == KEY_EVENT_NONE && evt.extra_size == 0) {
return;
}
inactivity_timer = 0; // æ<>•获到有效äºä»¶ï¼Œæ¸…é¶ä¼çœ è®¡æ—¶å™ï¼Œé‡<C3A9>ç½é—²ç½®è¶…æ—¶
// 串å<C2B2>£æ‰“å<E2809C>°è°ƒè¯•ä¿¡æ<C2A1>¯
XTELL_LOG("[EVENT] key=");
XTELL_LOG_HEX8((u8)evt.key_event);
XTELL_LOG("\r\n");
// SOS 按键紧æ¥å„ç<E2809E>†ï¼šè¥å½“å‰<C3A5>å‰<C3A5>å<EFBFBD>°ä¸<C3A4>为 SOS 应用,接收到 SOS é”动作,ç«å<E280B9>³å¼ºè¡Œåˆ‡å…¥åˆ° SOS_APP 并执行求æ•
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;
}
// 关机äºä»¶å¤„ç<E2809E>†ï¼šæ<C5A1>•èŽ·åˆ°é•¿æŒ‰å…³æœºæŒ‡ä»¤ï¼Œç´æŽ¥è°ƒç” Power_Off å…³æ­ç”µæº<C3A6>
if (evt.key_event == KEY_EVENT_POWER_OFF) {
Power_Off();
return;
}
// 常è„äºä»¶ï¼ˆå¦æ™®é€šçš„æŒ‰é”®ç¹å‡»ï¼‰ç´æŽ¥é<C2A5>传分å<E280A0>给当å‰<C3A5>å„于å‰<C3A5>å<EFBFBD>°æ´»è·ƒçš„应ç”
AppManager_DispatchEvent(evt);
}
/**
* @brief å®šæ—¶å™ 1 åˆ<C3A5>ååŒï¼Œè¾å®š 1ms 䏿–周期
*/
void Timer1_Init(void)
{
AUXR |= 0x40; // è®¾å®šå®šæ—¶å™ 1 ä¸ 1T 模å¼<C3A5> (无分频,主é‘直接输å…)
TMOD &= 0x0F; // è®¾ç½®å®šæ—¶å™ 1 模å¼<C3A5>寄存å™ï¼Œä¿<C3A4>留低åä½<C3A4> (定时å™0é…<C3A9>ç½®)
{
// 按照系统主é (MAIN_Fosc) 计算 1ms 对应的é‡<C3A9>装载å€
u16 reload = (u16)(65536UL - (MAIN_Fosc / 1000UL));
TL1 = (u8)reload; // è½½å…¥ä½ 8 ä½
TH1 = (u8)(reload >> 8);// è½½å…¥é« 8 ä½
}
ET1 = 1; // å¼å<C2BC>å®šæ—¶å™ 1 䏿å…<C3A5>è
TR1 = 1; // å<>动定时器 1 计数
EA = 1; // å¼å<C2BC>免局䏿å…<C3A5>è
}
// å…¨å±€æŒ‰é”®æ‰æ<E280B0><C3A6>触å<C2A6>æ ‡å¿
volatile bit key_scan_flag = 0;
/**
* @brief å®šæ—¶å™ 1 䏿æœ<C3A6>务ç¨åº<C3A5> (æ¯ 1ms 触å<C2A6>䏿¬)
* @details æ‰¿æ‹…ç³»ç»Ÿè½æ—¶é’Ÿè®¡ç®—ï¼Œå¹¶æ¯ 10ms ç½ä½<C3A4>主å¾çŽæŒ‰é”®æ‰æ<E280B0><C3A6>标志,ä¸<C3A4>ç´æŽ¥åœ¨ä¸æä¸è¿è ADC 多æ¡é‡‡æ ·ã
*/
void Timer1_Isr(void) interrupt 3
{
// 1ms å®šæ—¶æ›´æ–°è½æ—¶é’Ÿ
Clock_IncMS();
// 报è¦å±<C3A5>幕红边æ†ä»¥ 100ms 卿œŸäºç<C2BA>,è¿è¡Œéœè‰²çˆ†é—ªæŒ‡ç¤º
alarm_flash_flag = (ms_tick / 100) % 2;
/* 物ç<C2A9>†æŒ‰é”®å®šæ—¶è®¡æ•° (æ¯ 10ms ç½ä½<C3A4>一次标志ä½<C3A4>) */
key_scan_timer++;
if (key_scan_timer >= 10) {
key_scan_timer = 0; // é‡<C3A9>ç½®æ‰æ<E280B0><C3A6>分é¢è¡æ•°å™
key_scan_flag = 1; // ä»…åœ¨ä¸æé‡Œç½®èµ·æ ‡å¿—ä½<C3A4>,留待主å¾çŽä¸æ‰§èŒå®žé™…è»å<C2BB>与消æŠ
}
}
/**
* @brief ä¸»å¾ªçŽæŒ‰é”®æ‰æ<E280B0><C3A6>与消æŠå¤„ç<E2809E>†å‡½æ•°
* @details 由主å¾çŽæ¯ 10ms æ£æŸ¥å¹¶æ‰§èŒï¼Œå®Œå…¨åœ¨ä¸»çº¿ç¨ä¸è¿<C3A8>èŒï¼Œç»<C3A7>æ— ä¸æé‡<C3A9>入冲çª<C3A7>ã€
*/
void Event_KeyScan_Poll(void)
{
SystemEvent evt;
// 读å<C2BB>按键的电平信å<C2A1> (KEY_UP, KEY_CONFIRM 为低电平有效)
u8 raw_up = !KEY_UP;
u8 raw_down = ADC_IsKeyDown(); // KEY_DOWN 通过 P0.3 ADC 通é<C5A1>“判定 (常æ 2.0V, 按下 3.7V)
u8 raw_confirm = !KEY_CONFIRM;
u8 raw_sos = !KEY_SOS; // æ<>¢å SOS 物ç<C2A9>†æŒ‰é”®ç”µå¹³æ£æµ
key_scan_timer = 0; // é‡<C3A9>ç½®æ‰æ<E280B0><C3A6>分é¢è¡æ•°å™
// ã€<C3A3>SOS 按键电平实时诊断ã€
{
static u8 last_raw_sos = 99;
if (raw_sos != last_raw_sos) {
last_raw_sos = raw_sos;
Uart_SendString("[KEY-DIAG] KEY_SOS (P2.6) logic raw: ");
Uart_SendByte(raw_sos ? '1' : '0');
Uart_SendString(", Physical GPIO Pin: ");
Uart_SendByte(KEY_SOS ? '1' : '0');
Uart_SendString("\r\n");
}
}
// 按键调试诊断:若按键 ADC 值有å<E280B0>˜åŒæˆå„于高电平,串å<C2B2>£è¾“出真实 ADC å€
{
u16 down_val = ADC_ReadFiltered(ADC_CHANNEL_KEY_DOWN);
if (down_val > 2800) {
Uart_SendString("[KEY-DIAG] KEY_DOWN pressed! ADC Raw: ");
Uart_SendByte((u8)('0' + (down_val / 1000) % 10));
Uart_SendByte((u8)('0' + (down_val / 100) % 10));
Uart_SendByte((u8)('0' + (down_val / 10) % 10));
Uart_SendByte((u8)('0' + (down_val % 10)));
Uart_SendString("\r\n");
}
}
// æ£æµåˆ°æœ‰ä»»æ„<C3A6>按é”处于ä¸åŽçжæ<C2B6>,ç«å<E280B9>³å°†æ— æ“<C3A6>作闲置ä¼çœ è®¡æ—¶å™¨å½é
if (raw_up || raw_down || raw_confirm || raw_sos) {
inactivity_timer = 0;
} else {
// 妿žœåœ¨å¸¸æ€<C3A6>ä¸ï¼ˆé<CB86>žä¼çœ ã€<C3A3>é<EFBFBD>žæŠ¥è¦ã<C2A6>é<EFBFBD>žç´§æ¥æ±æ•ï¼‰ï¼Œç´¯åŠ é—²ç½æ—¶é—´
if (current_state != STATE_SLEEP && current_state != STATE_ALARM && current_state != STATE_SOS_EMITTED) {
inactivity_timer++;
}
}
// 默è¤å°†æ´¾å<C2BE>äºä»¶é‡<C3A9>置为空
evt.key_event = KEY_EVENT_NONE;
evt.priority = EVENT_PRIORITY_NORMAL;
evt.extra_data = 0;
evt.extra_size = 0;
// å<>Œé”®ç»„å<E2809E>ˆåˆ¤å®šï¼šâ² é” and â– é”å<E2809D>Œæ—¶æŒ‰ä¸çš„æ¶ˆæŠä¸Žç”Ÿæˆ<C3A6>
if (raw_up && raw_down) {
comb_hold++;
if (comb_hold == 300) { // æŒ<C3A6>续按ä¸è¾ 3 ç§ (300 * 10ms = 3s)
evt.key_event = KEY_EVENT_UP_DOWN_COMB;
EventQueue_Push(evt); // 压入队列
}
key_up_hold = 0; // 清é¶å<C2B6>•个按键计数,防止å<C2A2>Œå‡»äºä»¶å¹²æ‰
key_down_hold = 0;
} else {
comb_hold = 0; // 组å<E2809E>ˆé”æ<E2809D>¾å¼€å½é
// â– (KEY_UP) 按键状æ<C2B6>机
if (raw_up) {
key_up_hold++;
if (key_up_hold == 300) { // 达到 3 秒判定为长按
evt.key_event = KEY_EVENT_UP_LONG;
EventQueue_Push(evt);
}
} else {
// 妿žœæ<C593>¾å¼€æ—¶æŒ‰ä¸è¡æ•°åœ¨æ¶ˆæŠé˜ˆå€¼ï¼ˆ20ms)至长按阈å¼ï¼ˆ3s)ä¹é—´ï¼Œåˆ™åˆ¤å®šä¸ºä¸æ¬¡çŸ­æŒ
if (key_up_hold >= 2 && key_up_hold < 300) {
evt.key_event = KEY_EVENT_UP_CLICK;
EventQueue_Push(evt);
}
key_up_hold = 0; // 释放归零
}
// â– (KEY_DOWN / å¼å…³æœº) 按键状æ<C2B6>机
if (raw_down) {
key_down_hold++;
if (key_down_hold == 100) { // 长按 1 ç§ (100 * 10ms = 1000ms = 1s) 触å<C2A6>关机äºä»¶
evt.key_event = KEY_EVENT_POWER_OFF;
EventQueue_Push(evt);
}
} else {
// 妿žœæ<C593>¾å¼€æ—¶æŒ‰ä¸æ—¶é•¿åœ¨ 20ms è‡ 1s ä¹é—´ï¼Œè§¦å<C2A6>短按ä¸ç¿/选择事件
if (key_down_hold >= 2 && key_down_hold < 100) {
evt.key_event = KEY_EVENT_DOWN_CLICK;
EventQueue_Push(evt);
}
key_down_hold = 0; // 释放归零
}
// â– (KEY_CONFIRM) ç¡è®¤æŒ‰é”状æ<C2B6>机
if (raw_confirm) {
key_confirm_hold++;
if (key_confirm_hold == 300) { // 长按 3 ç§æ‰“å¼ä¸»è<C2BB>œå<C593>
evt.key_event = KEY_EVENT_CONFIRM_LONG;
EventQueue_Push(evt);
}
} else {
if (key_confirm_hold >= 2 && key_confirm_hold < 300) {
evt.key_event = KEY_EVENT_CONFIRM_CLICK;
EventQueue_Push(evt);
}
key_confirm_hold = 0; // 释放归零
}
// SOS ÎïÀíÇó¾È°´¼ü״̬»ú (ÒѽâËø)
if (raw_sos) {
key_sos_hold++;
if (key_sos_hold == 300) { // ³¤°´ 3 Ã룬·¢³öÇó¾È£¬²åÈë¶ÓÊ×
evt.key_event = KEY_EVENT_SOS_LONG;
evt.priority = EVENT_PRIORITY_URGENT;
EventQueue_InsertFront(evt);
Uart_SendString("[KEY-DIAG] SOS Long Press Dispatched!\r\n");
}
} 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);
Uart_SendString("[KEY-DIAG] SOS Click Dispatched!\r\n");
}
key_sos_hold = 0; // ÊͷŹéÁã
}
}
}