From 936b46fa71765bd69828c241ca3df92df600faa9 Mon Sep 17 00:00:00 2001 From: kopecdav Date: Fri, 25 Apr 2025 12:15:37 +0200 Subject: [PATCH] feat(core):Introduce charging controller [no changelog] --- .../stm32u5/power_manager_internal.h | 11 ++++- .../power_manager/stm32u5/power_monitoring.c | 46 ++++++++++++++++++- 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/core/embed/sys/power_manager/stm32u5/power_manager_internal.h b/core/embed/sys/power_manager/stm32u5/power_manager_internal.h index b4ff9b06f8..765e23dd33 100644 --- a/core/embed/sys/power_manager/stm32u5/power_manager_internal.h +++ b/core/embed/sys/power_manager/stm32u5/power_manager_internal.h @@ -31,8 +31,10 @@ #define POWER_MANAGER_SHUTDOWN_TIMEOUT_MS 15000 #define POWER_MANAGER_BATTERY_UNDERVOLT_THRESHOLD_V 3.0f #define POWER_MANAGER_BATTERY_UNDERVOLT_HYSTERESIS_V 0.5f -#define POWER_MANAGER_BATTERY_LOW_THRESHOLD_V 3.2f -#define POWER_MANAGER_BATTERY_LOW_RECOVERY_V 3.3f +#define POWER_MANAGER_BATTERY_LOW_THRESHOLD_V 3.15f +#define POWER_MANAGER_BATTERY_LOW_RECOVERY_V 3.2f +#define POWER_MANAGER_WPC_CHARGE_CURR_STEP_MA 50 +#define POWER_MANAGER_WPC_CHARGE_CURR_STEP_TIMEOUT_MS 1000 // Event flag manipulation macros #define PM_SET_EVENT(flags, event) ((flags) |= (event)) @@ -45,6 +47,10 @@ typedef struct { power_manager_state_t state; power_manager_event_t event_flags; + // Battery charging state + uint16_t charging_current_target_ma; + uint32_t charging_target_timestamp; + // Power source hardware state npm1300_report_t pmic_data; stwlc38_report_t wireless_data; @@ -82,6 +88,7 @@ extern power_manager_driver_t g_power_manager; void pm_monitor_power_sources(void); void pm_process_state_machine(void); void pm_pmic_data_ready(void* context, npm1300_report_t* report); +void pm_charging_controller(power_manager_driver_t* drv); // State handlers power_manager_state_t pm_handle_state_active(power_manager_driver_t* drv); diff --git a/core/embed/sys/power_manager/stm32u5/power_monitoring.c b/core/embed/sys/power_manager/stm32u5/power_monitoring.c index 5b9acfe883..4dfacba541 100644 --- a/core/embed/sys/power_manager/stm32u5/power_monitoring.c +++ b/core/embed/sys/power_manager/stm32u5/power_monitoring.c @@ -76,7 +76,10 @@ void pm_monitor_power_sources(void) { drv->battery_low = false; } - // Request fresh measurements + // Run battery charging controller + pm_charging_controller(drv); + + // Request fresh measurements from PMIC npm1300_measure(pm_pmic_data_ready, NULL); drv->pmic_measurement_ready = false; @@ -101,3 +104,44 @@ void pm_pmic_data_ready(void* context, npm1300_report_t* report) { drv->pmic_measurement_ready = true; } + +void pm_charging_controller(power_manager_driver_t* drv) { + // Check if external power is available + if (drv->usb_connected) { + // USB connected, set maximum charging current right away + drv->charging_current_target_ma = NPM1300_CHARGING_LIMIT_MAX; + + } else if (drv->wireless_connected) { + // Gradually increase charging current to the maximum + if (drv->charging_current_target_ma == NPM1300_CHARGING_LIMIT_MAX) { + // No action required + } else if (drv->charging_current_target_ma == 0) { + drv->charging_current_target_ma = NPM1300_CHARGING_LIMIT_MIN; + drv->charging_target_timestamp = systick_ms(); + } else if (systick_ms() - drv->charging_target_timestamp > + POWER_MANAGER_WPC_CHARGE_CURR_STEP_TIMEOUT_MS) { + drv->charging_current_target_ma += POWER_MANAGER_WPC_CHARGE_CURR_STEP_MA; + drv->charging_target_timestamp = systick_ms(); + + if (drv->charging_current_target_ma > NPM1300_CHARGING_LIMIT_MAX) { + drv->charging_current_target_ma = NPM1300_CHARGING_LIMIT_MAX; + } + } + + } else { + // No external power source, turn off charging + drv->charging_current_target_ma = 0; + } + + // Set charging target + if (drv->charging_current_target_ma != npm1300_get_charging_limit()) { + // Set charging current limit + npm1300_set_charging_limit(drv->charging_current_target_ma); + } + + if (drv->charging_current_target_ma == 0) { + npm1300_set_charging(false); + } else { + npm1300_set_charging(true); + } +}