From 15b7cb1f4cad0551bcbaeda3992f5e1ddbb39011 Mon Sep 17 00:00:00 2001 From: niklascfw Date: Sat, 14 Feb 2026 15:12:06 +0100 Subject: [PATCH] Add battery run protection: require charger below 10% - Add bq24193_charger_connected() for charger detection - Block install when battery < 10% and charger not plugged in - Show clear screen after charger detected before continuing - User can cancel with + and - to return to Hekate Co-authored-by: Cursor --- bdk/power/bq24193.c | 6 ++++++ bdk/power/bq24193.h | 3 +++ source/main.c | 52 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+) diff --git a/bdk/power/bq24193.c b/bdk/power/bq24193.c index c8d1d7d..c5aeb43 100644 --- a/bdk/power/bq24193.c +++ b/bdk/power/bq24193.c @@ -164,6 +164,12 @@ void bq24193_enable_charger() i2c_send_byte(I2C_1, BQ24193_I2C_ADDR, BQ24193_PORConfig, reg); } +bool bq24193_charger_connected() +{ + u8 status = bq24193_get_reg(BQ24193_Status); + return (status & BQ24193_STATUS_PG_MASK) != 0; +} + void bq24193_fake_battery_removal() { // Disable watchdog to keep BATFET disabled. diff --git a/bdk/power/bq24193.h b/bdk/power/bq24193.h index ee459d4..2327bac 100644 --- a/bdk/power/bq24193.h +++ b/bdk/power/bq24193.h @@ -19,6 +19,8 @@ #ifndef __BQ24193_H_ #define __BQ24193_H_ +#include + #define BQ24193_I2C_ADDR 0x6B // REG 0 masks. @@ -117,5 +119,6 @@ enum BQ24193_reg_prop { int bq24193_get_property(enum BQ24193_reg_prop prop, int *value); void bq24193_enable_charger(); void bq24193_fake_battery_removal(); +bool bq24193_charger_connected(); #endif /* __BQ24193_H_ */ diff --git a/source/main.c b/source/main.c index d8c23db..e16382d 100644 --- a/source/main.c +++ b/source/main.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include #include #include @@ -376,6 +378,56 @@ void ipl_main(void) { // Determine installation mode install_mode_t mode = current.is_installed ? INSTALL_MODE_UPDATE : INSTALL_MODE_CLEAN; + // Battery run protection: below 10% requires charger + #define BATT_LOW_THRESHOLD 10 + int batt_raw = 0; + int batt_pct = 100; + if (max17050_get_property(MAX17050_RepSOC, &batt_raw) == 0) { + batt_pct = batt_raw >> 8; // RepSOC: high byte = percent + } + while (batt_pct < BATT_LOW_THRESHOLD && !bq24193_charger_connected()) { + gfx_clear_grey(0x1B); + gfx_con_setpos(0, 0); + print_header(); + set_color(COLOR_RED); + gfx_printf("Akkustand zu niedrig! (%d%%)\n\n", batt_pct); + gfx_printf("Unter %d%% Akku darf die Installation nur\n", BATT_LOW_THRESHOLD); + gfx_printf("mit angeschlossenem Ladegeraet durchgefuehrt werden.\n\n"); + set_color(COLOR_YELLOW); + gfx_printf("Stecke das Ladegeraet an und warte...\n"); + gfx_printf("Oder druecke + und - zum Abbrechen.\n"); + set_color(COLOR_WHITE); + jc_init_hw(); + while (btn_read() & BTN_POWER) { msleep(50); } + bool user_cancelled = false; + while (batt_pct < BATT_LOW_THRESHOLD && !bq24193_charger_connected() && !user_cancelled) { + jc_gamepad_rpt_t *jc = joycon_poll(); + if (jc && jc->plus && jc->minus) { + user_cancelled = true; + break; + } + if (max17050_get_property(MAX17050_RepSOC, &batt_raw) == 0) { + batt_pct = batt_raw >> 8; + } + msleep(200); + } + if (user_cancelled) { + gfx_printf("\nAbgebrochen. Starte Hekate...\n"); + msleep(500); + if (file_exists(PAYLOAD_PATH)) { + launch_payload(PAYLOAD_PATH); + } else { + power_set_state(POWER_OFF_REBOOT); + } + return; + } + } + + // Charger detected or battery OK - clear the low-battery screen before continuing + gfx_clear_grey(0x1B); + gfx_con_setpos(0, 0); + print_header(); + // Show information set_color(COLOR_CYAN); gfx_printf("Installationsmodus: %s\n", mode == INSTALL_MODE_UPDATE ? "Update" : "Saubere Installation");