1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-07-28 09:28:13 +00:00

feat(core): introduce simple charging temperature controller.

[no changelog]
This commit is contained in:
kopecdav 2025-07-10 18:57:19 +02:00 committed by kopecdav
parent a9dff0224c
commit 6a7bd1c7fa
3 changed files with 53 additions and 1 deletions

View File

@ -159,6 +159,7 @@ pm_status_t pm_init(bool inherit_state) {
// Set default SOC target and max charging current limit
drv->soc_target = 100;
drv->charging_current_max_limit_ma = PM_BATTERY_CHARGING_CURRENT_MAX;
drv->i_chg_temp_limit_ma = PM_BATTERY_CHARGING_CURRENT_MAX;
// Fuel gauge SoC available, set fuel_gauge initialized.
drv->fuel_gauge_initialized = true;

View File

@ -55,6 +55,12 @@
#define PM_SUSPENDED_CHARGING_TIMEOUT_S 60
#define PM_STABILIZATION_TIMEOUT_MS 2000
// Temperature controller parameters
#define PM_TEMP_CONTROL_IDLE_PERIOD_MS 2 * 60 * 1000 // 2 minutes
#define PM_TEMP_CONTROL_BAND_1_MAX_TEMP 39.0f
#define PM_TEMP_CONTROL_BAND_2_MAX_TEMP 43.0f
#define PM_TEMP_CONTROL_BAND_3_MAX_TEMP 45.0f
#define PM_TEMP_CONTROL_BAND_4_MAX_TEMP 47.0f
// Power manager battery sampling data structure
typedef struct {
@ -93,6 +99,10 @@ typedef struct {
uint16_t charging_current_target_ma;
uint16_t charging_current_max_limit_ma;
// Temp controller
uint32_t temp_control_timeout;
uint16_t i_chg_temp_limit_ma;
// Power source hardware state
pmic_report_t pmic_data;
stwlc38_report_t wireless_data;

View File

@ -29,9 +29,21 @@
#include "../stwlc38/stwlc38.h"
#include "power_manager_internal.h"
static void pm_temperature_controller(pm_driver_t* drv);
static void pm_battery_sampling(float vbat, float ibat, float ntc_temp);
static void pm_parse_power_source_state(pm_driver_t* drv);
// Temperature controller LUT
static const struct {
float max_temp;
float current_limit_factor;
} temp_bands[] = {
{PM_TEMP_CONTROL_BAND_1_MAX_TEMP, 1.0},
{PM_TEMP_CONTROL_BAND_2_MAX_TEMP, 0.7},
{PM_TEMP_CONTROL_BAND_3_MAX_TEMP, 0.5},
{PM_TEMP_CONTROL_BAND_4_MAX_TEMP, 0.3},
};
void pm_monitor_power_sources(void) {
// Periodically called timer to request PMIC measurements. PMIC will call
// pm_pmic_data_ready() callback when the measurements are ready.
@ -162,6 +174,8 @@ void pm_charging_controller(pm_driver_t* drv) {
drv->charging_current_target_ma = drv->charging_current_max_limit_ma;
}
pm_temperature_controller(drv);
// Set charging target
if (drv->charging_current_target_ma != pmic_get_charging_limit()) {
// Set charging current limit
@ -195,7 +209,7 @@ void pm_charging_controller(pm_driver_t* drv) {
}
if (drv->soc_target_reached) {
drv->charging_current_target_ma = 0;
drv->i_chg_target_ma = 0;
}
if (drv->charging_current_target_ma == 0) {
@ -205,6 +219,33 @@ void pm_charging_controller(pm_driver_t* drv) {
}
}
static void pm_temperature_controller(pm_driver_t* drv) {
if (ticks_expired(drv->temp_control_timeout)) {
uint16_t i_chg_temp_limit_ma = 0;
i_chg_temp_limit_ma = 0; // Default to safety limit
for (size_t i = 0; i < sizeof(temp_bands) / sizeof(temp_bands[0]); ++i) {
if (drv->pmic_data.ntc_temp < temp_bands[i].max_temp) {
i_chg_temp_limit_ma = PM_BATTERY_CHARGING_CURRENT_MAX *
temp_bands[i].current_limit_factor;
break;
}
}
// If the temperature limit has changed, update the limit and reset the
// debounce timer
if (drv->i_chg_temp_limit_ma != i_chg_temp_limit_ma) {
drv->i_chg_temp_limit_ma = i_chg_temp_limit_ma;
drv->temp_control_timeout = ticks_timeout(PM_TEMP_CONTROL_IDLE_PERIOD_MS);
}
}
if (drv->charging_current_target_ma > drv->i_chg_temp_limit_ma) {
// Limit the charging current by temperature controller
drv->charging_current_target_ma = drv->i_chg_temp_limit_ma;
}
}
static void pm_battery_sampling(float vbat, float ibat, float ntc_temp) {
pm_driver_t* drv = &g_pm;