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

@ -64,23 +64,27 @@ void set_battery_capacity(int capacity)
#else /* not SIMULATOR */
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] =
{
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
/* values guessed, see http://www.seattlerobotics.org/encoder/200210/LiIon2.pdf */
/* until someone measures voltages over a decharging cycle */
/* values guessed, see
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
#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 */
/* 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 */
#endif
};
@ -95,18 +99,29 @@ void set_battery_capacity(int capacity)
#ifdef HAVE_CHARGE_CTRL
char power_message[POWER_MESSAGE_LEN] = ""; /* message that's shown in debug menu */
char charge_restart_level = CHARGE_RESTART_HI; /* level at which charging 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? */
char power_message[POWER_MESSAGE_LEN] = ""; /* message that's shown in
debug menu */
char charge_restart_level = CHARGE_RESTART_HI; /* level at which charging
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;
int trickle_sec = 0; /* how many seconds should the charger be enabled per minute for trickle charging? */
int charge_state = 0; /* at the beginning, the charger does nothing */
int trickle_sec = 0; /* how many seconds should the
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 */
/* until someone measures voltages over a charging cycle */
/* 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 */
};
@ -133,7 +148,8 @@ int battery_time(void)
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)
{
if (voltage <= table[0])
@ -148,7 +164,8 @@ int voltage_to_percent(int voltage, int* table)
i++;
/* interpolate linear between the smaller and greater value */
return i * 10 /* 10th */
+ (voltage - table[i]) * 10 / (table[i+1] - table[i]); /* 1th */
+ (voltage - table[i]) *
10 / (table[i+1] - table[i]); /* 1th */
}
}
@ -180,28 +197,34 @@ void battery_level_update(void)
#ifdef HAVE_CHARGE_CTRL
if (charge_state == 0) { /* decharge */
level = voltage_to_percent(level, percent_to_volt_decharge);
} else if (charge_state == 1) { /* charge */
}
else if (charge_state == 1) { /* charge */
level = voltage_to_percent(level, percent_to_volt_charge);
} else {/* in trickle charge, the battery is per definition 100% full */
}
else {/* in trickle charge, the battery is per definition 100% full */
battery_level_cached = level = 100;
}
#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
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 */
/* raise it by 5 % */
/* the battery voltage is usually a little lower directly after
turning on, because the disk was used heavily raise it by 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 */
/* and to be +1/-3 of the last value when usb is connected */
}
else {
/* 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)
level = battery_level_cached + 1;
if (usb_inserted()) {
if (level < battery_level_cached - 3)
level = battery_level_cached - 3;
} else {
}
else {
if (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])
return power_history[POWER_HISTORY_LEN-1] > BATTERY_LEVEL_DANGEROUS;
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)
@ -232,13 +256,11 @@ void set_poweroff_timeout(int timeout)
void set_sleep_timer(int seconds)
{
if(seconds)
{
if(seconds) {
sleeptimer_active = true;
sleeptimer_endtick = current_tick + seconds * HZ;
}
else
{
else {
sleeptimer_active = false;
sleeptimer_endtick = 0;
}
@ -324,7 +346,8 @@ static void power_thread(void)
#ifdef HAVE_CHARGE_CTRL
int delta;
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 trickle_time = 0; /* how many minutes trickle charging already? */
#endif
@ -360,9 +383,11 @@ static void power_thread(void)
power_history[i] = power_history[i+1];
/* 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
if ((powermgmt_last_cycle_startstop_min > 25) || (charge_state > 1))
#endif
@ -374,24 +399,30 @@ static void power_thread(void)
#ifdef HAVE_CHARGE_CTRL
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 {
current = usb_inserted() ? CURRENT_USB : CURRENT_NORMAL;
if ((backlight_get_timeout() == 1) || (charger_inserted() && backlight_get_on_when_charging()))
if ((backlight_get_timeout() == 1) ||
(charger_inserted() && backlight_get_on_when_charging()))
/* LED always on or LED on when charger connected */
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 */
powermgmt_est_runningtime_min = powermgmt_est_runningtime_min * 122 / 100;
powermgmt_est_runningtime_min =
powermgmt_est_runningtime_min * 122 / 100;
#endif /* MEM == 8 */
}
#else
current = usb_inserted() ? CURRENT_USB : CURRENT_NORMAL;
if (backlight_get_timeout() == 1) /* LED always on */
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 */
powermgmt_est_runningtime_min = powermgmt_est_runningtime_min * 122 / 100;
powermgmt_est_runningtime_min =
powermgmt_est_runningtime_min * 122 / 100;
#endif /* MEM == 8 */
#endif /* HAVE_CHARGE_CONTROL */
@ -404,89 +435,133 @@ static void power_thread(void)
if (charge_state == 1) {
/* charger inserted and enabled */
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) {
DEBUGF("power: charged_time > charge_max_time_now, enough!\n");
/* have charged too long and deltaV detection did not work! */
DEBUGF("power: charged_time > charge_max_time_now, "
"enough!\n");
/* have charged too long and deltaV detection did not
work! */
powermgmt_last_cycle_level = battery_level();
powermgmt_last_cycle_startstop_min = 0;
charger_enable(false);
snprintf(power_message, POWER_MESSAGE_LEN, "Chg tmout %d min", charge_max_time_now);
/* disable charging for several hours from this point, just to be sure */
snprintf(power_message, POWER_MESSAGE_LEN,
"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;
/* no trickle charge here, because the charging cycle didn't end the right way */
charge_state = 0; /* 0: decharging/charger off, 1: charge, 2: top-off, 3: trickle */
/* no trickle charge here, because the charging cycle
didn't end the right way */
charge_state = 0; /* 0: decharging/charger off, 1: charge,
2: top-off, 3: trickle */
} else {
if (charged_time > CHARGE_MIN_TIME) {
/* have charged continuously over the minimum charging time,
* so we monitor for deltaV going negative. Multiply things
* by 100 to get more accuracy without floating point arithmetic.
* power_history[] contains centivolts so after multiplying by 100
* the deltas are in tenths of millivolts (delta of 5 is
* 0.0005 V).
/* have charged continuously over the minimum charging
time, so we monitor for deltaV going
negative. Multiply thingsby 100 to get more
accuracy without floating point arithmetic.
power_history[] contains centivolts so after
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-1] * 100
+ power_history[POWER_HISTORY_LEN-2] * 100
- power_history[POWER_HISTORY_LEN-1-CHARGE_END_NEGD+1] * 100
- power_history[POWER_HISTORY_LEN-1-CHARGE_END_NEGD] * 100 )
- power_history[POWER_HISTORY_LEN-1-
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 */
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_startstop_min = 0;
charger_enable(false);
snprintf(power_message, POWER_MESSAGE_LEN, "end negd %d %dmin", delta, charged_time);
/* disable charging for several hours from this point, just to be sure */
snprintf(power_message, POWER_MESSAGE_LEN,
"end negd %d %dmin", delta, charged_time);
/* disable charging for several hours from this
point, just to be sure */
charge_pause = CHARGE_PAUSE_LEN;
/* enable trickle charging */
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;
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 {
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 we didn't disable the charger in the previous test, check for low positive delta */
delta = ( power_history[POWER_HISTORY_LEN-1] * 100
/* if we didn't disable the charger in the
previous test, check for low positive delta */
delta =
( power_history[POWER_HISTORY_LEN-1] * 100
+ power_history[POWER_HISTORY_LEN-2] * 100
- power_history[POWER_HISTORY_LEN-1-CHARGE_END_ZEROD+1] * 100
- power_history[POWER_HISTORY_LEN-1-CHARGE_END_ZEROD] * 100 )
- 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 */
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_startstop_min = 0;
charger_enable(false);
snprintf(power_message, POWER_MESSAGE_LEN, "end lowd %d %dmin", delta, charged_time);
/* disable charging for several hours from this point, just to be sure */
snprintf(power_message, POWER_MESSAGE_LEN,
"end lowd %d %dmin",
delta, charged_time);
/* disable charging for several hours from
this point, just to be sure */
charge_pause = CHARGE_PAUSE_LEN;
/* enable trickle charging */
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;
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 {
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 */
if ( ((charge_state == 2) && (power_history[POWER_HISTORY_LEN-1] > TOPOFF_VOLTAGE))
|| ((charge_state == 3) && (power_history[POWER_HISTORY_LEN-1] > TRICKLE_VOLTAGE)) ) { /* charging too much */
if ( ((charge_state == 2) &&
(power_history[POWER_HISTORY_LEN-1] > TOPOFF_VOLTAGE))
|| ((charge_state == 3) &&
(power_history[POWER_HISTORY_LEN-1] >
TRICKLE_VOLTAGE)) ) { /* charging too much */
trickle_sec--;
} else { /* charging too less */
}
else { /* charging too less */
trickle_sec++;
}
if (trickle_sec > 24) trickle_sec = 24;
if (trickle_sec < 1) trickle_sec = 1;
if (trickle_sec > 24)
trickle_sec = 24;
if (trickle_sec < 1)
trickle_sec = 1;
/* charge the calculated amount of seconds */
charger_enable(true);
@ -496,57 +571,76 @@ static void power_thread(void)
/* trickle charging long enough? */
if (trickle_time++ > TRICKLE_MAX_TIME + TOPOFF_MAX_TIME) {
trickle_sec = 0; /* show in debug menu that trickle is off */
charge_state = 0; /* 0: decharging/charger off, 1: charge, 2: top-off, 3: trickle */
trickle_sec = 0; /* show in debug menu that trickle is
off */
charge_state = 0; /* 0: decharging/charger off, 1: charge,
2: top-off, 3: trickle */
powermgmt_last_cycle_startstop_min = 0;
}
if ((charge_state == 2) && (trickle_time > TOPOFF_MAX_TIME)) /* change state? */
charge_state = 3; /* 0: decharging/charger off, 1: charge, 2: top-off, 3: trickle */
if ((charge_state == 2) &&
(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 */
/* 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 */
if (charger_enabled)
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 */
if ((charge_state == 0) || (charge_state > 1))
/* 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)
|| (power_history[POWER_HISTORY_LEN-1] < BATTERY_LEVEL_DANGEROUS)) {
|| (power_history[POWER_HISTORY_LEN-1] <
BATTERY_LEVEL_DANGEROUS)) {
if (charge_pause) {
DEBUGF("power: batt level < restart level, but charge pause, not enabling\n");
snprintf(power_message, POWER_MESSAGE_LEN, "chg pause %d min", charge_pause);
DEBUGF("power: batt level < restart level,"
" but charge pause, not enabling\n");
snprintf(power_message, POWER_MESSAGE_LEN,
"chg pause %d min", charge_pause);
} else {
/* calculate max charge time depending on current battery level */
/* take 35% more because some more energy is used for heating up the battery */
/* calculate max charge time depending on current
battery level */
/* take 35% more because some more energy is used for
heating up the battery */
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) {
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 */
/* depends on if the charger is on */
DEBUGF("power: charger inserted and battery not full, enabling\n");
/* enable the charger after the max time calc is done,
because battery_level depends on if the charger is
on */
DEBUGF("power: charger inserted and battery"
" not full, enabling\n");
powermgmt_last_cycle_level = battery_level();
powermgmt_last_cycle_startstop_min = 0;
charged_time = 0;
charger_enable(true);
charge_state = 1; /* 0: decharging/charger off, 1: charge, 2: top-off, 3: trickle */
/* clear the power history so that we don't use values before
* discharge for the long-term delta
charge_state = 1; /* 0: decharging/charger off, 1:
charge, 2: top-off, 3: trickle */
/* 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++)
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 */
trickle_sec = 0;
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");
}
/* charger not inserted and disabled, so we're discharging */
@ -588,11 +683,14 @@ void power_init(void)
memset(power_history, 0x00, sizeof(power_history));
/* initialize the history with a single sample to prevent level
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 */
battery_level_update();
/* calculate the remaining time to that the info screen displays something useful */
powermgmt_est_runningtime_min = battery_level() * battery_capacity / 100 * 60 / CURRENT_NORMAL;
/* calculate the remaining time to that the info screen displays something
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 */
powermgmt_est_runningtime_min = powermgmt_est_runningtime_min * 122 / 100;
#endif
@ -605,7 +703,8 @@ void power_init(void)
charger_enable(true);
#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 */