docs: optimize SOS button behavior, add 2-step pairing wizard, and IPC exit action

This commit is contained in:
2026-07-09 17:42:55 +08:00
parent 1168e747e6
commit 32c07c0466
16 changed files with 821 additions and 478 deletions

View File

@@ -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 -->

View File

@@ -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 轴偏移量 +52Y 轴偏移量 +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 -->

View File

@@ -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 -->

View File

@@ -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 -->

View File

@@ -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 -->