forked from len0rd/rockbox
Finally, merged the improved power code from Uwe Freese:
- The battery level (percentage) is more realistic and considers if the charger is on. - It considers the "lazyness" a battery shows when the charging has just turned on or off (see below). But this is not perfect by now. - The battery level is good enough to estimate the remaining running time and the remaining charging time. And so the info screen now shows this info. - The maximum time of a charging cycle is now dynamically calculated out of the battery level (percentage) and is not a fixed value. - A minimum of 60 minutes is waited after a charging cycle stops before another one starts. - Added another screen in the battery debug screen (press down three times). git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2913 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
67938f3451
commit
f09c5f4c63
5 changed files with 204 additions and 41 deletions
|
|
@ -78,9 +78,8 @@ bool dbg_os(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
lcd_update();
|
lcd_update();
|
||||||
sleep(HZ/10);
|
|
||||||
|
|
||||||
button = button_get(false);
|
button = button_get_w_tmo(HZ/10);
|
||||||
|
|
||||||
switch(button)
|
switch(button)
|
||||||
{
|
{
|
||||||
|
|
@ -112,9 +111,7 @@ bool dbg_os(void)
|
||||||
snprintf(buf, 32, "%d: %d%% ", currval, usage);
|
snprintf(buf, 32, "%d: %d%% ", currval, usage);
|
||||||
lcd_puts(0, 1, buf);
|
lcd_puts(0, 1, buf);
|
||||||
|
|
||||||
sleep(HZ/10);
|
button = button_get_w_tmo(HZ/10);
|
||||||
|
|
||||||
button = button_get(false);
|
|
||||||
|
|
||||||
switch(button)
|
switch(button)
|
||||||
{
|
{
|
||||||
|
|
@ -333,7 +330,7 @@ bool dbg_partitions(void)
|
||||||
lcd_puts(0, 0, "Partition");
|
lcd_puts(0, 0, "Partition");
|
||||||
lcd_puts(0, 1, "list");
|
lcd_puts(0, 1, "list");
|
||||||
lcd_update();
|
lcd_update();
|
||||||
sleep(HZ);
|
sleep(HZ/2);
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
|
|
@ -431,9 +428,7 @@ bool dbg_ports(void)
|
||||||
lcd_puts(0, 7, buf);
|
lcd_puts(0, 7, buf);
|
||||||
|
|
||||||
lcd_update();
|
lcd_update();
|
||||||
sleep(HZ/10);
|
button = button_get(HZ/10);
|
||||||
|
|
||||||
button = button_get(false);
|
|
||||||
|
|
||||||
switch(button)
|
switch(button)
|
||||||
{
|
{
|
||||||
|
|
@ -513,9 +508,7 @@ bool dbg_ports(void)
|
||||||
snprintf(buf, 32, "Batt: %d.%02dV", batt_int, batt_frac);
|
snprintf(buf, 32, "Batt: %d.%02dV", batt_int, batt_frac);
|
||||||
lcd_puts(0, 1, buf);
|
lcd_puts(0, 1, buf);
|
||||||
|
|
||||||
sleep(HZ/5);
|
button = button_get_w_tmo(HZ/5);
|
||||||
|
|
||||||
button = button_get(false);
|
|
||||||
|
|
||||||
switch(button)
|
switch(button)
|
||||||
{
|
{
|
||||||
|
|
@ -566,9 +559,8 @@ bool dbg_rtc(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
lcd_update();
|
lcd_update();
|
||||||
sleep(HZ/2);
|
|
||||||
|
|
||||||
button = button_get(false);
|
button = button_get_w_tmo(HZ/2);
|
||||||
|
|
||||||
switch(button)
|
switch(button)
|
||||||
{
|
{
|
||||||
|
|
@ -623,9 +615,8 @@ bool dbg_mas(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
lcd_update();
|
lcd_update();
|
||||||
sleep(HZ/16);
|
|
||||||
|
|
||||||
switch(button_get(false))
|
switch(button_get_w_tmo(HZ/16))
|
||||||
{
|
{
|
||||||
#ifdef HAVE_RECORDER_KEYPAD
|
#ifdef HAVE_RECORDER_KEYPAD
|
||||||
case BUTTON_DOWN:
|
case BUTTON_DOWN:
|
||||||
|
|
@ -674,9 +665,8 @@ bool dbg_mas_codec(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
lcd_update();
|
lcd_update();
|
||||||
sleep(HZ/16);
|
|
||||||
|
|
||||||
switch(button_get(false))
|
switch(button_get_w_tmo(HZ/16))
|
||||||
{
|
{
|
||||||
case BUTTON_DOWN:
|
case BUTTON_DOWN:
|
||||||
addr += 4;
|
addr += 4;
|
||||||
|
|
@ -805,12 +795,42 @@ bool view_battery(void)
|
||||||
lcd_puts(0, i+1, buf);
|
lcd_puts(0, i+1, buf);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 3: /* remeining time estimation: */
|
||||||
|
lcd_clear_display();
|
||||||
|
lcd_puts(0, 0, "Remaining time:");
|
||||||
|
|
||||||
|
snprintf(buf, 30, "Cycle time: %d m", powermgmt_last_cycle_startstop_min);
|
||||||
|
lcd_puts(0, 1, buf);
|
||||||
|
|
||||||
|
snprintf(buf, 30, "Lev.at cycle start: %d%%", powermgmt_last_cycle_level);
|
||||||
|
lcd_puts(0, 2, buf);
|
||||||
|
|
||||||
|
snprintf(buf, 30, "Last PwrHist val: %d.%02d V",
|
||||||
|
power_history[POWER_HISTORY_LEN-1] / 100,
|
||||||
|
power_history[POWER_HISTORY_LEN-1] % 100);
|
||||||
|
lcd_puts(0, 3, buf);
|
||||||
|
|
||||||
|
snprintf(buf, 30, "Lazy time amount: %d%%",
|
||||||
|
(powermgmt_last_cycle_startstop_min < 20)
|
||||||
|
? battery_lazyness[powermgmt_last_cycle_startstop_min]
|
||||||
|
: 0);
|
||||||
|
lcd_puts(0, 4, buf);
|
||||||
|
|
||||||
|
snprintf(buf, 30, "resulting act.lev: %d%%", battery_level());
|
||||||
|
lcd_puts(0, 5, buf);
|
||||||
|
|
||||||
|
snprintf(buf, 30, "Est. remaining: %d m", powermgmt_est_runningtime_min);
|
||||||
|
lcd_puts(0, 6, buf);
|
||||||
|
|
||||||
|
#ifdef HAVE_CHARGE_CTRL
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
lcd_update();
|
lcd_update();
|
||||||
sleep(HZ/2);
|
|
||||||
|
|
||||||
switch(button_get(false))
|
switch(button_get_w_tmo(HZ/2))
|
||||||
{
|
{
|
||||||
case BUTTON_UP:
|
case BUTTON_UP:
|
||||||
if (view)
|
if (view)
|
||||||
|
|
@ -818,7 +838,7 @@ bool view_battery(void)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BUTTON_DOWN:
|
case BUTTON_DOWN:
|
||||||
if (view < 2)
|
if (view < 3)
|
||||||
view++;
|
view++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1162,3 +1162,7 @@ desc: show only playlist
|
||||||
eng: "Playlists"
|
eng: "Playlists"
|
||||||
new:
|
new:
|
||||||
|
|
||||||
|
id: LANG_BATTERY_TIME
|
||||||
|
desc: battery level in % and estimated time remaining
|
||||||
|
eng: "%d%% %dh %dm"
|
||||||
|
new:
|
||||||
|
|
|
||||||
|
|
@ -183,21 +183,13 @@ bool show_info(void)
|
||||||
#endif
|
#endif
|
||||||
lcd_puts(0, y++, s);
|
lcd_puts(0, y++, s);
|
||||||
|
|
||||||
#ifdef HAVE_LCD_CHARCELLS
|
|
||||||
snprintf(s, sizeof(s), str(LANG_BATTERY_LEVEL_PLAYER),
|
|
||||||
battery_level(), battery_level_safe() ? "" : "!");
|
|
||||||
#else
|
|
||||||
#ifdef HAVE_CHARGE_CTRL
|
#ifdef HAVE_CHARGE_CTRL
|
||||||
if (charger_enabled)
|
if (charger_enabled)
|
||||||
snprintf(s, sizeof(s), str(LANG_BATTERY_CHARGE));
|
snprintf(s, sizeof(s), str(LANG_BATTERY_CHARGE));
|
||||||
else
|
else
|
||||||
snprintf(s, sizeof(s), str(LANG_BATTERY_LEVEL_RECORDER),
|
|
||||||
battery_level(), battery_level_safe() ? "" : " !!");
|
|
||||||
#else
|
|
||||||
snprintf(s, sizeof(s), str(LANG_BATTERY_LEVEL_RECORDER),
|
|
||||||
battery_level(), battery_level_safe() ? "" : " !!");
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
snprintf(s, sizeof(s), str(LANG_BATTERY_TIME), battery_level(),
|
||||||
|
battery_time() / 60, battery_time() % 60);
|
||||||
lcd_puts(0, y++, s);
|
lcd_puts(0, y++, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,11 @@ int battery_level(void)
|
||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int battery_time(void)
|
||||||
|
{
|
||||||
|
return 500;
|
||||||
|
}
|
||||||
|
|
||||||
bool battery_level_safe(void)
|
bool battery_level_safe(void)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -58,18 +63,62 @@ 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_nocharge[11] = /* voltages (centivolt) of 0%, 10%, ... 100% when charging disabled */
|
||||||
|
{
|
||||||
|
450, 481, 491, 497, 503, 507, 512, 514, 517, 528, 560
|
||||||
|
};
|
||||||
|
|
||||||
|
static int percent_to_volt_charge[11] = /* voltages (centivolt) of 0%, 10%, ... 100% when charging enabled */
|
||||||
|
{
|
||||||
|
476, 544, 551, 556, 561, 564, 566, 576, 582, 584, 585
|
||||||
|
};
|
||||||
|
|
||||||
|
int battery_lazyness[20] = /* how does the battery react when plugging in/out the charger */
|
||||||
|
{
|
||||||
|
0, 17, 31, 42, 52, 60, 67, 72, 77, 81, 84, 87, 89, 91, 92, 94, 95, 95, 96, 97
|
||||||
|
};
|
||||||
|
|
||||||
static char power_stack[DEFAULT_STACK_SIZE];
|
static char power_stack[DEFAULT_STACK_SIZE];
|
||||||
static char power_thread_name[] = "power";
|
static char power_thread_name[] = "power";
|
||||||
|
|
||||||
static int poweroff_timeout = 0;
|
static int poweroff_timeout = 0;
|
||||||
static long last_charge_time = 0;
|
static long last_charge_time = 0;
|
||||||
|
static int powermgmt_est_runningtime_min = -1;
|
||||||
|
|
||||||
unsigned short power_history[POWER_HISTORY_LEN];
|
unsigned short power_history[POWER_HISTORY_LEN];
|
||||||
#ifdef HAVE_CHARGE_CTRL
|
#ifdef HAVE_CHARGE_CTRL
|
||||||
char power_message[POWER_MESSAGE_LEN] = "";
|
char power_message[POWER_MESSAGE_LEN] = "";
|
||||||
char charge_restart_level = CHARGE_RESTART_HI;
|
char charge_restart_level = CHARGE_RESTART_HI;
|
||||||
|
|
||||||
|
int powermgmt_last_cycle_startstop_min = 20; /* how many minutes ago was the charging started or stopped? */
|
||||||
|
int powermgmt_last_cycle_level = 0; /* which level had the batteries at this time? */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
int battery_time(void)
|
||||||
|
{
|
||||||
|
return powermgmt_est_runningtime_min;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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])
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
if (voltage >= table[10])
|
||||||
|
return 100;
|
||||||
|
else {
|
||||||
|
/* search nearest value */
|
||||||
|
int i = 0;
|
||||||
|
while ((i < 10) && (table[i+1] < voltage))
|
||||||
|
i++;
|
||||||
|
/* interpolate linear between the smaller and greater value */
|
||||||
|
return i * 10 /* 10th */
|
||||||
|
+ (voltage - table[i]) * 10 / (table[i+1] - table[i]); /* 1th */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Returns battery level in percent */
|
/* Returns battery level in percent */
|
||||||
int battery_level(void)
|
int battery_level(void)
|
||||||
{
|
{
|
||||||
|
|
@ -95,7 +144,33 @@ int battery_level(void)
|
||||||
if(level < BATTERY_LEVEL_EMPTY)
|
if(level < BATTERY_LEVEL_EMPTY)
|
||||||
level = BATTERY_LEVEL_EMPTY;
|
level = BATTERY_LEVEL_EMPTY;
|
||||||
|
|
||||||
return ((level-BATTERY_LEVEL_EMPTY) * 100) / BATTERY_RANGE;
|
/* level now stores the voltage in centivolts */
|
||||||
|
/* let's calculate a percentage now with using the voltage arrays */
|
||||||
|
|
||||||
|
#ifdef HAVE_CHARGE_CTRL
|
||||||
|
if (powermgmt_last_cycle_startstop_min < 20) {
|
||||||
|
/* the batteries are lazy, so take a value between the result of the two table lookups */
|
||||||
|
if (charger_enabled)
|
||||||
|
level = (voltage_to_percent(level, percent_to_volt_charge)
|
||||||
|
* battery_lazyness[powermgmt_last_cycle_startstop_min]
|
||||||
|
+ voltage_to_percent(level, percent_to_volt_nocharge)
|
||||||
|
* (100 - battery_lazyness[powermgmt_last_cycle_startstop_min])) / 100;
|
||||||
|
else
|
||||||
|
level = (voltage_to_percent(level, percent_to_volt_nocharge)
|
||||||
|
* battery_lazyness[powermgmt_last_cycle_startstop_min]
|
||||||
|
+ voltage_to_percent(level, percent_to_volt_charge)
|
||||||
|
* (100 - battery_lazyness[powermgmt_last_cycle_startstop_min])) / 100;
|
||||||
|
} else {
|
||||||
|
if (charger_enabled)
|
||||||
|
level = voltage_to_percent(level, percent_to_volt_charge);
|
||||||
|
else
|
||||||
|
level = voltage_to_percent(level, percent_to_volt_nocharge);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
level = voltage_to_percent(level, percent_to_volt_nocharge); /* always use the nocharge table */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return level;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tells if the battery level is safe for disk writes */
|
/* Tells if the battery level is safe for disk writes */
|
||||||
|
|
@ -180,6 +255,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;
|
||||||
|
int charge_pause = 0; /* no charging pause at the beginning */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
|
|
@ -215,18 +292,43 @@ static void power_thread(void)
|
||||||
/* 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;
|
||||||
|
|
||||||
|
/* calculate estimated remaining running time */
|
||||||
|
/* not charging: remaining running time */
|
||||||
|
/* charging: remaining charging time */
|
||||||
#ifdef HAVE_CHARGE_CTRL
|
#ifdef HAVE_CHARGE_CTRL
|
||||||
|
if (charger_enabled)
|
||||||
|
/* if taking the nocharge battery level, charging lasts 30% longer than the value says */
|
||||||
|
/* so consider it because there's the battery lazyness inside the the battery_level */
|
||||||
|
if (powermgmt_last_cycle_startstop_min < 20) {
|
||||||
|
i = (100 - battery_lazyness[powermgmt_last_cycle_startstop_min]) * 30 / 100 ; /* 0..30 */
|
||||||
|
powermgmt_est_runningtime_min = (100 - battery_level()) * BATTERY_CAPACITY / 100 * (100 + i) / 100 * 60 / CURRENT_CHARGING;
|
||||||
|
} else {
|
||||||
|
powermgmt_est_runningtime_min = (100 - battery_level()) * BATTERY_CAPACITY / 100 * 60 / CURRENT_CHARGING;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
powermgmt_est_runningtime_min = battery_level() * BATTERY_CAPACITY / 100 * 60 / CURRENT_NORMAL;
|
||||||
|
|
||||||
|
#ifdef HAVE_CHARGE_CTRL
|
||||||
|
|
||||||
|
if (charge_pause > 0)
|
||||||
|
charge_pause--;
|
||||||
|
|
||||||
if (charger_inserted()) {
|
if (charger_inserted()) {
|
||||||
if (charger_enabled) {
|
if (charger_enabled) {
|
||||||
/* charger inserted and enabled */
|
/* charger inserted and enabled */
|
||||||
charged_time++;
|
charged_time++;
|
||||||
if (charged_time > CHARGE_MAX_TIME) {
|
snprintf(power_message, POWER_MESSAGE_LEN, "Chg %dm max %dm", charged_time, charge_max_time_now);
|
||||||
DEBUGF("power: charged_time > CHARGE_MAX_TIME, enough!\n");
|
|
||||||
|
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! */
|
/* 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);
|
charger_enable(false);
|
||||||
snprintf(power_message, POWER_MESSAGE_LEN, "Chg tmout %d min", CHARGE_MAX_TIME);
|
snprintf(power_message, POWER_MESSAGE_LEN, "Chg tmout %d min", charge_max_time_now);
|
||||||
/* Perhaps we should disable charging for several
|
/* disable charging for several hours from this point, just to be sure */
|
||||||
hours from this point, just to be sure. */
|
charge_pause = CHARGE_PAUSE_LEN;
|
||||||
} 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 time,
|
||||||
|
|
@ -244,8 +346,12 @@ static void power_thread(void)
|
||||||
|
|
||||||
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_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, "end negd %d %dmin", delta, charged_time);
|
||||||
|
/* disable charging for several hours from this point, just to be sure */
|
||||||
|
charge_pause = CHARGE_PAUSE_LEN;
|
||||||
} 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 previous test, check for low positive delta */
|
||||||
delta = ( power_history[POWER_HISTORY_LEN-1] * 100
|
delta = ( power_history[POWER_HISTORY_LEN-1] * 100
|
||||||
|
|
@ -256,8 +362,12 @@ static void power_thread(void)
|
||||||
|
|
||||||
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_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, "end lowd %d %dmin", delta, charged_time);
|
||||||
|
/* disable charging for several hours from this point, just to be sure */
|
||||||
|
charge_pause = CHARGE_PAUSE_LEN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -266,15 +376,33 @@ static void power_thread(void)
|
||||||
/* charged inserted but not enabled */
|
/* charged inserted but not enabled */
|
||||||
/* if battery is not full, enable charging */
|
/* if battery is not full, enable charging */
|
||||||
if (battery_level() < charge_restart_level) {
|
if (battery_level() < charge_restart_level) {
|
||||||
|
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);
|
||||||
|
} else {
|
||||||
|
/* calculate max charge time depending on current battery level */
|
||||||
|
/* take 20% more because battery level is not linear */
|
||||||
|
charge_max_time_now = CHARGE_MAX_TIME * (100 + 30 - battery_level()) / 100;
|
||||||
|
if (charge_max_time_now > CHARGE_MAX_TIME) {
|
||||||
|
charge_max_time_now = CHARGE_MAX_TIME;
|
||||||
|
}
|
||||||
|
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");
|
DEBUGF("power: charger inserted and battery not full, enabling\n");
|
||||||
charger_enable(true);
|
powermgmt_last_cycle_level = battery_level();
|
||||||
|
powermgmt_last_cycle_startstop_min = 0;
|
||||||
charged_time = 0;
|
charged_time = 0;
|
||||||
|
|
||||||
|
charger_enable(true);
|
||||||
|
|
||||||
/* clear the power history so that we don't use values before
|
/* clear the power history so that we don't use values before
|
||||||
* discharge for the long-term delta
|
* 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];
|
||||||
snprintf(power_message, POWER_MESSAGE_LEN, "Chg started at %d%%", battery_level());
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -282,11 +410,15 @@ static void power_thread(void)
|
||||||
if (charger_enabled) {
|
if (charger_enabled) {
|
||||||
/* charger not inserted but was enabled */
|
/* charger not inserted but was enabled */
|
||||||
DEBUGF("power: charger disconnected, disabling\n");
|
DEBUGF("power: charger disconnected, disabling\n");
|
||||||
|
powermgmt_last_cycle_level = battery_level();
|
||||||
|
powermgmt_last_cycle_startstop_min = 0;
|
||||||
charger_enable(false);
|
charger_enable(false);
|
||||||
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 */
|
||||||
}
|
}
|
||||||
|
powermgmt_last_cycle_startstop_min++;
|
||||||
|
|
||||||
#endif /* HAVE_CHARGE_CTRL*/
|
#endif /* HAVE_CHARGE_CTRL*/
|
||||||
|
|
||||||
/* sleep for roughly a minute */
|
/* sleep for roughly a minute */
|
||||||
|
|
@ -303,6 +435,8 @@ void power_init(void)
|
||||||
/* 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 remaining time to that the info screen displays something useful */
|
||||||
|
powermgmt_est_runningtime_min = battery_level() * BATTERY_CAPACITY / 100 * 60 / CURRENT_NORMAL;
|
||||||
|
|
||||||
#ifdef HAVE_CHARGE_CTRL
|
#ifdef HAVE_CHARGE_CTRL
|
||||||
snprintf(power_message, POWER_MESSAGE_LEN, "Powermgmt started");
|
snprintf(power_message, POWER_MESSAGE_LEN, "Powermgmt started");
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
#define BATTERY_LEVEL_SHUTDOWN 450 /* 4.5V */
|
#define BATTERY_LEVEL_SHUTDOWN 450 /* 4.5V */
|
||||||
#define BATTERY_LEVEL_EMPTY 465 /* 4.65V */
|
#define BATTERY_LEVEL_EMPTY 465 /* 4.65V */
|
||||||
#define BATTERY_LEVEL_DANGEROUS 475 /* 4.75V */
|
#define BATTERY_LEVEL_DANGEROUS 475 /* 4.75V */
|
||||||
#define BATTERY_LEVEL_FULL 520 /* 5.2V */
|
#define BATTERY_LEVEL_FULL 585 /* 5.85V */
|
||||||
|
|
||||||
#define BATTERY_RANGE (BATTERY_LEVEL_FULL - BATTERY_LEVEL_EMPTY)
|
#define BATTERY_RANGE (BATTERY_LEVEL_FULL - BATTERY_LEVEL_EMPTY)
|
||||||
|
|
||||||
|
|
@ -39,15 +39,27 @@
|
||||||
|
|
||||||
#ifdef HAVE_CHARGE_CTRL
|
#ifdef HAVE_CHARGE_CTRL
|
||||||
#define POWER_MESSAGE_LEN 32 /* power thread status message */
|
#define POWER_MESSAGE_LEN 32 /* power thread status message */
|
||||||
#define CHARGE_MAX_TIME 6*60 /* minutes: maximum charging time */
|
#define CHARGE_MAX_TIME 8*60 /* minutes: maximum charging time */
|
||||||
#define CHARGE_MIN_TIME 10 /* minutes: minimum charging time */
|
#define CHARGE_MIN_TIME 10 /* minutes: minimum charging time */
|
||||||
#define CHARGE_RESTART_HI 95 /* %: when to restart charging in 'charge' mode */
|
#define CHARGE_RESTART_HI 95 /* %: when to restart charging in 'charge' mode */
|
||||||
#define CHARGE_RESTART_LO 10 /* %: when to restart charging in 'discharge' mode */
|
#define CHARGE_RESTART_LO 10 /* %: when to restart charging in 'discharge' mode */
|
||||||
|
#define CHARGE_PAUSE_LEN 60 /* how many minutes to pause between charging cycles */
|
||||||
|
|
||||||
extern char power_message[POWER_MESSAGE_LEN];
|
extern char power_message[POWER_MESSAGE_LEN];
|
||||||
extern char charge_restart_level;
|
extern char charge_restart_level;
|
||||||
|
|
||||||
|
extern int powermgmt_last_cycle_startstop_min; /* how many minutes ago was the charging started or stopped? */
|
||||||
|
extern int powermgmt_last_cycle_level; /* which level had the batteries at this time? */
|
||||||
|
|
||||||
|
extern int battery_lazyness[20]; /* how does the battery react when plugging in/out the charger */
|
||||||
|
|
||||||
#endif /* HAVE_CHARGE_CTRL */
|
#endif /* HAVE_CHARGE_CTRL */
|
||||||
|
|
||||||
|
#define BATTERY_CAPACITY 1800 /* battery capacity in mAh for runtime estimation */
|
||||||
|
#define CURRENT_NORMAL 145 /* usual current in mA when using the AJB including some disk/backlight/... activity */
|
||||||
|
#define CURRENT_BACKLIGHT 30 /* additional current when backlight is always on */
|
||||||
|
#define CURRENT_CHARGING 300 /* charging current */
|
||||||
|
|
||||||
extern unsigned short power_history[POWER_HISTORY_LEN];
|
extern unsigned short power_history[POWER_HISTORY_LEN];
|
||||||
|
|
||||||
/* Start up power management thread */
|
/* Start up power management thread */
|
||||||
|
|
@ -57,6 +69,7 @@ void power_init(void);
|
||||||
|
|
||||||
/* Returns battery level in percent */
|
/* Returns battery level in percent */
|
||||||
int battery_level(void);
|
int battery_level(void);
|
||||||
|
int battery_time(void); /* minutes */
|
||||||
|
|
||||||
/* Tells if the battery level is safe for disk writes */
|
/* Tells if the battery level is safe for disk writes */
|
||||||
bool battery_level_safe(void);
|
bool battery_level_safe(void);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue