summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2021-11-30 14:16:13 +0000
committerAidan MacDonald <amachronic@protonmail.com>2021-12-23 11:39:58 +0000
commitad05c872fe1a0d925f478106bfb56e731f3ce53c (patch)
tree156bae0098029e193a9914b6c7049f31efa3805f
parent923f92cb12ee39364ddec340de140d126ced1347 (diff)
downloadrockbox-ad05c872fe1a0d925f478106bfb56e731f3ce53c.tar.gz
rockbox-ad05c872fe1a0d925f478106bfb56e731f3ce53c.zip
powermgmt: Add battery current measurement
This allows targets to report the actual discharging or charging current if they are able to. Change-Id: I0b538e6ac94346f1434e45f83c8da8c1260a53a3
-rw-r--r--firmware/export/config.h2
-rw-r--r--firmware/export/powermgmt.h7
-rw-r--r--firmware/powermgmt.c40
-rw-r--r--uisimulator/common/powermgmt-sim.c11
4 files changed, 52 insertions, 8 deletions
diff --git a/firmware/export/config.h b/firmware/export/config.h
index 17bc626a80..2ae7ef2c53 100644
--- a/firmware/export/config.h
+++ b/firmware/export/config.h
@@ -208,6 +208,8 @@
208 Usually application ports, and only 208 Usually application ports, and only
209 if the estimation is better that ours 209 if the estimation is better that ours
210 (which it probably is) */ 210 (which it probably is) */
211#define CURRENT_MEASURE 8 /* Target can report battery charge and/or
212 * discharge current */
211/* CONFIG_LCD */ 213/* CONFIG_LCD */
212#define LCD_SSD1815 1 /* as used by Sansa M200 and others */ 214#define LCD_SSD1815 1 /* as used by Sansa M200 and others */
213#define LCD_S1D15E06 3 /* as used by iRiver H100 series */ 215#define LCD_S1D15E06 3 /* as used by iRiver H100 series */
diff --git a/firmware/export/powermgmt.h b/firmware/export/powermgmt.h
index c6fc3d5bdf..9d4d4e06aa 100644
--- a/firmware/export/powermgmt.h
+++ b/firmware/export/powermgmt.h
@@ -94,6 +94,11 @@ void powermgmt_init(void) INIT_ATTR;
94#define BATT_AVE_SAMPLES 128 94#define BATT_AVE_SAMPLES 128
95#endif 95#endif
96 96
97#ifndef BATT_CURRENT_AVE_SAMPLES
98/* TODO may need tweaking */
99#define BATT_CURRENT_AVE_SAMPLES 16
100#endif
101
97#ifndef POWER_THREAD_STEP_TICKS 102#ifndef POWER_THREAD_STEP_TICKS
98/* 2HZ sample rate unless otherwise specified */ 103/* 2HZ sample rate unless otherwise specified */
99#define POWER_THREAD_STEP_TICKS (HZ/2) 104#define POWER_THREAD_STEP_TICKS (HZ/2)
@@ -118,6 +123,8 @@ int battery_current(void); /* battery current in milliamps
118int _battery_level(void); /* percent */ 123int _battery_level(void); /* percent */
119int _battery_time(void); /* minutes */ 124int _battery_time(void); /* minutes */
120int _battery_voltage(void); /* voltage in millivolts */ 125int _battery_voltage(void); /* voltage in millivolts */
126int _battery_current(void); /* (dis)charge current in milliamps */
127
121#if CONFIG_CHARGING >= CHARGING_TARGET 128#if CONFIG_CHARGING >= CHARGING_TARGET
122void powermgmt_init_target(void); 129void powermgmt_init_target(void);
123void charging_algorithm_close(void); 130void charging_algorithm_close(void);
diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c
index 8c9b17d52b..30d37927ca 100644
--- a/firmware/powermgmt.c
+++ b/firmware/powermgmt.c
@@ -110,7 +110,8 @@ static int percent_now; /* Cached to avoid polling too often */
110#if !(CONFIG_BATTERY_MEASURE & TIME_MEASURE) 110#if !(CONFIG_BATTERY_MEASURE & TIME_MEASURE)
111int _battery_time(void) { return -1; } 111int _battery_time(void) { return -1; }
112#endif 112#endif
113#if (CONFIG_BATTERY_MEASURE & TIME_MEASURE) || defined(CURRENT_NORMAL) 113#if (CONFIG_BATTERY_MEASURE & TIME_MEASURE) || \
114 defined(CURRENT_NORMAL) || (CONFIG_BATTERY_MEASURE & CURRENT_MEASURE)
114static int time_now; /* Cached to avoid polling too often */ 115static int time_now; /* Cached to avoid polling too often */
115#endif 116#endif
116 117
@@ -121,6 +122,12 @@ int _battery_voltage(void) { return -1; }
121static int voltage_avg, voltage_now; 122static int voltage_avg, voltage_now;
122#endif 123#endif
123 124
125#if !(CONFIG_BATTERY_MEASURE & CURRENT_MEASURE)
126int _battery_current(void) { return -1; }
127#else
128static int current_avg, current_now;
129#endif
130
124/* The battery level can be obtained in two ways. If the target reports 131/* The battery level can be obtained in two ways. If the target reports
125 * voltage, the battery level can be estminated using percent_to_volt_* 132 * voltage, the battery level can be estminated using percent_to_volt_*
126 * curves. If the target can report the percentage directly, then that 133 * curves. If the target can report the percentage directly, then that
@@ -142,7 +149,8 @@ int battery_level(void)
142 * on the battery level and the actual current usage. */ 149 * on the battery level and the actual current usage. */
143int battery_time(void) 150int battery_time(void)
144{ 151{
145#if (CONFIG_BATTERY_MEASURE & TIME_MEASURE) || defined(CURRENT_NORMAL) 152#if (CONFIG_BATTERY_MEASURE & TIME_MEASURE) || \
153 defined(CURRENT_NORMAL) || (CONFIG_BATTERY_MEASURE & CURRENT_MEASURE)
146 return time_now; 154 return time_now;
147#else 155#else
148 return -1; 156 return -1;
@@ -166,7 +174,9 @@ int battery_voltage(void)
166 * the power consumed by the backlight, remote display, SPDIF, etc. */ 174 * the power consumed by the backlight, remote display, SPDIF, etc. */
167int battery_current(void) 175int battery_current(void)
168{ 176{
169#if defined(CURRENT_NORMAL) 177#if CONFIG_BATTERY_MEASURE & CURRENT_MEASURE
178 return current_now;
179#elif defined(CURRENT_NORMAL)
170 int current = CURRENT_NORMAL; 180 int current = CURRENT_NORMAL;
171 181
172#ifndef BOOTLOADER 182#ifndef BOOTLOADER
@@ -223,8 +233,8 @@ int battery_current(void)
223#endif 233#endif
224} 234}
225 235
226/* Initialize the battery voltage filter. This is called once 236/* Initialize the battery voltage/current filters. This is called
227 * by the power thread before entering the main polling loop. */ 237 * once by the power thread before entering the main polling loop. */
228static void average_init(void) 238static void average_init(void)
229{ 239{
230#if CONFIG_BATTERY_MEASURE & VOLTAGE_MEASURE 240#if CONFIG_BATTERY_MEASURE & VOLTAGE_MEASURE
@@ -244,9 +254,14 @@ static void average_init(void)
244 254
245 voltage_avg = voltage_now * BATT_AVE_SAMPLES; 255 voltage_avg = voltage_now * BATT_AVE_SAMPLES;
246#endif /* CONFIG_BATTERY_MEASURE & VOLTAGE_MEASURE */ 256#endif /* CONFIG_BATTERY_MEASURE & VOLTAGE_MEASURE */
257
258#if CONFIG_BATTERY_MEASURE & CURRENT_MEASURE
259 current_now = _battery_current();
260 current_avg = current_now * BATT_CURRENT_AVE_SAMPLES;
261#endif
247} 262}
248 263
249/* Sample the battery voltage and update the filter. 264/* Sample the battery voltage/current and update the filters.
250 * Updated once every POWER_THREAD_STEP_TICKS. */ 265 * Updated once every POWER_THREAD_STEP_TICKS. */
251static void average_step(bool low_battery) 266static void average_step(bool low_battery)
252{ 267{
@@ -262,6 +277,11 @@ static void average_step(bool low_battery)
262#else 277#else
263 (void)low_battery; 278 (void)low_battery;
264#endif 279#endif
280
281#if CONFIG_BATTERY_MEASURE & CURRENT_MEASURE
282 current_avg += _battery_current() - current_avg / BATT_CURRENT_AVE_SAMPLES;
283 current_now = current_avg / BATT_CURRENT_AVE_SAMPLES;
284#endif
265} 285}
266 286
267/* Send system battery level update events on reaching certain significant 287/* Send system battery level update events on reaching certain significant
@@ -353,7 +373,7 @@ static void battery_status_update(void)
353 373
354#if CONFIG_BATTERY_MEASURE & TIME_MEASURE 374#if CONFIG_BATTERY_MEASURE & TIME_MEASURE
355 time_now = _battery_time(); 375 time_now = _battery_time();
356#elif defined(CURRENT_NORMAL) 376#elif defined(CURRENT_NORMAL) || (CONFIG_BATTERY_MEASURE & CURRENT_MEASURE)
357 int current = battery_current(); 377 int current = battery_current();
358 if(level >= 0 && current > 0 && battery_capacity > 0) { 378 if(level >= 0 && current > 0 && battery_capacity > 0) {
359#if CONFIG_CHARGING >= CHARGING_MONITOR 379#if CONFIG_CHARGING >= CHARGING_MONITOR
@@ -455,6 +475,11 @@ void reset_battery_filter(int millivolts)
455{ 475{
456 voltage_avg = millivolts * BATT_AVE_SAMPLES; 476 voltage_avg = millivolts * BATT_AVE_SAMPLES;
457 voltage_now = millivolts; 477 voltage_now = millivolts;
478#if CONFIG_BATTERY_MEASURE & CURRENT_MEASURE
479 /* current would probably be inaccurate too */
480 current_now = _battery_current();
481 current_avg = current_now * BATT_CURRENT_AVE_SAMPLES;
482#endif
458 battery_status_update(); 483 battery_status_update();
459} 484}
460#endif /* HAVE_BATTERY_SWITCH */ 485#endif /* HAVE_BATTERY_SWITCH */
@@ -589,7 +614,6 @@ static inline bool detect_charger(unsigned int pwr)
589} 614}
590#endif /* CONFIG_CHARGING */ 615#endif /* CONFIG_CHARGING */
591 616
592
593#if CONFIG_BATTERY_MEASURE & VOLTAGE_MEASURE 617#if CONFIG_BATTERY_MEASURE & VOLTAGE_MEASURE
594static int power_hist_item(void) 618static int power_hist_item(void)
595{ 619{
diff --git a/uisimulator/common/powermgmt-sim.c b/uisimulator/common/powermgmt-sim.c
index 5d669bcae2..1535971e29 100644
--- a/uisimulator/common/powermgmt-sim.c
+++ b/uisimulator/common/powermgmt-sim.c
@@ -43,6 +43,7 @@ static bool charging = false;
43static unsigned int batt_millivolts = BATT_MAXMVOLT; 43static unsigned int batt_millivolts = BATT_MAXMVOLT;
44static unsigned int batt_percent = 100; 44static unsigned int batt_percent = 100;
45static unsigned int batt_runtime = BATT_MAXRUNTIME; 45static unsigned int batt_runtime = BATT_MAXRUNTIME;
46static unsigned int batt_current = 0;
46 47
47void powermgmt_init_target(void) {} 48void powermgmt_init_target(void) {}
48 49
@@ -97,6 +98,8 @@ static void battery_status_update(void)
97 98
98 batt_percent = (batt_millivolts - BATT_MINMVOLT) / (BATT_MAXMVOLT - BATT_MINMVOLT); 99 batt_percent = (batt_millivolts - BATT_MINMVOLT) / (BATT_MAXMVOLT - BATT_MINMVOLT);
99 batt_runtime = batt_percent * BATT_MAXRUNTIME; 100 batt_runtime = batt_percent * BATT_MAXRUNTIME;
101 /* current is completely bogus... */
102 batt_current = charging ? BATT_CHARGE_STEP : BATT_DISCHARGE_STEP;
100} 103}
101 104
102const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = { 3200 }; 105const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = { 3200 };
@@ -132,6 +135,14 @@ int _battery_time(void)
132} 135}
133#endif 136#endif
134 137
138#if (CONFIG_BATTERY_MEASURE & CURRENT_MEASURE)
139int _battery_current(void)
140{
141 battery_status_update();
142 return batt_current;
143}
144#endif
145
135#if CONFIG_CHARGING 146#if CONFIG_CHARGING
136unsigned int power_input_status(void) 147unsigned int power_input_status(void)
137{ 148{