From 125eb00aa355f4b8b8e74ce570675f10c805935b Mon Sep 17 00:00:00 2001 From: yuquanjun Date: Wed, 16 Sep 2026 15:10:34 +0800 Subject: [PATCH] fix(power): prevent charge-boot long-press from auto power-off Consume the same power-key hold used for soft-off charge boot before setting powon, and ignore stale POWOFF_CHARG after power-on so mode select stays on screen. Co-authored-by: Cursor --- APP/app_adc.c | 4 +++- Global/Global.c | 26 ++++++++++++++++++-------- Global/Global.h | 1 + UI/UI_Idle.c | 19 ++++++++++++------- 4 files changed, 34 insertions(+), 16 deletions(-) diff --git a/APP/app_adc.c b/APP/app_adc.c index 0b95062..146449a 100644 --- a/APP/app_adc.c +++ b/APP/app_adc.c @@ -263,7 +263,9 @@ static void app_adc_charge_process(void) { /* 通知 UI 熄灭充电页并关主电 */ MainTask_Sendmsg(MSG_ID_POWOFF_CHARG, percentage, 0, 0); - BSP_MainPowerEnable(0); + /* 发消息可能让出 CPU:关电前再确认仍未开机,避免切断开机主电 */ + if (!powon) + BSP_MainPowerEnable(0); } } } diff --git a/Global/Global.c b/Global/Global.c index cb5b7f7..7ff2e5d 100644 --- a/Global/Global.c +++ b/Global/Global.c @@ -211,6 +211,8 @@ void System_PowerOn(void) LOG_I("PWR", "power_on begin"); s_pwr_rails_cut = 0u; s_pwr_off_grace_ms = 0u; + /* 本次长按已用于开机:先消耗,再置 powon,防止 TMR7 ISR 把同一按压力即判为关机 */ + Power_Key_ConsumePress(); /* 控制电源硬件;蓝牙按 NVM/系统设置开关恢复,勿强制常开 */ BSP_MainPowerEnable(1); BSP_DreamCorePowerEnable(1); @@ -317,10 +319,18 @@ void System_PowerOff_Poll(void) * TMR7 1ms(优先级高于伴奏 TMR6):与主循环解耦的关机键扫描。 * 正常:请求优雅关机;超时未切轨 → 紧急断电并复位。 */ +static uint16_t s_isr_hold_ms = 0; +static uint8_t s_isr_fired = 0; + +/* 开机时消耗本次按键:同一次长按已用于开机,须松开后重新长按 2s 才关机。 + * 须在 powon 置 true 前调用,避免 ISR 在开机瞬间把本次长按误判为关机。 */ +void Power_Key_ConsumePress(void) +{ + s_isr_fired = 1; +} + void Power_Key_IsrTick(void) { - static uint16_t isr_hold_ms = 0; - static uint8_t isr_fired = 0; flag_status st; /* RTT/USB 烧 ExtFlash 期间禁止软关机,避免长按/粘键打断 FLASH_ACK */ @@ -331,19 +341,19 @@ void Power_Key_IsrTick(void) if (st == KEY_PRESS_LEVEL) { - if (isr_hold_ms < 60000u) - isr_hold_ms++; + if (s_isr_hold_ms < 60000u) + s_isr_hold_ms++; } else { - isr_hold_ms = 0; - isr_fired = 0; + s_isr_hold_ms = 0; + s_isr_fired = 0; } /* 仅处理「开机态关机」;开机仍由主循环负责(需完整外设初始化) */ - if (powon && !isr_fired && isr_hold_ms >= PWR_OFF_HOLD_MS) + if (powon && !s_isr_fired && s_isr_hold_ms >= PWR_OFF_HOLD_MS) { - isr_fired = 1; + s_isr_fired = 1; System_RequestPowerOff(); } diff --git a/Global/Global.h b/Global/Global.h index ebdf71f..bf44600 100644 --- a/Global/Global.h +++ b/Global/Global.h @@ -169,6 +169,7 @@ void Power_Key_Scan(void); void Power_Key_IsrTick(void); void Power_Key_FaultLoop(void); void Power_Key_WatchdogInit(void); +void Power_Key_ConsumePress(void); void PowerOff_CutRails(void); void AutoPowerOff_Scan(void); void System_PowerOn(void); diff --git a/UI/UI_Idle.c b/UI/UI_Idle.c index d5ce4e2..6c55895 100644 --- a/UI/UI_Idle.c +++ b/UI/UI_Idle.c @@ -141,22 +141,25 @@ void Touch_Mode_Select_Action(int8_t FLAG, uint8_t ID, uint8_t areaIndex) } extern uint8_t bat_init_done; +/* 关机充电页已绘制标志:POWER_ON 需清除,以便再次软关机充电时重绘 */ +static bool s_charge_ui_drawn = false; void IdleProcess(DisplayTaskMessage_Type msg) { - uint8_t vol; switch (msg.MessageType) { - case MSG_ID_POWER_ON : + case MSG_ID_POWER_ON : + /* 充电软关机开机:滞后的拔电消息可能已切主电/关显示,强制恢复 */ + BSP_MainPowerEnable(1); + LCD_WR_REG(0x29); /* Display ON */ + s_charge_ui_drawn = false; LCD_BLK_Set(); LCD_WR_PIC_FROM_FLASH(0, 0, UI0902_BOOT_LOGO_W, UI0902_BOOT_LOGO_H, UI0902_BOOT_LOGO_ADDR); - BSP_SelectAdcChannel(6); /* 让出 CPU,避免忙等卡住触摸/主循环线程 */ rt_thread_mdelay(1000); LoadConfig(); - vol = ADC_ReadChannel(ADC_CHANNEL_1)>>5; - app_adc_sync_volume(vol); - Send_volume(vol); + /* 主音量不在此现场切通道读 ADC(会与扫描任务串通道): + * 待 StartScanTask 后由 MasterVolume_Reapply 统一补发 */ UI_DrawModeSelectScreen(); TM1629D_AllLedOn(LED_COLOR_G); @@ -227,7 +230,9 @@ void IdleProcess(DisplayTaskMessage_Type msg) case MSG_ID_POWOFF_CHARG: { - static bool s_charge_ui_drawn = false; + /* 已开机:忽略滞后的关机充电消息,勿覆盖模式选择页或切断主电 */ + if (powon) + break; if(!s_charge_ui_drawn) { uint8_t peek[4];