feat(core): introduce battery cycle counter.
What changed, and why it matters
This commit adds a new internal counter that tracks how much charge has flowed through the device's battery over time, similar to an odometer for battery wear. The counter is calculated and stored in memory, but the code that would actually report or save the value is commented out and not active. There is no security-relevant change here.
No security action required. If the telemetry integration is later enabled, ensure the cycle counter value is treated as diagnostic data and does not leak sensitive usage patterns unexpectedly.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch introduces a floating-point battery cycle counter in the battery driver. It accumulates |current| * dt / (2 * total_capacity) during bat_fg_update() and exposes bat_fetch_cycle_increment() to read and reset the counter. The only consumer in power_manager.c calls the fetch function but the result is unused and the telemetry integration is entirely commented out. No memory safety, cryptographic, access-control, or integrity changes are present.
Changed components
core/embed/io/power_manager/battery/battery.ccore/embed/io/power_manager/battery/battery.hcore/embed/io/power_manager/stm32u5/power_manager.cInspect captured patch +43 / −1
diff --git a/core/embed/io/power_manager/battery/battery.c b/core/embed/io/power_manager/battery/battery.c
index 7756e3bc6..be441fd88 100644
--- a/core/embed/io/power_manager/battery/battery.c
+++ b/core/embed/io/power_manager/battery/battery.c
@@ -24,6 +24,7 @@
#include "battery.h"
#include "battery_model.h"
#include "fuel_gauge.h"
+#include "math.h"
typedef struct {
float voltage_V;
@@ -48,6 +49,8 @@ typedef struct {
battery_model_t battery_model;
bat_sample_buffer_t sample_buf;
+ float cycle_counter;
+
} bat_driver_t;
bat_driver_t g_bat_driver = {
@@ -60,7 +63,6 @@ void bat_init(void) {
if (drv->initialized) {
return; // Already initialized
}
-
memset(drv, 0, sizeof(bat_driver_t));
battery_model_init(&drv->battery_model);
@@ -197,6 +199,10 @@ ts_t bat_fg_update(uint32_t dt_ms, float voltage_V, float current_mA,
return TS_EINVAL;
}
+ drv->cycle_counter += (fabsf(current_mA) * ((float)dt_ms / 3600000.0f)) /
+ (2 * battery_total_capacity(&drv->battery_model, 25.0f,
+ current_mA >= 0.0f));
+
fuel_gauge_update(&drv->fg_state, &drv->battery_model, dt_ms, voltage_V,
current_mA, temp_C);
@@ -224,6 +230,18 @@ ts_t bat_fg_compensate_soc(float* soc, uint32_t elapsed_s,
return TS_OK;
}
+float bat_fetch_cycle_increment(void) {
+ bat_driver_t* drv = &g_bat_driver;
+
+ if (!drv->initialized) {
+ return 0.0f;
+ }
+
+ float cycle_increment = (float)((uint16_t)drv->cycle_counter);
+ drv->cycle_counter = 0.0f;
+ return cycle_increment;
+}
+
float bat_soc_to_ocv(float soc, float temp_C, bool discharging_mode) {
bat_driver_t* drv = &g_bat_driver;
diff --git a/core/embed/io/power_manager/battery/battery.h b/core/embed/io/power_manager/battery/battery.h
index 9f99d0981..c811b204b 100644
--- a/core/embed/io/power_manager/battery/battery.h
+++ b/core/embed/io/power_manager/battery/battery.h
@@ -153,6 +153,21 @@ ts_t bat_fg_update(uint32_t dt_ms, float voltage_V, float current_mA,
ts_t bat_fg_compensate_soc(float* soc, uint32_t elapsed_s,
float avg_bat_current_mA, float avg_temp_C);
+/**
+ * @brief Fetch battery cycle count increment from the fuel gauge.
+ *
+ * Battery driver maintains an internal cycle counter based on the accumulated
+ * current throughput. This function retrieves the number reflecting the number
+ * of full charge-discharge cycles completed since the last fetch.
+ *
+ * calculation example:
+ * cycle_count = sum(current_mA * dt_hours) / (2 *
+ * battery_total_capacity_mah(@25C))
+ *
+ * @return Number of full charge-discharge cycles completed since last fetch
+ */
+float bat_fetch_cycle_increment(void);
+
/**
* @brief Convert battery SOC to OCV according to the battery model at given
* temperature point.
diff --git a/core/embed/io/power_manager/stm32u5/power_manager.c b/core/embed/io/power_manager/stm32u5/power_manager.c
index e8b89dea1..ab3a1d077 100644
--- a/core/embed/io/power_manager/stm32u5/power_manager.c
+++ b/core/embed/io/power_manager/stm32u5/power_manager.c
@@ -526,6 +526,15 @@ pm_status_t pm_store_data_to_backup_ram() {
return PM_ERROR;
}
+ /* Update battery cycle counter telemetry */
+ // float cycle_increment = bat_fetch_cycle_increment();
+ //
+ // Add cycle increment to telemetry
+ // #ifdef USE_TELEMETRY
+ // telemetry_add_battery_cycle_increment(cycle_increment);
+ // #endif
+ //
+
return PM_OK;
}
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.