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
This commit is contained in:
Jens Arnold 2007-08-15 23:57:27 +00:00
parent 653b996828
commit 1d1d9a8491
7 changed files with 157 additions and 184 deletions

View file

@ -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());

View file

@ -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;
}

View file

@ -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

View file

@ -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 */

View file

@ -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);

View file

@ -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));

View file

@ -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();