Files
JBao_Door_Clamp_FW/apps/usr_app/app_boot.c
T
2026-08-25 14:59:39 +08:00

149 lines
4.8 KiB
C

/******************************************************************************
* @file app_boot.c
* @brief 深睡唤醒 / 上电按键判定实现
* @author cyWu <1917507415@qq.com>
* @date 2026.08.25
* @version V1.0.0
* @history
* - V1.0.0, 2026.08.25, cyWu, 从 usr_jb_main 拆出
******************************************************************************/
#include "app_boot.h"
#include "app_pair.h"
#include "bsp_hw.h"
#include "board_pin.h"
#include "app_main.h"
#include "usr_le_api.h"
#include "asm/power/power_api.h"
#include "asm/power/power_reset.h"
#define LOG_TAG_CONST APP
#define LOG_TAG "[APP_BOOT]"
#define LOG_INFO_ENABLE
#include "debug.h"
extern void clr_wdt(void);
extern u32 timer_get_ms(void);
/**
* @brief 忙等若干毫秒,并喂狗
* @param ms 等待时长
* @return 无
*/
static void boot_delay_ms(uint32_t ms)
{
uint32_t t0 = timer_get_ms();
while ((timer_get_ms() - t0) < ms) {
clr_wdt();
}
}
/**
* @brief BLE 起来前进深睡(1ms 定时器尚未启动),原地喂狗不返回
* @note power_set_soft_poweroff() 只是向 SDK 底层发起软关机请求(置个标志位),
* 不是同步断电——仓库里其它调用点(如 app_power_manage.c)调用完都是
* 正常往下走/return,真正切电源是底层电源管理在之后某个时机才执行的。
* 此时 BLE 栈、1ms 业务定时器都还没起来,如果这里直接 return,代码会
* 接着把 usr_jb_init 剩下的初始化和开机流程跑完,等于白判定了。所以
* 必须用 while(1) 卡住不返回:一边喂狗防止看门狗把这个等待打断,
* 一边等底层真正把电断掉(或者外部条件变化触发复位)。
* @return 无(不会返回)
*/
static void boot_sleep(void)
{
log_info("boot sleep\n");
bsp_hw_enter_sleep_io();
power_set_soft_poweroff();
while (1) {
clr_wdt();
}
}
/**
* @brief 上电是否跳过 3s/5s 按键判定
* @note 只有“真的断电后重新插电池 / 用户主动按键”才需要走 3s/5s 判定;
* USB 在位、或者芯片自己意外重启的情况,都应该直接保持开机,
* 否则用户会遇到“设备莫名关机、还要求重新按 3 秒才能开机”的怪现象。
* @return 1=USB / 软复位 / LVD / 看门狗,保持开机且不进配对;0=需要走按键判定
*/
static uint8_t boot_skip_key_wait(void)
{
uint8_t i;
/* USB 在位(充电口有电):说明是插着电源,不是用户凭空按键开机 */
for (i = 0; i < 10; i++) {
if (bsp_chg_is_low() || bsp_vpwr_is_online()) {
log_info("boot usb, skip key wait\n");
return 1;
}
boot_delay_ms(5);
}
/* 以下都是“芯片自己意外重启了一下”,不是用户主动按开机键,
* 不能因此逼用户重新按键,否则相当于设备无故“关机”了一次 */
if (cpu_reset_by_soft() /* SDK 综合判断:是否软件复位 */
|| is_reset_source(MSYS_SOFT_RST) /* 主系统软件复位(断言/异常/OTA 后重启等) */
|| is_reset_source(P33_SOFT_RST) /* P33 软件复位,最常见的软复位入口 */
|| is_reset_source(P33_VDDIO_LVD_RST) /* VDDIO 低压复位(电机启动拉低电压误触发) */
|| is_reset_source(P11_WDT_RST)) { /* 看门狗复位(程序卡死被强制重启) */
log_info("boot reset-keep, skip key wait\n");
return 1;
}
return 0;
}
/**
* @brief 等待并判定开机按键
* @return 无(深睡分支不返回)
*/
void app_boot_wait_key(void)
{
uint32_t t0;
uint32_t elapsed;
uint8_t green_on = 0;
usr_var.usr_goto_pair = 0;
if (boot_skip_key_wait()) {
return;
}
if (!bsp_key_is_pressed()) {
log_info("boot no key, sleep\n");
boot_sleep();
}
t0 = timer_get_ms();
bsp_led_all_off();
log_info("boot key hold, wait 3s on / 5s pair\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);
return;
}
if (!green_on && (elapsed >= BOARD_KEY_POWER_MS)) {
green_on = 1;
bsp_led_green_set(1);
log_info("boot hold 3s, will power on\n");
}
}
elapsed = timer_get_ms() - t0;
if (elapsed < BOARD_KEY_POWER_MS) {
log_info("boot hold %ums < 3s, sleep\n", (unsigned)elapsed);
boot_sleep();
}
log_info("boot hold %ums, power on\n", (unsigned)elapsed);
}