1、低电 3.7V 只闪红灯不再 1 分钟后关机;电量低于约 5% 自动关机,未充电开机先闪 5 下红灯再睡回,只能充电后才能开机

2、自动/手动互相切换都闪 2 下灯;APP 发停止后再发自动模式可正常启动,手动残留停止不再挡住自动
3、自动模式 1~6 单次最长跑 10 分钟后回待机;关机时长按 12 秒进 OTA,OTA 期间红绿交替闪
This commit is contained in:
2026-08-27 10:20:48 +08:00
parent 3d445ae5c5
commit fdb43011b7
28 changed files with 945 additions and 165 deletions
+74 -10
View File
@@ -2,10 +2,11 @@
* @file app_boot.c
* @brief 深睡唤醒 / 上电按键判定实现
* @author cyWu <1917507415@qq.com>
* @date 2026.08.25
* @version V1.0.0
* @date 2026.08.26
* @version V1.1.0
* @history
* - V1.0.0, 2026.08.25, cyWu, 从 usr_jb_main 拆出
* - V1.0.0, 2026.08.25, cyWu, 首次发布,实现深睡唤醒按键判定(3s 开机 / 5s 配对)
* - V1.1.0, 2026.08.26, cyWu, 新增 12s 长按进 OTA、开机前低电量拦截
******************************************************************************/
#include "app_boot.h"
@@ -60,6 +61,42 @@ static void boot_sleep(void)
}
}
/**
* @brief 拒绝开机前的低电提示:红灯闪烁 BOARD_BOOT_LOWBAT_BLINK_N 下
* @return 无
*/
static void boot_blink_low_battery(void)
{
uint8_t i;
for (i = 0; i < BOARD_BOOT_LOWBAT_BLINK_N; i++) {
bsp_led_red_set(1);
boot_delay_ms(BOARD_BOOT_LOWBAT_ON_MS);
bsp_led_red_set(0);
boot_delay_ms(BOARD_BOOT_LOWBAT_OFF_MS);
}
}
/**
* @brief 开机前电量判定:连续采样取均值,避免单次毛刺误判
* @note 此时 app_battery/app_power 均未初始化,只能摸裸电压,不走那套
* 滤波/缓冲算法;和运行中的自动关机(app_power)共用同一门限
* BOARD_VBAT_SHUTDOWN_MV(约 5%),口径一致
* @return 1=电量过低(约 <=5%),0=正常
*/
static uint8_t boot_battery_too_low(void)
{
uint32_t acc = 0;
uint8_t i;
const uint8_t n = 4;
for (i = 0; i < n; i++) {
acc += bsp_vbat_mv();
boot_delay_ms(5);
}
return (uint8_t)((acc / n) <= BOARD_VBAT_SHUTDOWN_MV);
}
/**
* @brief 上电是否跳过 3s/5s 按键判定
* @note 只有“真的断电后重新插电池 / 用户主动按键”才需要走 3s/5s 判定;
@@ -96,6 +133,9 @@ static uint8_t boot_skip_key_wait(void)
/**
* @brief 等待并判定开机按键
* @note 配对(5s)不再一到点就立即提交:需要继续按住观察是否会按到 12s
* 触发 OTA,真正的配对提交放在松手那一刻做,行为上仍是“按满 5s
* 再松手即进配对”,只是多给了继续按到 12s 改道 OTA 的机会。
* @return 无(深睡分支不返回)
*/
void app_boot_wait_key(void)
@@ -103,9 +143,11 @@ void app_boot_wait_key(void)
uint32_t t0;
uint32_t elapsed;
uint8_t green_on = 0;
uint8_t pair_armed = 0;
usr_var.usr_goto_pair = 0;
/* USB 在位直接开机,不走 3s/5s/12s 按键判定 */
if (boot_skip_key_wait()) {
return;
}
@@ -115,22 +157,36 @@ void app_boot_wait_key(void)
boot_sleep();
}
/* 未充电时电量过低:闪灯提示后继续深睡,不给开机 */
if (boot_battery_too_low()) {
log_info("boot battery <=5%%, blink %d and stay off\n", BOARD_BOOT_LOWBAT_BLINK_N);
boot_blink_low_battery();
boot_sleep();
}
t0 = timer_get_ms();
bsp_led_all_off();
log_info("boot key hold, wait 3s on / 5s pair\n");
log_info("boot key hold, wait 3s on / 5s pair / 12s ota\n");
while (bsp_key_is_pressed()) {
elapsed = timer_get_ms() - t0;
clr_wdt();
if (elapsed >= BOARD_KEY_PAIR_MS) {
usr_var.usr_goto_pair = 1;
usr_clear_pair_info_noreset();
app_pair_start();
log_info("boot hold %ums, power on + pair\n", (unsigned)elapsed);
/* 12s 优先于配对:按满 12s 直接进 OTA,不再等松手 */
if (elapsed >= BOARD_KEY_OTA_MS) {
log_info("boot hold %ums, power on + ota\n", (unsigned)elapsed);
usr_app_ota_init();
return;
}
/* 5s 只武装配对,真正提交放到松手那一刻,给继续按到 12s 改道 OTA 的机会 */
if (!pair_armed && (elapsed >= BOARD_KEY_PAIR_MS)) {
pair_armed = 1;
log_info("boot hold %ums, pair armed (release now for pair, "
"keep holding to %ums for ota)\n",
(unsigned)elapsed, (unsigned)BOARD_KEY_OTA_MS);
}
if (!green_on && (elapsed >= BOARD_KEY_POWER_MS)) {
green_on = 1;
bsp_led_green_set(1);
@@ -144,5 +200,13 @@ void app_boot_wait_key(void)
boot_sleep();
}
log_info("boot hold %ums, power on\n", (unsigned)elapsed);
/* 松手时已过 5s(且没按到 12s):提交配对;否则只是正常开机 */
if (pair_armed) {
usr_var.usr_goto_pair = 1;
usr_clear_pair_info_noreset();
app_pair_start();
log_info("boot hold %ums, power on + pair\n", (unsigned)elapsed);
} else {
log_info("boot hold %ums, power on\n", (unsigned)elapsed);
}
}