From 1d1d9a8491ff478d3e3809df9366c87813993a73 Mon Sep 17 00:00:00 2001 From: Jens Arnold Date: Wed, 15 Aug 2007 23:57:27 +0000 Subject: [PATCH] Switch to using millivolt for battery voltage and other internal voltages. * Fix debug voltage history display. * Some code cleanup. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14364 a1c6a512-1295-4272-9138-f99709370657 --- apps/debug_menu.c | 72 +++++------ apps/gui/gwps-common.c | 2 +- apps/plugins/battery_bench.c | 5 +- apps/screens.c | 6 +- firmware/export/powermgmt.h | 13 +- firmware/powermgmt.c | 241 +++++++++++++++++------------------ flash/bootbox/main.c | 2 +- 7 files changed, 157 insertions(+), 184 deletions(-) diff --git a/apps/debug_menu.c b/apps/debug_menu.c index d3cfb30c76..064c7114a0 100644 --- a/apps/debug_menu.c +++ b/apps/debug_menu.c @@ -1048,10 +1048,9 @@ bool dbg_ports(void) snprintf(buf, 32, "AN3: %03x AN7: %03x", adc_read(3), adc_read(7)); lcd_puts(0, 5, buf); - battery_read_info(NULL, &adc_battery_voltage, - &adc_battery_level); - snprintf(buf, 32, "Batt: %d.%02dV %d%% ", adc_battery_voltage / 100, - adc_battery_voltage % 100, adc_battery_level); + battery_read_info(&adc_battery_voltage, &adc_battery_level); + snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000, + adc_battery_voltage % 1000, adc_battery_level); lcd_puts(0, 6, buf); lcd_update(); @@ -1068,7 +1067,7 @@ bool dbg_ports(void) unsigned int gpio_enable; unsigned int gpio1_enable; int adc_buttons, adc_remote; - int adc_battery, adc_battery_voltage, adc_battery_level; + int adc_battery_voltage, adc_battery_level; char buf[128]; int line; @@ -1108,8 +1107,7 @@ bool dbg_ports(void) adc_buttons = adc_read(ADC_BUTTONS); adc_remote = adc_read(ADC_REMOTE); - battery_read_info(&adc_battery, &adc_battery_voltage, - &adc_battery_level); + battery_read_info(&adc_battery_voltage, &adc_battery_level); #if defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IRIVER_H300_SERIES) snprintf(buf, sizeof(buf), "ADC_BUTTONS (%c): %02x", button_scan_enabled() ? '+' : '-', adc_buttons); @@ -1123,9 +1121,6 @@ bool dbg_ports(void) #else snprintf(buf, sizeof(buf), "ADC_REMOTE: %02x", adc_remote); #endif - - lcd_puts(0, line++, buf); - snprintf(buf, sizeof(buf), "ADC_BATTERY: %02x", adc_battery); lcd_puts(0, line++, buf); #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES) snprintf(buf, sizeof(buf), "ADC_REMOTEDETECT: %02x", @@ -1133,8 +1128,8 @@ bool dbg_ports(void) lcd_puts(0, line++, buf); #endif - snprintf(buf, 32, "Batt: %d.%02dV %d%% ", adc_battery_voltage / 100, - adc_battery_voltage % 100, adc_battery_level); + snprintf(buf, 32, "Batt: %d.%03dV %d%% ", adc_battery_voltage / 1000, + adc_battery_voltage % 1000, adc_battery_level); lcd_puts(0, line++, buf); #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES) @@ -1401,9 +1396,9 @@ bool dbg_ports(void) } lcd_puts(0, 0, buf); - battery_read_info(NULL, &adc_battery_voltage, NULL); - snprintf(buf, 32, "Batt: %d.%02dV", adc_battery_voltage / 100, - adc_battery_voltage % 100); + battery_read_info(&adc_battery_voltage, NULL); + snprintf(buf, 32, "Batt: %d.%03dV", adc_battery_voltage / 1000, + adc_battery_voltage % 1000); lcd_puts(0, 1, buf); lcd_update(); @@ -1510,29 +1505,20 @@ static bool view_battery(void) switch (view) { case 0: /* voltage history graph */ /* Find maximum and minimum voltage for scaling */ - maxv = 0; - minv = 65535; - for (i = 0; i < BAT_LAST_VAL; i++) { + minv = power_history[0]; + maxv = minv + 1; + for (i = 1; i < BAT_LAST_VAL && power_history[i]; i++) { if (power_history[i] > maxv) maxv = power_history[i]; - if (power_history[i] && (power_history[i] < minv)) - { + if (power_history[i] < minv) minv = power_history[i]; - } } - if ((minv < 1) || (minv >= 65535)) - minv = 1; - if (maxv < 2) - maxv = 2; - if (minv == maxv) - maxv < 65535 ? maxv++ : minv--; - - snprintf(buf, 30, "Battery %d.%02d", power_history[0] / 100, - power_history[0] % 100); + snprintf(buf, 30, "Battery %d.%03d", power_history[0] / 1000, + power_history[0] % 1000); lcd_puts(0, 0, buf); - snprintf(buf, 30, "scale %d.%02d-%d.%02d V", - minv / 100, minv % 100, maxv / 100, maxv % 100); + snprintf(buf, 30, "scale %d.%03d-%d.%03dV", + minv / 1000, minv % 1000, maxv / 1000, maxv % 1000); lcd_puts(0, 1, buf); x = 0; @@ -1551,12 +1537,12 @@ static bool view_battery(void) case 1: /* status: */ lcd_puts(0, 0, "Power status:"); - battery_read_info(NULL, &y, NULL); - snprintf(buf, 30, "Battery: %d.%02d V", y / 100, y % 100); + battery_read_info(&y, NULL); + snprintf(buf, 30, "Battery: %d.%03d V", y / 1000, y % 1000); lcd_puts(0, 1, buf); #ifdef ADC_EXT_POWER - y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 10000; - snprintf(buf, 30, "External: %d.%02d V", y / 100, y % 100); + y = (adc_read(ADC_EXT_POWER) * EXT_SCALE_FACTOR) / 1000; + snprintf(buf, 30, "External: %d.%03d V", y / 1000, y % 1000); lcd_puts(0, 2, buf); #endif #if CONFIG_CHARGING @@ -1614,10 +1600,10 @@ static bool view_battery(void) lcd_puts(0, 0, "Voltage deltas:"); for (i = 0; i <= 6; i++) { - y = power_history[i] - power_history[i+i]; - snprintf(buf, 30, "-%d min: %s%d.%02d V", i, - (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 100, - ((y < 0) ? y * -1 : y ) % 100); + y = power_history[i] - power_history[i+1]; + snprintf(buf, 30, "-%d min: %s%d.%03d V", i, + (y < 0) ? "-" : "", ((y < 0) ? y * -1 : y) / 1000, + ((y < 0) ? y * -1 : y ) % 1000); lcd_puts(0, i+1, buf); } break; @@ -1641,9 +1627,9 @@ static bool view_battery(void) lcd_puts(0, 4, buf); #endif /* CONFIG_CHARGING == CHARGING_CONTROL */ - snprintf(buf, 30, "Last PwrHist: %d.%02d V", - power_history[0] / 100, - power_history[0] % 100); + snprintf(buf, 30, "Last PwrHist: %d.%03dV", + power_history[0] / 1000, + power_history[0] % 1000); lcd_puts(0, 5, buf); snprintf(buf, 30, "battery level: %d%%", battery_level()); diff --git a/apps/gui/gwps-common.c b/apps/gui/gwps-common.c index 233bcfa566..694bc2a2c8 100644 --- a/apps/gui/gwps-common.c +++ b/apps/gui/gwps-common.c @@ -1015,7 +1015,7 @@ static char *get_token_value(struct gui_wps *gwps, case WPS_TOKEN_BATTERY_VOLTS: { unsigned int v = battery_voltage(); - snprintf(buf, buf_size, "%d.%02d", v/100, v%100); + snprintf(buf, buf_size, "%d.%02d", v / 1000, (v % 1000) / 10); return buf; } diff --git a/apps/plugins/battery_bench.c b/apps/plugins/battery_bench.c index 8c71f0ecce..1d3694cbc5 100644 --- a/apps/plugins/battery_bench.c +++ b/apps/plugins/battery_bench.c @@ -250,10 +250,9 @@ void thread(void) bat[j].eta / 60, bat[j].eta % 60, #if CONFIG_CHARGING || defined(HAVE_USB_POWER) (bat[j].voltage & - (~(BIT_CHARGER|BIT_CHARGING|BIT_USB_POWER))) - *10, + (~(BIT_CHARGER|BIT_CHARGING|BIT_USB_POWER))), #else - bat[j].voltage * 10, + bat[j].voltage, #endif temp + 1 + (j-i) #if CONFIG_CHARGING diff --git a/apps/screens.c b/apps/screens.c index 700164f10e..cb691b866a 100644 --- a/apps/screens.c +++ b/apps/screens.c @@ -194,8 +194,8 @@ static void charging_display_info(bool animate) #endif { int battv = battery_voltage(); - snprintf(buf, 32, " Batt: %d.%02dV %d%% ", battv / 100, - battv % 100, battery_level()); + snprintf(buf, 32, " Batt: %d.%02dV %d%% ", battv / 1000, + (battv % 1000) / 10, battery_level()); lcd_puts(0, 7, buf); } @@ -291,7 +291,7 @@ static void charging_display_info(bool animate) char buf[32]; battv = battery_voltage(); - snprintf(buf, sizeof(buf), " %d.%02dV", battv / 100, battv % 100); + snprintf(buf, sizeof(buf), " %d.%02dV", battv / 1000, (battv % 1000) / 10); lcd_puts(4, 1, buf); memcpy(buf, logo_pattern, 32); /* copy logo patterns */ diff --git a/firmware/export/powermgmt.h b/firmware/export/powermgmt.h index 4bdaa4387d..89a0350bb7 100644 --- a/firmware/export/powermgmt.h +++ b/firmware/export/powermgmt.h @@ -65,15 +65,14 @@ extern charger_input_state_type charger_input_state; /* actual max time depends also on BATTERY_CAPACITY! */ #define CHARGE_MIN_TIME 10 /* minutes: minimum charging time */ #define TOPOFF_MAX_TIME 90 /* After charging, go to top off charge. How long should top off charge be? */ -#define TOPOFF_VOLTAGE 565 /* which voltage is best? (centivolts) */ +#define TOPOFF_VOLTAGE 5650 /* which voltage is best? (millivolts) */ #define TRICKLE_MAX_TIME 12*60 /* After top off charge, go to trickle charge. How long should trickle charge be? */ -#define TRICKLE_VOLTAGE 545 /* which voltage is best? (centivolts) */ +#define TRICKLE_VOLTAGE 5450 /* which voltage is best? (millivolts) */ #define START_TOPOFF_SEC 25 /* initial trickle_sec for topoff */ #define START_TRICKLE_SEC 15 /* initial trickle_sec for trickle */ -#define PID_PCONST 2 /* PID proportional constant */ -#define PID_DEADZONE 2 /* PID proportional deadzone */ +#define PID_DEADZONE 4 /* PID proportional deadzone */ extern char power_message[POWER_MESSAGE_LEN]; @@ -147,11 +146,11 @@ void powermgmt_init(void); /* Returns battery statust */ int battery_level(void); /* percent */ int battery_time(void); /* minutes */ -int battery_adc_voltage(void); /* voltage from ADC in centivolts */ -unsigned int battery_voltage(void); /* filtered batt. voltage in centivolts */ +int battery_adc_voltage(void); /* voltage from ADC in millivolts */ +unsigned int battery_voltage(void); /* filtered batt. voltage in millivolts */ /* read unfiltered battery info */ -void battery_read_info(int *adc, int *voltage, int *level); +void battery_read_info(int *voltage, int *level); /* Tells if the battery level is safe for disk writes */ bool battery_level_safe(void); diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c index a202c71bbf..596922f891 100644 --- a/firmware/powermgmt.c +++ b/firmware/powermgmt.c @@ -86,11 +86,11 @@ charger_input_state_type charger_input_state IDATA_ATTR; #ifdef SIMULATOR /***********************************************************/ -#define BATT_MINCVOLT 250 /* minimum centivolts of battery */ -#define BATT_MAXCVOLT 450 /* maximum centivolts of battery */ +#define BATT_MINMVOLT 2500 /* minimum millivolts of battery */ +#define BATT_MAXMVOLT 4500 /* maximum millivolts of battery */ #define BATT_MAXRUNTIME (10 * 60) /* maximum runtime with full battery in minutes */ -static unsigned int batt_centivolts = (unsigned int)BATT_MAXCVOLT; +static unsigned int batt_millivolts = (unsigned int)BATT_MAXMVOLT; static int batt_level = 100; /* battery capacity level in percent */ static int batt_time = BATT_MAXRUNTIME; /* estimated remaining time in minutes */ static time_t last_change = 0; @@ -104,24 +104,21 @@ static void battery_status_update(void) last_change = now; /* change the values: */ - batt_centivolts -= (unsigned int)(BATT_MAXCVOLT - BATT_MINCVOLT) / 101; - if (batt_centivolts < (unsigned int)BATT_MINCVOLT) - batt_centivolts = (unsigned int)BATT_MAXCVOLT; + batt_millivolts -= (unsigned int)(BATT_MAXMVOLT - BATT_MINMVOLT) / 101; + if (batt_millivolts < (unsigned int)BATT_MINMVOLT) + batt_millivolts = (unsigned int)BATT_MAXMVOLT; - batt_level = 100 * (batt_centivolts - BATT_MINCVOLT) / (BATT_MAXCVOLT - BATT_MINCVOLT); + batt_level = 100 * (batt_millivolts - BATT_MINMVOLT) / (BATT_MAXMVOLT - BATT_MINMVOLT); batt_time = batt_level * BATT_MAXRUNTIME / 100; } } -void battery_read_info(int *adc, int *voltage, int *level) +void battery_read_info(int *voltage, int *level) { battery_status_update(); - if (adc) - *adc = batt_centivolts; /* just return something */ - if (voltage) - *voltage = batt_centivolts; + *voltage = batt_millivolts; if (level) *level = batt_level; @@ -130,7 +127,7 @@ void battery_read_info(int *adc, int *voltage, int *level) unsigned int battery_voltage(void) { battery_status_update(); - return batt_centivolts; + return batt_millivolts; } int battery_level(void) @@ -181,136 +178,136 @@ static const unsigned char poweroff_idle_timeout_value[15] = static const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = { #if CONFIG_BATTERY == BATT_LIION2200 /* FM Recorder, LiIon */ - 280 + 2800 #elif CONFIG_BATTERY == BATT_3AAA /* Ondio: Alkaline, NiHM */ - 310, 345 + 3100, 3450 #elif CONFIG_BATTERY == BATT_1AA /* iRiver iFP: Alkaline, NiHM */ - 105, 115 + 1050, 1150 #elif CONFIG_BATTERY == BATT_LIPOL1300 /* iRiver H1x0: LiPolymer */ - 338 + 3380 #elif CONFIG_BATTERY == BATT_LIION300 /* ipod nano */ - 333 + 3330 #elif CONFIG_BATTERY == BATT_LIION400 /* iPOD Video 30GB */ - 345 + 3450 #elif CONFIG_BATTERY == BATT_LIION750 /* Sansa e200 */ - 340 + 3400 #elif CONFIG_BATTERY == BATT_LIION830 /* Gigabeat F */ - 345 + 3450 #elif CONFIG_BATTERY == BATT_IAUDIO_X5M5 /* iAudio X5 */ - 354 + 3540 #elif CONFIG_BATTERY == BATT_LPCS355385 /* iriver H10 20GB: LiPolymer*/ - 376 + 3760 #elif CONFIG_BATTERY == BATT_BP009 /* iriver H10 5/6GB: LiPolymer */ - 372 + 3720 #else /* Player/recorder: NiMH */ - 475 + 4750 #endif }; static const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] = { #if CONFIG_BATTERY == BATT_LIION2200 /* FM Recorder */ - 258 + 2580 #elif CONFIG_BATTERY == BATT_3AAA /* Ondio */ - 270, 280 + 2700, 2800 #elif CONFIG_BATTERY == BATT_LIPOL1300 /* iRiver Hxxx */ - 302 + 3020 #elif CONFIG_BATTERY == BATT_LIION300 /* ipod nano */ - 323 + 3230 #elif CONFIG_BATTERY == BATT_LIION400 /* iPOD Video 30GB */ - 345 + 3450 #elif CONFIG_BATTERY == BATT_LIION750 /* Sansa e200 */ - 330 + 3300 #elif CONFIG_BATTERY == BATT_LIION830 /* Gigabeat F */ - 340 + 3400 #elif CONFIG_BATTERY == BATT_IAUDIO_X5M5 /* iAudio X5 */ - 350 + 3500 #elif CONFIG_BATTERY == BATT_LPCS355385 /* iriver H10 20GB */ - 365 + 3650 #elif CONFIG_BATTERY == BATT_BP009 /* iriver H10 5/6GB */ - 365 + 3650 #else /* Player/recorder: NiMH */ - 440 + 4400 #endif }; -/* voltages (centivolt) of 0%, 10%, ... 100% when charging disabled */ +/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */ static const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] = { #if CONFIG_BATTERY == BATT_LIION2200 /* measured values */ - { 260, 285, 295, 303, 311, 320, 330, 345, 360, 380, 400 } + { 2600, 2850, 2950, 3030, 3110, 3200, 3300, 3450, 3600, 3800, 4000 } #elif CONFIG_BATTERY == BATT_3AAA /* measured values */ - { 280, 325, 341, 353, 364, 374, 385, 395, 409, 427, 475 }, /* Alkaline */ - { 310, 355, 363, 369, 372, 374, 376, 378, 380, 386, 405 } /* NiMH */ + { 2800, 3250, 3410, 3530, 3640, 3740, 3850, 3950, 4090, 4270, 4750 }, /* Alkaline */ + { 3100, 3550, 3630, 3690, 3720, 3740, 3760, 3780, 3800, 3860, 4050 } /* NiMH */ #elif CONFIG_BATTERY == BATT_LIPOL1300 - /* Below 337 the backlight starts flickering during HD access */ - { 337, 365, 370, 374, 378, 382, 387, 393, 400, 408, 416 } + /* Below 3370 the backlight starts flickering during HD access */ + { 3370, 3650, 3700, 3740, 3780, 3820, 3870, 3930, 4000, 4080, 4160 } #elif CONFIG_BATTERY == BATT_IAUDIO_X5M5 /* average measured values from X5 and M5L */ - { 350, 365, 372, 374, 376, 379, 384, 390, 395, 404, 412 } + { 3500, 3650, 3720, 3740, 3760, 3790, 3840, 3900, 3950, 4040, 4120 } #elif CONFIG_BATTERY == BATT_LPCS355385 /* iriver H10 20GB */ - { 376, 380, 385, 387, 390, 395, 402, 407, 411, 418, 424 } + { 3760, 3800, 3850, 3870, 3900, 3950, 4020, 4070, 4110, 4180, 4240 } #elif CONFIG_BATTERY == BATT_BP009 /* iriver H10 5/6GB */ - { 372, 374, 380, 382, 384, 388, 394, 402, 406, 415, 424 } + { 3720, 3740, 3800, 3820, 3840, 3880, 3940, 4020, 4060, 4150, 4240 } #elif CONFIG_BATTERY == BATT_1AA /* These values are the same as for 3AAA divided by 3. */ /* May need recalibration. */ - { 93, 108, 114, 118, 121, 125, 128, 132, 136, 142, 158 }, /* alkaline */ - { 103, 118, 121, 123, 124, 125, 126, 127, 128, 129, 135 } /* NiMH */ + { 930, 1080, 1140, 1180, 1210, 1250, 1280, 1320, 1360, 1420, 1580 }, /* alkaline */ + { 1030, 1180, 1210, 1230, 1240, 1250, 1260, 1270, 1280, 1290, 1350 } /* NiMH */ #elif CONFIG_BATTERY == BATT_LIION830 /* Toshiba Gigabeat Li Ion 830mAH figured from discharge curve */ - { 348, 355, 359, 361, 363, 365, 370, 376, 380, 391, 399 }, + { 3480, 3550, 3590, 3610, 3630, 3650, 3700, 3760, 3800, 3910, 3990 }, #elif CONFIG_BATTERY == BATT_LIION750 /* Sansa Li Ion 750mAH FIXME this is a first linear approach */ - { 330, 339, 348, 357, 366, 375, 384, 393, 402, 411, 420 }, + { 3300, 3390, 3480, 3570, 3660, 3750, 3840, 3930, 4020, 4110, 4200 }, #elif CONFIG_BATTERY == BATT_LIION400 /* iPOD Video 30GB */ /* iPOD Video 30GB Li-Ion 400mAh, first approach based upon measurements */ - { 345, 367, 371, 375, 379, 383, 387, 393, 401, 410, 418 }, + { 3450, 3670, 3710, 3750, 3790, 3830, 3870, 3930, 4010, 4100, 4180 }, #elif CONFIG_BATTERY == BATT_LIION300 /* measured values */ - { 323, 362, 370, 373, 375, 378, 383, 389, 395, 403, 416 }, + { 3230, 3620, 3700, 3730, 3750, 3780, 3830, 3890, 3950, 4030, 4160 }, #else /* NiMH */ /* original values were taken directly after charging, but it should show 100% after turning off the device for some hours, too */ - { 450, 481, 491, 497, 503, 507, 512, 514, 517, 525, 540 } - /* orig. values: ...,528,560 */ + { 4500, 4810, 4910, 4970, 5030, 5070, 5120, 5140, 5170, 5250, 5400 } + /* orig. values: ...,5280,5600 */ #endif }; #if CONFIG_CHARGING -/* voltages (centivolt) of 0%, 10%, ... 100% when charging enabled */ +/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */ static const unsigned short percent_to_volt_charge[11] = { #if CONFIG_BATTERY == BATT_LIPOL1300 /* values measured over one full charging cycle */ - 354, 386, 393, 398, 400, 402, 404, 408, 413, 418, 423 /* LiPo */ + 3540, 3860, 3930, 3980, 4000, 4020, 4040, 4080, 4130, 4180, 4230 /* LiPo */ #elif CONFIG_BATTERY == BATT_LIION300 /* measured values */ - 323, 362, 370, 373, 375, 378, 383, 389, 395, 403, 416 + 3230, 3620, 3700, 3730, 3750, 3780, 3830, 3890, 3950, 4030, 4160 #elif CONFIG_BATTERY == BATT_LIION400 /* iPOD Video 30GB Li-Ion 400mAh, first approach based upon measurements */ - 345, 367, 371, 375, 379, 383, 387, 393, 401, 410, 418 + 3450, 3670, 3710, 3750, 3790, 3830, 3870, 3930, 4010, 4100, 4180 #elif CONFIG_BATTERY == BATT_LIION750 /* Sansa Li Ion 750mAH FIXME*/ - 330, 339, 348, 357, 366, 375, 384, 393, 402, 411, 420 + 3300, 3390, 3480, 3570, 3660, 3750, 3840, 3930, 4020, 4110, 4200 #elif CONFIG_BATTERY == BATT_LIION830 /* Toshiba Gigabeat Li Ion 830mAH */ - 348, 355, 359, 361, 363, 365, 370, 376, 380, 391, 399 + 3480, 3550, 3590, 3610, 3630, 3650, 3700, 3760, 3800, 3910, 3990 #elif CONFIG_BATTERY == BATT_LPCS355385 /* iriver H10 20GB */ - 399, 403, 406, 408, 410, 412, 415, 418, 422, 426, 431 + 3990, 4030, 4060, 4080, 4100, 4120, 4150, 4180, 4220, 4260, 4310 #elif CONFIG_BATTERY == BATT_BP009 /* iriver H10 5/6GB: Not yet calibrated */ - 388, 392, 396, 400, 406, 410, 415, 419, 424, 428, 433 + 3880, 3920, 3960, 4000, 4060, 4100, 4150, 4190, 4240, 4280, 4330 #else /* values guessed, see http://www.seattlerobotics.org/encoder/200210/LiIon2.pdf until someone measures voltages over a charging cycle */ - 476, 544, 551, 556, 561, 564, 566, 576, 582, 584, 585 /* NiMH */ + 4760, 5440, 5510, 5560, 5610, 5640, 5660, 5760, 5820, 5840, 5850 /* NiMH */ #endif }; #endif /* CONFIG_CHARGING */ @@ -342,7 +339,7 @@ int pid_i = 0; /* PID integral term */ * exponential filter. */ static unsigned int avgbat; /* average battery voltage (filtering) */ -static unsigned int battery_centivolts;/* filtered battery voltage, centvolts */ +static unsigned int battery_millivolts;/* filtered battery voltage, millivolts */ #ifdef HAVE_CHARGE_CTRL #define BATT_AVE_SAMPLES 32 /* filter constant / @ 2Hz sample rate */ #elif CONFIG_BATTERY == BATT_LIPOL1300 @@ -370,23 +367,19 @@ static long sleeptimer_endtick; static long last_event_tick; -static int voltage_to_battery_level(int battery_centivolts); +static int voltage_to_battery_level(int battery_millivolts); static void battery_status_update(void); static int runcurrent(void); -void battery_read_info(int *adc, int *voltage, int *level) +void battery_read_info(int *voltage, int *level) { - int adc_battery = adc_read(ADC_UNREG_POWER); - int centivolts = adc_battery*BATTERY_SCALE_FACTOR / 10000; - - if (adc) - *adc = adc_battery; + int millivolts = adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR / 1000; if (voltage) - *voltage = centivolts; + *voltage = millivolts; if (level) - *level = voltage_to_battery_level(centivolts); + *level = voltage_to_battery_level(millivolts); } void reset_poweroff_timer(void) @@ -425,22 +418,22 @@ int battery_level(void) return battery_percent; } -/* Returns filtered battery voltage [centivolts] */ +/* Returns filtered battery voltage [millivolts] */ unsigned int battery_voltage(void) { - return battery_centivolts; + return battery_millivolts; } -/* Returns battery voltage from ADC [centivolts] */ +/* Returns battery voltage from ADC [millivolts] */ int battery_adc_voltage(void) { - return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR + 5000) / 10000; + return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR + 500) / 1000; } /* Tells if the battery level is safe for disk writes */ bool battery_level_safe(void) { - return battery_centivolts > battery_level_dangerous[battery_type]; + return battery_millivolts > battery_level_dangerous[battery_type]; } void set_poweroff_timeout(int timeout) @@ -490,44 +483,44 @@ static int voltage_to_percent(int voltage, const short* table) /* update battery level and estimated runtime, called once per minute or * when battery capacity / type settings are changed */ -static int voltage_to_battery_level(int battery_centivolts) +static int voltage_to_battery_level(int battery_millivolts) { int level; #if defined(CONFIG_CHARGER) && CONFIG_BATTERY == BATT_LIPOL1300 if (charger_input_state == NO_CHARGER) { /* discharging. calculate new battery level and average with last */ - level = voltage_to_percent(battery_centivolts, + level = voltage_to_percent(battery_millivolts, percent_to_volt_discharge[battery_type]); if (level != (battery_percent - 1)) level = (level + battery_percent + 1) / 2; } else if (charger_input_state == CHARGER_UNPLUGGED) { /* just unplugged. adjust filtered values */ - battery_centivolts -= percent_to_volt_charge[battery_percent/10] - + battery_millivolts -= percent_to_volt_charge[battery_percent/10] - percent_to_volt_discharge[0][battery_percent/10]; - avgbat = battery_centivolts * 10000 * BATT_AVE_SAMPLES; + avgbat = battery_millivolts * 1000 * BATT_AVE_SAMPLES; level = battery_percent; } else if (charger_input_state == CHARGER_PLUGGED) { /* just plugged in. adjust battery values */ - battery_centivolts += percent_to_volt_charge[battery_percent/10] - + battery_millivolts += percent_to_volt_charge[battery_percent/10] - percent_to_volt_discharge[0][battery_percent/10]; - avgbat = battery_centivolts * 10000 * BATT_AVE_SAMPLES; + avgbat = battery_millivolts * 1000 * BATT_AVE_SAMPLES; level = MIN(12 * battery_percent / 10, 99); } else { /* charging. calculate new battery level */ - level = voltage_to_percent(battery_centivolts, + level = voltage_to_percent(battery_millivolts, percent_to_volt_charge); } #elif CONFIG_CHARGING >= CHARGING_MONITOR if (charge_state == DISCHARGING) { - level = voltage_to_percent(battery_centivolts, + level = voltage_to_percent(battery_millivolts, percent_to_volt_discharge[battery_type]); } else if (charge_state == CHARGING) { /* battery level is defined to be < 100% until charging is finished */ - level = MIN(voltage_to_percent(battery_centivolts, + level = MIN(voltage_to_percent(battery_millivolts, percent_to_volt_charge), 99); } else { /* in topoff/trickle charge, battery is by definition 100% full */ @@ -535,7 +528,7 @@ static int voltage_to_battery_level(int battery_centivolts) } #else /* always use the discharge table */ - level = voltage_to_percent(battery_centivolts, + level = voltage_to_percent(battery_millivolts, percent_to_volt_discharge[battery_type]); #endif @@ -544,7 +537,7 @@ static int voltage_to_battery_level(int battery_centivolts) static void battery_status_update(void) { - int level = voltage_to_battery_level(battery_centivolts); + int level = voltage_to_battery_level(battery_millivolts); /* calculate estimated remaining running time */ @@ -595,11 +588,11 @@ static void battery_status_update(void) else #endif /* BATT_LIPOL1300 */ { - if ((battery_centivolts + 2) > percent_to_volt_discharge[0][0]) + if ((battery_millivolts + 20) > percent_to_volt_discharge[0][0]) powermgmt_est_runningtime_min = (level + battery_percent) * 60 * battery_capacity / 200 / runcurrent(); else - powermgmt_est_runningtime_min = (battery_centivolts - + powermgmt_est_runningtime_min = (battery_millivolts - battery_level_shutoff[0]) / 2; } @@ -636,7 +629,7 @@ static void handle_auto_poweroff(void) /* switch off unit if battery level is too low for reliable operation */ #if (CONFIG_BATTERY!=BATT_4AA_NIMH) && (CONFIG_BATTERY!=BATT_3AAA)&& \ (CONFIG_BATTERY!=BATT_1AA) - if(battery_centivolts < battery_level_shutoff[battery_type]) { + if(battery_millivolts < battery_level_shutoff[battery_type]) { if(!shutdown_timeout) { backlight_on(); sys_poweroff(); @@ -847,9 +840,9 @@ static void power_thread_sleep(int ticks) avgbat += adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR - (avgbat / BATT_AVE_SAMPLES); /* - * battery_centivolts is the centivolt-scaled filtered battery value. + * battery_millivolts is the millivolt-scaled filtered battery value. */ - battery_centivolts = (avgbat / BATT_AVE_SAMPLES + 5000) / 10000; + battery_millivolts = (avgbat / BATT_AVE_SAMPLES + 500) / 1000; /* update battery status every time an update is available */ battery_status_update(); @@ -859,8 +852,8 @@ static void power_thread_sleep(int ticks) * Shut down if voltage drops below shutoff level and we are not * using NiMH or Alkaline batteries. */ - battery_centivolts = (battery_adc_voltage() + - battery_centivolts + 1) / 2; + battery_millivolts = (battery_adc_voltage() + + battery_millivolts + 1) / 2; /* update battery status every time an update is available */ battery_status_update(); @@ -868,11 +861,11 @@ static void power_thread_sleep(int ticks) #if (CONFIG_BATTERY!=BATT_4AA_NIMH) && (CONFIG_BATTERY!=BATT_3AAA)&& \ (CONFIG_BATTERY!=BATT_1AA) if (!shutdown_timeout && - (battery_centivolts < battery_level_shutoff[battery_type])) + (battery_millivolts < battery_level_shutoff[battery_type])) sys_poweroff(); else #endif - avgbat += battery_centivolts * 10000 + avgbat += battery_millivolts * 1000 - (avgbat / BATT_AVE_SAMPLES); } @@ -905,9 +898,8 @@ static void power_thread_sleep(int ticks) static void power_thread(void) { - int i; - short *phps, *phpd; /* power history rotation pointers */ #if CONFIG_CHARGING == CHARGING_CONTROL + int i; unsigned int target_voltage = TRICKLE_VOLTAGE; /* desired topoff/trickle * voltage level */ int charge_max_time_idle = 0; /* max. charging duration, calculated at @@ -929,22 +921,22 @@ static void power_thread(void) if(!charger_inserted()) /* only if charger not connected */ #endif avgbat += (percent_to_volt_discharge[battery_type][6] - - percent_to_volt_discharge[battery_type][5]) * 5000; + percent_to_volt_discharge[battery_type][5]) * 500; #endif /* not HAVE_MMC */ avgbat = avgbat * BATT_AVE_SAMPLES; - battery_centivolts = avgbat / BATT_AVE_SAMPLES / 10000; + battery_millivolts = avgbat / BATT_AVE_SAMPLES / 1000; #if CONFIG_CHARGING if(charger_inserted()) { - battery_percent = voltage_to_percent(battery_centivolts, + battery_percent = voltage_to_percent(battery_millivolts, percent_to_volt_charge); #if CONFIG_BATTERY == BATT_LIPOL1300 charger_input_state = CHARGER; #endif } else #endif - { battery_percent = voltage_to_percent(battery_centivolts, + { battery_percent = voltage_to_percent(battery_millivolts, percent_to_volt_discharge[battery_type]); battery_percent += (battery_percent < 100); } @@ -957,13 +949,11 @@ static void power_thread(void) while (1) { /* rotate the power history */ - phpd = &power_history[POWER_HISTORY_LEN - 1]; - phps = phpd - 1; - for (i = 0; i < POWER_HISTORY_LEN-1; i++) - *phpd-- = *phps--; + memmove(power_history + 1, power_history, + sizeof(power_history) - sizeof(power_history[0])); - /* insert new value at the start, in centivolts 8-) */ - power_history[0] = battery_centivolts; + /* insert new value at the start, in millivolts 8-) */ + power_history[0] = battery_millivolts; #if CONFIG_CHARGING == CHARGING_CONTROL if (charger_input_state == CHARGER_PLUGGED) { @@ -1046,15 +1036,15 @@ static void power_thread(void) power_history[CHARGE_END_LONGD - 1]; for(i = CHARGE_END_SHORTD; i < CHARGE_END_SHORTD + 10; i++) { - if(((power_history[i] - power_history[i+1]) > 5) || - ((power_history[i] - power_history[i+1]) < -5)) { + if(((power_history[i] - power_history[i+1]) > 50) || + ((power_history[i] - power_history[i+1]) < -50)) { long_delta = 777777; break; } } for(i = CHARGE_END_LONGD - 11; i < CHARGE_END_LONGD - 1 ; i++) { - if(((power_history[i] - power_history[i+1]) > 5) || - ((power_history[i] - power_history[i+1]) < -5)) { + if(((power_history[i] - power_history[i+1]) > 50) || + ((power_history[i] - power_history[i+1]) < -50)) { long_delta = 888888; break; } @@ -1069,10 +1059,10 @@ static void power_thread(void) * 1) Charged a long time * 2) DeltaV went negative for a short time ( & long delta static) * 3) DeltaV was negative over a longer period (no disk use only) - * Note: short_delta and long_delta are centivolts + * Note: short_delta and long_delta are millivolts */ if ((powermgmt_last_cycle_startstop_min >= charge_max_time_now) || - (short_delta <= -5 && long_delta < 5 ) || (long_delta < -2 && + (short_delta <= -50 && long_delta < 50 ) || (long_delta < -20 && last_disk_activity > CHARGE_END_LONGD)) { if (powermgmt_last_cycle_startstop_min > charge_max_time_now) { DEBUGF("power: powermgmt_last_cycle_startstop_min > charge_max_time_now, " @@ -1100,7 +1090,7 @@ static void power_thread(void) * trickle target is -0.15v from full voltage acheived * topup target is -0.05v from full voltage */ - target_voltage = power_history[0] - 15; + target_voltage = power_history[0] - 150; } else { if(short_delta <= -5) { @@ -1110,7 +1100,7 @@ static void power_thread(void) "end negd %d %dmin", short_delta, powermgmt_last_cycle_startstop_min); target_voltage = power_history[CHARGE_END_SHORTD - 1] - - 5; + - 50; } else { DEBUGF("power: long-term small " "positive delta, enough!\n"); @@ -1118,7 +1108,7 @@ static void power_thread(void) "end lowd %d %dmin", long_delta, powermgmt_last_cycle_startstop_min); target_voltage = power_history[CHARGE_END_LONGD - 1] - - 5; + - 50; } /* * Switch to top-off charging. @@ -1140,7 +1130,7 @@ static void power_thread(void) powermgmt_last_cycle_level = battery_percent; powermgmt_last_cycle_startstop_min = 0; charge_state = TRICKLE; - target_voltage = target_voltage - 10; + target_voltage = target_voltage - 100; } /* * Adjust trickle charge time (proportional and integral terms). @@ -1149,12 +1139,11 @@ static void power_thread(void) * generate more heat [gvb]. */ - pid_p = target_voltage - battery_centivolts; - if((pid_p > PID_DEADZONE) || (pid_p < -PID_DEADZONE)) - pid_p = pid_p * PID_PCONST; - else + pid_p = (target_voltage - battery_millivolts) / 5; + if((pid_p <= PID_DEADZONE) && (pid_p >= -PID_DEADZONE)) pid_p = 0; - if((unsigned) battery_centivolts < target_voltage) { + + if((unsigned) battery_millivolts < target_voltage) { if(pid_i < 60) { pid_i++; /* limit so it doesn't "wind up" */ } @@ -1227,7 +1216,7 @@ static void power_thread(void) fd = open(DEBUG_FILE_NAME, O_WRONLY | O_APPEND | O_CREAT); if(fd >= 0) { snprintf(debug_message, DEBUG_MESSAGE_LEN, - "cycle_min, bat_centivolts, bat_percent, chgr_state, charge_state, pid_p, pid_i, trickle_sec\n"); + "cycle_min, bat_millivolts, bat_percent, chgr_state, charge_state, pid_p, pid_i, trickle_sec\n"); write(fd, debug_message, strlen(debug_message)); wrcount = 99; /* force a flush */ } @@ -1235,7 +1224,7 @@ static void power_thread(void) if(fd >= 0) { snprintf(debug_message, DEBUG_MESSAGE_LEN, "%d, %d, %d, %d, %d, %d, %d, %d\n", - powermgmt_last_cycle_startstop_min, battery_centivolts, + powermgmt_last_cycle_startstop_min, battery_millivolts, battery_percent, charger_input_state, charge_state, pid_p, pid_i, trickle_sec); write(fd, debug_message, strlen(debug_message)); diff --git a/flash/bootbox/main.c b/flash/bootbox/main.c index 698a7e0954..5cc4bb66ae 100644 --- a/flash/bootbox/main.c +++ b/flash/bootbox/main.c @@ -99,7 +99,7 @@ void charging_screen(void) char buf[32]; int battv = battery_voltage(); snprintf(buf, sizeof(buf), "%d.%02dV %d%%", - battv / 100, battv % 100, battery_level()); + battv / 1000, (battv % 1000) / 10, battery_level()); lcd_puts(0, 1, buf); } lcd_update();