From 48ef5736498fa676aa45d7f78b0feb11a68d74b5 Mon Sep 17 00:00:00 2001 From: kopecdav Date: Mon, 19 May 2025 11:51:54 +0200 Subject: [PATCH] refactor(core): remove recursion from power manager state machine automat [no changelog] --- .../prodtest/cmd/prodtest_power_manager.c | 29 +++++------ .../sys/power_manager/stm32u5/power_states.c | 48 +++++++++++-------- 2 files changed, 40 insertions(+), 37 deletions(-) diff --git a/core/embed/projects/prodtest/cmd/prodtest_power_manager.c b/core/embed/projects/prodtest/cmd/prodtest_power_manager.c index ff7b32d5bd..63c1633721 100644 --- a/core/embed/projects/prodtest/cmd/prodtest_power_manager.c +++ b/core/embed/projects/prodtest/cmd/prodtest_power_manager.c @@ -328,17 +328,15 @@ void prodtest_pm_precharge(cli_t* cli) { return; } - // This test consider that the device is connected with USB and placed in - // ambient temperature. Battery will be charged with constanst current - // and precharge voltage is statically taken from the battery chaging curve - // - // It is expected that battery voltage during the charging is being lifted - // due to effect of internal resistance of the battery. So battery voltage - // will drop a bit after the charging is stopped. + // This test considers that the device is connected via USB and placed at + // ambient temperature. The battery will be charged with constant current, + // and the precharge voltage is statically derived from the battery charging + // curve. - // 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 + // During charging, the voltage rises because of the relatively high charging + // current. When the test ends upon reaching the specified precharge voltage, + // the charging current is cut off, which can cause the battery voltage to + // fall slightly. float precharge_voltage_V = 3.45f; pm_charging_enable(); @@ -359,15 +357,12 @@ void prodtest_pm_precharge(cli_t* cli) { return; } - cli_trace(cli, "Battery voltage: %d.%03d V -> taret %d.%03d V", - (int)report.battery_voltage_v, - (int)(report.battery_voltage_v * 1000) % 1000, + cli_trace(cli, "Precharging the device to %d.%03d V", (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); + + // Print power manager report. + prodtest_pm_report(cli); if (cli_aborted(cli)) { cli_trace(cli, "aborted"); diff --git a/core/embed/sys/power_manager/stm32u5/power_states.c b/core/embed/sys/power_manager/stm32u5/power_states.c index b355675f6f..085009972f 100644 --- a/core/embed/sys/power_manager/stm32u5/power_states.c +++ b/core/embed/sys/power_manager/stm32u5/power_states.c @@ -67,29 +67,37 @@ static const pm_state_handler_t state_handlers[] = { void pm_process_state_machine(void) { pm_driver_t* drv = &g_pm; - pm_internal_state_t old_state = drv->state; + pm_internal_state_t old_state; + pm_internal_state_t new_state; - // Get next state from current state's handler - pm_internal_state_t new_state = state_handlers[old_state].handle(drv); + // Loop until state machine converge to a stable state + while (true) { + // Get current state + old_state = drv->state; - // Handle state transition if needed - if (new_state != old_state) { - // Exit old state - if (state_handlers[old_state].exit != NULL) { - state_handlers[old_state].exit(drv); + // Call state handler to process the current state + new_state = state_handlers[old_state].handle(drv); + + // Check if the state has changed + if (new_state != old_state) { + // Exit old state + if (state_handlers[old_state].exit != NULL) { + state_handlers[old_state].exit(drv); + } + + // Update state + drv->state = new_state; + PM_SET_EVENT(drv->event_flags, PM_EVENT_STATE_CHANGED); + + // Enter new state + if (state_handlers[new_state].enter != NULL) { + state_handlers[new_state].enter(drv); + } + + } else { + // State has not changed, exit the loop + break; } - - // Update state - drv->state = new_state; - PM_SET_EVENT(drv->event_flags, PM_EVENT_STATE_CHANGED); - - // Enter new state - if (state_handlers[new_state].enter != NULL) { - state_handlers[new_state].enter(drv); - } - - // Process state machine again as new state might trigger another transition - pm_process_state_machine(); } }