From 9f2fd682e52d5c434c57563afdcb0be91bc0b2f0 Mon Sep 17 00:00:00 2001 From: Msprg <18015488+Msprg@users.noreply.github.com> Date: Wed, 2 Sep 2026 11:33:32 +0200 Subject: [PATCH] PM5 low-batt shutdown: gate power-off on VUSB pin, not charger PG bit The critical-shutdown path in bwm_lowbatt_check() was reached whenever the AW32001 System Status "power good" bit was clear. On this hardware that bit reads "power fail" even while the board is USB-powered under HF load (hw status shows power fail + ~400 mA discharge on PC USB), so a low pack could trip the latched power-off - Gpio_ARM_Power_ON_Low() + while(1) - while USB keeps the MCU alive, leaving it spinning. Confirm the cable really is out via the dedicated VUSB sense pin (Gpio_VUSB_Read, the same source WITH_PM5_AUTOOFF uses) before powering off; if USB is present, clear the streak and keep running. Also print a reason before cut-off, and fix a brace/formatting glitch on the trigger condition. --- armsrc/bwm_charger.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/armsrc/bwm_charger.c b/armsrc/bwm_charger.c index 160f04e23..7f51438a3 100644 --- a/armsrc/bwm_charger.c +++ b/armsrc/bwm_charger.c @@ -471,6 +471,7 @@ void bwm_lowbatt_check(void) { static uint32_t last_tick = 0; #ifdef WITH_PM5_LOWBATT_SHUTDOWN static uint8_t crit = 0; + static bool s_vusb_setup = false; #endif if ((last_tick != 0) && (GetTickCountDelta(last_tick) < BWM_LOWBATT_PERIOD_MS)) { @@ -503,11 +504,23 @@ void bwm_lowbatt_check(void) { // uncalibrated gauge - e.g. <3% reported at 3.6 V). Never let SoC alone // trigger power-off: require the pack to also be in the low-batt zone. if ((mv <= BWM_SHUTDOWN_MV) || - ((soc <= BWM_SHUTDOWN_SOC_PCT) && (mv <= BWM_LOWBATT_MV))) { if (++crit >= BWM_SHUTDOWN_CONFIRMATIONS) { - bwm_beep_low_batt(); // final audible warning before cut-off - LEDsoff(); - Gpio_ARM_Power_ON_Low(); - while (1); // wait for hardware power-off + ((soc <= BWM_SHUTDOWN_SOC_PCT) && (mv <= BWM_LOWBATT_MV))) { + if (++crit >= BWM_SHUTDOWN_CONFIRMATIONS) { + // Confirm on the VUSB pin, not the charger PG bit: PG can read + // "power fail" on USB under load, so only power off if USB is really out. + if (s_vusb_setup == false) { + gpio_vusb_setup(); + s_vusb_setup = true; + } + if (Gpio_VUSB_Read()) { + crit = 0; // USB present, not a real drain + } else { + Dbprintf(_RED_("[BWM] critical battery %u mV / %u%% - powering off"), mv, soc); + bwm_beep_low_batt(); // last warning before cut-off + LEDsoff(); + Gpio_ARM_Power_ON_Low(); + while (1); // wait for power-off + } } } else { crit = 0; // recovered above the floor -> reset the streak