From a530fb2c76fee4f9ec4cabb82a6c20e3a26e72d7 Mon Sep 17 00:00:00 2001 From: kopecdav Date: Mon, 12 May 2025 14:31:53 +0200 Subject: [PATCH] feat(core): add pm_charging_set_max_current function to API [no changelog] --- .../prodtest/cmd/prodtest_power_manager.c | 21 ++++----- .../sys/power_manager/inc/sys/power_manager.h | 2 +- .../sys/power_manager/stm32u5/power_manager.c | 46 +++++++++++-------- .../stm32u5/power_manager_internal.h | 4 +- .../power_manager/stm32u5/power_monitoring.c | 18 ++++---- .../models/T3W1/trezor_t3w1_revA.py | 4 +- .../models/T3W1/trezor_t3w1_revB.py | 5 +- .../models/T3W1/trezor_t3w1_revC.py | 5 +- 8 files changed, 51 insertions(+), 54 deletions(-) diff --git a/core/embed/projects/prodtest/cmd/prodtest_power_manager.c b/core/embed/projects/prodtest/cmd/prodtest_power_manager.c index 49dde5bd31..ff7b32d5bd 100644 --- a/core/embed/projects/prodtest/cmd/prodtest_power_manager.c +++ b/core/embed/projects/prodtest/cmd/prodtest_power_manager.c @@ -336,17 +336,16 @@ void prodtest_pm_precharge(cli_t* cli) { // due to effect of internal resistance of the battery. So battery voltage // will drop a bit after the charging is stopped. - // voltage while charging is being lifted due to charging with quite high charging - // current. When the test terminate by reaching the given woltage. The current - // and + // voltage while charging is being lifted due to charging with quite high + // charging current. When the test terminate by reaching the given woltage. + // The current and float precharge_voltage_V = 3.45f; pm_charging_enable(); cli_trace(cli, "Precharging the device..."); - while(true){ - + while (true) { pm_report_t report; pm_status_t status = pm_get_report(&report); @@ -365,11 +364,10 @@ void prodtest_pm_precharge(cli_t* cli) { (int)(report.battery_voltage_v * 1000) % 1000, (int)precharge_voltage_V, (int)(precharge_voltage_V * 1000) % 1000); - cli_progress(cli,"%d.%03d %d.%03d", - (int)report.battery_voltage_v, - (int)(report.battery_voltage_v * 1000) % 1000, - (int)precharge_voltage_V, - (int)(precharge_voltage_V * 1000) % 1000); + cli_progress(cli, "%d.%03d %d.%03d", (int)report.battery_voltage_v, + (int)(report.battery_voltage_v * 1000) % 1000, + (int)precharge_voltage_V, + (int)(precharge_voltage_V * 1000) % 1000); if (cli_aborted(cli)) { cli_trace(cli, "aborted"); @@ -377,7 +375,7 @@ void prodtest_pm_precharge(cli_t* cli) { } // Check if the battery voltage is above the precharge voltag - if(report.battery_voltage_v >= precharge_voltage_V){ + if (report.battery_voltage_v >= precharge_voltage_V) { // Target achieved cli_trace(cli, "Battery voltage reached the target voltage."); break; @@ -387,7 +385,6 @@ void prodtest_pm_precharge(cli_t* cli) { cli_ok(cli, ""); } - // clang-format off PRODTEST_CLI_CMD( diff --git a/core/embed/sys/power_manager/inc/sys/power_manager.h b/core/embed/sys/power_manager/inc/sys/power_manager.h index eaadb0c588..e5e0129bc3 100644 --- a/core/embed/sys/power_manager/inc/sys/power_manager.h +++ b/core/embed/sys/power_manager/inc/sys/power_manager.h @@ -107,8 +107,8 @@ pm_status_t pm_turn_on(void); pm_status_t pm_get_report(pm_report_t* report); pm_status_t pm_charging_enable(void); pm_status_t pm_charging_disable(void); +pm_status_t pm_charging_set_max_current(uint16_t current_ma); pm_status_t pm_store_data_to_backup_ram(); -pm_status_t pm_wait_until_active(uint32_t timeout_ms); pm_status_t pm_wakeup_flags_set(pm_wakeup_flags_t flags); pm_status_t pm_wakeup_flags_reset(void); pm_status_t pm_wakeup_flags_get(pm_wakeup_flags_t* flags); diff --git a/core/embed/sys/power_manager/stm32u5/power_manager.c b/core/embed/sys/power_manager/stm32u5/power_manager.c index 5af1582fa7..97a1bd810c 100644 --- a/core/embed/sys/power_manager/stm32u5/power_manager.c +++ b/core/embed/sys/power_manager/stm32u5/power_manager.c @@ -106,8 +106,9 @@ pm_status_t pm_init(bool inherit_state) { // Fuel gauge SoC available, set fuel_gauge initialized. drv->fuel_gauge_initialized = true; - // Enable charging by default + // Enable charging by default to max current drv->charging_enabled = true; + pm_charging_set_max_current(PM_BATTERY_CHARGING_CURRENT_MAX); // Poll until fuel_gauge is initialized and first PMIC & WLC measurements // propagates into power_monitor. @@ -294,7 +295,9 @@ pm_status_t pm_charging_enable(void) { } drv->charging_enabled = true; + irq_key_t irq_key = irq_lock(); pm_charging_controller(drv); + irq_unlock(irq_key); return PM_OK; } @@ -307,7 +310,29 @@ pm_status_t pm_charging_disable(void) { } drv->charging_enabled = false; + irq_key_t irq_key = irq_lock(); pm_charging_controller(drv); + irq_unlock(irq_key); + + return PM_OK; +} + +pm_status_t pm_charging_set_max_current(uint16_t current_ma) { + pm_driver_t* drv = &g_pm; + + if (!drv->initialized) { + return PM_NOT_INITIALIZED; + } + + if (current_ma > PM_BATTERY_CHARGING_CURRENT_MAX) { + return PM_REQUEST_REJECTED; + } + + if (current_ma < PM_BATTERY_CHARGING_CURRENT_MIN) { + return PM_REQUEST_REJECTED; + } + + drv->charging_current_max_limit_ma = current_ma; return PM_OK; } @@ -342,25 +367,6 @@ pm_status_t pm_store_data_to_backup_ram() { return PM_OK; } -pm_status_t pm_wait_until_active(uint32_t timeout_ms) { - pm_driver_t* drv = &g_pm; - uint32_t expire_time = ticks_timeout(timeout_ms); - - while (1) { - if (ticks_expired(expire_time)) { - // Timeout expired - return PM_REQUEST_REJECTED; - } - - if ((drv->state == PM_STATE_ACTIVE) || - (drv->state == PM_STATE_POWER_SAVE)) { - return PM_OK; - } - } - - return PM_OK; -} - pm_status_t pm_wakeup_flags_set(pm_wakeup_flags_t flags) { pm_driver_t* drv = &g_pm; if (!drv->initialized) { 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 7787ef6703..b8212c577b 100644 --- a/core/embed/sys/power_manager/stm32u5/power_manager_internal.h +++ b/core/embed/sys/power_manager/stm32u5/power_manager_internal.h @@ -34,7 +34,8 @@ #define PM_BATTERY_UNDERVOLT_THR_V 3.0f #define PM_BATTERY_UNDERVOLT_RECOVERY_THR_V 3.3f #define PM_BATTERY_LOW_THRESHOLD_SOC 15 - +#define PM_BATTERY_CHARGING_CURRENT_MAX PMIC_CHARGING_LIMIT_MAX +#define PM_BATTERY_CHARGING_CURRENT_MIN PMIC_CHARGING_LIMIT_MIN #define PM_BATTERY_SAMPLING_BUF_SIZE 10 #define PM_WPC_CHARGE_CURR_STEP_MA 50 @@ -75,6 +76,7 @@ typedef struct { // Battery charging state bool charging_enabled; uint16_t charging_current_target_ma; + uint16_t charging_current_max_limit_ma; uint32_t charging_target_timestamp; // Power source hardware state diff --git a/core/embed/sys/power_manager/stm32u5/power_monitoring.c b/core/embed/sys/power_manager/stm32u5/power_monitoring.c index 766d69aab3..cba9d55528 100644 --- a/core/embed/sys/power_manager/stm32u5/power_monitoring.c +++ b/core/embed/sys/power_manager/stm32u5/power_monitoring.c @@ -64,7 +64,6 @@ void pm_monitor_power_sources(void) { // Check battery voltage for critical (undervoltage) threshold if ((drv->pmic_data.vbat < PM_BATTERY_UNDERVOLT_THR_V) && !drv->battery_critical) { - // Force Fuel gauge to 0, keep the covariance fuel_gauge_set_soc(&drv->fuel_gauge, 0.0f, drv->fuel_gauge.P); @@ -95,7 +94,7 @@ void pm_monitor_power_sources(void) { drv->pmic_data.ntc_temp); // Charging completed - if(drv->pmic_data.charge_status & 0x1){ + if (drv->pmic_data.charge_status & 0x1) { // Force fuel gauge to 100%, keep the covariance fuel_gauge_set_soc(&drv->fuel_gauge, 1.0f, drv->fuel_gauge.P); } @@ -162,23 +161,19 @@ void pm_charging_controller(pm_driver_t* drv) { } } else if (drv->usb_connected) { // USB connected, set maximum charging current right away - drv->charging_current_target_ma = PMIC_CHARGING_LIMIT_MAX; + drv->charging_current_target_ma = drv->charging_current_max_limit_ma; } else if (drv->wireless_connected) { // Gradually increase charging current to the maximum - if (drv->charging_current_target_ma == PMIC_CHARGING_LIMIT_MAX) { + if (drv->charging_current_target_ma == drv->charging_current_max_limit_ma) { // No action required } else if (drv->charging_current_target_ma == 0) { - drv->charging_current_target_ma = PMIC_CHARGING_LIMIT_MIN; + drv->charging_current_target_ma = drv->charging_current_max_limit_ma; drv->charging_target_timestamp = systick_ms(); } else if (systick_ms() - drv->charging_target_timestamp > PM_WPC_CHARGE_CURR_STEP_TIMEOUT_MS) { drv->charging_current_target_ma += PM_WPC_CHARGE_CURR_STEP_MA; drv->charging_target_timestamp = systick_ms(); - - if (drv->charging_current_target_ma > PMIC_CHARGING_LIMIT_MAX) { - drv->charging_current_target_ma = PMIC_CHARGING_LIMIT_MAX; - } } } else { @@ -186,6 +181,11 @@ void pm_charging_controller(pm_driver_t* drv) { drv->charging_current_target_ma = 0; } + // charging current software limit + if (drv->charging_current_target_ma > drv->charging_current_max_limit_ma) { + drv->charging_current_target_ma = drv->charging_current_max_limit_ma; + } + // Set charging target if (drv->charging_current_target_ma != pmic_get_charging_limit()) { // Set charging current limit diff --git a/core/site_scons/models/T3W1/trezor_t3w1_revA.py b/core/site_scons/models/T3W1/trezor_t3w1_revA.py index 06f0372fbf..e3b090e505 100644 --- a/core/site_scons/models/T3W1/trezor_t3w1_revA.py +++ b/core/site_scons/models/T3W1/trezor_t3w1_revA.py @@ -236,9 +236,7 @@ def configure( ] if ("pmic" in features_wanted) or ("power_manager" in features_wanted): - sources += [ - "embed/sys/power_manager/npm1300/npm1300.c" - ] + sources += ["embed/sys/power_manager/npm1300/npm1300.c"] paths += ["embed/sys/power_manager/inc"] defines += ["USE_PMIC"] features_available.append("pmic") diff --git a/core/site_scons/models/T3W1/trezor_t3w1_revB.py b/core/site_scons/models/T3W1/trezor_t3w1_revB.py index 525b298950..9760f386bf 100644 --- a/core/site_scons/models/T3W1/trezor_t3w1_revB.py +++ b/core/site_scons/models/T3W1/trezor_t3w1_revB.py @@ -241,9 +241,7 @@ def configure( ] if ("pmic" in features_wanted) or ("power_manager" in features_wanted): - sources += [ - "embed/sys/power_manager/npm1300/npm1300.c" - ] + sources += ["embed/sys/power_manager/npm1300/npm1300.c"] paths += ["embed/sys/power_manager/inc"] defines += ["USE_PMIC"] features_available.append("pmic") @@ -263,7 +261,6 @@ def configure( defines += [("USE_POWER_MANAGER", "1")] features_available.append("power_manager") - env.get("ENV")["LINKER_SCRIPT"] = linker_script return features_available diff --git a/core/site_scons/models/T3W1/trezor_t3w1_revC.py b/core/site_scons/models/T3W1/trezor_t3w1_revC.py index 80f18b36c8..30ee832ccd 100644 --- a/core/site_scons/models/T3W1/trezor_t3w1_revC.py +++ b/core/site_scons/models/T3W1/trezor_t3w1_revC.py @@ -241,9 +241,7 @@ def configure( ] if ("pmic" in features_wanted) or ("power_manager" in features_wanted): - sources += [ - "embed/sys/power_manager/npm1300/npm1300.c" - ] + sources += ["embed/sys/power_manager/npm1300/npm1300.c"] paths += ["embed/sys/power_manager/inc"] defines += ["USE_PMIC"] features_available.append("pmic") @@ -263,7 +261,6 @@ def configure( defines += [("USE_POWER_MANAGER", "1")] features_available.append("power_manager") - env.get("ENV")["LINKER_SCRIPT"] = linker_script return features_available