Add true power-off via BQ25896 BATFET disconnect

Hibernate (deep sleep) leaves the BQ25896 charger IC powered, drawing
~30-60uA quiescent from BAT. This adds a second option on the shutdown
page -- "power off" -- that writes the BATFET_DIS bit in BQ25896 REG09
to fully disconnect the battery from VSYS. Leakage drops to ~12-23uA
(IC internal only). Wake requires USB-C plug-in.

Shutdown page now shows two options with a cursor (up/down to toggle):
  > hibernate: long press/Enter   (T-Deck Pro)
    power off: long press/Enter
  > hibernate: long press          (T5S3 / other)
    power off: long press

Selecting "hibernate" triggers immediately (unchanged behaviour).
Selecting "power off" shows a confirmation prompt:
  power off device?
  usb-c to wake
  Enter:yes  q:no

Power-off display suppresses the header (node name, clock, battery)
and shows only "powering off..." and "plug in USB-C to turn on".

The 's' key shortcut to settings is gated on the shutdown page so it
passes through to the hibernate/power-off selection toggle instead.
Both the TCA8418 handler (loop) and the broader handler
(handleKeyboardInput) are gated via isHomeOnShutdownPage().

PRESS_LABEL macro: removed dead UI_HAS_JOYSTICK branch (no Meck
device has a joystick), collapsed to a single #define "long press".
Joystick input polling block in loop() also removed (dead code behind
#if UI_HAS_JOYSTICK, never compiled for any Meck build).

BQ25896 I2C sequence follows TI recommendation (E2E forum, Jeff/TI):
  1. Read REG09
  2. Write BATFET_DLY=1 (bit 3) -- delays disconnect so I2C completes
  3. Write BATFET_DIS=1 | BATFET_DLY=1 (bits 5+3) -- last I2C write
The write happens after display turnOff but before board powerOff, so
I2C pull-ups on VDD3V3 are still alive. Board enters deep sleep, then
BATFET opens after tSM_DLY (~10-15s). Skipping the delay risks leaving
the BQ25896 I2C engine in an undefined state that can prevent wake on
USB-C plug-in (device soft-brick requiring battery disconnect).

REG09 bit map (confirmed from Linux kernel bq25890_charger.c):
  Bit 7: FORCE_ICO
  Bit 6: TMR2X_EN
  Bit 5: BATFET_DIS  (0x20) -- disconnect battery
  Bit 4: JEITA_VSET
  Bit 3: BATFET_DLY  (0x08) -- delay before disconnect
  Bit 2: BATFET_RST_EN (0x04) -- QON wake (not wired on T-Deck Pro)
  Bit 1: PUMPX_UP
  Bit 0: PUMPX_DN

Schematic confirms QON (pin 12) has R4 10K pull-up to REGN with no
user-accessible button -- USB-C is the only wake path from ship mode.

Guarded by #ifdef I2C_ADDR_BQ25896 so it compiles on all platforms
but only activates on boards with the charger (T-Deck Pro, T5S3).

Files changed:
  UITask.h   -- _full_poweroff, setFullPowerOff(), isHomeOnShutdownPage()
  UITask.cpp -- shutdown page UI, input handling, BATFET write,
                PRESS_LABEL cleanup, joystick removal
  main.cpp   -- 's' key gated on shutdown page (both handlers)
This commit is contained in:
pelgraine
2026-05-03 20:24:20 +10:00
parent 00b3f66bc4
commit c2bfc3c985
3 changed files with 137 additions and 44 deletions
+8 -1
View File
@@ -3269,7 +3269,13 @@ void loop() {
case 'e': ui_task.gotoTextReader(); break;
case 'n': ui_task.gotoNotesScreen(); break;
#endif
case 's': ui_task.gotoSettingsScreen(); break;
case 's':
if (ui_task.isHomeOnShutdownPage()) {
ui_task.injectKey(ckb);
} else {
ui_task.gotoSettingsScreen();
}
break;
case 'f': ui_task.gotoDiscoveryScreen(); break;
case 'h': ui_task.gotoLastHeardScreen(); break;
case (char)0xF3: ui_task.injectKey(KEY_LEFT); break; // Left arrow → prev page
@@ -4599,6 +4605,7 @@ void handleKeyboardInput() {
#ifdef MECK_AUDIO_VARIANT
|| ui_task.isOnAlarmScreen()
#endif
|| ui_task.isHomeOnShutdownPage()
) {
ui_task.injectKey('s'); // Pass directly for scrolling
} else {