1
0
Fork 0
forked from len0rd/rockbox

Massively code-policed. We keep source lines less than 80 columns...

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@3378 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Daniel Stenberg 2003-03-04 05:59:38 +00:00
parent 975e240a0c
commit 2573879fb1

View file

@ -63,24 +63,28 @@ void set_battery_capacity(int capacity)
} }
#else /* not SIMULATOR */ #else /* not SIMULATOR */
int battery_capacity = 1500; /* only a default value */ int battery_capacity = 1500; /* only a default value */
int battery_level_cached = -1; /* battery level of this minute, updated once per minute */ int battery_level_cached = -1; /* battery level of this minute, updated once
per minute */
static int poweroff_idle_timeout_value[15] = static int poweroff_idle_timeout_value[15] =
{ {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 30, 45, 60 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 30, 45, 60
}; };
static int percent_to_volt_decharge[11] = /* voltages (centivolt) of 0%, 10%, ... 100% when charging disabled */ static int percent_to_volt_decharge[11] =
/* voltages (centivolt) of 0%, 10%, ... 100% when charging disabled */
{ {
#ifdef HAVE_LIION #ifdef HAVE_LIION
/* values guessed, see http://www.seattlerobotics.org/encoder/200210/LiIon2.pdf */ /* values guessed, see
/* until someone measures voltages over a decharging cycle */ http://www.seattlerobotics.org/encoder/200210/LiIon2.pdf until someone
measures voltages over a decharging cycle */
260, 280, 300, 320, 340, 350, 360, 370, 380, 390, 400 260, 280, 300, 320, 340, 350, 360, 370, 380, 390, 400
#else /* NiMH */ #else /* NiMH */
/* original values were taken directly after charging, */ /* original values were taken directly after charging, but it should show
/* but it should show 100% after turning off the device for some hours, too */ 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 */ 450, 481, 491, 497, 503, 507, 512, 514, 517, 525, 540 /* orig. values:
...,528,560 */
#endif #endif
}; };
@ -95,18 +99,29 @@ void set_battery_capacity(int capacity)
#ifdef HAVE_CHARGE_CTRL #ifdef HAVE_CHARGE_CTRL
char power_message[POWER_MESSAGE_LEN] = ""; /* message that's shown in debug menu */ char power_message[POWER_MESSAGE_LEN] = ""; /* message that's shown in
char charge_restart_level = CHARGE_RESTART_HI; /* level at which charging starts */ debug menu */
int powermgmt_last_cycle_startstop_min = 25; /* how many minutes ago was the charging started or stopped? */ char charge_restart_level = CHARGE_RESTART_HI; /* level at which charging
int powermgmt_last_cycle_level = 0; /* which level had the batteries at this time? */ starts */
int powermgmt_last_cycle_startstop_min = 25; /* how many minutes ago was the
charging started or
stopped? */
int powermgmt_last_cycle_level = 0; /* which level had the
batteries at this time? */
bool trickle_charge_enabled = true; bool trickle_charge_enabled = true;
int trickle_sec = 0; /* how many seconds should the charger be enabled per minute for trickle charging? */ int trickle_sec = 0; /* how many seconds should the
int charge_state = 0; /* at the beginning, the charger does nothing */ charger be enabled per
minute for trickle
charging? */
int charge_state = 0; /* at the beginning, the
charger does nothing */
static int percent_to_volt_charge[11] = /* voltages (centivolt) of 0%, 10%, ... 100% when charging enabled */ static int percent_to_volt_charge[11] = /* voltages (centivolt) of 0%, 10%,
... 100% when charging enabled */
{ {
/* values guessed, see http://www.seattlerobotics.org/encoder/200210/LiIon2.pdf */ /* values guessed, see
/* until someone measures voltages over a charging cycle */ 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 */ 476, 544, 551, 556, 561, 564, 566, 576, 582, 584, 585 /* NiMH */
}; };
@ -133,23 +148,25 @@ int battery_time(void)
return powermgmt_est_runningtime_min; return powermgmt_est_runningtime_min;
} }
/* look into the percent_to_volt_* table and get a realistic battery level percentage */ /* look into the percent_to_volt_* table and get a realistic battery level
percentage */
int voltage_to_percent(int voltage, int* table) int voltage_to_percent(int voltage, int* table)
{ {
if (voltage <= table[0]) if (voltage <= table[0])
return 0; return 0;
else else
if (voltage >= table[10]) if (voltage >= table[10])
return 100; return 100;
else { else {
/* search nearest value */ /* search nearest value */
int i = 0; int i = 0;
while ((i < 10) && (table[i+1] < voltage)) while ((i < 10) && (table[i+1] < voltage))
i++; i++;
/* interpolate linear between the smaller and greater value */ /* interpolate linear between the smaller and greater value */
return i * 10 /* 10th */ return i * 10 /* 10th */
+ (voltage - table[i]) * 10 / (table[i+1] - table[i]); /* 1th */ + (voltage - table[i]) *
} 10 / (table[i+1] - table[i]); /* 1th */
}
} }
/* update battery level, called only once per minute */ /* update battery level, called only once per minute */
@ -180,28 +197,34 @@ void battery_level_update(void)
#ifdef HAVE_CHARGE_CTRL #ifdef HAVE_CHARGE_CTRL
if (charge_state == 0) { /* decharge */ if (charge_state == 0) { /* decharge */
level = voltage_to_percent(level, percent_to_volt_decharge); level = voltage_to_percent(level, percent_to_volt_decharge);
} else if (charge_state == 1) { /* charge */ }
level = voltage_to_percent(level, percent_to_volt_charge); else if (charge_state == 1) { /* charge */
} else {/* in trickle charge, the battery is per definition 100% full */ level = voltage_to_percent(level, percent_to_volt_charge);
}
else {/* in trickle charge, the battery is per definition 100% full */
battery_level_cached = level = 100; battery_level_cached = level = 100;
} }
#else #else
level = voltage_to_percent(level, percent_to_volt_decharge); /* always use the decharge table */ level = voltage_to_percent(level, percent_to_volt_decharge);
/* always use the decharge table */
#endif #endif
if (battery_level_cached == -1) { /* first run of this procedure */ if (battery_level_cached == -1) { /* first run of this procedure */
/* the battery voltage is usually a little lower directly after turning on, because the disk was used heavily */ /* the battery voltage is usually a little lower directly after
/* raise it by 5 % */ turning on, because the disk was used heavily raise it by 5 % */
battery_level_cached = (level > 95) ? 100 : level + 5; battery_level_cached = (level > 95) ? 100 : level + 5;
} else { }
/* the level is allowed to be +1/-1 of the last value when usb not connected */ else {
/* and to be +1/-3 of the last value when usb is connected */ /* the level is allowed to be +1/-1 of the last value when usb not
connected and to be +1/-3 of the last value when usb is
connected */
if (level > battery_level_cached + 1) if (level > battery_level_cached + 1)
level = battery_level_cached + 1; level = battery_level_cached + 1;
if (usb_inserted()) { if (usb_inserted()) {
if (level < battery_level_cached - 3) if (level < battery_level_cached - 3)
level = battery_level_cached - 3; level = battery_level_cached - 3;
} else { }
else {
if (level < battery_level_cached - 1) if (level < battery_level_cached - 1)
level = battery_level_cached - 1; level = battery_level_cached - 1;
} }
@ -222,7 +245,8 @@ bool battery_level_safe(void)
if (power_history[POWER_HISTORY_LEN-1]) if (power_history[POWER_HISTORY_LEN-1])
return power_history[POWER_HISTORY_LEN-1] > BATTERY_LEVEL_DANGEROUS; return power_history[POWER_HISTORY_LEN-1] > BATTERY_LEVEL_DANGEROUS;
else else
return adc_read(ADC_UNREG_POWER) > (BATTERY_LEVEL_DANGEROUS * 10000) / BATTERY_SCALE_FACTOR; return adc_read(ADC_UNREG_POWER) > (BATTERY_LEVEL_DANGEROUS * 10000) /
BATTERY_SCALE_FACTOR;
} }
void set_poweroff_timeout(int timeout) void set_poweroff_timeout(int timeout)
@ -232,13 +256,11 @@ void set_poweroff_timeout(int timeout)
void set_sleep_timer(int seconds) void set_sleep_timer(int seconds)
{ {
if(seconds) if(seconds) {
{
sleeptimer_active = true; sleeptimer_active = true;
sleeptimer_endtick = current_tick + seconds * HZ; sleeptimer_endtick = current_tick + seconds * HZ;
} }
else else {
{
sleeptimer_active = false; sleeptimer_active = false;
sleeptimer_endtick = 0; sleeptimer_endtick = 0;
} }
@ -324,7 +346,8 @@ static void power_thread(void)
#ifdef HAVE_CHARGE_CTRL #ifdef HAVE_CHARGE_CTRL
int delta; int delta;
int charged_time = 0; int charged_time = 0;
int charge_max_time_now = 0; /* max. charging duration, calculated at beginning of charging */ int charge_max_time_now = 0; /* max. charging duration, calculated at
beginning of charging */
int charge_pause = 0; /* no charging pause at the beginning */ int charge_pause = 0; /* no charging pause at the beginning */
int trickle_time = 0; /* how many minutes trickle charging already? */ int trickle_time = 0; /* how many minutes trickle charging already? */
#endif #endif
@ -360,9 +383,11 @@ static void power_thread(void)
power_history[i] = power_history[i+1]; power_history[i] = power_history[i+1];
/* insert new value in the end, in centivolts 8-) */ /* insert new value in the end, in centivolts 8-) */
power_history[POWER_HISTORY_LEN-1] = (avg * BATTERY_SCALE_FACTOR) / 10000; power_history[POWER_HISTORY_LEN-1] =
(avg * BATTERY_SCALE_FACTOR) / 10000;
/* update battery level every minute, ignoring first 15 minutes after start charge/decharge */ /* update battery level every minute, ignoring first 15 minutes after
start charge/decharge */
#ifdef HAVE_CHARGE_CTRL #ifdef HAVE_CHARGE_CTRL
if ((powermgmt_last_cycle_startstop_min > 25) || (charge_state > 1)) if ((powermgmt_last_cycle_startstop_min > 25) || (charge_state > 1))
#endif #endif
@ -374,24 +399,30 @@ static void power_thread(void)
#ifdef HAVE_CHARGE_CTRL #ifdef HAVE_CHARGE_CTRL
if (charge_state == 1) if (charge_state == 1)
powermgmt_est_runningtime_min = (100 - battery_level()) * battery_capacity / 100 * 60 / CURRENT_CHARGING; powermgmt_est_runningtime_min = (100 - battery_level()) *
battery_capacity / 100 * 60 / CURRENT_CHARGING;
else { else {
current = usb_inserted() ? CURRENT_USB : CURRENT_NORMAL; current = usb_inserted() ? CURRENT_USB : CURRENT_NORMAL;
if ((backlight_get_timeout() == 1) || (charger_inserted() && backlight_get_on_when_charging())) if ((backlight_get_timeout() == 1) ||
/* LED always on or LED on when charger connected */ (charger_inserted() && backlight_get_on_when_charging()))
/* LED always on or LED on when charger connected */
current += CURRENT_BACKLIGHT; current += CURRENT_BACKLIGHT;
powermgmt_est_runningtime_min = battery_level() * battery_capacity / 100 * 60 / current; powermgmt_est_runningtime_min = battery_level() *
battery_capacity / 100 * 60 / current;
#if MEM == 8 /* assuming 192 kbps, the running time is 22% longer with 8MB */ #if MEM == 8 /* assuming 192 kbps, the running time is 22% longer with 8MB */
powermgmt_est_runningtime_min = powermgmt_est_runningtime_min * 122 / 100; powermgmt_est_runningtime_min =
powermgmt_est_runningtime_min * 122 / 100;
#endif /* MEM == 8 */ #endif /* MEM == 8 */
} }
#else #else
current = usb_inserted() ? CURRENT_USB : CURRENT_NORMAL; current = usb_inserted() ? CURRENT_USB : CURRENT_NORMAL;
if (backlight_get_timeout() == 1) /* LED always on */ if (backlight_get_timeout() == 1) /* LED always on */
current += CURRENT_BACKLIGHT; current += CURRENT_BACKLIGHT;
powermgmt_est_runningtime_min = battery_level() * battery_capacity / 100 * 60 / current; powermgmt_est_runningtime_min = battery_level() *
battery_capacity / 100 * 60 / current;
#if MEM == 8 /* assuming 192 kbps, the running time is 22% longer with 8MB */ #if MEM == 8 /* assuming 192 kbps, the running time is 22% longer with 8MB */
powermgmt_est_runningtime_min = powermgmt_est_runningtime_min * 122 / 100; powermgmt_est_runningtime_min =
powermgmt_est_runningtime_min * 122 / 100;
#endif /* MEM == 8 */ #endif /* MEM == 8 */
#endif /* HAVE_CHARGE_CONTROL */ #endif /* HAVE_CHARGE_CONTROL */
@ -404,89 +435,133 @@ static void power_thread(void)
if (charge_state == 1) { if (charge_state == 1) {
/* charger inserted and enabled */ /* charger inserted and enabled */
charged_time++; charged_time++;
snprintf(power_message, POWER_MESSAGE_LEN, "Chg %dm max %dm", charged_time, charge_max_time_now); snprintf(power_message, POWER_MESSAGE_LEN,
"Chg %dm max %dm", charged_time, charge_max_time_now);
if (charged_time > charge_max_time_now) { if (charged_time > charge_max_time_now) {
DEBUGF("power: charged_time > charge_max_time_now, enough!\n"); DEBUGF("power: charged_time > charge_max_time_now, "
/* have charged too long and deltaV detection did not work! */ "enough!\n");
/* have charged too long and deltaV detection did not
work! */
powermgmt_last_cycle_level = battery_level(); powermgmt_last_cycle_level = battery_level();
powermgmt_last_cycle_startstop_min = 0; powermgmt_last_cycle_startstop_min = 0;
charger_enable(false); charger_enable(false);
snprintf(power_message, POWER_MESSAGE_LEN, "Chg tmout %d min", charge_max_time_now); snprintf(power_message, POWER_MESSAGE_LEN,
/* disable charging for several hours from this point, just to be sure */ "Chg tmout %d min", charge_max_time_now);
/* disable charging for several hours from this point,
just to be sure */
charge_pause = CHARGE_PAUSE_LEN; charge_pause = CHARGE_PAUSE_LEN;
/* no trickle charge here, because the charging cycle didn't end the right way */ /* no trickle charge here, because the charging cycle
charge_state = 0; /* 0: decharging/charger off, 1: charge, 2: top-off, 3: trickle */ didn't end the right way */
charge_state = 0; /* 0: decharging/charger off, 1: charge,
2: top-off, 3: trickle */
} else { } else {
if (charged_time > CHARGE_MIN_TIME) { if (charged_time > CHARGE_MIN_TIME) {
/* have charged continuously over the minimum charging time, /* have charged continuously over the minimum charging
* so we monitor for deltaV going negative. Multiply things time, so we monitor for deltaV going
* by 100 to get more accuracy without floating point arithmetic. negative. Multiply thingsby 100 to get more
* power_history[] contains centivolts so after multiplying by 100 accuracy without floating point arithmetic.
* the deltas are in tenths of millivolts (delta of 5 is power_history[] contains centivolts so after
* 0.0005 V). multiplying by 100 the deltas are in tenths of
millivolts (delta of 5 is 0.0005 V).
*/ */
delta = ( power_history[POWER_HISTORY_LEN-1] * 100 delta =
+ power_history[POWER_HISTORY_LEN-2] * 100 ( power_history[POWER_HISTORY_LEN-1] * 100
- power_history[POWER_HISTORY_LEN-1-CHARGE_END_NEGD+1] * 100 + power_history[POWER_HISTORY_LEN-2] * 100
- power_history[POWER_HISTORY_LEN-1-CHARGE_END_NEGD] * 100 ) - power_history[POWER_HISTORY_LEN-1-
/ CHARGE_END_NEGD / 2; CHARGE_END_NEGD+1] * 100
- power_history[POWER_HISTORY_LEN-1-
CHARGE_END_NEGD] * 100 )
/ CHARGE_END_NEGD / 2;
if (delta < -100) { /* delta < -10 mV */ if (delta < -100) { /* delta < -10 mV */
DEBUGF("power: short-term negative delta, enough!\n"); DEBUGF("power: short-term negative"
" delta, enough!\n");
powermgmt_last_cycle_level = battery_level(); powermgmt_last_cycle_level = battery_level();
powermgmt_last_cycle_startstop_min = 0; powermgmt_last_cycle_startstop_min = 0;
charger_enable(false); charger_enable(false);
snprintf(power_message, POWER_MESSAGE_LEN, "end negd %d %dmin", delta, charged_time); snprintf(power_message, POWER_MESSAGE_LEN,
/* disable charging for several hours from this point, just to be sure */ "end negd %d %dmin", delta, charged_time);
/* disable charging for several hours from this
point, just to be sure */
charge_pause = CHARGE_PAUSE_LEN; charge_pause = CHARGE_PAUSE_LEN;
/* enable trickle charging */ /* enable trickle charging */
if (trickle_charge_enabled) { if (trickle_charge_enabled) {
trickle_sec = CURRENT_NORMAL * 60 / CURRENT_CHARGING; /* first guess, maybe consider if LED backlight is on, disk is active,... */ trickle_sec = CURRENT_NORMAL * 60 /
CURRENT_CHARGING;
/* first guess, maybe consider if LED
backlight is on, disk is active,... */
trickle_time = 0; trickle_time = 0;
charge_state = 2; /* 0: decharging/charger off, 1: charge, 2: top-off, 3: trickle */ charge_state = 2; /* 0: decharging/charger
off, 1: charge,
2: top-off, 3: trickle */
} else { } else {
charge_state = 0; /* 0: decharging/charger off, 1: charge, 2: top-off, 3: trickle */ charge_state = 0; /* 0: decharging/charger
off, 1: charge,
2: top-off, 3: trickle */
} }
} else { } else {
/* if we didn't disable the charger in the previous test, check for low positive delta */ /* if we didn't disable the charger in the
delta = ( power_history[POWER_HISTORY_LEN-1] * 100 previous test, check for low positive delta */
+ power_history[POWER_HISTORY_LEN-2] * 100 delta =
- power_history[POWER_HISTORY_LEN-1-CHARGE_END_ZEROD+1] * 100 ( power_history[POWER_HISTORY_LEN-1] * 100
- power_history[POWER_HISTORY_LEN-1-CHARGE_END_ZEROD] * 100 ) + power_history[POWER_HISTORY_LEN-2] * 100
/ CHARGE_END_ZEROD / 2; - power_history[POWER_HISTORY_LEN-1-
CHARGE_END_ZEROD+1] * 100
- power_history[POWER_HISTORY_LEN-1-
CHARGE_END_ZEROD] * 100 )
/ CHARGE_END_ZEROD / 2;
if (delta < 1) { /* delta < 0.1 mV */ if (delta < 1) { /* delta < 0.1 mV */
DEBUGF("power: long-term small positive delta, enough!\n"); DEBUGF("power: long-term small "
"positive delta, enough!\n");
powermgmt_last_cycle_level = battery_level(); powermgmt_last_cycle_level = battery_level();
powermgmt_last_cycle_startstop_min = 0; powermgmt_last_cycle_startstop_min = 0;
charger_enable(false); charger_enable(false);
snprintf(power_message, POWER_MESSAGE_LEN, "end lowd %d %dmin", delta, charged_time); snprintf(power_message, POWER_MESSAGE_LEN,
/* disable charging for several hours from this point, just to be sure */ "end lowd %d %dmin",
delta, charged_time);
/* disable charging for several hours from
this point, just to be sure */
charge_pause = CHARGE_PAUSE_LEN; charge_pause = CHARGE_PAUSE_LEN;
/* enable trickle charging */ /* enable trickle charging */
if (trickle_charge_enabled) { if (trickle_charge_enabled) {
trickle_sec = CURRENT_NORMAL * 60 / CURRENT_CHARGING; /* first guess, maybe consider if LED backlight is on, disk is active,... */ trickle_sec =
CURRENT_NORMAL * 60 / CURRENT_CHARGING;
/* first guess, maybe consider if LED
backlight is on, disk is active,... */
trickle_time = 0; trickle_time = 0;
charge_state = 2; /* 0: decharging/charger off, 1: charge, 2: top-off, 3: trickle */ charge_state = 2;
/* 0: decharging/charger off, 1: charge,
2: top-off, 3: trickle */
} else { } else {
charge_state = 0; /* 0: decharging/charger off, 1: charge, 2: top-off, 3: trickle */ charge_state = 0;
/* 0: decharging/charger off, 1: charge,
2: top-off, 3: trickle */
} }
} }
} }
} }
} }
} else if (charge_state > 1) { /* top off or trickle? */ }
else if (charge_state > 1) { /* top off or trickle? */
/* adjust trickle charge time */ /* adjust trickle charge time */
if ( ((charge_state == 2) && (power_history[POWER_HISTORY_LEN-1] > TOPOFF_VOLTAGE)) if ( ((charge_state == 2) &&
|| ((charge_state == 3) && (power_history[POWER_HISTORY_LEN-1] > TRICKLE_VOLTAGE)) ) { /* charging too much */ (power_history[POWER_HISTORY_LEN-1] > TOPOFF_VOLTAGE))
|| ((charge_state == 3) &&
(power_history[POWER_HISTORY_LEN-1] >
TRICKLE_VOLTAGE)) ) { /* charging too much */
trickle_sec--; trickle_sec--;
} else { /* charging too less */ }
else { /* charging too less */
trickle_sec++; trickle_sec++;
} }
if (trickle_sec > 24) trickle_sec = 24; if (trickle_sec > 24)
if (trickle_sec < 1) trickle_sec = 1; trickle_sec = 24;
if (trickle_sec < 1)
trickle_sec = 1;
/* charge the calculated amount of seconds */ /* charge the calculated amount of seconds */
charger_enable(true); charger_enable(true);
@ -496,57 +571,76 @@ static void power_thread(void)
/* trickle charging long enough? */ /* trickle charging long enough? */
if (trickle_time++ > TRICKLE_MAX_TIME + TOPOFF_MAX_TIME) { if (trickle_time++ > TRICKLE_MAX_TIME + TOPOFF_MAX_TIME) {
trickle_sec = 0; /* show in debug menu that trickle is off */ trickle_sec = 0; /* show in debug menu that trickle is
charge_state = 0; /* 0: decharging/charger off, 1: charge, 2: top-off, 3: trickle */ off */
charge_state = 0; /* 0: decharging/charger off, 1: charge,
2: top-off, 3: trickle */
powermgmt_last_cycle_startstop_min = 0; powermgmt_last_cycle_startstop_min = 0;
} }
if ((charge_state == 2) && (trickle_time > TOPOFF_MAX_TIME)) /* change state? */ if ((charge_state == 2) &&
charge_state = 3; /* 0: decharging/charger off, 1: charge, 2: top-off, 3: trickle */ (trickle_time > TOPOFF_MAX_TIME)) /* change state? */
charge_state = 3; /* 0: decharging/charger off, 1: charge,
2: top-off, 3: trickle */
} else { /* charge_state == 0 */ } else { /* charge_state == 0 */
/* the charger is enabled here only in one case: if it was turned on at boot time (power_init) */ /* the charger is enabled here only in one case: if it was
turned on at boot time (power_init) */
/* turn it off now */ /* turn it off now */
if (charger_enabled) if (charger_enabled)
charger_enable(false); charger_enable(false);
} }
/* Start new charge cycle? This must be possible also in trickle/top-off, because when usb connected, */ /* Start new charge cycle? This must be possible also in
trickle/top-off, because when usb connected, */
/* the trickle charge amount may not be enough */ /* the trickle charge amount may not be enough */
if ((charge_state == 0) || (charge_state > 1)) if ((charge_state == 0) || (charge_state > 1))
/* if battery is not full, enable charging */ /* if battery is not full, enable charging */
/* make sure charging starts if 1%-lazyness in battery_level_update() is too slow */ /* make sure charging starts if 1%-lazyness in
battery_level_update() is too slow */
if ( (battery_level() < charge_restart_level) if ( (battery_level() < charge_restart_level)
|| (power_history[POWER_HISTORY_LEN-1] < BATTERY_LEVEL_DANGEROUS)) { || (power_history[POWER_HISTORY_LEN-1] <
BATTERY_LEVEL_DANGEROUS)) {
if (charge_pause) { if (charge_pause) {
DEBUGF("power: batt level < restart level, but charge pause, not enabling\n"); DEBUGF("power: batt level < restart level,"
snprintf(power_message, POWER_MESSAGE_LEN, "chg pause %d min", charge_pause); " but charge pause, not enabling\n");
snprintf(power_message, POWER_MESSAGE_LEN,
"chg pause %d min", charge_pause);
} else { } else {
/* calculate max charge time depending on current battery level */ /* calculate max charge time depending on current
/* take 35% more because some more energy is used for heating up the battery */ battery level */
/* take 35% more because some more energy is used for
heating up the battery */
i = CHARGE_MAX_TIME_1500 * battery_capacity / 1500; i = CHARGE_MAX_TIME_1500 * battery_capacity / 1500;
charge_max_time_now = i * (100 + 35 - battery_level()) / 100; charge_max_time_now =
i * (100 + 35 - battery_level()) / 100;
if (charge_max_time_now > i) { if (charge_max_time_now > i) {
charge_max_time_now = i; charge_max_time_now = i;
} }
snprintf(power_message, POWER_MESSAGE_LEN, "ChgAt %d%% max %dm", battery_level(), charge_max_time_now); snprintf(power_message, POWER_MESSAGE_LEN,
"ChgAt %d%% max %dm", battery_level(),
charge_max_time_now);
/* enable the charger after the max time calc is done, because battery_level */ /* enable the charger after the max time calc is done,
/* depends on if the charger is on */ because battery_level depends on if the charger is
DEBUGF("power: charger inserted and battery not full, enabling\n"); on */
DEBUGF("power: charger inserted and battery"
" not full, enabling\n");
powermgmt_last_cycle_level = battery_level(); powermgmt_last_cycle_level = battery_level();
powermgmt_last_cycle_startstop_min = 0; powermgmt_last_cycle_startstop_min = 0;
charged_time = 0; charged_time = 0;
charger_enable(true); charger_enable(true);
charge_state = 1; /* 0: decharging/charger off, 1: charge, 2: top-off, 3: trickle */ charge_state = 1; /* 0: decharging/charger off, 1:
/* clear the power history so that we don't use values before charge, 2: top-off, 3: trickle */
* discharge for the long-term delta /* clear the power history so that we don't use values
before discharge for the long-term delta
*/ */
for (i = 0; i < POWER_HISTORY_LEN-1; i++) for (i = 0; i < POWER_HISTORY_LEN-1; i++)
power_history[i] = power_history[POWER_HISTORY_LEN-1]; power_history[i] =
power_history[POWER_HISTORY_LEN-1];
} }
} }
@ -560,7 +654,8 @@ static void power_thread(void)
/* show in debug menu that trickle is off */ /* show in debug menu that trickle is off */
trickle_sec = 0; trickle_sec = 0;
charger_enable(false); charger_enable(false);
charge_state = 0; /* 0: decharging/charger off, 1: charge, 2: top-off, 3: trickle */ charge_state = 0; /* 0: decharging/charger off, 1: charge, 2:
top-off, 3: trickle */
snprintf(power_message, POWER_MESSAGE_LEN, "Charger disc"); snprintf(power_message, POWER_MESSAGE_LEN, "Charger disc");
} }
/* charger not inserted and disabled, so we're discharging */ /* charger not inserted and disabled, so we're discharging */
@ -588,11 +683,14 @@ void power_init(void)
memset(power_history, 0x00, sizeof(power_history)); memset(power_history, 0x00, sizeof(power_history));
/* initialize the history with a single sample to prevent level /* initialize the history with a single sample to prevent level
flickering during the first minute of execution */ flickering during the first minute of execution */
power_history[POWER_HISTORY_LEN-1] = (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) / 10000; power_history[POWER_HISTORY_LEN-1] =
(adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) / 10000;
/* calculate the first battery level */ /* calculate the first battery level */
battery_level_update(); battery_level_update();
/* calculate the remaining time to that the info screen displays something useful */ /* calculate the remaining time to that the info screen displays something
powermgmt_est_runningtime_min = battery_level() * battery_capacity / 100 * 60 / CURRENT_NORMAL; useful */
powermgmt_est_runningtime_min =
battery_level() * battery_capacity / 100 * 60 / CURRENT_NORMAL;
#if MEM == 8 /* assuming 192 kbps, the running time is 22% longer with 8MB */ #if MEM == 8 /* assuming 192 kbps, the running time is 22% longer with 8MB */
powermgmt_est_runningtime_min = powermgmt_est_runningtime_min * 122 / 100; powermgmt_est_runningtime_min = powermgmt_est_runningtime_min * 122 / 100;
#endif #endif
@ -605,7 +703,8 @@ void power_init(void)
charger_enable(true); charger_enable(true);
#endif #endif
create_thread(power_thread, power_stack, sizeof(power_stack), power_thread_name); create_thread(power_thread, power_stack, sizeof(power_stack),
power_thread_name);
} }
#endif /* SIMULATOR */ #endif /* SIMULATOR */