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 <cursoragent@cursor.com>
This commit is contained in:
yuquanjun 2026-09-16 15:10:34 +08:00
parent 65b0a84c4a
commit 125eb00aa3
4 changed files with 34 additions and 16 deletions

View File

@ -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);
}
}
}

View File

@ -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();
}

View File

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

View File

@ -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 :
/* 充电软关机开机:滞后的拔电消息可能已切主电/关显示,强制恢复 */
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];