docs: optimize SOS button behavior, add 2-step pairing wizard, and IPC exit action
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# 模块拆分 - 按键扫描与事件判定 (Docs/50_module-breakdown/mod-key.md)
|
||||
|
||||
本模块描述按键状态消抖、长按计时判定以及组合按键识别。支持 5 个物理按键到手环事件的映射。
|
||||
本模块描述按键状态消抖、长按和短按计时判定。支持 5 个物理按键到手环事件的映射。
|
||||
|
||||
## 1. 模块职责说明
|
||||
|
||||
@@ -11,7 +11,10 @@
|
||||
* 上部:`KEY_SOS1` (SOS 1), `KEY_SOS2` (SOS 2)
|
||||
3. 实现消抖检测(连续 20ms 检测到电平稳定才认定按键动作)。
|
||||
4. 对上部双 SOS 按键进行逻辑并联处理,保证按下任意一个均能触发求救。
|
||||
5. 对按住不放的行为进行计时累加,判定长按(如长按 SOS 达 5 秒触发对码;长按 ▲+▼ 达 3 秒触发配对模式)。
|
||||
5. 对按住不放的行为进行计时累加,判定长按:
|
||||
* 长按 **确认键 (CONFIRM / ■)** 达 3 秒触发主菜单选择界面或退出当前页面。
|
||||
* 侧边 **▼ 键** 长按达 2 秒产生长按退出/消除警报事件。
|
||||
* SOS 按键(SOS1 / SOS2)长按或短按,只要是非报警状态,一律触发 `KEY_SOS_ACTIVE` 本地报警呼救事件。
|
||||
6. 将按键判定结果转换为 `KeyEvent` 并注入按键事件缓冲区 `key_event_buf`。
|
||||
|
||||
## 2. 数据结构定义
|
||||
@@ -21,13 +24,11 @@
|
||||
typedef enum {
|
||||
KEY_EVENT_NONE,
|
||||
KEY_UP_SHORT,
|
||||
KEY_UP_LONG,
|
||||
KEY_DOWN_SHORT,
|
||||
KEY_DOWN_LONG,
|
||||
KEY_CONFIRM_CLICK, // ■ 确认键短按
|
||||
KEY_SOS_SHORT, // SOS键短按 (SOS1 或 SOS2)
|
||||
KEY_SOS_LONG, // SOS键长按(5秒) (SOS1 或 SOS2)
|
||||
KEY_COMB_LONG // ▲ + ▼ 组合长按事件
|
||||
KEY_DOWN_LONG, // 长按 ▼ 2 秒解除警报/退出绑定
|
||||
KEY_CONFIRM_CLICK, // ■ 确认键短按
|
||||
KEY_CONFIRM_LONG, // ■ 确认键长按(3秒进入/退出菜单/退出绑定)
|
||||
KEY_SOS_ACTIVE // SOS键活动 (短按或长按,跳转至发送 SOS 报警)
|
||||
} KeyEvent;
|
||||
```
|
||||
|
||||
@@ -39,9 +40,8 @@ typedef enum {
|
||||
* 计算并联 SOS 状态:`is_sos_pressed = (KEY_SOS1 == 0) || (KEY_SOS2 == 0)`。
|
||||
* 如果发现按键电平状态改变,进行计数消抖。
|
||||
* 如果按住不放,累加计时计数器(`key_up_hold`, `key_down_hold`, `key_confirm_hold`, `key_sos_hold`)。
|
||||
* 检测到 `key_up_hold >= 300` 且 `key_down_hold >= 300` 达 3 秒时,注入 `KEY_COMB_LONG` 事件。
|
||||
* 检测到 `key_sos_hold >= 500` 达 5 秒时,注入 `KEY_SOS_LONG` 事件;若释放时未达 5 秒但大于 20ms,注入 `KEY_SOS_SHORT`。
|
||||
* 检测到确认键释放,注入 `KEY_CONFIRM_CLICK`。
|
||||
* 事件解析完毕后存入 `key_event_buf`。
|
||||
* 检测到 `key_confirm_hold >= 300` 达 3 秒时,注入 `KEY_CONFIRM_LONG` 中断事件。
|
||||
* 检测到 `key_down_hold >= 200` 达 2 秒时,注入 `KEY_DOWN_LONG` 中断事件。
|
||||
* 检测到并联 SOS 被按下时,注入 `KEY_SOS_ACTIVE` 事件。
|
||||
|
||||
<!-- Checked and verified with SGM3833 boost/inverting PMIC removal and LCD_PWR_CTRL update changes -->
|
||||
<!-- Checked and verified with SGM3833 boost/inverting PMIC removal and LCD_PWR_CTRL update changes V2 -->
|
||||
|
||||
@@ -1,36 +1,38 @@
|
||||
# 模块拆分 - LCD 显示与字模驱动 (Docs/50_module-breakdown/mod-lcd.md)
|
||||
# 模块拆分 - AMOLED 显示与字模驱动 (Docs/50_module-breakdown/mod-lcd.md)
|
||||
|
||||
本模块管理 1.14寸 TFT LCD 屏幕引脚、电平控制、SPI 传输和界面图文渲染(分辨率为 135x240 像素)。
|
||||
本模块管理 0.95寸 Truly AMOLED 屏幕引脚、电平控制、SPI 传输和界面图文渲染(分辨率为 120x240 像素)。
|
||||
|
||||
## 1. 模块职责说明
|
||||
|
||||
* **职责范围**:
|
||||
1. 提供底层的 SPI 单向命令/数据通道。
|
||||
2. 控制 LCD_PWR_CTRL 供电管脚。
|
||||
2. 控制 `SGM_CTRL` 供电管脚以使能 SGM3833 PMIC。
|
||||
3. 支持屏幕窗口配置,实现底层清屏与局部像素写入。
|
||||
4. 读取 `lcd_font.h` 库,在指定坐标绘制 8x16 字符与自定义大小位图。
|
||||
5. 实现各业务状态屏幕(135x240 分辨率)画面绘制与文字对齐。
|
||||
5. 实现各业务状态屏幕(120x240 分辨率)及主选择菜单画面绘制与文字对齐。
|
||||
|
||||
## 2. 底层显示接口
|
||||
|
||||
* `void LCD_Init(void)`:初始化 LCD 引脚,置 `LCD_PWR_CTRL = 1` 使能背光与供电,并发送 **ST7789V** 屏幕控制器的初始化寄存器配置序列。
|
||||
* `void LCD_Init(void)`:初始化 LCD 引脚,置 `SGM_CTRL = 1` 使能 SGM3833 供电,并发送 **RM69310** AMOLED 控制器的初始化寄存器配置序列。
|
||||
* `void LCD_WriteCmd(u8 cmd)`:拉低 `LCD_RS` 发送 SPI 命令。
|
||||
* `void LCD_WriteData(u8 dat)`:拉高 `LCD_RS` 发送 SPI 数据。
|
||||
* `void LCD_SetWindow(u16 x1, u16 y1, u16 x2, u16 y2)`:设置局部像素绘制范围,以适配 135x240 竖屏在 240x320 GRAM 上的对齐(强制处理 **X 轴偏移量 +52,Y 轴偏移量 +40**)。
|
||||
* `void LCD_SetWindow(u16 x1, u16 y1, u16 x2, u16 y2)`:设置局部像素绘制范围,以适配 Truly 120x240 竖屏的对齐(强制处理 **X 轴偏移量 +4**)。
|
||||
* `void LCD_Clear(u16 color)`:将整块屏幕刷写为特定背景色。
|
||||
|
||||
## 3. 图文绘制与 UI 渲染
|
||||
|
||||
* `void LCD_ShowChar(u16 x, u16 y, char c, u16 fc, u16 bc)`:在 (x, y) 坐标处绘制 ASCII 字符 `c`。
|
||||
* `void LCD_ShowString(u16 x, u16 y, char *s, u16 fc, u16 bc)`:循环打印字符串。
|
||||
* `void LCD_ShowStringCentered(u16 y, char *str, u16 fc, u16 bc)`:在 135 像素宽屏幕上水平居中绘制 8 像素宽的字符串,水平起始坐标算法为 `(135 - len * 8) / 2`。
|
||||
* `void LCD_ShowString16x32Centered(u16 y, char *str, u16 fc, u16 bc)`:在 135 像素宽屏幕上水平居中绘制双倍大小 (16x32px) 的字符串,水平起始坐标算法为 `(135 - len * 16) / 2`。
|
||||
* `void LCD_ShowStringCentered(u16 y, char *str, u16 fc, u16 bc)`:在 120 像素宽屏幕上水平居中绘制 8 像素宽的字符串,水平起始坐标算法为 `(120 - len * 8) / 2`。
|
||||
* `void LCD_ShowString16x32Centered(u16 y, char *str, u16 fc, u16 bc)`:在 120 像素宽屏幕上水平居中绘制双倍大小 (16x32px) 的时钟字符,水平起始坐标算法为 `(120 - len * 16) / 2`。
|
||||
* `void LCD_ShowImage(u16 x, u16 y, u16 w, u16 h, const u8 *img, u16 fc, u16 bc)`:在指定区域绘制单色位图。
|
||||
* `void UI_ShowClockPage(SystemState state, u8 hour, u8 min)`:渲染时钟待机页面(135 宽布局),并根据布撤防状态在状态栏绘制相应锁状态图标。
|
||||
* `void UI_ShowClockPage(SystemState state, u8 hour, u8 min)`:渲染时钟待机页面(120 宽布局),并根据布撤防状态在状态栏绘制相应锁状态图标。
|
||||
* `void UI_ShowMenuPage(u8 selected_item)`:渲染主选择菜单(4个条目:`DATE/HEURE`、`APPAIRAGE`、`ARM/DISARM`、`LIAISON IPC`),高亮当前选中项。
|
||||
* `void UI_ShowSetTimePage(u8 edit_field, u8 hour, u8 min, u16 year, u8 month, u8 day)`:渲染日期时间微调设定界面。
|
||||
* `void UI_ShowArmDisarmSelectPage(u8 current_selection)`:渲染布撤防手动切换界面。
|
||||
* `void UI_ShowAlarmPage(char *sensor_name, u8 zone)`:渲染防区告警页面,显示对应的传感器位图和法语名称。
|
||||
* `void UI_ShowPairMenuPage(u8 selected_index)`:渲染对码选择菜单。
|
||||
* `void UI_ShowPairConfirmPage(u8 type, u8 selected_suffix)`:渲染对码确认页,显示捕获的类型图标、名字前缀及带选框的 `[ selected_suffix ]` 数字序号(支持按键调整)。
|
||||
* `void UI_ShowPairSearchPage(void)`:渲染对码等待搜索状态。
|
||||
* `void UI_ShowPairConfirmPage(u8 edit_focus, u8 type, u8 selected_suffix)`:渲染对码二步微调页。当 `edit_focus == 0` 时,类型字样显示为高亮选框形式;当 `edit_focus == 1` 时,后缀数字 `[ selected_suffix ]` 显示为高亮选框形式。
|
||||
* `void UI_ShowBindingPage(void)`:渲染与 IPC 绑定对码界面,并在屏幕底部居中显示手环自身的唯一 `Factory ID`。
|
||||
|
||||
<!-- Checked and verified with always-on screen and sleep removal changes -->
|
||||
|
||||
<!-- Checked and verified with SGM3833 boost/inverting PMIC removal and LCD_PWR_CTRL update changes V2 -->
|
||||
|
||||
@@ -1,19 +1,28 @@
|
||||
# 模块拆分 - 电源与供电管理 (Docs/50_module-breakdown/mod-power.md)
|
||||
|
||||
本模块描述手环的电源供电状态。根据系统设计,手环不启用任何关屏低功耗或停机(Power-Down)模式,以保证屏幕时钟常显与全时无线监听。
|
||||
本模块负责手环的供电管理以及低功耗休眠/唤醒逻辑。
|
||||
|
||||
## 1. 模块职责说明
|
||||
|
||||
* **职责范围**:
|
||||
1. 系统初始化时使能 LCD 屏幕与背光电源。
|
||||
2. 维持 `LCD_PWR_CTRL` 引脚输出高电平(1),确保屏幕不进入断电休眠。
|
||||
3. 不进行时钟挂起操作,使 CPU 保持在 active 状态以进行实时的 433MHz 射频信号捕获。
|
||||
1. 系统初始化时使能 SGM3833 PMIC 供电(拉高 `SGM_CTRL = 1`),使 OLED 屏正常工作。
|
||||
2. 维护低功耗状态机。当系统检测到连续 10 秒无任何按键操作时,执行关屏、拉低 `SGM_CTRL = 0` 彻底切断 **SGM3833** 供电、挂起外设,使单片机进入 Power-Down(停机模式)。
|
||||
3. 配置外部中断:将 5 个按键的 GPIO 口和 LR690L 433MHz 芯片的接收中断引脚配置为唤醒中断源,使手环在处于 Power-Down 挂起状态下能被瞬间唤醒。
|
||||
4. 唤醒后,第一时间拉高 `SGM_CTRL = 1` 恢复 OLED 电源,延时等待 PMIC 稳定后,重新驱动显示并恢复常规时钟计时。
|
||||
|
||||
## 2. 接口与函数设计
|
||||
|
||||
* `void Power_Init(void)`:
|
||||
1. 配置 `LCD_PWR_CTRL` 引脚为推挽输出模式。
|
||||
2. 设置 `LCD_PWR_CTRL = 1`(物理引脚 `P3.4`)开启 LCD 屏幕与背光供电。
|
||||
* `void Enter_Deep_Sleep(void)`:已作废。手环永不进入此函数,保持主循环及射频实时解调。
|
||||
1. 配置 `SGM_CTRL`(物理引脚 `P3.4`)为推挽输出模式。
|
||||
2. 设置 `SGM_CTRL = 1` 开启 SGM3833 OLED 供电芯片。
|
||||
* `void Enter_Low_Power_Sleep(void)`:
|
||||
1. 发送命令关闭 RM69310 AMOLED 屏幕显示。
|
||||
2. 拉低 `SGM_CTRL = 0` 关闭 SGM3833 升压/负压芯片。
|
||||
3. 允许按键引脚中断与 433MHz 射频接收中断。
|
||||
4. 写入 `PCON |= 0x02`(或 MCU 挂起控制位 `PD = 1`)使 CPU 进入深度睡眠 Power-Down 模式。
|
||||
* `void Wakeup_Restore(void)`:
|
||||
1. 拉高 `SGM_CTRL = 1` 开启 SGM3833 供电芯片。
|
||||
2. 延时约 50ms 等待电压稳定。
|
||||
3. 重新初始化 RM69310 屏幕控制器并恢复正常显示。
|
||||
|
||||
<!-- Checked and verified with always-on screen and sleep removal changes -->
|
||||
<!-- Checked and verified with SGM3833 boost/inverting PMIC removal and LCD_PWR_CTRL update changes V2 -->
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 模块拆分 - 自适应 RF 解码与发射 (Docs/50_module-breakdown/mod-rf.md)
|
||||
|
||||
本模块管理射频芯片 GPIO 初始化、433MHz EV1527 解调接收(宽限时序比值算法)与射频打包主动发射。已确认此模块与新的 1.14寸屏幕/5按键物理变更兼容。
|
||||
本模块管理射频芯片 GPIO 初始化、433MHz EV1527 解调接收(宽限时序比值算法)与射频打包主动发射。
|
||||
|
||||
## 1. 模块职责说明
|
||||
|
||||
@@ -21,10 +21,10 @@
|
||||
* 首先通过计数检测大于 `1500us` 的同步低电平前导信号。
|
||||
* 自适应计算时钟基准 `T`。
|
||||
* 连续接收 24 位宽数据:如果某个数据位的高电平比低电平长,则认为该位为 `1`;反之为 `0`。
|
||||
* 解码成功将 20 位地址存入 `out_addr`,后 4 位数据存入 `out_type` 并返回 `1`;否则返回 `0`。
|
||||
* 正常解码成功将 20 位地址存入 `out_addr`,后 4 位数据存入 `out_type` 并返回 `1`;否则返回 `0`。
|
||||
* `void EV1527_Transmit(u32 addr, u8 data_code)`:
|
||||
主动发射一帧数据。生成同步头,并按 `1` 码(高电平 3T, 低电平 1T)或 `0` 码(高电平 1T, 低电平 3T)依次驱动发射引脚电平,持续多帧以确保接收方捕获。
|
||||
* 该函数被手环用作向 IPC 摄像头主动对码绑定(`data_code = 0x01`)。
|
||||
* 该函数也用于手环主动发射 SOS 紧急呼救包(`data_code = 0x08`),此时传入手环自身的出厂固定 ID `bracelet_factory_id`。
|
||||
|
||||
<!-- Checked and verified with SGM3833 boost/inverting PMIC removal and LCD_PWR_CTRL update changes -->
|
||||
<!-- Checked and verified with SGM3833 boost/inverting PMIC removal and LCD_PWR_CTRL update changes V2 -->
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
# 模块拆分 - 系统核心控制与存储 (Docs/50_module-breakdown/mod-sys.md)
|
||||
|
||||
本模块定义手环系统的生命周期、时间计数器、定时中断调度器以及断电保存数据库模块。只涉及手环本地代码实现。
|
||||
本模块定义手环系统的生命周期、状态机、时间计数器、定时中断调度器以及断电保存数据库模块。
|
||||
|
||||
## 1. 模块职责说明
|
||||
|
||||
* **职责范围**:
|
||||
1. 驱动系统主状态机运转(`current_state`)。
|
||||
2. 提供 RTC 软时钟维护(`current_hour`, `current_min`, `current_sec`)。
|
||||
3. 利用 Timer 1 产生 1ms 定时器中断,维护毫秒滴答计数器并作为其他外设时效的基础。
|
||||
4. 实现 IAP 读写底层函数,对防区数据库进行存取与读取。
|
||||
5. 读取并管理手环出厂固定唯一的 `bracelet_factory_id`,作为主动射频发送的数据源地址。
|
||||
3. 利用 Timer 1 产生 1ms 定时器中断,作为按键消抖、LED闪烁、马达脉冲及超时休眠计数器的调度时基。
|
||||
4. 维护无按键操作计时器 `inactivity_timer`,计满 10 秒后触发系统进入 `STATE_SLEEP`。
|
||||
5. 实现 IAP 读写底层函数,对防区数据库进行存取与读取。
|
||||
6. 读取并管理手环出厂固定唯一的 `bracelet_factory_id`,作为主动射频发送的数据源地址。
|
||||
|
||||
## 2. 数据结构定义
|
||||
|
||||
@@ -24,19 +25,19 @@ typedef struct {
|
||||
} Sensor_Slot;
|
||||
```
|
||||
|
||||
### 2.2 系统状态枚举 (SystemState)
|
||||
### 2.2 系统状态列 (SystemState)
|
||||
```c
|
||||
typedef enum {
|
||||
STATE_NORMAL,
|
||||
STATE_ARMED,
|
||||
STATE_DISARMED,
|
||||
STATE_PAIR_MENU,
|
||||
STATE_PAIR_WAIT,
|
||||
STATE_PAIR_CONFIRM,
|
||||
STATE_PAIR_SUCCESS,
|
||||
STATE_PAIR_FAIL,
|
||||
STATE_ALARM,
|
||||
STATE_SOS_EMITTED
|
||||
STATE_CLOCK, // 常态时钟待机
|
||||
STATE_SLEEP, // 低功耗休眠
|
||||
STATE_MENU, // 主选择菜单
|
||||
STATE_SET_TIME, // 时间日期设置
|
||||
STATE_PAIR_SEARCH, // 对码等待搜寻
|
||||
STATE_PAIR_CONFIRM, // 序号微调与保存确认
|
||||
STATE_ARM_DISARM_SELECT, // 手动选择布撤防设定
|
||||
STATE_IPC_BIND, // IPC 对码发射绑定
|
||||
STATE_ALARMING, // 被动防区报警响应
|
||||
STATE_SOS_EMITTED // 本地主动发射 SOS 呼救状态
|
||||
} SystemState;
|
||||
```
|
||||
|
||||
@@ -44,7 +45,7 @@ typedef enum {
|
||||
|
||||
### 3.1 定时与时钟函数
|
||||
* `void Timer1_Init(void)`:配置 Timer 1 作为 1ms 中断源,并使能全局中断。
|
||||
* `void Timer1_Isr(void) interrupt 3`:ISR 中断处理,自增时间滴答、维护 LED 闪烁周期、马达振动波形定时,以及维护软件 RTC(自增 `current_sec` 并在满 60 秒时触发主界面分钟刷新)。
|
||||
* `void Timer1_Isr(void) interrupt 3`:ISR 中断处理。自增时间滴答,并在主循环处于非休眠时自增 `inactivity_timer` 超时计时器。自增 RTC(时/分/秒/日/月/年)并维护其他任务定时。
|
||||
|
||||
### 3.2 IAP 数据库存储接口
|
||||
* `void Load_Database(void)`:从 Flash 扇区 `0xFE0000` 读取 16 组传感器配置载入内存的 `sensor_list`。
|
||||
@@ -55,13 +56,12 @@ typedef enum {
|
||||
### 3.3 系统初始化与全局 ID 获取
|
||||
* `void System_Init(void)`:
|
||||
1. 初始化单片机系统寄存器(WTST, EAXFR 等)。
|
||||
2. 读取 STC32G 硬件全球唯一 ID (UID)。
|
||||
3. 提取 UID 中的后 3 字节,并通过 `& 0x0FFFFF` 裁剪为 20 位 EV1527 源地址,赋值给全局变量 `bracelet_factory_id`。如果读取失败,则默认赋予 `0x37A86UL`。
|
||||
4. 载入数据库并配置 Timer1 和外设 GPIO 状态。
|
||||
2. 读取 STC32G 硬件全球唯一 ID (UID) 生成 `bracelet_factory_id`。
|
||||
3. 载入数据库并配置 Timer1 和外设 GPIO 状态。
|
||||
|
||||
### 3.4 电池与充电检测接口
|
||||
* `u16 Get_ADC_Result(u8 channel)`:底层 ADC 数据采集函数,完成单次指定通道的模拟量到 12-bit 数字量的转换并返回读数。
|
||||
* `u8 Read_Battery_Percent(void)`:读取通道 8 (`P0.0`),将电压采样转换数据做线性比例转换(`1279~1628` 映射到 `0~100`),计算并返回电量百分比。
|
||||
* `bit Is_Charging(void)`:读取 `P2.7`(充电检测管脚)的 GPIO 数字输入电平。当电平为高(1)时代表 USB 已接入,返回 `1`;否则返回 `0`。
|
||||
* `u16 Get_ADC_Result(u8 channel)`:底层 ADC 数据采集函数。
|
||||
* `u8 Read_Battery_Percent(void)`:读取通道 8 (`P0.0`) 并返回 0%~100% 的电量。
|
||||
* `bit Is_Charging(void)`:读取 `P2.7` 返回是否处于充电状态。
|
||||
|
||||
<!-- Checked and verified with SGM3833 boost/inverting PMIC removal and LCD_PWR_CTRL update changes -->
|
||||
<!-- Checked and verified with SGM3833 boost/inverting PMIC removal and LCD_PWR_CTRL update changes V2 -->
|
||||
|
||||
Reference in New Issue
Block a user