summaryrefslogtreecommitdiff
path: root/firmware/powermgmt.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/powermgmt.c')
-rw-r--r--firmware/powermgmt.c183
1 files changed, 21 insertions, 162 deletions
diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c
index 570fcfa065..50a2579cb5 100644
--- a/firmware/powermgmt.c
+++ b/firmware/powermgmt.c
@@ -175,143 +175,6 @@ static const unsigned char poweroff_idle_timeout_value[15] =
175 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 30, 45, 60 175 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 30, 45, 60
176}; 176};
177 177
178static const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
179{
180#if CONFIG_BATTERY == BATT_LIION2200 /* FM Recorder, LiIon */
181 2800
182#elif CONFIG_BATTERY == BATT_3AAA /* Ondio: Alkaline, NiHM */
183 3100, 3450
184#elif CONFIG_BATTERY == BATT_1AA /* iRiver iFP: Alkaline, NiHM */
185 1050, 1150
186#elif CONFIG_BATTERY == BATT_LIPOL1300 /* iRiver H1x0: LiPolymer */
187 3380
188#elif CONFIG_BATTERY == BATT_LIION300 /* ipod nano */
189 3330
190#elif CONFIG_BATTERY == BATT_LIION400 /* iPOD Video 30GB */
191 3450
192#elif CONFIG_BATTERY == BATT_LIION750 /* Sansa e200 */
193 3400
194#elif CONFIG_BATTERY == BATT_LIION830 /* Gigabeat F */
195 3450
196#elif CONFIG_BATTERY == BATT_IAUDIO_X5M5 /* iAudio X5 */
197 3540
198#elif CONFIG_BATTERY == BATT_LPCS355385 /* iriver H10 20GB: LiPolymer*/
199 3760
200#elif CONFIG_BATTERY == BATT_BP009 /* iriver H10 5/6GB: LiPolymer */
201 3720
202#else /* Player/recorder: NiMH */
203 4750
204#endif
205};
206
207static const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
208{
209#if CONFIG_BATTERY == BATT_LIION2200 /* FM Recorder */
210 2580
211#elif CONFIG_BATTERY == BATT_3AAA /* Ondio */
212 2700, 2800
213#elif CONFIG_BATTERY == BATT_LIPOL1300 /* iRiver Hxxx */
214 3020
215#elif CONFIG_BATTERY == BATT_LIION300 /* ipod nano */
216 3230
217#elif CONFIG_BATTERY == BATT_LIION400 /* iPOD Video 30GB */
218 3450
219#elif CONFIG_BATTERY == BATT_LIION750 /* Sansa e200 */
220 3300
221#elif CONFIG_BATTERY == BATT_LIION830 /* Gigabeat F */
222 3400
223#elif CONFIG_BATTERY == BATT_IAUDIO_X5M5 /* iAudio X5 */
224 3500
225#elif CONFIG_BATTERY == BATT_LPCS355385 /* iriver H10 20GB */
226 3650
227#elif CONFIG_BATTERY == BATT_BP009 /* iriver H10 5/6GB */
228 3650
229#else /* Player/recorder: NiMH */
230 4400
231#endif
232};
233
234/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
235static const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
236{
237#if CONFIG_BATTERY == BATT_LIION2200
238 /* measured values */
239 { 2600, 2850, 2950, 3030, 3110, 3200, 3300, 3450, 3600, 3800, 4000 }
240#elif CONFIG_BATTERY == BATT_3AAA
241 /* measured values */
242 { 2800, 3250, 3410, 3530, 3640, 3740, 3850, 3950, 4090, 4270, 4750 }, /* Alkaline */
243 { 3100, 3550, 3630, 3690, 3720, 3740, 3760, 3780, 3800, 3860, 4050 } /* NiMH */
244#elif CONFIG_BATTERY == BATT_LIPOL1300
245 /* Below 3370 the backlight starts flickering during HD access */
246 { 3370, 3650, 3700, 3740, 3780, 3820, 3870, 3930, 4000, 4080, 4160 }
247#elif CONFIG_BATTERY == BATT_IAUDIO_X5M5
248 /* average measured values from X5 and M5L */
249 { 3500, 3650, 3720, 3740, 3760, 3790, 3840, 3900, 3950, 4040, 4120 }
250#elif CONFIG_BATTERY == BATT_LPCS355385
251 /* iriver H10 20GB */
252 { 3760, 3800, 3850, 3870, 3900, 3950, 4020, 4070, 4110, 4180, 4240 }
253#elif CONFIG_BATTERY == BATT_BP009
254 /* iriver H10 5/6GB */
255 { 3720, 3740, 3800, 3820, 3840, 3880, 3940, 4020, 4060, 4150, 4240 }
256#elif CONFIG_BATTERY == BATT_1AA
257 /* These values are the same as for 3AAA divided by 3. */
258 /* May need recalibration. */
259 { 930, 1080, 1140, 1180, 1210, 1250, 1280, 1320, 1360, 1420, 1580 }, /* alkaline */
260 { 1030, 1180, 1210, 1230, 1240, 1250, 1260, 1270, 1280, 1290, 1350 } /* NiMH */
261#elif CONFIG_BATTERY == BATT_LIION830
262 /* Toshiba Gigabeat Li Ion 830mAH figured from discharge curve */
263 { 3480, 3550, 3590, 3610, 3630, 3650, 3700, 3760, 3800, 3910, 3990 },
264#elif CONFIG_BATTERY == BATT_LIION750
265 /* Sansa Li Ion 750mAH FIXME this is a first linear approach */
266 { 3300, 3390, 3480, 3570, 3660, 3750, 3840, 3930, 4020, 4110, 4200 },
267#elif CONFIG_BATTERY == BATT_LIION400 /* iPOD Video 30GB */
268 /* iPOD Video 30GB Li-Ion 400mAh, first approach based upon measurements */
269 { 3450, 3670, 3710, 3750, 3790, 3830, 3870, 3930, 4010, 4100, 4180 },
270#elif CONFIG_BATTERY == BATT_LIION300
271 /* measured values */
272 { 3230, 3620, 3700, 3730, 3750, 3780, 3830, 3890, 3950, 4030, 4160 },
273#else /* NiMH */
274 /* original values were taken directly after charging, but it should show
275 100% after turning off the device for some hours, too */
276 { 4500, 4810, 4910, 4970, 5030, 5070, 5120, 5140, 5170, 5250, 5400 }
277 /* orig. values: ...,5280,5600 */
278#endif
279};
280
281#if CONFIG_CHARGING
282/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
283static const unsigned short percent_to_volt_charge[11] =
284{
285#if CONFIG_BATTERY == BATT_LIPOL1300
286 /* values measured over one full charging cycle */
287 3540, 3860, 3930, 3980, 4000, 4020, 4040, 4080, 4130, 4180, 4230 /* LiPo */
288#elif CONFIG_BATTERY == BATT_LIION300
289 /* measured values */
290 3230, 3620, 3700, 3730, 3750, 3780, 3830, 3890, 3950, 4030, 4160
291#elif CONFIG_BATTERY == BATT_LIION400
292 /* iPOD Video 30GB Li-Ion 400mAh, first approach based upon measurements */
293 3450, 3670, 3710, 3750, 3790, 3830, 3870, 3930, 4010, 4100, 4180
294#elif CONFIG_BATTERY == BATT_LIION750
295 /* Sansa Li Ion 750mAH FIXME*/
296 3300, 3390, 3480, 3570, 3660, 3750, 3840, 3930, 4020, 4110, 4200
297#elif CONFIG_BATTERY == BATT_LIION830
298 /* Toshiba Gigabeat Li Ion 830mAH */
299 3480, 3550, 3590, 3610, 3630, 3650, 3700, 3760, 3800, 3910, 3990
300#elif CONFIG_BATTERY == BATT_LPCS355385
301 /* iriver H10 20GB */
302 3990, 4030, 4060, 4080, 4100, 4120, 4150, 4180, 4220, 4260, 4310
303#elif CONFIG_BATTERY == BATT_BP009
304 /* iriver H10 5/6GB: Not yet calibrated */
305 3880, 3920, 3960, 4000, 4060, 4100, 4150, 4190, 4240, 4280, 4330
306#else
307 /* values guessed, see
308 http://www.seattlerobotics.org/encoder/200210/LiIon2.pdf until someone
309 measures voltages over a charging cycle */
310 4760, 5440, 5510, 5560, 5610, 5640, 5660, 5760, 5820, 5840, 5850 /* NiMH */
311#endif
312};
313#endif /* CONFIG_CHARGING */
314
315#if CONFIG_CHARGING == CHARGING_CONTROL 178#if CONFIG_CHARGING == CHARGING_CONTROL
316int long_delta; /* long term delta battery voltage */ 179int long_delta; /* long term delta battery voltage */
317int short_delta; /* short term delta battery voltage */ 180int short_delta; /* short term delta battery voltage */
@@ -340,12 +203,11 @@ int pid_i = 0; /* PID integral term */
340 */ 203 */
341static unsigned int avgbat; /* average battery voltage (filtering) */ 204static unsigned int avgbat; /* average battery voltage (filtering) */
342static unsigned int battery_millivolts;/* filtered battery voltage, millivolts */ 205static unsigned int battery_millivolts;/* filtered battery voltage, millivolts */
206
343#ifdef HAVE_CHARGE_CTRL 207#ifdef HAVE_CHARGE_CTRL
344#define BATT_AVE_SAMPLES 32 /* filter constant / @ 2Hz sample rate */ 208#define BATT_AVE_SAMPLES 32 /* filter constant / @ 2Hz sample rate */
345#elif CONFIG_BATTERY == BATT_LIPOL1300
346#define BATT_AVE_SAMPLES 128 /* slow filter for iriver */
347#else 209#else
348#define BATT_AVE_SAMPLES 64 /* medium filter constant for all others */ 210#define BATT_AVE_SAMPLES 128 /* slw filter constant for all others */
349#endif 211#endif
350 212
351/* battery level (0-100%) of this minute, updated once per minute */ 213/* battery level (0-100%) of this minute, updated once per minute */
@@ -373,7 +235,7 @@ static int runcurrent(void);
373 235
374void battery_read_info(int *voltage, int *level) 236void battery_read_info(int *voltage, int *level)
375{ 237{
376 int millivolts = adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR / 1000; 238 int millivolts = battery_adc_voltage();
377 239
378 if (voltage) 240 if (voltage)
379 *voltage = millivolts; 241 *voltage = millivolts;
@@ -424,12 +286,6 @@ unsigned int battery_voltage(void)
424 return battery_millivolts; 286 return battery_millivolts;
425} 287}
426 288
427/* Returns battery voltage from ADC [millivolts] */
428int battery_adc_voltage(void)
429{
430 return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR + 500) / 1000;
431}
432
433/* Tells if the battery level is safe for disk writes */ 289/* Tells if the battery level is safe for disk writes */
434bool battery_level_safe(void) 290bool battery_level_safe(void)
435{ 291{
@@ -487,7 +343,10 @@ static int voltage_to_battery_level(int battery_millivolts)
487{ 343{
488 int level; 344 int level;
489 345
490#if defined(CONFIG_CHARGER) && CONFIG_BATTERY == BATT_LIPOL1300 346#if defined(CONFIG_CHARGER) \
347 && (defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES))
348 /* Checking for iriver is a temporary kludge.
349 * This code needs rework/unification */
491 if (charger_input_state == NO_CHARGER) { 350 if (charger_input_state == NO_CHARGER) {
492 /* discharging. calculate new battery level and average with last */ 351 /* discharging. calculate new battery level and average with last */
493 level = voltage_to_percent(battery_millivolts, 352 level = voltage_to_percent(battery_millivolts,
@@ -549,7 +408,10 @@ static void battery_status_update(void)
549 / 100 / (CURRENT_MAX_CHG - runcurrent()); 408 / 100 / (CURRENT_MAX_CHG - runcurrent());
550 } 409 }
551 else 410 else
552#elif CONFIG_CHARGING && CONFIG_BATTERY == BATT_LIPOL1300 411#elif CONFIG_CHARGING \
412 && (defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES))
413 /* Checking for iriver is a temporary kludge.
414 * This code needs rework/unification */
553 if (charger_inserted()) { 415 if (charger_inserted()) {
554#ifdef IRIVER_H300_SERIES 416#ifdef IRIVER_H300_SERIES
555 /* H300_SERIES use CURRENT_MAX_CHG for basic charge time (80%) 417 /* H300_SERIES use CURRENT_MAX_CHG for basic charge time (80%)
@@ -626,9 +488,8 @@ static void handle_auto_poweroff(void)
626 } 488 }
627#endif 489#endif
628 490
491#ifndef NO_LOW_BATTERY_SHUTDOWN
629 /* switch off unit if battery level is too low for reliable operation */ 492 /* switch off unit if battery level is too low for reliable operation */
630#if (CONFIG_BATTERY!=BATT_4AA_NIMH) && (CONFIG_BATTERY!=BATT_3AAA)&& \
631 (CONFIG_BATTERY!=BATT_1AA)
632 if(battery_millivolts < battery_level_shutoff[battery_type]) { 493 if(battery_millivolts < battery_level_shutoff[battery_type]) {
633 if(!shutdown_timeout) { 494 if(!shutdown_timeout) {
634 backlight_on(); 495 backlight_on();
@@ -837,12 +698,11 @@ static void power_thread_sleep(int ticks)
837 * likely always be spinning in USB mode). 698 * likely always be spinning in USB mode).
838 */ 699 */
839 if (!ata_disk_is_active() || usb_inserted()) { 700 if (!ata_disk_is_active() || usb_inserted()) {
840 avgbat += adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR 701 avgbat += battery_adc_voltage() - (avgbat / BATT_AVE_SAMPLES);
841 - (avgbat / BATT_AVE_SAMPLES);
842 /* 702 /*
843 * battery_millivolts is the millivolt-scaled filtered battery value. 703 * battery_millivolts is the millivolt-scaled filtered battery value.
844 */ 704 */
845 battery_millivolts = (avgbat / BATT_AVE_SAMPLES + 500) / 1000; 705 battery_millivolts = avgbat / BATT_AVE_SAMPLES;
846 706
847 /* update battery status every time an update is available */ 707 /* update battery status every time an update is available */
848 battery_status_update(); 708 battery_status_update();
@@ -858,15 +718,13 @@ static void power_thread_sleep(int ticks)
858 /* update battery status every time an update is available */ 718 /* update battery status every time an update is available */
859 battery_status_update(); 719 battery_status_update();
860 720
861#if (CONFIG_BATTERY!=BATT_4AA_NIMH) && (CONFIG_BATTERY!=BATT_3AAA)&& \ 721#ifndef NO_LOW_BATTERY_SHUTDOWN
862 (CONFIG_BATTERY!=BATT_1AA)
863 if (!shutdown_timeout && 722 if (!shutdown_timeout &&
864 (battery_millivolts < battery_level_shutoff[battery_type])) 723 (battery_millivolts < battery_level_shutoff[battery_type]))
865 sys_poweroff(); 724 sys_poweroff();
866 else 725 else
867#endif 726#endif
868 avgbat += battery_millivolts * 1000 727 avgbat += battery_millivolts - (avgbat / BATT_AVE_SAMPLES);
869 - (avgbat / BATT_AVE_SAMPLES);
870 } 728 }
871 729
872#if CONFIG_CHARGING == CHARGING_CONTROL 730#if CONFIG_CHARGING == CHARGING_CONTROL
@@ -912,7 +770,7 @@ static void power_thread(void)
912#endif 770#endif
913 771
914 /* initialize the voltages for the exponential filter */ 772 /* initialize the voltages for the exponential filter */
915 avgbat = adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR + 15000; 773 avgbat = battery_adc_voltage() + 15;
916 774
917#ifndef HAVE_MMC /* this adjustment is only needed for HD based */ 775#ifndef HAVE_MMC /* this adjustment is only needed for HD based */
918 /* The battery voltage is usually a little lower directly after 776 /* The battery voltage is usually a little lower directly after
@@ -921,17 +779,18 @@ static void power_thread(void)
921 if(!charger_inserted()) /* only if charger not connected */ 779 if(!charger_inserted()) /* only if charger not connected */
922#endif 780#endif
923 avgbat += (percent_to_volt_discharge[battery_type][6] - 781 avgbat += (percent_to_volt_discharge[battery_type][6] -
924 percent_to_volt_discharge[battery_type][5]) * 500; 782 percent_to_volt_discharge[battery_type][5]) / 2;
925#endif /* not HAVE_MMC */ 783#endif /* not HAVE_MMC */
926 784
927 avgbat = avgbat * BATT_AVE_SAMPLES; 785 avgbat = avgbat * BATT_AVE_SAMPLES;
928 battery_millivolts = avgbat / BATT_AVE_SAMPLES / 1000; 786 battery_millivolts = avgbat / BATT_AVE_SAMPLES;
929 787
930#if CONFIG_CHARGING 788#if CONFIG_CHARGING
931 if(charger_inserted()) { 789 if(charger_inserted()) {
932 battery_percent = voltage_to_percent(battery_millivolts, 790 battery_percent = voltage_to_percent(battery_millivolts,
933 percent_to_volt_charge); 791 percent_to_volt_charge);
934#if CONFIG_BATTERY == BATT_LIPOL1300 792#if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
793 /* Checking for iriver is a temporary kludge. */
935 charger_input_state = CHARGER; 794 charger_input_state = CHARGER;
936#endif 795#endif
937 } else 796 } else