feat(core/prodtest): add pm-battery-test command to prodtest.
What changed, and why it matters
This commit adds a new factory-testing command called pm-battery-test to Trezor's production-test firmware. It simply reads the battery voltage and temperature several times and reports whether the values are within expected hardware limits. There is no user-facing wallet feature, no handling of secrets, and no security-relevant change.
No security action required. Treat as a normal feature addition to production-test tooling.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change introduces prodtest_pm_battery_test() in core/embed/projects/prodtest/cmd/prodtest_power_manager.c. The function is registered as a PRODTEST_CLI_CMD named pm-battery-test. It optionally accepts a tested_samples argument (default 10), calls pm_get_report() in a loop, checks battery_voltage_v against (2.95, 3.65) V and battery_temp_c against (-10, 65) °C, prints PROGRESS lines, and returns OK or ERROR. It also updates the prodtest README and adds a changelog fragment. No cryptographic, authentication, or secret-handling code is modified.
Changed components
core/embed/projects/prodtest/cmd/prodtest_power_manager.ccore/embed/projects/prodtest/README.mdcore/embed/projects/prodtest/.changelog.d/6333.addedInspect captured patch +103 / −0
diff --git a/core/embed/projects/prodtest/.changelog.d/6333.added b/core/embed/projects/prodtest/.changelog.d/6333.added
new file mode 100644
index 000000000..fbd772cfe
--- /dev/null
+++ b/core/embed/projects/prodtest/.changelog.d/6333.added
@@ -0,0 +1 @@
+add pm-battery-test command to improve test coverage in production.
diff --git a/core/embed/projects/prodtest/README.md b/core/embed/projects/prodtest/README.md
index 1da37d634..072407ad8 100644
--- a/core/embed/projects/prodtest/README.md
+++ b/core/embed/projects/prodtest/README.md
@@ -1072,6 +1072,31 @@ pm-hibernate
OK
```
+### pm-battery-test
+Acquire <tested_samples> (default=10) battery measurements and check
+the following criteria to pass the test
+ - Every sample battery voltage is within range <2.95, 3.65> V
+ - Every sample NTC temperature is within range <-10, 65> °C
+
+In case any sample fails the test, the line is marked with `!` and test
+ends up with `ERROR error "Battery test failed."`.
+
+Example:
+```
+> pm-battery-test [<tested_samples>]
+PROGRESS Sample 1: Voltage 3.445 V, Temp 23.874 C
+PROGRESS Sample 2: Voltage 3.450 V, Temp 23.874 C
+PROGRESS Sample 3: Voltage 3.445 V, Temp 23.772 C
+PROGRESS Sample 4: Voltage 3.445 V, Temp 23.670 C
+PROGRESS Sample 5: Voltage 3.450 V, Temp 23.772 C
+PROGRESS Sample 6: Voltage 3.445 V, Temp 23.874 C
+PROGRESS Sample 7: Voltage 3.445 V, Temp 23.772 C
+PROGRESS Sample 8: Voltage 3.445 V, Temp 23.670 C
+PROGRESS Sample 9: Voltage 3.445 V, Temp 23.772 C
+PROGRESS Sample 10: Voltage 3.445 V, Temp 23.874 C
+OK Battery test passed.
+```
+
### tamper-read
Reads the state of the tamper detection inputs.
Up to 8 inputs can be read, each represented by a single bit in the response.
diff --git a/core/embed/projects/prodtest/cmd/prodtest_power_manager.c b/core/embed/projects/prodtest/cmd/prodtest_power_manager.c
index 4e7cc8f21..4852c87f7 100644
--- a/core/embed/projects/prodtest/cmd/prodtest_power_manager.c
+++ b/core/embed/projects/prodtest/cmd/prodtest_power_manager.c
@@ -375,6 +375,76 @@ void prodtest_pm_new_soc_estimate(cli_t* cli) {
cli_error(cli, CLI_ERROR, "failed to reboot");
}
+void prodtest_pm_battery_test(cli_t* cli) {
+ uint32_t tested_samples = 10;
+
+ if (cli_has_arg(cli, "tested_samples")) {
+ if (!cli_arg_uint32(cli, "tested_samples", &tested_samples)) {
+ cli_error_arg(cli,
+ "tested_samples argument is expected in integer format.");
+ return;
+ }
+
+ if (cli_arg_count(cli) > 1) {
+ cli_error_arg_count(cli);
+ return;
+ }
+
+ } else {
+ if (cli_arg_count(cli) > 0) {
+ cli_error_arg_count(cli);
+ return;
+ }
+ }
+
+ bool passed = true;
+
+ /** Acquire <tested_samples> battery measurements and check
+ * the following criteria to pass the test
+ * - Every sample battery voltage is within range <2.95, 3,65> V
+ * - Every sample NTC temperature is within range <-10,65> °C
+ */
+ for (uint8_t i = 0; i < tested_samples; i++) {
+ if (cli_aborted(cli)) {
+ cli_error(cli, CLI_ERROR, "Aborted.");
+ goto cleanup;
+ }
+
+ pm_report_t report;
+ pm_status_t status = pm_get_report(&report);
+ if (status != PM_OK) {
+ cli_error(cli, CLI_ERROR, "Failed to get power manager report.");
+ goto cleanup;
+ }
+
+ char* err_mark = "";
+
+ if (report.battery_voltage_v < 2.95f || report.battery_voltage_v > 3.65f ||
+ report.battery_temp_c < -10.0f || report.battery_temp_c > 65.0f) {
+ passed = false;
+ err_mark = "!";
+ }
+
+ cli_progress(cli, "Sample %d: Voltage %d.%03d V, Temp %d.%03d C %s", i + 1,
+ (int)report.battery_voltage_v,
+ (int)(report.battery_voltage_v * 1000) % 1000,
+ (int)report.battery_temp_c,
+ (int)(report.battery_temp_c * 1000) % 1000, err_mark);
+
+ systick_delay_ms(100);
+ }
+
+ if (passed) {
+ cli_ok(cli, "Battery test passed.");
+ } else {
+ cli_error(cli, CLI_ERROR, "Battery test failed.");
+ }
+
+cleanup:
+ prodtest_show_homescreen();
+ return;
+}
+
// clang-format off
PRODTEST_CLI_CMD(
@@ -440,4 +510,11 @@ PRODTEST_CLI_CMD(
.args = ""
);
+PRODTEST_CLI_CMD(
+ .name = "pm-battery-test",
+ .func = prodtest_pm_battery_test,
+ .info = "Run battery voltage and temperature test",
+ .args = "[<tested_samples>]"
+)
+
#endif /* USE_POWER_MANAGER */
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.