From d0c1458a19a3dd87f5758260bfaff49bdb26182e Mon Sep 17 00:00:00 2001 From: kopecdav Date: Mon, 23 Jun 2025 14:30:50 +0200 Subject: [PATCH] feat(core/prodtest): add pm-new-soc-estimate command. [no changelog] --- core/embed/projects/prodtest/README.md | 10 ++++++ .../prodtest/cmd/prodtest_power_manager.c | 33 +++++++++++++++++++ .../embed/sys/backup_ram/inc/sys/backup_ram.h | 11 +++++++ .../embed/sys/backup_ram/stm32u5/backup_ram.c | 15 +++++++++ 4 files changed, 69 insertions(+) diff --git a/core/embed/projects/prodtest/README.md b/core/embed/projects/prodtest/README.md index 4ca4d96edc..7f901d8da5 100644 --- a/core/embed/projects/prodtest/README.md +++ b/core/embed/projects/prodtest/README.md @@ -712,6 +712,16 @@ optiga-counter-read OK 0E ``` +### pm-new-soc-estimate +Erase power manager recovery data from the backup RAM and immediately reboot the device to run new battery SoC estimate. + +Example: +``` +pm-new-soc-estimate +# Erasing backup RAM and rebooting... +OK +``` + ### pm-set-soc-limit Sets the battery state of charge (SOC) limit. The SOC limit is a percentage value between 10 and 100. diff --git a/core/embed/projects/prodtest/cmd/prodtest_power_manager.c b/core/embed/projects/prodtest/cmd/prodtest_power_manager.c index 93edcf0c00..1e1173978d 100644 --- a/core/embed/projects/prodtest/cmd/prodtest_power_manager.c +++ b/core/embed/projects/prodtest/cmd/prodtest_power_manager.c @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include #include #include @@ -410,6 +412,30 @@ void prodtest_pm_set_soc_limit(cli_t* cli) { cli_ok(cli, ""); } +void prodtest_pm_new_soc_estimate(cli_t* cli) { + if (cli_arg_count(cli) > 0) { + cli_error_arg_count(cli); + return; + } + + // Run new battery SoC initialization by erasing the recovery data from + // backup RAM followed by forced imediate reboot. + + cli_trace(cli, "Erasing backup RAM and rebooting..."); + cli_ok(cli, ""); + systick_delay_ms(100); + + // Deinitialize power manager so the monitor stop feeding the recovery data + // to backup RAM. + pm_deinit(); + + // Erase PM recovery data from backup RAM + backup_ram_erase_item(BACKUP_RAM_KEY_PM_RECOVERY); + reboot_device(); + + cli_error(cli, CLI_ERROR, "failed to reboot"); +} + // clang-format off PRODTEST_CLI_CMD( @@ -475,4 +501,11 @@ PRODTEST_CLI_CMD( .args = "" ); +PRODTEST_CLI_CMD( + .name = "pm-new-soc-estimate", + .func = prodtest_pm_new_soc_estimate, + .info = "Run new battery SoC initialization", + .args = "" +); + #endif /* USE_POWER_MANAGER */ diff --git a/core/embed/sys/backup_ram/inc/sys/backup_ram.h b/core/embed/sys/backup_ram/inc/sys/backup_ram.h index 4cced0f8fc..26e5332e7c 100644 --- a/core/embed/sys/backup_ram/inc/sys/backup_ram.h +++ b/core/embed/sys/backup_ram/inc/sys/backup_ram.h @@ -54,6 +54,17 @@ void backup_ram_deinit(void); bool backup_ram_erase(void); +/** + * @brief Erases a single item in backup RAM by its key. + * + * If the item with the given key does not exist, the function does nothing. + * + * @param key Key of the item to erase + * + * @return true if the operation was successful, false otherwise. + */ +bool backup_ram_erase_item(uint16_t key); + #define BACKUP_RAM_INVALID_KEY 0xFFFF /** diff --git a/core/embed/sys/backup_ram/stm32u5/backup_ram.c b/core/embed/sys/backup_ram/stm32u5/backup_ram.c index e2fcaf0dde..d4cca18f89 100644 --- a/core/embed/sys/backup_ram/stm32u5/backup_ram.c +++ b/core/embed/sys/backup_ram/stm32u5/backup_ram.c @@ -354,6 +354,21 @@ uint16_t backup_ram_search(uint16_t min_key) { return key; } +bool backup_ram_erase_item(uint16_t key) { + backup_ram_driver_t* drv = &g_backup_ram_driver; + + if (!drv->initialized) { + return false; + } + + // Writing NULL data will just remove the item with the given key + irq_key_t irq_key = irq_lock(); + bool status = backup_ram_write(key, NULL, 0); + irq_unlock(irq_key); + + return status; +} + bool backup_ram_read(uint16_t key, void* buffer, size_t buffer_size, size_t* data_size) { bool success = false;