summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2021-11-30 01:26:59 +0000
committerAidan MacDonald <amachronic@protonmail.com>2021-12-05 15:11:34 -0500
commitf02cd18ad027cdb4992a19a16cfbd336ffb63124 (patch)
treea412532ad38baac5390015d89696a5f67eaabe57
parent8a8dfa0e52d0d7001d52ff29a2da60986b3e5101 (diff)
downloadrockbox-f02cd18ad027cdb4992a19a16cfbd336ffb63124.tar.gz
rockbox-f02cd18ad027cdb4992a19a16cfbd336ffb63124.zip
powermgmt: Refactor battery current estimation
Create a new battery_current() function to report the the battery's charging/discharging current. Move the old runcurrent() implementation into it and clean up some of the related defines. Change-Id: I7dbe5b6532d291fa72add1cb23b30e3cbac8c3ca
-rw-r--r--firmware/export/config/iaudiox5.h1
-rw-r--r--firmware/export/config/ipod6g.h1
-rw-r--r--firmware/export/config/mrobe500.h2
-rw-r--r--firmware/export/config/samsungypr0.h1
-rw-r--r--firmware/export/config/samsungypr1.h1
-rw-r--r--firmware/export/powermgmt.h19
-rw-r--r--firmware/powermgmt.c75
7 files changed, 45 insertions, 55 deletions
diff --git a/firmware/export/config/iaudiox5.h b/firmware/export/config/iaudiox5.h
index 0164cd20fa..cae83dd952 100644
--- a/firmware/export/config/iaudiox5.h
+++ b/firmware/export/config/iaudiox5.h
@@ -151,6 +151,7 @@
151#define CURRENT_NORMAL 65 /*2250mah/35h = 65 ma*/ 151#define CURRENT_NORMAL 65 /*2250mah/35h = 65 ma*/
152#define CURRENT_BACKLIGHT 25 152#define CURRENT_BACKLIGHT 25
153#define CURRENT_REMOTE 8 /* additional current when remote connected */ 153#define CURRENT_REMOTE 8 /* additional current when remote connected */
154#define CURRENT_RECORD 2 /* FIXME: placeholder value */
154 155
155/* Define this if your LCD can set contrast */ 156/* Define this if your LCD can set contrast */
156#define HAVE_LCD_CONTRAST 157#define HAVE_LCD_CONTRAST
diff --git a/firmware/export/config/ipod6g.h b/firmware/export/config/ipod6g.h
index fdf7e8e516..2e4afbdf63 100644
--- a/firmware/export/config/ipod6g.h
+++ b/firmware/export/config/ipod6g.h
@@ -158,6 +158,7 @@
158/* define current usage levels */ 158/* define current usage levels */
159#define CURRENT_NORMAL 18 /* playback @48MHz clock, backlight off */ 159#define CURRENT_NORMAL 18 /* playback @48MHz clock, backlight off */
160#define CURRENT_BACKLIGHT 23 /* maximum brightness */ 160#define CURRENT_BACKLIGHT 23 /* maximum brightness */
161#define CURRENT_RECORD 2 /* FIXME: placeholder value */
161 162
162/* define this if the unit can be powered or charged via USB */ 163/* define this if the unit can be powered or charged via USB */
163#define HAVE_USB_POWER 164#define HAVE_USB_POWER
diff --git a/firmware/export/config/mrobe500.h b/firmware/export/config/mrobe500.h
index a7d72f76ac..ffc8a6bfb8 100644
--- a/firmware/export/config/mrobe500.h
+++ b/firmware/export/config/mrobe500.h
@@ -198,7 +198,7 @@
198/* define current usage levels */ 198/* define current usage levels */
199#define CURRENT_NORMAL 85 /* Measured */ 199#define CURRENT_NORMAL 85 /* Measured */
200#define CURRENT_BACKLIGHT 200 /* Over 200 mA total measured when on */ 200#define CURRENT_BACKLIGHT 200 /* Over 200 mA total measured when on */
201#define CURRENT_RECORD 0 /* no recording */ 201#define CURRENT_REMOTE 2 /* FIXME: placeholder value */
202 202
203/* Hardware controlled charging with monitoring */ 203/* Hardware controlled charging with monitoring */
204#define CONFIG_CHARGING CHARGING_MONITOR 204#define CONFIG_CHARGING CHARGING_MONITOR
diff --git a/firmware/export/config/samsungypr0.h b/firmware/export/config/samsungypr0.h
index 520eb08d01..88ba96504d 100644
--- a/firmware/export/config/samsungypr0.h
+++ b/firmware/export/config/samsungypr0.h
@@ -121,6 +121,7 @@
121/* Define current usage levels. */ 121/* Define current usage levels. */
122#define CURRENT_NORMAL 24 /* ~25h, on 600mAh that's about 24mA */ 122#define CURRENT_NORMAL 24 /* ~25h, on 600mAh that's about 24mA */
123#define CURRENT_BACKLIGHT 62 /* ~6,5h -> 92mA. Minus 24mA normal that gives us 68mA */ 123#define CURRENT_BACKLIGHT 62 /* ~6,5h -> 92mA. Minus 24mA normal that gives us 68mA */
124#define CURRENT_RECORD 2 /* FIXME: placeholder value */
124 125
125#endif /* SIMULATOR */ 126#endif /* SIMULATOR */
126 127
diff --git a/firmware/export/config/samsungypr1.h b/firmware/export/config/samsungypr1.h
index 50abfa323e..8ef76d60af 100644
--- a/firmware/export/config/samsungypr1.h
+++ b/firmware/export/config/samsungypr1.h
@@ -163,5 +163,6 @@
163/* Define current usage levels. */ 163/* Define current usage levels. */
164#define CURRENT_NORMAL 24 /* ~25h, on 600mAh that's about 24mA */ 164#define CURRENT_NORMAL 24 /* ~25h, on 600mAh that's about 24mA */
165#define CURRENT_BACKLIGHT 62 /* ~6,5h -> 92mA. Minus 24mA normal that gives us 68mA */ 165#define CURRENT_BACKLIGHT 62 /* ~6,5h -> 92mA. Minus 24mA normal that gives us 68mA */
166#define CURRENT_RECORD 2 /* FIXME: placeholder value */
166 167
167#endif /* SIMULATOR */ 168#endif /* SIMULATOR */
diff --git a/firmware/export/powermgmt.h b/firmware/export/powermgmt.h
index a4b924915c..c6fc3d5bdf 100644
--- a/firmware/export/powermgmt.h
+++ b/firmware/export/powermgmt.h
@@ -81,28 +81,13 @@ void powermgmt_init(void) INIT_ATTR;
81/* Generic current values that are intentionally meaningless - config header 81/* Generic current values that are intentionally meaningless - config header
82 * should define proper numbers.*/ 82 * should define proper numbers.*/
83 83
84
85#ifndef CURRENT_BACKLIGHT
86#define CURRENT_BACKLIGHT 5 /* additional current when backlight always on */
87#endif
88
89#if defined(HAVE_RECORDING) && !defined(CURRENT_RECORD)
90#define CURRENT_RECORD 2 /* additional recording current */
91#endif /* HAVE_RECORDING && !CURRENT_RECORD*/
92
93#ifndef CURRENT_USB 84#ifndef CURRENT_USB
94#define CURRENT_USB 2 /* usual current in mA in USB mode */ 85#define CURRENT_USB 2 /* usual current in mA in USB mode */
95#endif 86#endif
96 87
97#if defined(HAVE_REMOTE_LCD) && !defined(CURRENT_REMOTE) 88#if CONFIG_CHARGING && !defined(CURRENT_MAX_CHG)
98#define CURRENT_REMOTE 2 /* additional current when remote connected */
99#endif /* CURRENT_REMOTE && !HAVE_REMOTE_LCD */
100
101#if CONFIG_CHARGING
102#ifndef CURRENT_MAX_CHG
103#define CURRENT_MAX_CHG 350 /* maximum charging current */ 89#define CURRENT_MAX_CHG 350 /* maximum charging current */
104#endif 90#endif
105#endif /* CONFIG_CHARGING */
106 91
107#ifndef BATT_AVE_SAMPLES 92#ifndef BATT_AVE_SAMPLES
108/* slw filter constant unless otherwise specified */ 93/* slw filter constant unless otherwise specified */
@@ -126,6 +111,8 @@ extern const unsigned short percent_to_volt_charge[11];
126int battery_level(void); /* percent */ 111int battery_level(void); /* percent */
127int battery_time(void); /* minutes */ 112int battery_time(void); /* minutes */
128int battery_voltage(void); /* filtered batt. voltage in millivolts */ 113int battery_voltage(void); /* filtered batt. voltage in millivolts */
114int battery_current(void); /* battery current in milliamps
115 * (may just be a rough estimate) */
129 116
130/* Implemented by the target, unfiltered */ 117/* Implemented by the target, unfiltered */
131int _battery_level(void); /* percent */ 118int _battery_level(void); /* percent */
diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c
index 313486889e..13e810e926 100644
--- a/firmware/powermgmt.c
+++ b/firmware/powermgmt.c
@@ -83,7 +83,7 @@ void handle_auto_poweroff(void);
83static int poweroff_timeout = 0; 83static int poweroff_timeout = 0;
84static long last_event_tick = 0; 84static long last_event_tick = 0;
85 85
86#if (CONFIG_BATTERY_MEASURE & PERCENTAGE_MEASURE) == PERCENTAGE_MEASURE 86#if CONFIG_BATTERY_MEASURE & PERCENTAGE_MEASURE
87#ifdef SIMULATOR 87#ifdef SIMULATOR
88int _battery_level(void) { return -1; } 88int _battery_level(void) { return -1; }
89#endif 89#endif
@@ -91,7 +91,7 @@ int _battery_level(void) { return -1; }
91int _battery_level(void) { return -1; } 91int _battery_level(void) { return -1; }
92#endif 92#endif
93 93
94#if (CONFIG_BATTERY_MEASURE & VOLTAGE_MEASURE) == VOLTAGE_MEASURE 94#if CONFIG_BATTERY_MEASURE & VOLTAGE_MEASURE
95/* 95/*
96 * Average battery voltage and charger voltage, filtered via a digital 96 * Average battery voltage and charger voltage, filtered via a digital
97 * exponential filter (aka. exponential moving average, scaled): 97 * exponential filter (aka. exponential moving average, scaled):
@@ -109,8 +109,12 @@ const unsigned short percent_to_volt_charge[11];
109#endif 109#endif
110 110
111#if !(CONFIG_BATTERY_MEASURE & TIME_MEASURE) 111#if !(CONFIG_BATTERY_MEASURE & TIME_MEASURE)
112#ifdef CURRENT_NORMAL
112static int powermgmt_est_runningtime_min; 113static int powermgmt_est_runningtime_min;
113int _battery_time(void) { return powermgmt_est_runningtime_min; } 114int _battery_time(void) { return powermgmt_est_runningtime_min; }
115#else
116int _battery_time(void) { return -1; }
117#endif
114#endif 118#endif
115 119
116/* default value, mAh */ 120/* default value, mAh */
@@ -141,10 +145,6 @@ static const char power_thread_name[] = "power";
141static int voltage_to_battery_level(int battery_millivolts); 145static int voltage_to_battery_level(int battery_millivolts);
142static void battery_status_update(void); 146static void battery_status_update(void);
143 147
144#ifdef CURRENT_NORMAL /*only used if we have run current*/
145static int runcurrent(void);
146#endif
147
148#if BATTERY_TYPES_COUNT > 1 148#if BATTERY_TYPES_COUNT > 1
149void set_battery_type(int type) 149void set_battery_type(int type)
150{ 150{
@@ -179,19 +179,15 @@ int get_battery_capacity(void)
179 179
180int battery_time(void) 180int battery_time(void)
181{ 181{
182#if ((CONFIG_BATTERY_MEASURE & TIME_MEASURE) == 0) 182#if !(CONFIG_BATTERY_MEASURE & TIME_MEASURE)
183 183 /* Note: This should not really be possible but it might occur
184#ifndef CURRENT_NORMAL /* no estimation without current */ 184 * as a degenerate case for targets that don't define any battery
185 return -1; 185 * capacity at all..? */
186#else 186 if(battery_capacity <= 0)
187 if (battery_capacity <= 0) /* nor without capacity */
188 return -1; 187 return -1;
189 return _battery_time();
190#endif 188#endif
191 189
192#else
193 return _battery_time(); 190 return _battery_time();
194#endif
195} 191}
196 192
197/* Returns battery level in percent */ 193/* Returns battery level in percent */
@@ -209,7 +205,7 @@ bool battery_level_safe(void)
209{ 205{
210#if defined(NO_LOW_BATTERY_SHUTDOWN) 206#if defined(NO_LOW_BATTERY_SHUTDOWN)
211 return true; 207 return true;
212#elif (CONFIG_BATTERY_MEASURE & PERCENTAGE_MEASURE) 208#elif CONFIG_BATTERY_MEASURE & PERCENTAGE_MEASURE
213 return (battery_percent > 0); 209 return (battery_percent > 0);
214#elif defined(HAVE_BATTERY_SWITCH) 210#elif defined(HAVE_BATTERY_SWITCH)
215 /* Cannot rely upon the battery reading to be valid and the 211 /* Cannot rely upon the battery reading to be valid and the
@@ -278,40 +274,36 @@ static void battery_status_update(void)
278 if (level < 0) 274 if (level < 0)
279 level = voltage_to_battery_level(millivolt); 275 level = voltage_to_battery_level(millivolt);
280 276
281#ifdef CURRENT_NORMAL /*don't try to estimate run or charge 277#ifdef CURRENT_NORMAL
282 time without normal current defined*/ 278 int current = battery_current();
283 /* calculate estimated remaining running time */ 279
284#if CONFIG_CHARGING >= CHARGING_MONITOR 280#if CONFIG_CHARGING >= CHARGING_MONITOR
285 if (charging_state()) { 281 if (charging_state()) {
286 /* charging: remaining charging time */ 282 /* charging: remaining charging time */
287 powermgmt_est_runningtime_min = (100 - level)*battery_capacity*60 283 if(current > 0) {
288 / 100 / (CURRENT_MAX_CHG - runcurrent()); 284 powermgmt_est_runningtime_min =
285 (100 - level) * battery_capacity * 60 / 100 / current;
286 }
289 } 287 }
290 else 288 else
291#endif 289#endif
292 290
293 /* discharging: remaining running time */ 291 /* discharging: remaining running time */
294 if (level > 0 && (millivolt > percent_to_volt_discharge[battery_type][0] 292 if (level >= 0 && current > 0) {
295 || millivolt < 0)) { 293 powermgmt_est_runningtime_min =
296 /* linear extrapolation */ 294 (level + battery_percent) * battery_capacity * 60 / 200 / current;
297 powermgmt_est_runningtime_min = (level + battery_percent)*60
298 * battery_capacity / 200 / runcurrent();
299 } 295 }
300 if (0 > powermgmt_est_runningtime_min) { 296
297 if (powermgmt_est_runningtime_min < 0 || current <= 0)
301 powermgmt_est_runningtime_min = 0; 298 powermgmt_est_runningtime_min = 0;
302 }
303#endif 299#endif
304 300
305 battery_percent = level; 301 battery_percent = level;
306 send_battery_level_event(); 302 send_battery_level_event();
307} 303}
308 304
309#ifdef CURRENT_NORMAL /*check that we have a current defined in a config file*/ 305#ifdef CURRENT_NORMAL
310 306int battery_current(void)
311/*
312 * Estimate how much current we are drawing just to run.
313 */
314static int runcurrent(void)
315{ 307{
316 int current = CURRENT_NORMAL; 308 int current = CURRENT_NORMAL;
317 309
@@ -328,7 +320,7 @@ static int runcurrent(void)
328 current = CURRENT_USB; 320 current = CURRENT_USB;
329 } 321 }
330 322
331#if defined(HAVE_BACKLIGHT) 323#if defined(HAVE_BACKLIGHT) && defined(CURRENT_BACKLIGHT)
332 if (backlight_get_current_timeout() == 0) /* LED always on */ 324 if (backlight_get_current_timeout() == 0) /* LED always on */
333 current += CURRENT_BACKLIGHT; 325 current += CURRENT_BACKLIGHT;
334#endif 326#endif
@@ -338,12 +330,12 @@ static int runcurrent(void)
338 current += CURRENT_RECORD; 330 current += CURRENT_RECORD;
339#endif 331#endif
340 332
341#ifdef HAVE_SPDIF_POWER 333#if defined(HAVE_SPDIF_POWER) && defined(CURRENT_SPDIF_OUT)
342 if (spdif_powered()) 334 if (spdif_powered())
343 current += CURRENT_SPDIF_OUT; 335 current += CURRENT_SPDIF_OUT;
344#endif 336#endif
345 337
346#ifdef HAVE_REMOTE_LCD 338#if defined(HAVE_REMOTE_LCD) && defined(CURRENT_REMOTE)
347 if (remote_detect()) 339 if (remote_detect())
348 current += CURRENT_REMOTE; 340 current += CURRENT_REMOTE;
349#endif 341#endif
@@ -353,11 +345,18 @@ static int runcurrent(void)
353 current += CURRENT_ATA; 345 current += CURRENT_ATA;
354#endif 346#endif
355 347
348#if CONFIG_CHARGING >= CHARGING_MONITOR
349 /* While charging we must report the charging current. */
350 if (charging_state()) {
351 current = CURRENT_MAX_CHG - current;
352 current = MIN(current, 1);
353 }
354#endif
355
356#endif /* BOOTLOADER */ 356#endif /* BOOTLOADER */
357 357
358 return current; 358 return current;
359} 359}
360
361#endif /* CURRENT_NORMAL */ 360#endif /* CURRENT_NORMAL */
362 361
363/* Check to see whether or not we've received an alarm in the last second */ 362/* Check to see whether or not we've received an alarm in the last second */