diff --git a/core/SConscript.prodtest b/core/SConscript.prodtest index 6627f780ac..cee126beaa 100644 --- a/core/SConscript.prodtest +++ b/core/SConscript.prodtest @@ -137,6 +137,7 @@ 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_get_cpuid.c', 'embed/projects/prodtest/cmd/prodtest_haptic.c', diff --git a/core/embed/projects/prodtest/README.md b/core/embed/projects/prodtest/README.md index 236383fdc4..26d859c759 100644 --- a/core/embed/projects/prodtest/README.md +++ b/core/embed/projects/prodtest/README.md @@ -969,6 +969,7 @@ Example: nfc-write_card # NFC reader on, put the card on the reader (timeout s) # Writting URI to NFC tag 7AF403 + ### unit-test-run Prodtest have capability to verify the overall firmware functionality by running built-in unit tests which should excercise the basic features of the firmware drivers. This command will run all registered unit tests and return 'OK' if all tests passed. @@ -991,3 +992,22 @@ Example: # ut-pmic-init-deinit - Test PMIC driver initialization and deinitialization OK ``` + +### fuel-gauge +Activates fuel gauge which monitors battery state of charge and reports it on +display and command line, exit the fuel gauge monitor with CTRL+C + +Example: +fuel-gauge +PROGRESS :V: 3.12 I: 122.13 SOC: 0.28 +PROGRESS :V: 3.12 I: 122.13 SOC: 0.28 +PROGRESS :V: 3.12 I: 122.13 SOC: 0.28 +CTRL+C pressed, exiting fuel gauge monitor +OK +``` + + + + + + diff --git a/core/embed/projects/prodtest/cmd/prodtest_fuel_gauge.c b/core/embed/projects/prodtest/cmd/prodtest_fuel_gauge.c new file mode 100644 index 0000000000..2c9b7be8d2 --- /dev/null +++ b/core/embed/projects/prodtest/cmd/prodtest_fuel_gauge.c @@ -0,0 +1,115 @@ +/* + * 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/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; + } + + cli_trace(cli, "Initializing the PMIC driver ..."); + if (!npm1300_init()) { + cli_error(cli, CLI_ERROR, "Failed to initialize PMIC driver."); + return; + } + + char display_text[100]; + + fuel_gauge_state_t fg; + + float Q = 0.001f; + float R = 3000.0f; + float R_agressive = 3000.0f; + float Q_agressive = 0.001f; + float P_init = 0.1; + + cli_trace(cli, "Initialize Fuel gauge."); + + void fuel_gauge_init(fuel_gauge_state_t * state, float R, float Q, + float R_aggressive, float Q_aggressive, float P_init); + + fuel_gauge_init(&fg, R, Q, R_agressive, Q_agressive, P_init); + + npm1300_report_t report; + if (!npm1300_measure_sync(&report)) { + cli_error(cli, CLI_ERROR, "Failed to measure 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 measure PMIC."); + break; + } + + fuel_gauge_update(&fg, systick_ms() - tick, report.vbat, report.ibat, + report.ntc_temp); + tick = systick_ms(); + + cli_progress(cli, "V: %d.%02d I: %d.%02d SOC: %d.%02d", (int)report.vbat, + (int)(report.vbat * 1000) % 1000, (int)report.ibat, + (int)(report.ibat * 1000) % 1000, (int)fg.soc, + (int)(fg.soc * 1000) % 1000); + + mini_snprintf(display_text, 100, "V: %d.%02d I: %d.%02d SOC: %d.%02d", + (int)report.vbat, (int)(report.vbat * 1000) % 1000, + (int)report.ibat, (int)(report.ibat * 1000) % 1000, + (int)fg.soc, (int)(fg.soc * 1000) % 1000); + screen_prodtest_show_text(display_text, strlen(display_text)); + + // Wait a second + systick_delay_ms(1000); + } + + cli_trace(cli, "Cleanup PMIC driver."); + npm1300_deinit(); +} + +// clang-format off + +PRODTEST_CLI_CMD( + .name = "fuel-gauge", + .func = prodtest_fuel_gauge, + .info = "Test fuel gauge", + .args = "" +); + +#endif // USE_POWERCTL \ No newline at end of file diff --git a/core/site_scons/models/T3W1/trezor_t3w1_revB.py b/core/site_scons/models/T3W1/trezor_t3w1_revB.py index 6f2db8e1da..1f2492163b 100644 --- a/core/site_scons/models/T3W1/trezor_t3w1_revB.py +++ b/core/site_scons/models/T3W1/trezor_t3w1_revB.py @@ -236,6 +236,8 @@ def configure( sources += [ "embed/sys/powerctl/npm1300/npm1300.c", + "embed/sys/powerctl/fuel_gauge/fuel_gauge.c", + "embed/sys/powerctl/fuel_gauge/battery_model.c", "embed/sys/powerctl/stwlc38/stwlc38.c", "embed/sys/powerctl/stwlc38/stwlc38_patching.c", "embed/sys/powerctl/stm32u5/powerctl.c", diff --git a/core/site_scons/models/T3W1/trezor_t3w1_revC.py b/core/site_scons/models/T3W1/trezor_t3w1_revC.py index e0e0562ae6..32f18f1c71 100644 --- a/core/site_scons/models/T3W1/trezor_t3w1_revC.py +++ b/core/site_scons/models/T3W1/trezor_t3w1_revC.py @@ -236,6 +236,8 @@ def configure( sources += [ "embed/sys/powerctl/npm1300/npm1300.c", + "embed/sys/powerctl/fuel_gauge/fuel_gauge.c", + "embed/sys/powerctl/fuel_gauge/battery_model.c", "embed/sys/powerctl/stwlc38/stwlc38.c", "embed/sys/powerctl/stwlc38/stwlc38_patching.c", "embed/sys/powerctl/stm32u5/powerctl.c",