diff --git a/core/SConscript.prodtest b/core/SConscript.prodtest index 6afb2fad36..7be3f1ba45 100644 --- a/core/SConscript.prodtest +++ b/core/SConscript.prodtest @@ -137,7 +137,6 @@ SOURCE_PRODTEST = [ 'embed/projects/prodtest/cmd/prodtest_bootloader.c', 'embed/projects/prodtest/cmd/prodtest_button.c', 'embed/projects/prodtest/cmd/prodtest_display.c', - 'embed/projects/prodtest/cmd/prodtest_fuel_gauge.c', 'embed/projects/prodtest/cmd/prodtest_prodtest.c', 'embed/projects/prodtest/cmd/prodtest_backup_ram.c', 'embed/projects/prodtest/cmd/prodtest_get_cpuid.c', @@ -150,7 +149,6 @@ SOURCE_PRODTEST = [ 'embed/projects/prodtest/cmd/prodtest_otp_batch.c', 'embed/projects/prodtest/cmd/prodtest_otp_variant.c', 'embed/projects/prodtest/cmd/prodtest_ping.c', - 'embed/projects/prodtest/cmd/prodtest_pmic.c', 'embed/projects/prodtest/cmd/prodtest_power_manager.c', 'embed/projects/prodtest/cmd/prodtest_reboot.c', 'embed/projects/prodtest/cmd/prodtest_rgbled.c', diff --git a/core/embed/projects/prodtest/cmd/prodtest_fuel_gauge.c b/core/embed/projects/prodtest/cmd/prodtest_fuel_gauge.c deleted file mode 100644 index ee1eb1c2ab..0000000000 --- a/core/embed/projects/prodtest/cmd/prodtest_fuel_gauge.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * This file is part of the Trezor project, https://trezor.io/ - * - * Copyright (c) SatoshiLabs - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifdef USE_POWERCTL - -#include -#include -#include - -#include -#include -#include - -#include "../../../sys/powerctl/fuel_gauge/fuel_gauge.h" -#include "../../../sys/powerctl/npm1300/npm1300.h" - -static void prodtest_fuel_gauge(cli_t *cli) { - if (cli_arg_count(cli) > 0) { - cli_error_arg_count(cli); - return; - } - - char display_text[100]; - - fuel_gauge_state_t fg; - - // Fuel gauge noise covariance parameters. - // These parameters are used in the Kalman filter to adjust the weight - // given to the measurements versus the model predictions. - // Parameters are fine-tuned on battery model simulation. - float Q = 0.001f; - float R = 3000.0f; - float R_aggressive = 3000.0f; - float Q_aggressive = 0.001f; - float P_init = 0.1; - - cli_trace(cli, "Initialize Fuel gauge."); - - fuel_gauge_init(&fg, R, Q, R_aggressive, Q_aggressive, P_init); - - npm1300_report_t report; - if (!npm1300_measure_sync(&report)) { - cli_error(cli, CLI_ERROR, "Failed to get measurement data from PMIC."); - return; - } - - fuel_gauge_initial_guess(&fg, report.vbat, report.ibat, report.ntc_temp); - uint32_t tick = systick_ms(); - - systick_delay_ms(1000); - - while (true) { - if (cli_aborted(cli)) { - cli_trace(cli, "Abort fuel gauge test."); - break; - } - - if (!npm1300_measure_sync(&report)) { - cli_error(cli, CLI_ERROR, "Failed to get measurement data from PMIC."); - break; - } - - fuel_gauge_update(&fg, systick_ms() - tick, report.vbat, report.ibat, - report.ntc_temp); - tick = systick_ms(); - - // Calculate the integer and fractional parts correctly - int vbat_int = (int)report.vbat; - int vbat_frac = - abs((int)((report.vbat - vbat_int) * 1000)); // Only 3 decimal places - - int ibat_int = (int)report.ibat; - int ibat_frac = - abs((int)((report.ibat - ibat_int) * 1000)); // Only 3 decimal places - - int soc_int = (int)fg.soc; - int soc_frac = - abs((int)((fg.soc - soc_int) * 1000)); // Only 3 decimal places - - const char *charge_state_str; - if (report.ibat > 0) { - charge_state_str = "DISCHARGING"; - } else if (report.ibat < 0) { - charge_state_str = "CHARGING"; - } else { - charge_state_str = "IDLE"; - } - - cli_progress(cli, "%d.%03d %d.%03d %d.%03d %s", vbat_int, vbat_frac, - ibat_int, ibat_frac, soc_int, soc_frac, charge_state_str); - - mini_snprintf(display_text, 100, "V: %d.%03d I: %d.%03d SOC: %d.%03d", - vbat_int, vbat_frac, ibat_int, ibat_frac, soc_int, soc_frac); - - screen_prodtest_show_text(display_text, strlen(display_text)); - - // Wait a second - systick_delay_ms(1000); - } -} - -// clang-format off - -PRODTEST_CLI_CMD( - .name = "fuel-gauge", - .func = prodtest_fuel_gauge, - .info = "Test fuel gauge", - .args = "" -); - -#endif // USE_POWERCTL diff --git a/core/embed/projects/prodtest/cmd/prodtest_pmic.c b/core/embed/projects/prodtest/cmd/prodtest_pmic.c deleted file mode 100644 index f9c99fdf84..0000000000 --- a/core/embed/projects/prodtest/cmd/prodtest_pmic.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - * This file is part of the Trezor project, https://trezor.io/ - * - * Copyright (c) SatoshiLabs - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifdef USE_POWERCTL - -#include - -#include -#include -#include - -#include -#include "../../../sys/powerctl/npm1300/npm1300.h" - -static void prodtest_pmic_init(cli_t* cli) { - cli_trace(cli, "Initializing the NPM1300 driver..."); - - if (cli_arg_count(cli) > 0) { - cli_error_arg_count(cli); - return; - } - - npm1300_deinit(); - - if (!npm1300_init()) { - cli_error(cli, CLI_ERROR, "Failed to initialize NPM1300 driver."); - return; - } - - cli_ok(cli, ""); -} - -static void prodtest_pmic_charge_enable(cli_t* cli) { - if (cli_arg_count(cli) > 0) { - cli_error_arg_count(cli); - return; - } - - cli_trace(cli, "Enabling battery charging @ %dmA...", - npm1300_get_charging_limit()); - - if (!npm1300_set_charging(true)) { - cli_error(cli, CLI_ERROR, "Failed to enable battery charging."); - return; - } - - cli_ok(cli, ""); -} - -static void prodtest_pmic_charge_disable(cli_t* cli) { - if (cli_arg_count(cli) > 0) { - cli_error_arg_count(cli); - return; - } - - cli_trace(cli, "Disabling battery charging..."); - - if (!npm1300_set_charging(false)) { - cli_error(cli, CLI_ERROR, "Failed to disable battery charging."); - return; - } - - cli_ok(cli, ""); -} - -static void prodtest_pmic_charge_set_limit(cli_t* cli) { - uint32_t i_charge = 0; - - if (!cli_arg_uint32(cli, "limit", &i_charge) || - i_charge < NPM1300_CHARGING_LIMIT_MIN || - i_charge > NPM1300_CHARGING_LIMIT_MAX) { - cli_error_arg(cli, "Expecting charging limit in range %d-%d mA.", - NPM1300_CHARGING_LIMIT_MIN, NPM1300_CHARGING_LIMIT_MAX); - return; - } - - if (cli_arg_count(cli) > 1) { - cli_error_arg_count(cli); - return; - } - - cli_trace(cli, "Setting battery charging limit to %d mA...", i_charge); - - if (!npm1300_set_charging_limit(i_charge)) { - cli_error(cli, CLI_ERROR, "Failed to set battery charging limit."); - return; - } - - cli_ok(cli, ""); -} - -static void prodtest_pmic_buck_set_mode(cli_t* cli) { - npm1300_buck_mode_t buck_mode = NPM1300_BUCK_MODE_AUTO; - - const char* mode = cli_arg(cli, "mode"); - if (strcmp(mode, "pwm") == 0) { - buck_mode = NPM1300_BUCK_MODE_PWM; - } else if (strcmp(mode, "pfm") == 0) { - buck_mode = NPM1300_BUCK_MODE_PFM; - } else if (strcmp(mode, "auto") == 0) { - buck_mode = NPM1300_BUCK_MODE_AUTO; - } else { - cli_error_arg(cli, "Buck converter mode expected (pwm, pfm or auto)."); - return; - } - - if (cli_arg_count(cli) > 1) { - cli_error_arg_count(cli); - return; - } - - cli_trace(cli, "Setting the buck converter mode..."); - - if (!npm1300_set_buck_mode(buck_mode)) { - cli_error(cli, CLI_ERROR, "Failed to set buck converter mode."); - return; - } - - cli_ok(cli, ""); -} - -static void prodtest_pmic_report(cli_t* cli) { - uint32_t count = 1; - uint32_t period = 1000; - - if (cli_has_arg(cli, "count") && !cli_arg_uint32(cli, "count", &count)) { - cli_error_arg(cli, "Expecting count of measurements."); - return; - } - - if (cli_has_arg(cli, "period") && !cli_arg_uint32(cli, "period", &period)) { - cli_error_arg(cli, "Expecting period in milliseconds."); - return; - } - - if (cli_arg_count(cli) > 2) { - cli_error_arg_count(cli); - return; - } - - cli_trace(cli, - " time vbat ibat ntc vsys die bat buck mode"); - - uint32_t ticks = hal_ticks_ms(); - - while (count-- > 0) { - npm1300_report_t report; - - if (!npm1300_measure_sync(&report)) { - cli_error(cli, CLI_ERROR, "Failed to get NPM1300 report."); - return; - } - - const char* state = "IDLE"; - - bool ibat_discharging = ((report.ibat_meas_status >> 2) & 0x03) == 1; - bool ibat_charging = ((report.ibat_meas_status >> 2) & 0x03) == 3; - - if (ibat_discharging) { - state = "DISCHARGING"; - } else if (ibat_charging) { - state = "CHARGING"; - } - - cli_progress( - cli, "%09d %d.%03d %d.%03d %d.%03d %d.%03d %d.%03d 0x%02X 0x%02X %s", - ticks, (int)report.vbat, (int)(report.vbat * 1000) % 1000, - (int)report.ibat, (int)abs(report.ibat * 1000) % 1000, - (int)report.ntc_temp, (int)abs(report.ntc_temp * 1000) % 1000, - (int)report.vsys, (int)(report.vsys * 1000) % 1000, - (int)report.die_temp, (int)abs(report.die_temp * 1000) % 1000, - report.ibat_meas_status, report.buck_status, state); - - if (count > 0) { - do { - if (cli_aborted(cli)) { - return; - } - } while (!ticks_expired(ticks + period)); - ticks += period; - } - } - - cli_ok(cli, ""); -} - -// ut-pmic-init-deinit -// This unit test verifies the PMIC driver initialization and deinitialization -// routine could be called repeatably witout failure. It should verify that all -// driver components are properly cleaned by deinit function. -static ut_status_t ut_pmic_init_deinit() { - ut_status_t ut_result = UT_PASSED; - - for (uint8_t i = 0; i < 5; i++) { - // deinitilize the pmic driver - npm1300_deinit(); - if (npm1300_init() == false) { - ut_result = UT_FAILED; - break; - } - } - - npm1300_deinit(); - - return ut_result; -} - -// ut-pmic-battery -// This unit test verifies the battery connection to NPM1300 PMIC. -// Firstly it initilize the PMIC driver and request the measurement -// report. From the measurement report it checks, if the battery voltage and -// NTC temperature are within the expeted range. At last, it checks if NTC -// temperature measurement is not too far away from the die temperarture. -static ut_status_t ut_pmic_battery() { - ut_status_t ut_result = UT_PASSED; - npm1300_report_t report; - - if (npm1300_init() == false) { - ut_result = UT_FAILED; - } else { - // Request mesaurement report from PMIC - if (npm1300_measure_sync(&report) == false) { - ut_result = UT_FAILED; - } else { - // Battery voltage outside given range - if (report.vbat < 3.0 || report.vbat > 3.8) { - ut_result = UT_FAILED; - } - - // Battery NTC outside given range - if (report.ntc_temp < -40.0 || report.ntc_temp > 50.0) { - ut_result = UT_FAILED; - } - - // Battery NTC too far from die temp - if (abs(report.ntc_temp - report.die_temp) > 10.0) { - ut_result = UT_FAILED; - } - } - } - - npm1300_deinit(); - return ut_result; -} - -// clang-format off - -PRODTEST_CLI_CMD( - .name = "pmic-init", - .func = prodtest_pmic_init, - .info = "Initialize the PMIC driver", - .args = "" -); - -PRODTEST_CLI_CMD( - .name = "pmic-charge-enable", - .func = prodtest_pmic_charge_enable, - .info = "Enable battery charging", - .args = "" -); - -PRODTEST_CLI_CMD( - .name = "pmic-charge-disable", - .func = prodtest_pmic_charge_disable, - .info = "Disable battery charging", - .args = "" -); - -PRODTEST_CLI_CMD( - .name = "pmic-charge-set-limit", - .func = prodtest_pmic_charge_set_limit, - .info = "Set the battery charging limit", - .args = "" -); - -PRODTEST_CLI_CMD( - .name = "pmic-buck-set-mode", - .func = prodtest_pmic_buck_set_mode, - .info = "Set the buck converter mode", - .args = "" -) - -PRODTEST_CLI_CMD( - .name = "pmic-report", - .func = prodtest_pmic_report, - .info = "Retrieve PMIC report", - .args = "[] []" -); - -REGISTER_UNIT_TEST( - .name = "ut-pmic-init-deinit", - .func = ut_pmic_init_deinit, - .info = "Test PMIC driver initialization and deinitialization", -) - -REGISTER_UNIT_TEST( - .name = "ut-pmic-battery", - .func = ut_pmic_battery, - .info = "Test PMIC battery connection", -) - -#endif // USE_POWERCTL diff --git a/core/embed/projects/prodtest/cmd/prodtest_power_manager.c b/core/embed/projects/prodtest/cmd/prodtest_power_manager.c index 281ba9f995..0c2e08a00a 100644 --- a/core/embed/projects/prodtest/cmd/prodtest_power_manager.c +++ b/core/embed/projects/prodtest/cmd/prodtest_power_manager.c @@ -65,7 +65,41 @@ void prodtest_pm_suspend(cli_t* cli) { cli_ok(cli, ""); } -void prodtest_pm_watch(cli_t* cli) { +void prodtest_pm_charge_disable(cli_t* cli) { + if (cli_arg_count(cli) > 0) { + cli_error_arg_count(cli); + return; + } + + cli_trace(cli, "Enabling battery charging"); + + pm_status_t status = pm_charging_disable(); + if (status != PM_OK) { + cli_error(cli, CLI_ERROR, "Failed to enable battery charging"); + return; + } + + cli_ok(cli, ""); +} + +void prodtest_pm_charge_enable(cli_t* cli) { + if (cli_arg_count(cli) > 0) { + cli_error_arg_count(cli); + return; + } + + cli_trace(cli, "Enabling battery charging"); + + pm_status_t status = pm_charging_enable(); + if (status != PM_OK) { + cli_error(cli, CLI_ERROR, "Failed to enable battery charging"); + return; + } + + cli_ok(cli, ""); +} + +void prodtest_pm_fuel_gauge_monitor(cli_t* cli) { if (cli_arg_count(cli) > 0) { cli_error_arg_count(cli); return; @@ -157,7 +191,7 @@ void prodtest_pm_report(cli_t* cli) { cli_ok(cli, ""); } -void prodtest_pm_monitor(cli_t* cli) { +void prodtest_pm_event_monitor(cli_t* cli) { if (cli_arg_count(cli) > 0) { cli_error_arg_count(cli); return; @@ -225,38 +259,52 @@ void prodtest_pm_monitor(cli_t* cli) { // clang-format off PRODTEST_CLI_CMD( - .name = "power-manager-monitor", - .func = prodtest_pm_monitor, - .info = "Run power manager monitor", - .args = "" -); - -PRODTEST_CLI_CMD( - .name = "power-manager-watch", - .func = prodtest_pm_watch, - .info = "Watch power manager reports", - .args = "" -); - -PRODTEST_CLI_CMD( - .name = "power-manager-report", - .func = prodtest_pm_report, - .info = "Get power manager report", - .args = "" -); - -PRODTEST_CLI_CMD( - .name = "power-manager-suspend", + .name = "pm-suspend", .func = prodtest_pm_suspend, .info = "Suspend the device to low-power mode", .args = "" ); PRODTEST_CLI_CMD( - .name = "power-manager-hibernate", + .name = "pm-hibernate", .func = prodtest_pm_hibernate, .info = "Hibernate the device into a near power-off state", .args = "" ); +PRODTEST_CLI_CMD( + .name = "pm-charge-enable", + .func = prodtest_pm_charge_enable, + .info = "Enable battery charging", + .args = "" +); + +PRODTEST_CLI_CMD( + .name = "pm-charge-disable", + .func = prodtest_pm_charge_disable, + .info = "Disable battery charging", + .args = "" +); + +PRODTEST_CLI_CMD( + .name = "pm-event-monitor", + .func = prodtest_pm_event_monitor, + .info = "Run power manager event monitor", + .args = "" +); + +PRODTEST_CLI_CMD( +.name = "pm-fuel-gauge-monitor", +.func = prodtest_pm_fuel_gauge_monitor, +.info = "Watch fuel gauge ", +.args = "" +); + +PRODTEST_CLI_CMD( + .name = "pm-report", + .func = prodtest_pm_report, + .info = "Get power manager report", + .args = "" +); + #endif /* USE POWER_MANAGER */ diff --git a/core/embed/projects/prodtest/cmd/prodtest_wpc.c b/core/embed/projects/prodtest/cmd/prodtest_wpc.c index e5b5299598..b2891014f9 100644 --- a/core/embed/projects/prodtest/cmd/prodtest_wpc.c +++ b/core/embed/projects/prodtest/cmd/prodtest_wpc.c @@ -17,165 +17,37 @@ * along with this program. If not, see . */ -#ifdef USE_POWERCTL +#ifdef USE_POWER_MANAGER #include #include #include +#include #include -#include "../../../sys/powerctl/stwlc38/stwlc38.h" - -static void prodtest_wpc_init(cli_t* cli) { - if (cli_arg_count(cli) > 0) { - cli_error_arg_count(cli); - return; - } - - cli_trace(cli, "Initializing the WPC driver..."); - - stwlc38_deinit(); - - if (!stwlc38_init()) { - cli_error(cli, CLI_ERROR, "Failed to initialize STWLC38."); - return; - } - - cli_ok(cli, ""); -} - -static void prodtest_wpc_enable(cli_t* cli) { - if (cli_arg_count(cli) > 0) { - cli_error_arg_count(cli); - return; - } - - cli_trace(cli, "Enabling STWLC38..."); - - if (!stwlc38_enable(true)) { - cli_error(cli, CLI_ERROR, "Failed to enable STWLC38."); - return; - } - - cli_ok(cli, ""); -} - -static void prodtest_wpc_disable(cli_t* cli) { - if (cli_arg_count(cli) > 0) { - cli_error_arg_count(cli); - return; - } - - cli_trace(cli, "Disabling STWLC38..."); - - if (!stwlc38_enable(false)) { - cli_error(cli, CLI_ERROR, "Failed to disable STWLC38."); - return; - } - - cli_ok(cli, ""); -} - -static void prodtest_wpc_vout_enable(cli_t* cli) { - if (cli_arg_count(cli) > 0) { - cli_error_arg_count(cli); - return; - } - - cli_trace(cli, "Enabling STWLC38 output..."); - - if (!stwlc38_enable_vout(true)) { - cli_error(cli, CLI_ERROR, "Failed to enable STWLC38 output."); - return; - } - - cli_ok(cli, ""); -} - -static void prodtest_wpc_vout_disable(cli_t* cli) { - if (cli_arg_count(cli) > 0) { - cli_error_arg_count(cli); - return; - } - - cli_trace(cli, "Disabling STWLC38 output..."); - - if (!stwlc38_enable_vout(false)) { - cli_error(cli, CLI_ERROR, "Failed to disable STWLC38 output."); - return; - } - - cli_ok(cli, ""); -} - -static void prodtest_wpc_report(cli_t* cli) { - uint32_t count = 1; - uint32_t period = 1000; - - if (cli_has_arg(cli, "count") && !cli_arg_uint32(cli, "count", &count)) { - cli_error_arg(cli, "Expecting count of measurements."); - return; - } - - if (cli_has_arg(cli, "timeout") && !cli_arg_uint32(cli, "timeout", &period)) { - cli_error_arg(cli, "Expecting period in milliseconds."); - return; - } - - if (cli_arg_count(cli) > 2) { - cli_error_arg_count(cli); - return; - } - - cli_trace( - cli, - " time ready vout_ready vrect vout icur tmeas opfreq ntc"); - - uint32_t ticks = hal_ticks_ms(); - - while (count-- > 0) { - stwlc38_report_t report; - - if (!stwlc38_get_report(&report)) { - cli_error(cli, CLI_ERROR, "Failed to get STWLC38 report."); - return; - } - - cli_progress(cli, "%09d %d %d %d.%03d %d.%03d %d.%03d %d.%03d %d %d.%03d", - ticks, report.ready ? 1 : 0, report.vout_ready ? 1 : 0, - (int)report.vrect, (int)abs(report.vrect * 1000) % 1000, - (int)report.vout, (int)(report.vout * 1000) % 1000, - (int)report.icur, (int)abs(report.icur * 1000) % 1000, - (int)report.tmeas, (int)abs(report.tmeas * 1000) % 1000, - report.opfreq, (int)report.ntc, - (int)abs(report.ntc * 1000) % 1000); - - if (count > 0) { - do { - if (cli_aborted(cli)) { - return; - } - } while (!ticks_expired(ticks + period)); - ticks += period; - } - } - - cli_ok(cli, ""); -} +#include "../stwlc38/stwlc38.h" static void prodtest_wpc_info(cli_t* cli) { + if (cli_arg_count(cli) > 0) { cli_error_arg_count(cli); return; } stwlc38_chip_info_t chip_info; + pm_status_t status_pm; + + // Deinit power manager to not interfere with STWLC38 + pm_deinit(); + + + stwlc38_init(); cli_trace(cli, "Reading STWLC38 info..."); if (!stwlc38_read_chip_info(&chip_info)) { cli_error(cli, CLI_ERROR, "Cannot read STWLC38 info."); - return; + goto cleanup; } char device_id[sizeof(chip_info.device_id) * 2 + 1]; @@ -183,7 +55,7 @@ static void prodtest_wpc_info(cli_t* cli) { if (!cstr_encode_hex(device_id, sizeof(device_id), chip_info.device_id, sizeof(chip_info.device_id))) { cli_error(cli, CLI_ERROR_FATAL, "Buffer too small."); - return; + goto cleanup; } cli_trace(cli, "chip_id 0x%d ", chip_info.chip_id); @@ -205,7 +77,27 @@ static void prodtest_wpc_info(cli_t* cli) { cli_trace(cli, " nvm_patch_err: 0x%X ", chip_info.nvm_patch_err); cli_trace(cli, " nvm_prod_info_err: 0x%X ", chip_info.nvm_prod_info_err); + + stwlc38_deinit(); + + // initlize power manager again + status_pm = pm_init(true); + if (status_pm != PM_OK) { + cli_error(cli, CLI_ERROR, "Failed to reinitialize power manager."); + return; + } + cli_ok(cli, ""); + +cleanup: + + // initlize power manager again + status_pm = pm_init(true); + if (status_pm != PM_OK) { + cli_error(cli, CLI_ERROR, "Failed to reinitialize power manager."); + return; + } + } static void prodtest_wpc_update(cli_t* cli) { @@ -214,12 +106,19 @@ static void prodtest_wpc_update(cli_t* cli) { return; } + pm_status_t status_pm; + + // Deinit power manager to not interfere with STWLC38 + pm_deinit(); + + stwlc38_init(); + cli_trace(cli, "Updating STWLC38..."); stwlc38_chip_info_t chip_info; if (!stwlc38_read_chip_info(&chip_info)) { cli_error(cli, CLI_ERROR, "Cannot read STWLC38 info."); - return; + goto cleanup; } if (chip_info.chip_rev == STWLC38_CUT_1_2) { @@ -228,7 +127,7 @@ static void prodtest_wpc_update(cli_t* cli) { cli_trace(cli, "STWLC38 chip revision 1.3"); } else { cli_error(cli, CLI_ERROR, "Unknown chip revision, update aborted."); - return; + goto cleanup; } // Update STWLC38 firmware and configuration @@ -238,57 +137,34 @@ static void prodtest_wpc_update(cli_t* cli) { if (status == false) { cli_error(cli, CLI_ERROR, "Failed to update STWLC38."); - return; + goto cleanup; } cli_trace(cli, "WPC update completed {%d ms}", update_time); + + stwlc38_deinit(); + + // initlize power manager again + status_pm = pm_init(true); + if (status_pm != PM_OK) { + cli_error(cli, CLI_ERROR, "Failed to reinitialize power manager."); + return; + } + cli_ok(cli, ""); + +cleanup: + + // initlize power manager again + status_pm = pm_init(true); + if (status_pm != PM_OK) { + cli_error(cli, CLI_ERROR, "Failed to reinitialize power manager."); + return; + } } // clang-format off -PRODTEST_CLI_CMD( - .name = "wpc-init", - .func = prodtest_wpc_init, - .info = "Initialize the WPC driver", - .args = "" -); - -PRODTEST_CLI_CMD( - .name = "wpc-enable", - .func = prodtest_wpc_enable, - .info = "Enable the WPC chip", - .args = "" -); - -PRODTEST_CLI_CMD( - .name = "wpc-disable", - .func = prodtest_wpc_disable, - .info = "Disable the WPC chip", - .args = "" -); - -PRODTEST_CLI_CMD( - .name = "wpc-out-enable", - .func = prodtest_wpc_vout_enable, - .info = "Enable WPC output", - .args = "" -); - -PRODTEST_CLI_CMD( - .name = "wpc-out-disable", - .func = prodtest_wpc_vout_disable, - .info = "Disable WPC output", - .args = "" -); - -PRODTEST_CLI_CMD( - .name = "wpc-report", - .func = prodtest_wpc_report, - .info = "Retrieve WPC report", - .args = "[] []" -); - PRODTEST_CLI_CMD( .name = "wpc-info", .func = prodtest_wpc_info, @@ -303,4 +179,4 @@ PRODTEST_CLI_CMD( .args = "" ); -#endif // USE_POWERCTL +#endif // USE_POWER_MANAGER diff --git a/core/embed/sys/power_manager/stm32u5/power_manager.c b/core/embed/sys/power_manager/stm32u5/power_manager.c index 08a68a35c6..c9ad5996ba 100644 --- a/core/embed/sys/power_manager/stm32u5/power_manager.c +++ b/core/embed/sys/power_manager/stm32u5/power_manager.c @@ -109,6 +109,10 @@ pm_status_t pm_init(bool skip_bootup_sequence) { void pm_deinit(void) { pm_driver_t* drv = &g_pm; + if(drv->fuel_gauge_initialized){ + pm_store_data_to_backup_ram(); + } + if (drv->monitoring_timer) { systimer_delete(drv->monitoring_timer); drv->monitoring_timer = NULL; @@ -121,6 +125,9 @@ void pm_deinit(void) { npm1300_deinit(); stwlc38_deinit(); + + drv->initialized = false; + } pm_status_t pm_get_events(pm_event_t* event_flags) { @@ -373,4 +380,5 @@ pm_status_t pm_wakeup_flags_get(pm_wakeup_flags_t *flags) { *flags = drv->wakeup_flags; irq_unlock(irq_key); return PM_OK; + } \ No newline at end of file