summaryrefslogtreecommitdiffstats
path: root/firmware
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2021-12-31 16:47:44 +0000
committerAidan MacDonald <amachronic@protonmail.com>2022-01-02 20:11:03 +0000
commitaf872b54ec3f8f7ad6ec111e4fe80dd2c7ac9946 (patch)
tree83b03175ca50757359d98d2ad965ca8dfdfc773f /firmware
parenta7703e4926075ee41269ca96d1806444107e65f2 (diff)
downloadrockbox-af872b54ec3f8f7ad6ec111e4fe80dd2c7ac9946.tar.gz
rockbox-af872b54ec3f8f7ad6ec111e4fe80dd2c7ac9946.zip
powermgmt: Bugfixes to time estimation code
Guard against division by zero and prevent the time_now value from going negative if the counter drops below zero. Change-Id: Ia8cadfe76086d6d0200964c1f27bab0be708b135
Diffstat (limited to 'firmware')
-rw-r--r--firmware/powermgmt.c31
1 files changed, 19 insertions, 12 deletions
diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c
index 0f5b104d7c..2cafd4b759 100644
--- a/firmware/powermgmt.c
+++ b/firmware/powermgmt.c
@@ -392,17 +392,20 @@ static void battery_status_update(void)
int current = battery_current();
int resolution = battery_capacity * 36;
- int time_est;
+ int time_est = 0;
+ if(level >= 0 && current > 0) {
#if CONFIG_CHARGING >= CHARGING_MONITOR
- if (charging_state())
- time_est = (100 - level) * battery_capacity * 36 / current;
- else
+ if (charging_state())
+ time_est = (100 - level) * battery_capacity * 36 / current;
+ else
#endif
- time_est = level * battery_capacity * 36 / current;
+ time_est = level * battery_capacity * 36 / current;
+
+ /* The first term nudges the counter toward the estimate. */
+ time_err += current * (time_est - time_cnt);
+ }
- /* The first term nudges the counter toward the estimate.
- * The second term decrements the counter due to elapsed time. */
- time_err += current * (time_est - time_cnt);
+ /* The second term decrements the counter due to elapsed time. */
time_err -= resolution;
/* Arbitrary cutoff to ensure we don't get too far out
@@ -413,13 +416,17 @@ static void battery_status_update(void)
time_err = 0;
}
- /* Convert the error into a time and adjust the counter. */
- int64_t adjustment = time_err / (2 * resolution);
- time_cnt += adjustment;
- time_err -= adjustment * (2 * resolution);
+ if(resolution > 0) {
+ /* Convert the error into a time and adjust the counter. */
+ int64_t adjustment = time_err / (2 * resolution);
+ time_cnt += adjustment;
+ time_err -= adjustment * (2 * resolution);
+ }
/* Update the reported time based on the counter. */
time_now = (time_cnt + 30) / 60;
+ if(time_now < 0)
+ time_now = 0;
#endif
percent_now = level;