From cdacab3d89cdbbd8fd7c20b3b340e27352e6737e Mon Sep 17 00:00:00 2001 From: Brandon Low Date: Thu, 19 Jan 2006 07:47:34 +0000 Subject: Charging state reporting on H3x0 Don't read the GPIO every refresh of statusbar or gwps for plugged state, use a variable exported from powermgmt instead. Allow Custom WPS to access %bc for battery charge state on targets that support this. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8383 a1c6a512-1295-4272-9138-f99709370657 --- apps/gui/gwps-common.c | 18 ++++++++++++++- apps/gui/statusbar.c | 18 ++++++++++----- firmware/drivers/power.c | 6 +++++ firmware/export/config-h300.h | 3 +++ firmware/export/power.h | 1 + firmware/export/powermgmt.h | 30 +++++++++++++++++++++--- firmware/powermgmt.c | 53 +++++++++++++++++++++++++++---------------- 7 files changed, 100 insertions(+), 29 deletions(-) diff --git a/apps/gui/gwps-common.c b/apps/gui/gwps-common.c index 3af52b5396..37f4fea310 100644 --- a/apps/gui/gwps-common.c +++ b/apps/gui/gwps-common.c @@ -655,11 +655,27 @@ static char* get_tag(struct wps_data* wps_data, case 'p': /* External power plugged in? */ { - if(charger_inserted()) + if(charger_input_state==CHARGER) return "p"; else return NULL; } +#if defined(HAVE_CHARGE_CTRL) || \ + defined (HAVE_CHARGE_STATE) || \ + CONFIG_BATTERY == BATT_LIION2200 + case 'c': /* Charging */ + { + if (charge_state == CHARGING +#ifdef HAVE_CHARGE_CTRL + || charge_state == TOPOFF +#endif + ) { + return "c"; + } else { + return NULL; + } + } +#endif } break; diff --git a/apps/gui/statusbar.c b/apps/gui/statusbar.c index 80de707a72..b4070394f9 100644 --- a/apps/gui/statusbar.c +++ b/apps/gui/statusbar.c @@ -127,7 +127,7 @@ void gui_statusbar_draw(struct gui_statusbar * bar, bool force_redraw) #endif /* HAVE_LCD_CHARCELLS */ bar->info.volume = sound_val2phys(SOUND_VOLUME, global_settings.volume); - bar->info.inserted = charger_inserted(); + bar->info.inserted = (charger_input_state == CHARGER); bar->info.battlevel = battery_level(); bar->info.battery_safe = battery_level_safe(); @@ -178,16 +178,21 @@ void gui_statusbar_draw(struct gui_statusbar * bar, bool force_redraw) #ifdef HAVE_CHARGING if (bar->info.inserted) { battery_state = true; -#if defined(HAVE_CHARGE_CTRL) || CONFIG_BATTERY == BATT_LIION2200 +#if defined(HAVE_CHARGE_CTRL) || \ + defined(HAVE_CHARGE_STATE) || \ + CONFIG_BATTERY == BATT_LIION2200 /* zero battery run time if charging */ - if (charge_state > 0) { + if (charge_state > DISCHARGING) { global_settings.runtime = 0; lasttime = current_tick; } /* animate battery if charging */ - if ((charge_state == 1) || - (charge_state == 2)) { + if ((charge_state == CHARGING) +#ifdef HAVE_CHARGE_CTRL + || (charge_state == TOPOFF) +#endif + ) { #else global_settings.runtime = 0; lasttime = current_tick; @@ -323,7 +328,8 @@ void gui_statusbar_icon_battery(struct screen * display, int percent) if (fill > 100) fill = 100; -#if defined(HAVE_CHARGE_CTRL) && !defined(SIMULATOR) /* Rec v1 target only */ +#if (defined(HAVE_CHARGE_CTRL) || defined(HAVE_CHARGE_STATE)) && \ + !defined(SIMULATOR) /* Certain charge controlled targets */ /* show graphical animation when charging instead of numbers */ if ((global_settings.battery_display) && (charge_state != 1) && diff --git a/firmware/drivers/power.c b/firmware/drivers/power.c index da97233e57..8a20890228 100644 --- a/firmware/drivers/power.c +++ b/firmware/drivers/power.c @@ -148,6 +148,12 @@ void charger_enable(bool on) } #endif +#ifdef HAVE_CHARGE_STATE +bool charging_state(void) { + return (GPIO_READ & 0x00800000)?true:false; +} +#endif + #ifdef HAVE_SPDIF_POWER void spdif_power_enable(bool on) { diff --git a/firmware/export/config-h300.h b/firmware/export/config-h300.h index 806ae0a079..ded20c9129 100644 --- a/firmware/export/config-h300.h +++ b/firmware/export/config-h300.h @@ -72,6 +72,9 @@ /* Define this if the platform can charge batteries */ #define HAVE_CHARGING 1 +/* For units with a hardware charger that reports charge state */ +#define HAVE_CHARGE_STATE 1 + /* define this if the hardware can be powered off while charging */ #define HAVE_POWEROFF_WHILE_CHARGING diff --git a/firmware/export/power.h b/firmware/export/power.h index bf645522ef..9f91e25f15 100644 --- a/firmware/export/power.h +++ b/firmware/export/power.h @@ -25,6 +25,7 @@ extern bool charger_enabled; void power_init(void); bool charger_inserted(void); +bool charging_state(void); void charger_enable(bool on); void ide_power_enable(bool on); bool ide_powered(void); diff --git a/firmware/export/powermgmt.h b/firmware/export/powermgmt.h index 3c4a61fb87..25c18eabad 100644 --- a/firmware/export/powermgmt.h +++ b/firmware/export/powermgmt.h @@ -79,18 +79,38 @@ extern int trickle_sec; /* trickle charge: How many seconds per minute #endif /* HAVE_CHARGE_CTRL */ -#if defined(HAVE_CHARGE_CTRL) || (CONFIG_BATTERY == BATT_LIION2200) +#if defined(HAVE_CHARGE_CTRL) || \ + (CONFIG_BATTERY == BATT_LIION2200) || \ + defined(HAVE_CHARGE_STATE) typedef enum { DISCHARGING, CHARGING, +#ifdef HAVE_CHARGE_CTRL TOPOFF, TRICKLE +#endif } charge_state_type; /* tells what the charger is doing */ extern charge_state_type charge_state; #endif /* defined(HAVE_CHARGE_CTRL) || (CONFIG_BATTERY == BATT_LIION2200) */ +#ifdef HAVE_CHARGING +/* + * Flag that the charger has been plugged in/removed: this is set for exactly + * one time through the power loop when the charger has been plugged in. + */ +typedef enum { + NO_CHARGER, + CHARGER_UNPLUGGED, /* transient state */ + CHARGER_PLUGGED, /* transient state */ + CHARGER +} charger_input_state_type; + +/* tells the state of the charge input */ +extern charger_input_state_type charger_input_state; +#endif + #ifdef HAVE_MMC /* Values for Ondio */ # define CURRENT_NORMAL 95 /* average, nearly proportional to 1/U */ # define CURRENT_USB 1 /* host powered in USB mode; avoid zero-div */ @@ -106,9 +126,13 @@ extern charge_state_type charge_state; # define CURRENT_MIN_CHG 70 /* minimum charge current */ # define MIN_CHG_V 8500 /* at 8.5v charger voltage get CURRENT_MIN_CHG */ -# define CURRENT_MAX_CHG 350 /* maximum charging current */ +# ifdef IRIVER_H300_SERIES +# define CURRENT_MAX_CHG 650 /* maximum charging current */ +# else +# define CURRENT_MAX_CHG 350 /* maximum charging current */ +# endif # define MAX_CHG_V 10250 /* anything over 10.25v gives CURRENT_MAX_CHG */ -#endif /* HAVE_MMC */ +#endif /* not HAVE_MMC */ extern unsigned int bat; /* filtered battery voltage, centivolts */ extern unsigned short power_history[POWER_HISTORY_LEN]; diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c index 4b3999751c..7bf2d58284 100644 --- a/firmware/powermgmt.c +++ b/firmware/powermgmt.c @@ -145,33 +145,28 @@ static const short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] = }; #ifdef HAVE_CHARGING +charger_input_state_type charger_input_state IDATA_ATTR; + /* voltages (centivolt) of 0%, 10%, ... 100% when charging enabled */ static const short percent_to_volt_charge[11] = { +#if CONFIG_BATTERY == BATT_LIPOL1300 + 340, 349, 358, 367, 376, 385, 394, 403, 408, 413, 418 /* Estimated */ +#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 */ +#endif }; #endif /* HAVE_CHARGING */ -#if defined(HAVE_CHARGE_CTRL) || CONFIG_BATTERY == BATT_LIION2200 +#if defined(HAVE_CHARGE_CTRL) || \ + CONFIG_BATTERY == BATT_LIION2200 || \ + defined(HAVE_CHARGE_STATE) charge_state_type charge_state; /* charging mode */ #endif -#ifdef HAVE_CHARGING -/* - * Flag that the charger has been plugged in/removed: this is set for exactly - * one time through the power loop when the charger has been plugged in. - */ -static enum { - NO_CHARGER, - CHARGER_UNPLUGGED, /* transient state */ - CHARGER_PLUGGED, /* transient state */ - CHARGER -} charger_input_state; -#endif - #ifdef HAVE_CHARGE_CTRL int long_delta; /* long term delta battery voltage */ int short_delta; /* short term delta battery voltage */ @@ -317,7 +312,7 @@ static void battery_status_update(void) { int level; -#ifdef HAVE_CHARGE_CTRL +#if defined(HAVE_CHARGE_CTRL) || defined(HAVE_CHARGE_STATE) if (charge_state == DISCHARGING) { level = voltage_to_percent(battery_centivolts, percent_to_volt_discharge[battery_type]); @@ -520,6 +515,23 @@ static void power_thread_sleep(int ticks) } } #endif +#ifdef HAVE_CHARGE_STATE + switch (charger_input_state) { + case CHARGER_UNPLUGGED: + charge_state = DISCHARGING; + case NO_CHARGER: + break; + case CHARGER_PLUGGED: + case CHARGER: + if (charging_state()) { + charge_state = CHARGING; + } else { + charge_state = DISCHARGING; + } + break; + } + +#endif /* HAVE_CHARGE_STATE */ small_ticks = MIN(HZ/2, ticks); sleep(small_ticks); @@ -551,6 +563,7 @@ static void power_thread_sleep(int ticks) battery_centivolts = avgbat / BATT_AVE_SAMPLES / 10000; } + #if defined(DEBUG_FILE) && defined(HAVE_CHARGE_CTRL) /* * If we have a lot of pending writes or if the disk is spining, @@ -821,7 +834,7 @@ static void power_thread(void) snprintf(power_message, POWER_MESSAGE_LEN, "Charger: discharge"); } -#endif /* HAVE_CHARGE_CTRL*/ +#endif /* end HAVE_CHARGE_CTRL */ /* sleep for a minute */ @@ -840,7 +853,7 @@ static void power_thread(void) #if defined(DEBUG_FILE) && defined(HAVE_CHARGE_CTRL) if(usb_inserted()) { if(fd >= 0) { - /* It is probably too late to close the file but we can try... */ + /* It is probably too late to close the file but we can try...*/ close(fd); fd = -1; } @@ -855,9 +868,11 @@ static void power_thread(void) } } if(fd >= 0) { - snprintf(debug_message, DEBUG_MESSAGE_LEN, "%d, %d, %d, %d, %d, %d, %d, %d\n", + snprintf(debug_message, DEBUG_MESSAGE_LEN, + "%d, %d, %d, %d, %d, %d, %d, %d\n", powermgmt_last_cycle_startstop_min, battery_centivolts, - battery_percent, charger_input_state, charge_state, pid_p, pid_i, trickle_sec); + battery_percent, charger_input_state, charge_state, + pid_p, pid_i, trickle_sec); write(fd, debug_message, strlen(debug_message)); wrcount++; } -- cgit v1.2.3