Simplify powermgmt thread loops so it calls functions turn (no more power_thread_sleep). Do other target-friendly simplifications, generic battery switch handling and split sim-specific code. Whoever can, please verify charging on the Archos Recorder (due to change in the charger duty cycle code).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19579 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
0f9729739f
commit
3157e13956
34 changed files with 1337 additions and 1124 deletions
|
@ -1603,10 +1603,10 @@ static bool view_battery(void)
|
|||
lcd_puts(0, 2, buf);
|
||||
#endif
|
||||
#if CONFIG_CHARGING
|
||||
#if CONFIG_CHARGING == CHARGING_CONTROL
|
||||
#if defined ARCHOS_RECORDER
|
||||
snprintf(buf, 30, "Chgr: %s %s",
|
||||
charger_inserted() ? "present" : "absent",
|
||||
charger_enabled ? "on" : "off");
|
||||
charger_enabled() ? "on" : "off");
|
||||
lcd_puts(0, 3, buf);
|
||||
snprintf(buf, 30, "short delta: %d", short_delta);
|
||||
lcd_puts(0, 5, buf);
|
||||
|
@ -1616,13 +1616,11 @@ static bool view_battery(void)
|
|||
snprintf(buf, 30, "USB Inserted: %s",
|
||||
usb_inserted() ? "yes" : "no");
|
||||
lcd_puts(0, 8, buf);
|
||||
#if defined IRIVER_H300_SERIES
|
||||
#elif defined IRIVER_H300_SERIES
|
||||
snprintf(buf, 30, "USB Charging Enabled: %s",
|
||||
usb_charging_enabled() ? "yes" : "no");
|
||||
lcd_puts(0, 9, buf);
|
||||
#endif
|
||||
#else /* CONFIG_CHARGING != CHARGING_CONTROL */
|
||||
#if defined IPOD_NANO || defined IPOD_VIDEO
|
||||
#elif defined IPOD_NANO || defined IPOD_VIDEO
|
||||
int usb_pwr = (GPIOL_INPUT_VAL & 0x10)?true:false;
|
||||
int ext_pwr = (GPIOL_INPUT_VAL & 0x08)?false:true;
|
||||
int dock = (GPIOA_INPUT_VAL & 0x10)?true:false;
|
||||
|
@ -1644,12 +1642,8 @@ static bool view_battery(void)
|
|||
snprintf(buf, 30, "Headphone: %s",
|
||||
headphone ? "connected" : "disconnected");
|
||||
lcd_puts(0, 7, buf);
|
||||
#else
|
||||
snprintf(buf, 30, "Charger: %s",
|
||||
charger_inserted() ? "present" : "absent");
|
||||
lcd_puts(0, 3, buf);
|
||||
#if defined TOSHIBA_GIGABEAT_S
|
||||
int line = 4;
|
||||
#elif defined TOSHIBA_GIGABEAT_S
|
||||
int line = 3;
|
||||
unsigned int st;
|
||||
|
||||
static const unsigned char * const chrgstate_strings[] =
|
||||
|
@ -1663,6 +1657,10 @@ static bool view_battery(void)
|
|||
"<unknown>",
|
||||
};
|
||||
|
||||
snprintf(buf, 30, "Charger: %s",
|
||||
charger_inserted() ? "present" : "absent");
|
||||
lcd_puts(0, line++, buf);
|
||||
|
||||
st = power_input_status() &
|
||||
(POWER_INPUT_CHARGER | POWER_INPUT_BATTERY);
|
||||
snprintf(buf, 30, "%s%s",
|
||||
|
@ -1730,9 +1728,11 @@ static bool view_battery(void)
|
|||
}
|
||||
|
||||
lcd_puts(0, line++, buf);
|
||||
#endif /* defined TOSHIBA_GIGABEAT_S */
|
||||
#endif /* defined IPOD_NANO || defined IPOD_VIDEO */
|
||||
#endif /* CONFIG_CHARGING != CHARGING_CONTROL */
|
||||
#else
|
||||
snprintf(buf, 30, "Charger: %s",
|
||||
charger_inserted() ? "present" : "absent");
|
||||
lcd_puts(0, 3, buf);
|
||||
#endif /* target type */
|
||||
#endif /* CONFIG_CHARGING */
|
||||
break;
|
||||
|
||||
|
@ -1750,7 +1750,7 @@ static bool view_battery(void)
|
|||
|
||||
case 3: /* remaining time estimation: */
|
||||
|
||||
#if CONFIG_CHARGING == CHARGING_CONTROL
|
||||
#ifdef ARCHOS_RECORDER
|
||||
snprintf(buf, 30, "charge_state: %d", charge_state);
|
||||
lcd_puts(0, 0, buf);
|
||||
|
||||
|
@ -1765,7 +1765,7 @@ static bool view_battery(void)
|
|||
|
||||
snprintf(buf, 30, "Trickle sec: %d/60", trickle_sec);
|
||||
lcd_puts(0, 4, buf);
|
||||
#endif /* CONFIG_CHARGING == CHARGING_CONTROL */
|
||||
#endif /* ARCHOS_RECORDER */
|
||||
|
||||
snprintf(buf, 30, "Last PwrHist: %d.%03dV",
|
||||
power_history[0] / 1000,
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "lang.h"
|
||||
#include "action.h"
|
||||
#include "settings.h"
|
||||
#include "power.h"
|
||||
#include "powermgmt.h"
|
||||
#include "menu.h"
|
||||
#include "misc.h"
|
||||
|
@ -199,15 +200,14 @@ static char* info_getname(int selected_item, void *data,
|
|||
if (charge_state == CHARGING)
|
||||
return (char *)str(LANG_BATTERY_CHARGE);
|
||||
else
|
||||
#if CONFIG_CHARGING == CHARGING_CONTROL
|
||||
#ifdef ARCHOS_RECORDER
|
||||
if (charge_state == TOPOFF)
|
||||
return (char *)str(LANG_BATTERY_TOPOFF_CHARGE);
|
||||
else
|
||||
#endif
|
||||
if (charge_state == TRICKLE)
|
||||
else if (charge_state == TRICKLE)
|
||||
return (char *)str(LANG_BATTERY_TRICKLE_CHARGE);
|
||||
else
|
||||
#endif
|
||||
#endif /* ARCHOS_RECORDER */
|
||||
#endif /* CONFIG_CHARGING = */
|
||||
if (battery_level() >= 0)
|
||||
snprintf(buffer, buffer_len, (char *)str(LANG_BATTERY_TIME),
|
||||
battery_level(), battery_time() / 60, battery_time() % 60);
|
||||
|
@ -282,22 +282,21 @@ static int info_speak_item(int selected_item, void * data)
|
|||
}
|
||||
case INFO_BATTERY: /* battery */
|
||||
#if CONFIG_CHARGING == CHARGING_SIMPLE
|
||||
if (charger_input_state == CHARGER)
|
||||
if (charger_inserted())
|
||||
talk_id(LANG_BATTERY_CHARGE, true);
|
||||
else
|
||||
#elif CONFIG_CHARGING >= CHARGING_MONITOR
|
||||
if (charge_state == CHARGING)
|
||||
talk_id(LANG_BATTERY_CHARGE, true);
|
||||
else
|
||||
#if CONFIG_CHARGING == CHARGING_CONTROL
|
||||
#ifdef ARCHOS_RECORDER
|
||||
if (charge_state == TOPOFF)
|
||||
talk_id(LANG_BATTERY_TOPOFF_CHARGE, true);
|
||||
else
|
||||
#endif
|
||||
if (charge_state == TRICKLE)
|
||||
else if (charge_state == TRICKLE)
|
||||
talk_id(LANG_BATTERY_TRICKLE_CHARGE, true);
|
||||
else
|
||||
#endif
|
||||
#endif /* ARCHOS_RECORDER */
|
||||
#endif /* CONFIG_CHARGING = */
|
||||
if (battery_level() >= 0)
|
||||
{
|
||||
talk_id(LANG_BATTERY_TIME, false);
|
||||
|
|
|
@ -209,8 +209,7 @@ static void charging_display_info(bool animate)
|
|||
lcd_puts(0, 7, buf);
|
||||
}
|
||||
|
||||
#if CONFIG_CHARGING == CHARGING_CONTROL
|
||||
|
||||
#ifdef ARCHOS_RECORER
|
||||
snprintf(buf, 32, "Charge mode:");
|
||||
lcd_puts(0, 2, buf);
|
||||
|
||||
|
@ -224,10 +223,9 @@ static void charging_display_info(bool animate)
|
|||
snprintf(buf, 32, "not charging");
|
||||
|
||||
lcd_puts(0, 3, buf);
|
||||
if (!charger_enabled)
|
||||
if (!charger_enabled())
|
||||
animate = false;
|
||||
#endif /* CONFIG_CHARGING == CHARGING_CONTROL */
|
||||
|
||||
#endif /* ARCHOS_RECORER */
|
||||
|
||||
/* middle part */
|
||||
memset(charging_logo+3, 0x00, 32);
|
||||
|
|
|
@ -129,6 +129,11 @@
|
|||
/* define this if the unit can be powered or charged via USB */
|
||||
#define HAVE_USB_POWER
|
||||
|
||||
/* define current usage levels */
|
||||
#define CURRENT_NORMAL 45 /* Should be nearly identical to E200 */
|
||||
#define CURRENT_BACKLIGHT 40 /* Screen is about 20, blue LEDs are another 20, so 40 if both */
|
||||
#define CURRENT_RECORD 40 /* flash player, so this is just unboosted current*/
|
||||
|
||||
/** Non-simulator section **/
|
||||
#ifndef SIMULATOR
|
||||
|
||||
|
|
|
@ -123,6 +123,11 @@
|
|||
/* Hardware controlled charging? FIXME */
|
||||
#define CONFIG_CHARGING CHARGING_SIMPLE
|
||||
|
||||
/* define current usage levels */
|
||||
#define CURRENT_NORMAL 45 /* Mike's measurements in Jan 2008 */
|
||||
#define CURRENT_BACKLIGHT 40 /* Screen is about 20, blue LEDs are another 20, so 40 if both */
|
||||
#define CURRENT_RECORD 40 /* flash player, so this is just unboosted current*/
|
||||
|
||||
/* define this if the unit can be powered or charged via USB */
|
||||
#define HAVE_USB_POWER
|
||||
|
||||
|
|
|
@ -110,9 +110,16 @@
|
|||
#define BATTERY_TYPES_COUNT 1 /* only one type */
|
||||
|
||||
/* Hardware controlled charging */
|
||||
//#define CONFIG_CHARGING CHARGING_SIMPLE
|
||||
|
||||
#define CONFIG_CHARGING CHARGING_MONITOR /* FIXME: remove that once monitoring is fixed properly */
|
||||
|
||||
/* define current usage levels */
|
||||
#define CURRENT_NORMAL 80 /* 16h playback on 1300mAh battery */
|
||||
#define CURRENT_BACKLIGHT 23 /* from IriverBattery twiki page */
|
||||
#define CURRENT_SPDIF_OUT 10 /* optical SPDIF output on */
|
||||
#define CURRENT_RECORD 105 /* additional current while recording */
|
||||
#define CURRENT_REMOTE 8 /* additional current when remote connected */
|
||||
|
||||
#ifndef SIMULATOR
|
||||
|
||||
/* Define this if you have a Motorola SCF5249 */
|
||||
|
|
|
@ -110,9 +110,15 @@
|
|||
#define BATTERY_TYPES_COUNT 1 /* only one type */
|
||||
|
||||
/* Hardware controlled charging */
|
||||
//#define CONFIG_CHARGING CHARGING_SIMPLE
|
||||
#define CONFIG_CHARGING CHARGING_MONITOR /* FIXME: remove that once monitoring is fixed properly */
|
||||
|
||||
/* define current usage levels */
|
||||
#define CURRENT_NORMAL 80 /* 16h playback on 1300mAh battery */
|
||||
#define CURRENT_BACKLIGHT 23 /* from IriverBattery twiki page */
|
||||
#define CURRENT_SPDIF_OUT 10 /* optical SPDIF output on */
|
||||
#define CURRENT_RECORD 105 /* additional current while recording */
|
||||
#define CURRENT_REMOTE 8 /* additional current when remote connected */
|
||||
|
||||
#ifndef SIMULATOR
|
||||
|
||||
/* Define this if you have a Motorola SCF5249 */
|
||||
|
|
|
@ -112,6 +112,13 @@
|
|||
/* define this if the unit can be powered or charged via USB */
|
||||
#define HAVE_USB_POWER
|
||||
|
||||
/* define current usage levels */
|
||||
#define CURRENT_NORMAL 80 /* 16h playback on 1300mAh battery from IriverRuntime wiki page */
|
||||
#define CURRENT_BACKLIGHT 23 /* FIXME: This needs to be measured, copied from H100 */
|
||||
#define CURRENT_RECORD 110 /* additional current while recording */
|
||||
#define CURRENT_MAX_CHG 650 /* maximum charging current */
|
||||
#define CURRENT_REMOTE 8 /* additional current when remote connected */
|
||||
|
||||
/* define this if the unit can have USB charging disabled by user -
|
||||
* if USB/MAIN power is discernable and hardware doesn't compel charging */
|
||||
#define HAVE_USB_CHARGING_ENABLE
|
||||
|
|
|
@ -102,6 +102,9 @@
|
|||
/* Hardware controlled charging? FIXME */
|
||||
#define CONFIG_CHARGING CHARGING_SIMPLE
|
||||
|
||||
/* define current usage levels */
|
||||
#define CURRENT_REMOTE 8 /* additional current when remote connected */
|
||||
|
||||
#ifndef SIMULATOR
|
||||
|
||||
/* Define this if your LCD can set contrast */
|
||||
|
|
|
@ -105,6 +105,9 @@
|
|||
/* Hardware controlled charging? FIXME */
|
||||
#define CONFIG_CHARGING CHARGING_SIMPLE
|
||||
|
||||
/* define current usage levels */
|
||||
#define CURRENT_REMOTE 8 /* additional current when remote connected */
|
||||
|
||||
#ifndef SIMULATOR
|
||||
|
||||
/* Define this if your LCD can set contrast */
|
||||
|
|
|
@ -122,6 +122,9 @@
|
|||
/* Hardware controlled charging? FIXME */
|
||||
#define CONFIG_CHARGING CHARGING_SIMPLE
|
||||
|
||||
/* define current usage levels */
|
||||
#define CURRENT_REMOTE 8 /* additional current when remote connected */
|
||||
|
||||
#ifndef SIMULATOR
|
||||
|
||||
/* define this if the backlight thread is used for fade, not for sim, needs
|
||||
|
|
|
@ -120,6 +120,13 @@
|
|||
/* define this if the unit can be powered or charged via USB */
|
||||
#define HAVE_USB_POWER
|
||||
|
||||
/* define current usage levels */
|
||||
#define CURRENT_NORMAL 100 /* MP3: ~10.5h out of 1100mAh battery */
|
||||
#define CURRENT_BACKLIGHT 20 /* FIXME: this needs adjusting */
|
||||
#if defined(HAVE_RECORDING)
|
||||
#define CURRENT_RECORD 35 /* FIXME: this needs adjusting */
|
||||
#endif
|
||||
|
||||
#ifndef SIMULATOR
|
||||
|
||||
/* Define this if you have a PortalPlayer PP5020 */
|
||||
|
|
|
@ -115,6 +115,12 @@
|
|||
/* define this if the unit can be powered or charged via USB */
|
||||
#define HAVE_USB_POWER
|
||||
|
||||
#define CURRENT_NORMAL 32 /* MP3: ~9h playback out of 300mAh battery */
|
||||
#define CURRENT_BACKLIGHT 20 /* FIXME: this needs adjusting */
|
||||
#if defined(HAVE_RECORDING)
|
||||
#define CURRENT_RECORD 35 /* FIXME: this needs adjusting */
|
||||
#endif
|
||||
|
||||
#ifndef SIMULATOR
|
||||
|
||||
/* Define this if you have a PortalPlayer PP5022 */
|
||||
|
|
|
@ -123,6 +123,13 @@
|
|||
/* define this if the unit can be powered or charged via USB */
|
||||
#define HAVE_USB_POWER
|
||||
|
||||
/* define current usage levels */
|
||||
#define CURRENT_NORMAL 35 /* MP3: ~11h out of 400mAh battery (30GB) or ~17h out of 600mAh (60GB) */
|
||||
#define CURRENT_BACKLIGHT 20 /* FIXME: this needs adjusting */
|
||||
#if defined(HAVE_RECORDING)
|
||||
#define CURRENT_RECORD 35 /* FIXME: this needs adjusting */
|
||||
#endif
|
||||
|
||||
#ifndef SIMULATOR
|
||||
|
||||
/* Define this if you have a PortalPlayer PP5022 */
|
||||
|
|
|
@ -69,6 +69,11 @@
|
|||
/* define this if the unit can be powered or charged via USB */
|
||||
#define HAVE_USB_POWER
|
||||
|
||||
/* define current usage levels */
|
||||
#define CURRENT_NORMAL 95 /* average, nearly proportional to 1/U */
|
||||
#define CURRENT_USB 1 /* host powered in USB mode; avoid zero-div */
|
||||
#define CURRENT_BACKLIGHT 0 /* no backlight */
|
||||
|
||||
#ifndef SIMULATOR
|
||||
|
||||
/* Define this if you have a SH7034 */
|
||||
|
|
|
@ -58,6 +58,11 @@
|
|||
/* define this if the unit can be powered or charged via USB */
|
||||
#define HAVE_USB_POWER
|
||||
|
||||
/* define current usage levels */
|
||||
#define CURRENT_NORMAL 95 /* average, nearly proportional to 1/U */
|
||||
#define CURRENT_USB 1 /* host powered in USB mode; avoid zero-div */
|
||||
#define CURRENT_BACKLIGHT 0 /* no backlight */
|
||||
|
||||
#ifndef SIMULATOR
|
||||
|
||||
/* Define this if you have a SH7034 */
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
#define NO_LOW_BATTERY_SHUTDOWN
|
||||
|
||||
/* Software controlled charging */
|
||||
#define CONFIG_CHARGING CHARGING_CONTROL
|
||||
#define CONFIG_CHARGING CHARGING_TARGET
|
||||
|
||||
#ifndef SIMULATOR
|
||||
|
||||
|
|
|
@ -114,11 +114,13 @@
|
|||
#define X5_REMOTE 3
|
||||
|
||||
/* CONFIG_CHARGING */
|
||||
|
||||
/* Generic types */
|
||||
#define CHARGING_SIMPLE 1 /* Simple, hardware controlled charging */
|
||||
#define CHARGING_MONITOR 2 /* Hardware controlled charging with monitoring */
|
||||
#define CHARGING_CONTROL 3 /* Software controlled charging */
|
||||
#define CHARGING_TARGET 4 /* Anything the target implements that is not
|
||||
a generic implementation */
|
||||
|
||||
/* Mostly target-specific code in the /target tree */
|
||||
#define CHARGING_TARGET 3
|
||||
|
||||
/* CONFIG_LCD */
|
||||
#define LCD_SSD1815 1 /* as used by Archos Recorders and Ondios */
|
||||
|
|
|
@ -21,11 +21,6 @@
|
|||
#ifndef _POWER_H_
|
||||
#define _POWER_H_
|
||||
|
||||
#if CONFIG_CHARGING == CHARGING_CONTROL
|
||||
extern bool charger_enabled;
|
||||
void charger_enable(bool on);
|
||||
#endif
|
||||
|
||||
#if CONFIG_CHARGING
|
||||
enum power_input_flags {
|
||||
/* No external power source? Default. */
|
||||
|
@ -82,9 +77,9 @@ bool power_input_present(void);
|
|||
void power_off(void);
|
||||
void ide_power_enable(bool on);
|
||||
|
||||
# if CONFIG_CHARGING == CHARGING_MONITOR
|
||||
#if CONFIG_CHARGING >= CHARGING_MONITOR
|
||||
bool charging_state(void);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef SIMULATOR
|
||||
|
||||
|
@ -102,4 +97,4 @@ bool spdif_powered(void);
|
|||
bool tuner_power(bool status);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif /* _POWER_H_ */
|
||||
|
|
|
@ -25,149 +25,103 @@
|
|||
|
||||
#define POWER_HISTORY_LEN 2*60 /* 2 hours of samples, one per minute */
|
||||
|
||||
#define CHARGE_END_SHORTD 6 /* stop when N minutes have passed with
|
||||
* avg delta being < -0.05 V */
|
||||
#define CHARGE_END_LONGD 50 /* stop when N minutes have passed with
|
||||
* avg delta being < -0.02 V */
|
||||
|
||||
typedef enum { /* sorted by increasing charging current */
|
||||
enum charge_state_type
|
||||
{
|
||||
/* sorted by increasing charging current */
|
||||
#if CONFIG_CHARGING >= CHARGING_MONITOR
|
||||
CHARGE_STATE_DISABLED = -2, /* Disable charger use */
|
||||
CHARGE_STATE_ERROR = -1, /* Some error occurred that should not allow
|
||||
further attempts without user intervention */
|
||||
CHARGE_STATE_DISABLED = -2, /* Disable charger use (safety measure) */
|
||||
CHARGE_STATE_ERROR = -1, /* Some error occurred that should not allow
|
||||
turning on the charger again by software
|
||||
without user intervention (ie. replug) */
|
||||
#endif
|
||||
DISCHARGING = 0,
|
||||
#if CONFIG_CHARGING >= CHARGING_MONITOR
|
||||
TRICKLE, /* Can occur for CONFIG_CHARGING >= CHARGING_MONITOR */
|
||||
/* For LiIon, the low-current precharge mode if battery
|
||||
was very low */
|
||||
TOPOFF, /* Can occur for CONFIG_CHARGING == CHARGING_CONTROL */
|
||||
TRICKLE, /* For NiCd, battery maintenence phase */
|
||||
/* For LiIon, low-current precharge phase */
|
||||
TOPOFF, /* For NiCd, waiting for dead zone */
|
||||
/* For LiIon, constant voltage phase */
|
||||
CHARGING, /* Can occur for all CONFIG_CHARGING options */
|
||||
/* For LiIon, the constant current phase */
|
||||
CHARGING, /* For NiCd, main charge phase */
|
||||
/* For LiIon, constant current phase */
|
||||
#endif
|
||||
} charge_state_type;
|
||||
};
|
||||
|
||||
/* tells what the charger is doing */
|
||||
extern charge_state_type charge_state;
|
||||
extern enum charge_state_type charge_state;
|
||||
|
||||
#ifdef CONFIG_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 {
|
||||
enum charger_input_state_type
|
||||
{
|
||||
NO_CHARGER = 0, /* No charger is present */
|
||||
CHARGER_UNPLUGGED, /* Transitional state during CHARGER=>NO_CHARGER */
|
||||
CHARGER_PLUGGED, /* Transitional state during NO_CHARGER=>CHARGER */
|
||||
CHARGER /* Charger is present */
|
||||
} charger_input_state_type;
|
||||
};
|
||||
|
||||
/* tells the state of the charge input */
|
||||
extern charger_input_state_type charger_input_state;
|
||||
#endif
|
||||
extern enum charger_input_state_type charger_input_state;
|
||||
|
||||
#ifndef SIMULATOR
|
||||
/* Power input status saved on the power thread each loop */
|
||||
extern unsigned int power_thread_inputs;
|
||||
|
||||
#if CONFIG_CHARGING == CHARGING_CONTROL
|
||||
#define START_TOPOFF_CHG 85 /* Battery % to start at top-off */
|
||||
#define START_TRICKLE_CHG 95 /* Battery % to start at trickle */
|
||||
|
||||
#define POWER_MESSAGE_LEN 32 /* power thread status message */
|
||||
#define CHARGE_MAX_TIME_1500 450 /* minutes: maximum charging time for 1500 mAh batteries */
|
||||
/* 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 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 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_DEADZONE 4 /* PID proportional deadzone */
|
||||
|
||||
extern char power_message[POWER_MESSAGE_LEN];
|
||||
|
||||
extern int long_delta; /* long term delta battery voltage */
|
||||
extern int short_delta; /* short term delta battery voltage */
|
||||
|
||||
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 pid_p; /* PID proportional term */
|
||||
extern int pid_i; /* PID integral term */
|
||||
extern int trickle_sec; /* trickle charge: How many seconds per minute are we charging actually? */
|
||||
|
||||
#endif /* CONFIG_CHARGING == CHARGING_CONTROL */
|
||||
|
||||
#if defined(ARCHOS_ONDIOSP) || defined(ARCHOS_ONDIOFM) /* 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 */
|
||||
# define CURRENT_BACKLIGHT 0 /* no backlight */
|
||||
#else /* Values for HD based jukeboxes */
|
||||
#ifdef IRIVER_H100_SERIES
|
||||
# define CURRENT_NORMAL 80 /* 16h playback on 1300mAh battery */
|
||||
# define CURRENT_BACKLIGHT 23 /* from IriverBattery twiki page */
|
||||
# define CURRENT_SPDIF_OUT 10 /* optical SPDIF output on */
|
||||
# define CURRENT_RECORD 105 /* additional current while recording */
|
||||
#elif defined(IRIVER_H300_SERIES)
|
||||
# define CURRENT_NORMAL 80 /* 16h playback on 1300mAh battery from IriverRuntime wiki page */
|
||||
# define CURRENT_BACKLIGHT 23 /* FIXME: This needs to be measured, copied from H100 */
|
||||
# define CURRENT_RECORD 110 /* additional current while recording */
|
||||
#elif defined(IPOD_NANO) /* iPOD Nano */
|
||||
# define CURRENT_NORMAL 32 /* MP3: ~9h playback out of 300mAh battery */
|
||||
# define CURRENT_BACKLIGHT 20 /* FIXME: this needs adjusting */
|
||||
#if defined(HAVE_RECORDING)
|
||||
# define CURRENT_RECORD 35 /* FIXME: this needs adjusting */
|
||||
#endif
|
||||
#elif defined(IPOD_VIDEO) /* iPOD Video */
|
||||
# define CURRENT_NORMAL 35 /* MP3: ~11h out of 400mAh battery (30GB) or ~17h out of 600mAh (60GB) */
|
||||
# define CURRENT_BACKLIGHT 20 /* FIXME: this needs adjusting */
|
||||
#if defined(HAVE_RECORDING)
|
||||
# define CURRENT_RECORD 35 /* FIXME: this needs adjusting */
|
||||
#endif
|
||||
#elif defined(SANSA_E200) /* Sandisk E200v1 */
|
||||
# define CURRENT_NORMAL 45 /* Mike's measurements in Jan 2008 */
|
||||
# define CURRENT_BACKLIGHT 40 /* Screen is about 20, blue LEDs are another 20, so 40 if both */
|
||||
# define CURRENT_RECORD 40 /* flash player, so this is just unboosted current*/
|
||||
#elif defined(SANSA_C200) /* Sandisk C200v1 */
|
||||
# define CURRENT_NORMAL 45 /* Should be nearly identical to E200 */
|
||||
# define CURRENT_BACKLIGHT 40 /* Screen is about 20, blue LEDs are another 20, so 40 if both */
|
||||
# define CURRENT_RECORD 40 /* flash player, so this is just unboosted current*/
|
||||
#elif defined(IPOD_4G) /* iPOD 4G */
|
||||
# define CURRENT_NORMAL 100 /* MP3: ~10.5h out of 1100mAh battery */
|
||||
# define CURRENT_BACKLIGHT 20 /* FIXME: this needs adjusting */
|
||||
#if defined(HAVE_RECORDING)
|
||||
# define CURRENT_RECORD 35 /* FIXME: this needs adjusting */
|
||||
#endif
|
||||
#else /* Not iriver H1x0, H3x0, nor Archos Ondio, nor iPod nano/Video/4G, nor Sansas */
|
||||
# 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 always on */
|
||||
#if defined(HAVE_RECORDING)
|
||||
# define CURRENT_RECORD 35 /* FIXME: this needs adjusting */
|
||||
#endif
|
||||
#endif /* Not Archos Ondio */
|
||||
#define CURRENT_USB 500 /* usual current in mA in USB mode */
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
# define CURRENT_REMOTE 8 /* add. current when H100-remote connected */
|
||||
#endif /* HAVE_REMOTE_LCD */
|
||||
|
||||
# define CURRENT_MIN_CHG 70 /* minimum charge current */
|
||||
# define MIN_CHG_V 8500 /* at 8.5v charger voltage get CURRENT_MIN_CHG */
|
||||
# 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 /* not ONDIO */
|
||||
#endif /* CONFIG_CHARGING */
|
||||
|
||||
#if CONFIG_CHARGING == CHARGING_TARGET
|
||||
/* Include target-specific definitions */
|
||||
#include "powermgmt-target.h"
|
||||
#endif
|
||||
|
||||
#ifndef SIMULATOR
|
||||
|
||||
/* Generic current values that are really rather meaningless - config header
|
||||
* should define proper numbers. */
|
||||
#ifndef CURRENT_NORMAL
|
||||
#define CURRENT_NORMAL 145 /* usual current in mA */
|
||||
#endif
|
||||
|
||||
#ifndef CURRENT_BACKLIGHT
|
||||
#define CURRENT_BACKLIGHT 30 /* additional current when backlight always on */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_RECORDING
|
||||
#ifndef CURRENT_RECORD
|
||||
#define CURRENT_RECORD 35 /* additional recording current */
|
||||
#endif
|
||||
#endif /* HAVE_RECORDING */
|
||||
|
||||
#ifndef CURRENT_USB
|
||||
#define CURRENT_USB 500 /* usual current in mA in USB mode */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
#define CURRENT_REMOTE 8 /* additional current when remote connected */
|
||||
#endif /* HAVE_REMOTE_LCD */
|
||||
|
||||
#if CONFIG_CHARGING
|
||||
#ifndef CURRENT_MAX_CHG
|
||||
#define CURRENT_MAX_CHG 350 /* maximum charging current */
|
||||
#endif
|
||||
#endif /* CONFIG_CHARGING */
|
||||
|
||||
#ifdef CHARGING_DEBUG_FILE
|
||||
#define POWERMGMT_DEBUG_STACK ((0x1000)/sizeof(long))
|
||||
#else
|
||||
#define POWERMGMT_DEBUG_STACK 0
|
||||
#endif
|
||||
|
||||
#ifndef BATT_AVE_SAMPLES
|
||||
/* slw filter constant unless otherwise specified */
|
||||
#define BATT_AVE_SAMPLES 128
|
||||
#endif
|
||||
|
||||
#ifndef POWER_THREAD_STEP_TICKS
|
||||
/* 2HZ sample rate unless otherwise specified */
|
||||
#define POWER_THREAD_STEP_TICKS (HZ/2)
|
||||
#endif
|
||||
|
||||
extern unsigned short power_history[POWER_HISTORY_LEN];
|
||||
extern const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT];
|
||||
extern const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT];
|
||||
|
@ -179,12 +133,6 @@ extern const unsigned short percent_to_volt_charge[11];
|
|||
/* Start up power management thread */
|
||||
void powermgmt_init(void);
|
||||
|
||||
/* Do target portion of init (for CHARGING_TARGET) - called on power thread */
|
||||
void powermgmt_init_target(void);
|
||||
|
||||
/* Handle frequent tasks and call charging_algorithm_small_step */
|
||||
void power_thread_sleep(int ticks);
|
||||
|
||||
#endif /* SIMULATOR */
|
||||
|
||||
/* Returns battery statust */
|
||||
|
@ -193,9 +141,15 @@ int battery_time(void); /* minutes */
|
|||
unsigned int battery_adc_voltage(void); /* voltage from ADC in millivolts */
|
||||
unsigned int battery_voltage(void); /* filtered batt. voltage in millivolts */
|
||||
|
||||
#ifdef HAVE_BATTERY_SWITCH
|
||||
unsigned int input_millivolts(void); /* voltage that device is running from */
|
||||
|
||||
/* Set the filtered battery voltage (to adjust it before beginning a charge
|
||||
cycle for instance where old, loaded readings will likely be invalid). */
|
||||
void set_filtered_battery_voltage(int millivolts);
|
||||
* cycle for instance where old, loaded readings will likely be invalid).
|
||||
* Also readjust when battery switch is opened or closed.
|
||||
*/
|
||||
void reset_battery_filter(int millivolts);
|
||||
#endif /* HAVE_BATTERY_SWITCH */
|
||||
|
||||
/* read unfiltered battery info */
|
||||
void battery_read_info(int *voltage, int *level);
|
||||
|
@ -203,13 +157,10 @@ void battery_read_info(int *voltage, int *level);
|
|||
/* Tells if the battery level is safe for disk writes */
|
||||
bool battery_level_safe(void);
|
||||
|
||||
#ifdef TARGET_POWERMGMT_FILTER_CHARGE_STATE
|
||||
int powermgmt_filter_charge_state(void);
|
||||
#endif
|
||||
|
||||
void set_poweroff_timeout(int timeout);
|
||||
void set_battery_capacity(int capacity); /* set local battery capacity value */
|
||||
void set_battery_type(int type); /* set local battery type */
|
||||
int get_battery_capacity(void); /* get local battery capacity value */
|
||||
void set_battery_type(int type); /* set local battery type */
|
||||
|
||||
void set_sleep_timer(int seconds);
|
||||
int get_sleep_timer(void);
|
||||
|
|
1232
firmware/powermgmt.c
1232
firmware/powermgmt.c
File diff suppressed because it is too large
Load diff
|
@ -168,7 +168,7 @@ int battery_adc_temp(void)
|
|||
/* All code has a preference for the main charger being connected over
|
||||
* USB. USB is considered in the algorithm only if it is the sole source. */
|
||||
static uint32_t int_sense0 = 0; /* Interrupt Sense 0 bits */
|
||||
static unsigned int power_status = POWER_INPUT_NONE; /* Detect input changes */
|
||||
static unsigned int last_inputs = POWER_INPUT_NONE; /* Detect input changes */
|
||||
static int charger_total_timer = 0; /* Total allowed charging time */
|
||||
static int icharger_ave = 0; /* Filtered charging current */
|
||||
static bool charger_close = false; /* Shutdown notification */
|
||||
|
@ -181,7 +181,7 @@ static int autorecharge_counter = 0 ; /* Battery < threshold debounce */
|
|||
static int chgcurr_timer = 0; /* Countdown to CHGCURR error */
|
||||
#define AUTORECHARGE_COUNTDOWN (10*2) /* 10s debounce */
|
||||
#define WATCHDOG_TIMEOUT (10*2) /* If not serviced, poweroff in 10s */
|
||||
#define CHGCURR_TIMEOUT (2*2) /* 2s debounce */
|
||||
#define CHGCURR_TIMEOUT (4*2) /* 4s debounce */
|
||||
|
||||
/* Temperature monitoring */
|
||||
static enum
|
||||
|
@ -217,7 +217,7 @@ static bool charger_current_filter_step(void)
|
|||
/* Return true if the main charger is connected. */
|
||||
static bool main_charger_connected(void)
|
||||
{
|
||||
return (power_status &
|
||||
return (last_inputs &
|
||||
POWER_INPUT_MAIN_CHARGER &
|
||||
POWER_INPUT_CHARGER) != 0;
|
||||
}
|
||||
|
@ -233,16 +233,14 @@ static unsigned int auto_recharge_voltage(void)
|
|||
return BATT_USB_VAUTO_RECHARGE;
|
||||
}
|
||||
|
||||
#ifndef NO_LOW_BATTERY_SHUTDOWN
|
||||
/* Return greater of supply (BP) or filtered battery voltage. */
|
||||
static unsigned int input_millivolts(void)
|
||||
unsigned int input_millivolts(void)
|
||||
{
|
||||
unsigned int app_millivolts = application_supply_adc_voltage();
|
||||
unsigned int bat_millivolts = battery_voltage();
|
||||
|
||||
return MAX(app_millivolts, bat_millivolts);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Get smoothed readings for initializing filtered data. */
|
||||
static int stat_battery_reading(int type)
|
||||
|
@ -292,7 +290,7 @@ static bool update_filtered_battery_voltage(void)
|
|||
|
||||
if (millivolts != INT_MIN)
|
||||
{
|
||||
set_filtered_battery_voltage(millivolts);
|
||||
reset_battery_filter(millivolts);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -357,13 +355,13 @@ static bool adjust_charger_current(void)
|
|||
int usb_select;
|
||||
uint32_t i;
|
||||
|
||||
usb_select = ((power_status & POWER_INPUT) == POWER_INPUT_USB)
|
||||
usb_select = ((last_inputs & POWER_INPUT) == POWER_INPUT_USB)
|
||||
? 1 : 0;
|
||||
|
||||
if (charge_state == DISCHARGING && usb_select == 1)
|
||||
{
|
||||
/* USB-only, DISCHARGING, = maintaining battery */
|
||||
int select = (power_status & POWER_INPUT_CHARGER) ? 0 : 1;
|
||||
int select = (last_inputs & POWER_INPUT_CHARGER) ? 0 : 1;
|
||||
charger_setting = charger_bits[CHARGING+1][select];
|
||||
}
|
||||
else
|
||||
|
@ -458,7 +456,7 @@ static bool charging_ok(void)
|
|||
if (ok)
|
||||
{
|
||||
/* Is the battery even connected? */
|
||||
ok = (power_status & POWER_INPUT_BATTERY) != 0;
|
||||
ok = (last_inputs & POWER_INPUT_BATTERY) != 0;
|
||||
}
|
||||
|
||||
if (ok)
|
||||
|
@ -591,20 +589,6 @@ void powermgmt_init_target(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
/* Returns CHARGING or DISCHARGING since that's all we really do. */
|
||||
int powermgmt_filter_charge_state(void)
|
||||
{
|
||||
switch(charge_state)
|
||||
{
|
||||
case TRICKLE:
|
||||
case TOPOFF:
|
||||
case CHARGING:
|
||||
return CHARGING;
|
||||
default:
|
||||
return DISCHARGING;
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns true if the unit is charging the batteries. */
|
||||
bool charging_state(void)
|
||||
{
|
||||
|
@ -625,24 +609,6 @@ int battery_charge_current(void)
|
|||
return icharger_ave / ICHARGER_AVE_SAMPLES;
|
||||
}
|
||||
|
||||
bool query_force_shutdown(void)
|
||||
{
|
||||
#ifndef NO_LOW_BATTERY_SHUTDOWN
|
||||
return input_millivolts() < battery_level_shutoff[0];
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool battery_level_safe(void)
|
||||
{
|
||||
#ifndef NO_LOW_BATTERY_SHUTDOWN
|
||||
return input_millivolts() > battery_level_dangerous[0];
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void charger_plugged(void)
|
||||
{
|
||||
adc_enable_channel(ADC_BATTERY_TEMP, true);
|
||||
|
@ -662,7 +628,7 @@ static void charger_unplugged(void)
|
|||
}
|
||||
|
||||
/* Might need to reevaluate these bits in charger_none. */
|
||||
power_status &= ~(POWER_INPUT | POWER_INPUT_CHARGER);
|
||||
last_inputs &= ~(POWER_INPUT | POWER_INPUT_CHARGER);
|
||||
temp_state = TEMP_STATE_NORMAL;
|
||||
autorecharge_counter = 0;
|
||||
chgcurr_timer = 0;
|
||||
|
@ -672,15 +638,11 @@ static void charger_unplugged(void)
|
|||
|
||||
static void charger_none(void)
|
||||
{
|
||||
unsigned int pwr = power_input_status();
|
||||
unsigned int pwr = power_thread_inputs;
|
||||
|
||||
if (power_status != pwr)
|
||||
if (last_inputs != pwr)
|
||||
{
|
||||
/* If battery switch state changed, reset filter. */
|
||||
if ((power_status ^ pwr) & POWER_INPUT_BATTERY)
|
||||
update_filtered_battery_voltage();
|
||||
|
||||
power_status = pwr;
|
||||
last_inputs = pwr;
|
||||
|
||||
if (charge_state == CHARGE_STATE_DISABLED)
|
||||
return;
|
||||
|
@ -696,7 +658,7 @@ static void charger_none(void)
|
|||
else
|
||||
{
|
||||
charger_unplugged();
|
||||
power_status = pwr; /* Restore status */
|
||||
last_inputs = pwr; /* Restore status */
|
||||
}
|
||||
}
|
||||
else if (charger_setting != 0)
|
||||
|
@ -716,17 +678,13 @@ static void charger_none(void)
|
|||
|
||||
static void charger_control(void)
|
||||
{
|
||||
unsigned int pwr = power_input_status();
|
||||
unsigned int pwr = power_thread_inputs;
|
||||
|
||||
if (power_status != pwr)
|
||||
if (last_inputs != pwr)
|
||||
{
|
||||
unsigned int changed = power_status ^ pwr;
|
||||
unsigned int changed = last_inputs ^ pwr;
|
||||
|
||||
power_status = pwr;
|
||||
|
||||
/* If battery switch state changed, reset filter. */
|
||||
if (changed & POWER_INPUT_BATTERY)
|
||||
update_filtered_battery_voltage();
|
||||
last_inputs = pwr;
|
||||
|
||||
if (charger_setting != 0)
|
||||
charger_setting = CHARGER_ADJUST;
|
||||
|
@ -771,12 +729,11 @@ static void charger_control(void)
|
|||
{
|
||||
/* Battery voltage may have dropped and a charge cycle should
|
||||
* start again. Debounced. */
|
||||
if (autorecharge_counter < 0)
|
||||
if (autorecharge_counter < 0 &&
|
||||
battery_adc_voltage() < BATT_FULL_VOLTAGE)
|
||||
{
|
||||
/* Try starting a cycle now regardless of battery level to
|
||||
* allow user to ensure the battery is topped off. It
|
||||
* will soon turn off if already full. */
|
||||
autorecharge_counter = 0;
|
||||
/* Try starting a cycle now if battery isn't already topped
|
||||
* off to allow user to ensure the battery is full. */
|
||||
}
|
||||
else if (battery_voltage() > auto_recharge_voltage())
|
||||
{
|
||||
|
@ -791,6 +748,8 @@ static void charger_control(void)
|
|||
break;
|
||||
}
|
||||
|
||||
autorecharge_counter = 0;
|
||||
|
||||
charging_set_thread_priority(true);
|
||||
|
||||
if (stat_battery_reading(ADC_BATTERY) < BATT_VTRICKLE_CHARGE)
|
||||
|
@ -858,10 +817,12 @@ static void charger_control(void)
|
|||
}
|
||||
|
||||
/* Main charging algorithm - called from powermgmt.c */
|
||||
void charging_algorithm_small_step(void)
|
||||
void charging_algorithm_step(void)
|
||||
{
|
||||
#ifdef IMX31_ALLOW_CHARGING
|
||||
if (service_wdt)
|
||||
watchdog_service();
|
||||
#endif
|
||||
|
||||
/* Switch by input state */
|
||||
switch (charger_input_state)
|
||||
|
@ -909,12 +870,6 @@ void charging_algorithm_small_step(void)
|
|||
}
|
||||
}
|
||||
|
||||
void charging_algorithm_big_step(void)
|
||||
{
|
||||
/* Sleep for one minute */
|
||||
power_thread_sleep(HZ*60);
|
||||
}
|
||||
|
||||
/* Disable the charger and prepare for poweroff - called off-thread so we
|
||||
* signal the charging thread to prepare to quit. */
|
||||
void charging_algorithm_close(void)
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#define BATT_VTRICKLE_CHARGE 2900 /* Must charge slowly */
|
||||
#define BATT_VSLOW_CHARGE 3500 /* Lower-current charge mode below
|
||||
* this level */
|
||||
#define BATT_FULL_VOLTAGE 4161 /* Battery already topped */
|
||||
#define BATT_VAUTO_RECHARGE 4100 /* When to begin another cycle */
|
||||
#define BATT_USB_VAUTO_RECHARGE 4000 /* When to cycle with USB only */
|
||||
#define BATT_USB_VSTOP 4140 /* When to "stop" when USB only */
|
||||
|
@ -92,23 +93,13 @@
|
|||
#define BATT_AVE_SAMPLES 32
|
||||
#define ICHARGER_AVE_SAMPLES 32
|
||||
|
||||
void powermgmt_init_target(void);
|
||||
void charging_algorithm_step(void);
|
||||
void charging_algorithm_close(void);
|
||||
|
||||
/* Provide filtered charge current */
|
||||
int battery_charge_current(void);
|
||||
|
||||
#ifndef SIMULATOR
|
||||
/* Indicate various functions that require implementation at the target level.
|
||||
* This is because the battery could be low or the battery switch is off but
|
||||
* with the main charger attached which implies safe power for anything. The
|
||||
* true battery reading is always reported for voltage readings and not the
|
||||
* value at the application supply. */
|
||||
#define TARGET_QUERY_FORCE_SHUTDOWN
|
||||
|
||||
/* For this the application supply is read out if the charger is attached or
|
||||
* the battery read if not (completely hardware selected at BP). */
|
||||
#define TARGET_BATTERY_LEVEL_SAFE
|
||||
|
||||
/* The state should be adjusted to CHARGING or DISCHARGING */
|
||||
#define TARGET_POWERMGMT_FILTER_CHARGE_STATE
|
||||
#endif /* SIMULATOR */
|
||||
#define CURRENT_MAX_CHG battery_charge_current()
|
||||
|
||||
#endif /* POWERMGMT_TARGET_H */
|
||||
|
|
|
@ -33,10 +33,6 @@
|
|||
#include "logf.h"
|
||||
#include "usb.h"
|
||||
|
||||
#if CONFIG_CHARGING == CHARGING_CONTROL
|
||||
bool charger_enabled;
|
||||
#endif
|
||||
|
||||
#if CONFIG_TUNER
|
||||
|
||||
bool tuner_power(bool status)
|
||||
|
|
|
@ -29,10 +29,6 @@
|
|||
#include "logf.h"
|
||||
#include "usb.h"
|
||||
|
||||
#if CONFIG_CHARGING == CHARGING_CONTROL
|
||||
bool charger_enabled;
|
||||
#endif
|
||||
|
||||
void power_init(void)
|
||||
{
|
||||
/* Enable power-off bit */
|
||||
|
|
|
@ -29,10 +29,6 @@
|
|||
#include "logf.h"
|
||||
#include "usb.h"
|
||||
|
||||
#if CONFIG_CHARGING == CHARGING_CONTROL
|
||||
bool charger_enabled;
|
||||
#endif
|
||||
|
||||
void power_init(void)
|
||||
{
|
||||
/* power off bit */
|
||||
|
|
|
@ -19,9 +19,10 @@
|
|||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "adc.h"
|
||||
#include "power.h"
|
||||
#include "powermgmt.h"
|
||||
|
||||
const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
|
||||
|
@ -58,3 +59,17 @@ unsigned int battery_adc_voltage(void)
|
|||
return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10;
|
||||
}
|
||||
|
||||
unsigned int input_millivolts(void)
|
||||
{
|
||||
|
||||
unsigned int batt_millivolts = battery_voltage();
|
||||
|
||||
if ((power_thread_inputs & POWER_INPUT_BATTERY) == 0) {
|
||||
/* Just return a safe value if battery isn't connected */
|
||||
return 4050;
|
||||
}
|
||||
|
||||
return batt_millivolts;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -33,10 +33,6 @@
|
|||
#include "logf.h"
|
||||
#include "usb.h"
|
||||
|
||||
#if CONFIG_CHARGING == CHARGING_CONTROL
|
||||
bool charger_enabled;
|
||||
#endif
|
||||
|
||||
void power_init(void)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -25,9 +25,10 @@
|
|||
#include "kernel.h"
|
||||
#include "system.h"
|
||||
#include "power.h"
|
||||
#include "powermgmt-target.h"
|
||||
#include "usb.h"
|
||||
|
||||
bool charger_enabled;
|
||||
static bool charger_on;
|
||||
|
||||
void power_init(void)
|
||||
{
|
||||
|
@ -48,13 +49,18 @@ void charger_enable(bool on)
|
|||
if(on)
|
||||
{
|
||||
and_b(~0x20, &PBDRL);
|
||||
charger_enabled = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
or_b(0x20, &PBDRL);
|
||||
charger_enabled = 0;
|
||||
}
|
||||
|
||||
charger_on = on;
|
||||
}
|
||||
|
||||
bool charger_enabled(void)
|
||||
{
|
||||
return charger_on;
|
||||
}
|
||||
|
||||
void ide_power_enable(bool on)
|
||||
|
|
|
@ -19,9 +19,13 @@
|
|||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include <sprintf.h>
|
||||
#include "debug.h"
|
||||
#include "storage.h"
|
||||
#include "adc.h"
|
||||
#include "power.h"
|
||||
#include "powermgmt.h"
|
||||
|
||||
const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
|
||||
|
@ -60,3 +64,434 @@ unsigned int battery_adc_voltage(void)
|
|||
{
|
||||
return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10;
|
||||
}
|
||||
|
||||
/** Charger control **/
|
||||
#ifdef CHARGING_DEBUG_FILE
|
||||
#include "file.h"
|
||||
#define DEBUG_FILE_NAME "/powermgmt.csv"
|
||||
#define DEBUG_MESSAGE_LEN 133
|
||||
static char debug_message[DEBUG_MESSAGE_LEN];
|
||||
static int fd = -1; /* write debug information to this file */
|
||||
static int wrcount = 0;
|
||||
#endif /* CHARGING_DEBUG_FILE */
|
||||
|
||||
/*
|
||||
* For a complete description of the charging algorithm read
|
||||
* docs/CHARGING_ALGORITHM.
|
||||
*/
|
||||
int long_delta; /* long term delta battery voltage */
|
||||
int short_delta; /* short term delta battery voltage */
|
||||
bool disk_activity_last_cycle = false; /* flag set to aid charger time
|
||||
* calculation */
|
||||
char power_message[POWER_MESSAGE_LEN] = ""; /* message that's shown in
|
||||
debug menu */
|
||||
/* percentage at which charging
|
||||
starts */
|
||||
int powermgmt_last_cycle_startstop_min = 0; /* how many minutes ago was the
|
||||
charging started or
|
||||
stopped? */
|
||||
int powermgmt_last_cycle_level = 0; /* which level had the
|
||||
batteries at this time? */
|
||||
int trickle_sec = 0; /* how many seconds should the
|
||||
charger be enabled per
|
||||
minute for trickle
|
||||
charging? */
|
||||
int pid_p = 0; /* PID proportional term */
|
||||
int pid_i = 0; /* PID integral term */
|
||||
|
||||
static unsigned int target_voltage = TRICKLE_VOLTAGE; /* desired topoff/trickle
|
||||
* voltage level */
|
||||
static int charge_max_time_idle = 0; /* max. charging duration, calculated at
|
||||
* beginning of charging */
|
||||
static int charge_max_time_now = 0; /* max. charging duration including
|
||||
* hdd activity */
|
||||
static int minutes_disk_activity = 0; /* count minutes of hdd use during
|
||||
* charging */
|
||||
static int last_disk_activity = CHARGE_END_LONGD + 1; /* last hdd use x mins ago */
|
||||
|
||||
#ifdef CHARGING_DEBUG_FILE
|
||||
static void debug_file_close(void)
|
||||
{
|
||||
if (fd >= 0) {
|
||||
close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void debug_file_log(void)
|
||||
{
|
||||
if (usb_inserted()) {
|
||||
/* It is probably too late to close the file but we can try... */
|
||||
debug_file_close();
|
||||
}
|
||||
else if (fd < 0) {
|
||||
fd = open(DEBUG_FILE_NAME, O_WRONLY | O_APPEND | O_CREAT);
|
||||
|
||||
if (fd >= 0) {
|
||||
snprintf(debug_message, DEBUG_MESSAGE_LEN,
|
||||
"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 */
|
||||
}
|
||||
}
|
||||
else {
|
||||
snprintf(debug_message, DEBUG_MESSAGE_LEN,
|
||||
"%d, %d, %d, %d, %d, %d, %d, %d\n",
|
||||
powermgmt_last_cycle_startstop_min, battery_voltage(),
|
||||
battery_level(), charger_input_state, charge_state,
|
||||
pid_p, pid_i, trickle_sec);
|
||||
write(fd, debug_message, strlen(debug_message));
|
||||
wrcount++;
|
||||
}
|
||||
}
|
||||
|
||||
static void debug_file_sync(void)
|
||||
{
|
||||
/*
|
||||
* If we have a lot of pending writes or if the disk is spining,
|
||||
* fsync the debug log file.
|
||||
*/
|
||||
if (wrcount > 10 || (wrcount > 0 && storage_disk_is_active())) {
|
||||
if (fd >= 0)
|
||||
fsync(fd);
|
||||
|
||||
wrcount = 0;
|
||||
}
|
||||
}
|
||||
#else /* !CHARGING_DEBUG_FILE */
|
||||
#define debug_file_close()
|
||||
#define debug_file_log()
|
||||
#define debug_file_sync()
|
||||
#endif /* CHARGING_DEBUG_FILE */
|
||||
|
||||
/*
|
||||
* Do tasks that should be done every step.
|
||||
*/
|
||||
static void do_frequent_tasks(void)
|
||||
{
|
||||
if (storage_disk_is_active()) {
|
||||
/* flag hdd use for charging calculation */
|
||||
disk_activity_last_cycle = true;
|
||||
}
|
||||
|
||||
debug_file_sync();
|
||||
}
|
||||
|
||||
/*
|
||||
* The charger was just plugged in. If the battery level is
|
||||
* nearly charged, just trickle. If the battery is low, start
|
||||
* a full charge cycle. If the battery level is in between,
|
||||
* top-off and then trickle.
|
||||
*/
|
||||
static void charger_plugged(void)
|
||||
{
|
||||
int battery_percent = battery_level();
|
||||
|
||||
pid_p = 0;
|
||||
pid_i = 0;
|
||||
powermgmt_last_cycle_level = battery_percent;
|
||||
powermgmt_last_cycle_startstop_min = 0;
|
||||
|
||||
snprintf(power_message, POWER_MESSAGE_LEN, "Charger plugged in");
|
||||
|
||||
if (battery_percent > START_TOPOFF_CHG) {
|
||||
|
||||
if (battery_percent >= START_TRICKLE_CHG) {
|
||||
charge_state = TRICKLE;
|
||||
target_voltage = TRICKLE_VOLTAGE;
|
||||
}
|
||||
else {
|
||||
charge_state = TOPOFF;
|
||||
target_voltage = TOPOFF_VOLTAGE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Start the charger full strength
|
||||
*/
|
||||
int i = CHARGE_MAX_MIN_1500 * get_battery_capacity() / 1500;
|
||||
charge_max_time_idle = i * (100 + 35 - battery_percent) / 100;
|
||||
|
||||
if (charge_max_time_idle > i)
|
||||
charge_max_time_idle = i;
|
||||
|
||||
charge_max_time_now = charge_max_time_idle;
|
||||
|
||||
snprintf(power_message, POWER_MESSAGE_LEN,
|
||||
"ChgAt %d%% max %dm", battery_percent,
|
||||
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, charging\n");
|
||||
trickle_sec = 60;
|
||||
long_delta = short_delta = 999999;
|
||||
charge_state = CHARGING;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The charger was just unplugged.
|
||||
*/
|
||||
static void charger_unplugged(void)
|
||||
{
|
||||
DEBUGF("power: charger disconnected, disabling\n");
|
||||
|
||||
charger_enable(false);
|
||||
powermgmt_last_cycle_level = battery_level();
|
||||
powermgmt_last_cycle_startstop_min = 0;
|
||||
trickle_sec = 0;
|
||||
pid_p = 0;
|
||||
pid_i = 0;
|
||||
charge_state = DISCHARGING;
|
||||
snprintf(power_message, POWER_MESSAGE_LEN, "Charger: discharge");
|
||||
}
|
||||
|
||||
static void charging_step(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* alter charge time max length with extra disk use */
|
||||
if (disk_activity_last_cycle) {
|
||||
minutes_disk_activity++;
|
||||
charge_max_time_now = charge_max_time_idle +
|
||||
minutes_disk_activity*2 / 5;
|
||||
disk_activity_last_cycle = false;
|
||||
last_disk_activity = 0;
|
||||
}
|
||||
else {
|
||||
last_disk_activity++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the delta voltage over the last X minutes so we can do
|
||||
* our end-of-charge logic based on the battery level change
|
||||
* (no longer use minimum time as logic for charge end has 50
|
||||
* minutes minimum charge built in).
|
||||
*/
|
||||
if (powermgmt_last_cycle_startstop_min > CHARGE_END_SHORTD) {
|
||||
short_delta = power_history[0] -
|
||||
power_history[CHARGE_END_SHORTD - 1];
|
||||
}
|
||||
|
||||
if (powermgmt_last_cycle_startstop_min > CHARGE_END_LONGD) {
|
||||
/*
|
||||
* Scan the history: the points where measurement is taken need to
|
||||
* be fairly static. Check prior to short delta 'area'. Also only
|
||||
* check first and last 10 cycles (delta in middle OK).
|
||||
*/
|
||||
long_delta = power_history[0] -
|
||||
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]) > 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]) > 50 ||
|
||||
(power_history[i] - power_history[i+1]) < -50) {
|
||||
long_delta = 888888;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(power_message, POWER_MESSAGE_LEN,
|
||||
"Chg %dm, max %dm", powermgmt_last_cycle_startstop_min,
|
||||
charge_max_time_now);
|
||||
|
||||
/*
|
||||
* End of charge criteria (any qualify):
|
||||
* 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 millivolts
|
||||
*/
|
||||
if (powermgmt_last_cycle_startstop_min >= charge_max_time_now ||
|
||||
(short_delta <= -50 && long_delta < 50) ||
|
||||
(long_delta < -20 && last_disk_activity > CHARGE_END_LONGD)) {
|
||||
|
||||
int battery_percent = battery_level();
|
||||
|
||||
if (powermgmt_last_cycle_startstop_min > charge_max_time_now) {
|
||||
DEBUGF("power: powermgmt_last_cycle_startstop_min > charge_max_time_now, "
|
||||
"enough!\n");
|
||||
/*
|
||||
* Have charged too long and deltaV detection did not
|
||||
* work!
|
||||
*/
|
||||
snprintf(power_message, POWER_MESSAGE_LEN,
|
||||
"Chg tmout %d min", charge_max_time_now);
|
||||
/*
|
||||
* Switch to trickle charging. We skip the top-off
|
||||
* since we've effectively done the top-off operation
|
||||
* already since we charged for the maximum full
|
||||
* charge time.
|
||||
*/
|
||||
powermgmt_last_cycle_level = battery_percent;
|
||||
powermgmt_last_cycle_startstop_min = 0;
|
||||
charge_state = TRICKLE;
|
||||
|
||||
/*
|
||||
* Set trickle charge target to a relative voltage instead
|
||||
* of an arbitrary value - the fully charged voltage may
|
||||
* vary according to ambient temp, battery condition etc.
|
||||
* Trickle target is -0.15v from full voltage acheived.
|
||||
* Topup target is -0.05v from full voltage.
|
||||
*/
|
||||
target_voltage = power_history[0] - 150;
|
||||
|
||||
}
|
||||
else {
|
||||
if(short_delta <= -5) {
|
||||
DEBUGF("power: short-term negative"
|
||||
" delta, enough!\n");
|
||||
snprintf(power_message, POWER_MESSAGE_LEN,
|
||||
"end negd %d %dmin", short_delta,
|
||||
powermgmt_last_cycle_startstop_min);
|
||||
target_voltage = power_history[CHARGE_END_SHORTD - 1] - 50;
|
||||
}
|
||||
else {
|
||||
DEBUGF("power: long-term small "
|
||||
"positive delta, enough!\n");
|
||||
snprintf(power_message, POWER_MESSAGE_LEN,
|
||||
"end lowd %d %dmin", long_delta,
|
||||
powermgmt_last_cycle_startstop_min);
|
||||
target_voltage = power_history[CHARGE_END_LONGD - 1] - 50;
|
||||
}
|
||||
|
||||
/*
|
||||
* Switch to top-off charging.
|
||||
*/
|
||||
powermgmt_last_cycle_level = battery_percent;
|
||||
powermgmt_last_cycle_startstop_min = 0;
|
||||
charge_state = TOPOFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void topoff_trickle_step(void)
|
||||
{
|
||||
unsigned int millivolts;
|
||||
|
||||
/*
|
||||
*Time to switch from topoff to trickle?
|
||||
*/
|
||||
if (charge_state == TOPOFF &&
|
||||
powermgmt_last_cycle_startstop_min > TOPOFF_MAX_MIN) {
|
||||
|
||||
powermgmt_last_cycle_level = battery_level();
|
||||
powermgmt_last_cycle_startstop_min = 0;
|
||||
charge_state = TRICKLE;
|
||||
target_voltage = target_voltage - 100;
|
||||
}
|
||||
/*
|
||||
* Adjust trickle charge time (proportional and integral terms).
|
||||
* Note: I considered setting the level higher if the USB is
|
||||
* plugged in, but it doesn't appear to be necessary and will
|
||||
* generate more heat [gvb].
|
||||
*/
|
||||
millivolts = battery_voltage();
|
||||
|
||||
pid_p = ((signed)target_voltage - (signed)millivolts) / 5;
|
||||
if (pid_p <= PID_DEADZONE && pid_p >= -PID_DEADZONE)
|
||||
pid_p = 0;
|
||||
|
||||
if ((unsigned)millivolts < target_voltage) {
|
||||
if (pid_i < 60)
|
||||
pid_i++; /* limit so it doesn't "wind up" */
|
||||
}
|
||||
else {
|
||||
if (pid_i > 0)
|
||||
pid_i--; /* limit so it doesn't "wind up" */
|
||||
}
|
||||
|
||||
trickle_sec = pid_p + pid_i;
|
||||
|
||||
if (trickle_sec > 60)
|
||||
trickle_sec = 60;
|
||||
|
||||
if (trickle_sec < 0)
|
||||
trickle_sec = 0;
|
||||
}
|
||||
|
||||
void charging_algorithm_step(void)
|
||||
{
|
||||
static int pwm_counter = 0; /* PWM total cycle in steps */
|
||||
static int pwm_duty = 0; /* PWM duty cycle in steps */
|
||||
|
||||
switch (charger_input_state)
|
||||
{
|
||||
case CHARGER_PLUGGED:
|
||||
charger_plugged();
|
||||
break;
|
||||
|
||||
case CHARGER_UNPLUGGED:
|
||||
charger_unplugged();
|
||||
break;
|
||||
|
||||
case CHARGER:
|
||||
case NO_CHARGER:
|
||||
do_frequent_tasks();
|
||||
|
||||
if (pwm_counter > 0) {
|
||||
if (pwm_duty > 0 && --pwm_duty <= 0)
|
||||
charger_enable(false); /* Duty cycle expired */
|
||||
|
||||
if (--pwm_counter > 0)
|
||||
return;
|
||||
|
||||
/* PWM cycle is complete */
|
||||
powermgmt_last_cycle_startstop_min++;
|
||||
debug_file_log();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (charge_state)
|
||||
{
|
||||
case CHARGING:
|
||||
charging_step();
|
||||
break;
|
||||
|
||||
case TOPOFF:
|
||||
case TRICKLE:
|
||||
topoff_trickle_step();
|
||||
break;
|
||||
|
||||
case DISCHARGING:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* If 100%, ensure pwm_on never expires and briefly disables the
|
||||
* charger. */
|
||||
pwm_duty = (trickle_sec < 60) ? trickle_sec*2 : 0;
|
||||
pwm_counter = 60*2;
|
||||
charger_enable(trickle_sec > 0);
|
||||
}
|
||||
|
||||
#ifdef CHARGING_DEBUG_FILE
|
||||
void charging_algorithm_close(void)
|
||||
{
|
||||
debug_file_close();
|
||||
}
|
||||
#endif /* CHARGING_DEBUG_FILE */
|
||||
|
||||
/* Returns true if the unit is charging the batteries. */
|
||||
bool charging_state(void)
|
||||
{
|
||||
return charge_state == CHARGING;
|
||||
}
|
||||
|
|
101
firmware/target/sh/archos/recorder/powermgmt-target.h
Normal file
101
firmware/target/sh/archos/recorder/powermgmt-target.h
Normal file
|
@ -0,0 +1,101 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese
|
||||
* Revisions copyright (C) 2005 by Gerald Van Baren
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef POWERMGMT_TARGET_H
|
||||
#define POWERMGMT_TARGET_H
|
||||
|
||||
/*
|
||||
* Define CHARGING_DEBUG_FILE to create a csv (spreadsheet) with battery
|
||||
* information in it (one sample per minute/connect/disconnect).
|
||||
*
|
||||
* This is only for very low level debug.
|
||||
*/
|
||||
#undef CHARGING_DEBUG_FILE
|
||||
|
||||
|
||||
/* stop when N minutes have passed with avg delta being < -0.05 V */
|
||||
#define CHARGE_END_SHORTD 6
|
||||
/* stop when N minutes have passed with avg delta being < -0.02 V */
|
||||
#define CHARGE_END_LONGD 50
|
||||
|
||||
/* Battery % to start at top-off */
|
||||
#define START_TOPOFF_CHG 85
|
||||
/* Battery % to start at trickle */
|
||||
#define START_TRICKLE_CHG 95
|
||||
/* power thread status message */
|
||||
#define POWER_MESSAGE_LEN 32
|
||||
/* minutes: maximum charging time for 1500 mAh batteries
|
||||
* actual max time depends also on BATTERY_CAPACITY! */
|
||||
#define CHARGE_MAX_MIN_1500 450
|
||||
/* minutes: minimum charging time */
|
||||
#define CHARGE_MIN_MIN 10
|
||||
/* After charging, go to top off charge. How long should top off charge be? */
|
||||
#define TOPOFF_MAX_MIN 90
|
||||
/* which voltage is best? (millivolts) */
|
||||
#define TOPOFF_VOLTAGE 5650
|
||||
/* After top off charge, go to trickle harge. How long should trickle
|
||||
* charge be? */
|
||||
#define TRICKLE_MAX_MIN 720 /* 12 hrs */
|
||||
/* which voltage is best? (millivolts) */
|
||||
#define TRICKLE_VOLTAGE 5450
|
||||
/* initial trickle_sec for topoff */
|
||||
#define START_TOPOFF_SEC 25
|
||||
/* initial trickle_sec for trickle */
|
||||
#define START_TRICKLE_SEC 15
|
||||
|
||||
#define PID_DEADZONE 4 /* PID proportional deadzone */
|
||||
|
||||
extern char power_message[POWER_MESSAGE_LEN];
|
||||
|
||||
extern int long_delta; /* long term delta battery voltage */
|
||||
extern int short_delta; /* short term delta battery voltage */
|
||||
|
||||
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 pid_p; /* PID proportional term */
|
||||
extern int pid_i; /* PID integral term */
|
||||
extern int trickle_sec; /* how many seconds should the
|
||||
charger be enabled per
|
||||
minute for trickle
|
||||
charging? */
|
||||
void charger_enable(bool on);
|
||||
bool charger_enabled(void);
|
||||
|
||||
/* Battery filter lengths in samples */
|
||||
#define BATT_AVE_SAMPLES 32
|
||||
|
||||
/* No init to do */
|
||||
static inline void powermgmt_init_target(void) {}
|
||||
void charging_algorithm_step(void);
|
||||
|
||||
#ifdef CHARGING_DEBUG_FILE
|
||||
/* Need to flush and close debug file */
|
||||
void charging_algorithm_close(void);
|
||||
#else
|
||||
/* No poweroff operation to do */
|
||||
static inline void charging_algorithm_close(void) {}
|
||||
#endif
|
||||
|
||||
#endif /* POWERMGMT_TARGET_H */
|
|
@ -75,7 +75,7 @@ static void charging_screen(void)
|
|||
|
||||
do
|
||||
{
|
||||
#if CONFIG_CHARGING == CHARGING_CONTROL
|
||||
#ifdef ARCHOS_RECORDER
|
||||
if (charge_state == CHARGING)
|
||||
msg = "charging";
|
||||
else if (charge_state == TOPOFF)
|
||||
|
@ -84,7 +84,6 @@ static void charging_screen(void)
|
|||
msg = "trickle charge";
|
||||
else
|
||||
msg = "not charging";
|
||||
|
||||
#else
|
||||
msg = "charging";
|
||||
#endif
|
||||
|
|
|
@ -7,3 +7,5 @@ lcd-playersim.c
|
|||
#endif
|
||||
sim_icons.c
|
||||
stubs.c
|
||||
powermgmt-sim.c
|
||||
|
||||
|
|
159
uisimulator/common/powermgmt-sim.c
Normal file
159
uisimulator/common/powermgmt-sim.c
Normal file
|
@ -0,0 +1,159 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese
|
||||
* Revisions copyright (C) 2005 by Gerald Van Baren
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include <time.h>
|
||||
#include "kernel.h"
|
||||
#include "powermgmt.h"
|
||||
|
||||
#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 */
|
||||
|
||||
extern void send_battery_level_event(void);
|
||||
extern int last_sent_battery_level;
|
||||
extern int battery_percent;
|
||||
|
||||
static unsigned int battery_millivolts = BATT_MAXMVOLT;
|
||||
/* estimated remaining time in minutes */
|
||||
static int powermgmt_est_runningtime_min = BATT_MAXRUNTIME;
|
||||
|
||||
static void battery_status_update(void)
|
||||
{
|
||||
static time_t last_change = 0;
|
||||
static bool charging = false;
|
||||
time_t now;
|
||||
|
||||
time(&now);
|
||||
|
||||
if (last_change < now) {
|
||||
last_change = now;
|
||||
|
||||
/* change the values: */
|
||||
if (charging) {
|
||||
if (battery_millivolts >= BATT_MAXMVOLT) {
|
||||
/* Pretend the charger was disconnected */
|
||||
charging = false;
|
||||
queue_broadcast(SYS_CHARGER_DISCONNECTED, 0);
|
||||
last_sent_battery_level = 100;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (battery_millivolts <= BATT_MINMVOLT) {
|
||||
/* Pretend the charger was connected */
|
||||
charging = true;
|
||||
queue_broadcast(SYS_CHARGER_CONNECTED, 0);
|
||||
last_sent_battery_level = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (charging) {
|
||||
battery_millivolts += (BATT_MAXMVOLT - BATT_MINMVOLT) / 50;
|
||||
}
|
||||
else {
|
||||
battery_millivolts -= (BATT_MAXMVOLT - BATT_MINMVOLT) / 100;
|
||||
}
|
||||
|
||||
battery_percent = 100 * (battery_millivolts - BATT_MINMVOLT) /
|
||||
(BATT_MAXMVOLT - BATT_MINMVOLT);
|
||||
|
||||
powermgmt_est_runningtime_min =
|
||||
battery_percent * BATT_MAXRUNTIME / 100;
|
||||
}
|
||||
|
||||
send_battery_level_event();
|
||||
}
|
||||
|
||||
void battery_read_info(int *voltage, int *level)
|
||||
{
|
||||
battery_status_update();
|
||||
|
||||
if (voltage)
|
||||
*voltage = battery_millivolts;
|
||||
|
||||
if (level)
|
||||
*level = battery_percent;
|
||||
}
|
||||
|
||||
unsigned int battery_voltage(void)
|
||||
{
|
||||
battery_status_update();
|
||||
return battery_millivolts;
|
||||
}
|
||||
|
||||
int battery_level(void)
|
||||
{
|
||||
battery_status_update();
|
||||
return battery_percent;
|
||||
}
|
||||
|
||||
int battery_time(void)
|
||||
{
|
||||
battery_status_update();
|
||||
return powermgmt_est_runningtime_min;
|
||||
}
|
||||
|
||||
bool battery_level_safe(void)
|
||||
{
|
||||
return battery_level() >= 10;
|
||||
}
|
||||
|
||||
void set_poweroff_timeout(int timeout)
|
||||
{
|
||||
(void)timeout;
|
||||
}
|
||||
|
||||
void set_battery_capacity(int capacity)
|
||||
{
|
||||
(void)capacity;
|
||||
}
|
||||
|
||||
#if BATTERY_TYPES_COUNT > 1
|
||||
void set_battery_type(int type)
|
||||
{
|
||||
(void)type;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ACCESSORY_SUPPLY
|
||||
void accessory_supply_set(bool enable)
|
||||
{
|
||||
(void)enable;
|
||||
}
|
||||
#endif
|
||||
|
||||
void reset_poweroff_timer(void)
|
||||
{
|
||||
}
|
||||
|
||||
void shutdown_hw(void)
|
||||
{
|
||||
}
|
||||
|
||||
void sys_poweroff(void)
|
||||
{
|
||||
}
|
||||
|
||||
void cancel_shutdown(void)
|
||||
{
|
||||
}
|
Loading…
Reference in a new issue