mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-14 07:35:15 -05:00
Archos V1 recorder charging path #2927 by Alun Thomas
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8898 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
c7838b8418
commit
ea5df70e46
3 changed files with 88 additions and 36 deletions
|
|
@ -176,3 +176,4 @@ Aaron F. Gonzalez
|
||||||
Aleksey Kozyulin
|
Aleksey Kozyulin
|
||||||
Jani Kinnunen
|
Jani Kinnunen
|
||||||
Rui Marinho
|
Rui Marinho
|
||||||
|
Alun Thomas
|
||||||
|
|
|
||||||
|
|
@ -39,10 +39,10 @@
|
||||||
|
|
||||||
#define POWER_HISTORY_LEN 2*60 /* 2 hours of samples, one per minute */
|
#define POWER_HISTORY_LEN 2*60 /* 2 hours of samples, one per minute */
|
||||||
|
|
||||||
#define CHARGE_END_NEGD 6 /* stop when N minutes have passed with
|
#define CHARGE_END_SHORTD 6 /* stop when N minutes have passed with
|
||||||
* avg delta being < -0.05 V */
|
* avg delta being < -0.05 V */
|
||||||
#define CHARGE_END_ZEROD 50 /* stop when N minutes have passed with
|
#define CHARGE_END_LONGD 50 /* stop when N minutes have passed with
|
||||||
* avg delta being < 0.005 V */
|
* avg delta being < -0.02 V */
|
||||||
|
|
||||||
#ifndef SIMULATOR
|
#ifndef SIMULATOR
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -175,7 +175,8 @@ charge_state_type charge_state; /* charging mode */
|
||||||
#ifdef HAVE_CHARGE_CTRL
|
#ifdef HAVE_CHARGE_CTRL
|
||||||
int long_delta; /* long term delta battery voltage */
|
int long_delta; /* long term delta battery voltage */
|
||||||
int short_delta; /* short 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
|
char power_message[POWER_MESSAGE_LEN] = ""; /* message that's shown in
|
||||||
debug menu */
|
debug menu */
|
||||||
/* percentage at which charging
|
/* percentage at which charging
|
||||||
|
|
@ -580,7 +581,12 @@ static void power_thread_sleep(int ticks)
|
||||||
battery_status_update();
|
battery_status_update();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#ifdef HAVE_CHARGE_CTRL
|
||||||
|
if (ata_disk_is_active()) {
|
||||||
|
/* flag hdd use for charging calculation */
|
||||||
|
disk_activity_last_cycle = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#if defined(DEBUG_FILE) && defined(HAVE_CHARGE_CTRL)
|
#if defined(DEBUG_FILE) && defined(HAVE_CHARGE_CTRL)
|
||||||
/*
|
/*
|
||||||
* If we have a lot of pending writes or if the disk is spining,
|
* If we have a lot of pending writes or if the disk is spining,
|
||||||
|
|
@ -608,9 +614,15 @@ static void power_thread(void)
|
||||||
int i;
|
int i;
|
||||||
short *phps, *phpd; /* power history rotation pointers */
|
short *phps, *phpd; /* power history rotation pointers */
|
||||||
#ifdef HAVE_CHARGE_CTRL
|
#ifdef HAVE_CHARGE_CTRL
|
||||||
unsigned int target_voltage; /* desired topoff/trickle voltage level */
|
unsigned int target_voltage = TRICKLE_VOLTAGE; /* desired topoff/trickle
|
||||||
int charge_max_time_now = 0; /* max. charging duration, calculated at
|
* voltage level */
|
||||||
beginning of charging */
|
int charge_max_time_idle = 0; /* max. charging duration, calculated at
|
||||||
|
* beginning of charging */
|
||||||
|
int charge_max_time_now = 0; /* max. charging duration including
|
||||||
|
* hdd activity */
|
||||||
|
int minutes_disk_activity = 0; /* count minutes of hdd use during
|
||||||
|
* charging */
|
||||||
|
int last_disk_activity = CHARGE_END_LONGD + 1; /* last hdd use x mins ago */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* initialize the voltages for the exponential filter */
|
/* initialize the voltages for the exponential filter */
|
||||||
|
|
@ -669,19 +681,23 @@ static void power_thread(void)
|
||||||
powermgmt_last_cycle_startstop_min = 0;
|
powermgmt_last_cycle_startstop_min = 0;
|
||||||
if(battery_percent >= START_TRICKLE_CHG) {
|
if(battery_percent >= START_TRICKLE_CHG) {
|
||||||
charge_state = TRICKLE;
|
charge_state = TRICKLE;
|
||||||
|
target_voltage = TRICKLE_VOLTAGE;
|
||||||
} else {
|
} else {
|
||||||
charge_state = TOPOFF;
|
charge_state = TOPOFF;
|
||||||
|
target_voltage = TOPOFF_VOLTAGE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* Start the charger full strength
|
* Start the charger full strength
|
||||||
*/
|
*/
|
||||||
i = CHARGE_MAX_TIME_1500 * battery_capacity / 1500;
|
i = CHARGE_MAX_TIME_1500 * battery_capacity / 1500;
|
||||||
charge_max_time_now =
|
charge_max_time_idle =
|
||||||
i * (100 + 35 - battery_percent) / 100;
|
i * (100 + 35 - battery_percent) / 100;
|
||||||
if (charge_max_time_now > i) {
|
if (charge_max_time_idle > i) {
|
||||||
charge_max_time_now = i;
|
charge_max_time_idle = i;
|
||||||
}
|
}
|
||||||
|
charge_max_time_now = charge_max_time_idle;
|
||||||
|
|
||||||
snprintf(power_message, POWER_MESSAGE_LEN,
|
snprintf(power_message, POWER_MESSAGE_LEN,
|
||||||
"ChgAt %d%% max %dm", battery_level(),
|
"ChgAt %d%% max %dm", battery_level(),
|
||||||
charge_max_time_now);
|
charge_max_time_now);
|
||||||
|
|
@ -699,26 +715,44 @@ static void power_thread(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (charge_state == CHARGING) {
|
if (charge_state == CHARGING) {
|
||||||
snprintf(power_message, POWER_MESSAGE_LEN,
|
/* alter charge time max length with extra disk use */
|
||||||
"Chg %dm, max %dm", powermgmt_last_cycle_startstop_min,
|
if (disk_activity_last_cycle) {
|
||||||
charge_max_time_now);
|
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
|
* Check the delta voltage over the last X minutes so we can do
|
||||||
* our end-of-charge logic based on the battery level change.
|
* 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_MIN_TIME) {
|
if (powermgmt_last_cycle_startstop_min > CHARGE_END_SHORTD) {
|
||||||
short_delta = power_history[0] -
|
short_delta = power_history[0] -
|
||||||
power_history[CHARGE_END_NEGD - 1];
|
power_history[CHARGE_END_SHORTD - 1];
|
||||||
}
|
}
|
||||||
if (powermgmt_last_cycle_startstop_min > CHARGE_END_ZEROD) {
|
|
||||||
|
if (powermgmt_last_cycle_startstop_min > CHARGE_END_LONGD) {
|
||||||
/*
|
/*
|
||||||
* Scan the history: if we have a big delta in the middle of
|
* Scan the history: the points where measurement is taken need to
|
||||||
* our history, the long term delta isn't a valid end-of-charge
|
* be fairly static. (check prior to short delta 'area')
|
||||||
* indicator.
|
* (also only check first and last 10 cycles - delta in middle OK)
|
||||||
*/
|
*/
|
||||||
long_delta = power_history[0] -
|
long_delta = power_history[0] -
|
||||||
power_history[CHARGE_END_ZEROD - 1];
|
power_history[CHARGE_END_LONGD - 1];
|
||||||
for(i = 0; i < CHARGE_END_ZEROD; i++) {
|
|
||||||
|
for(i = CHARGE_END_SHORTD; i < CHARGE_END_SHORTD + 10; i++) {
|
||||||
|
if(((power_history[i] - power_history[i+1]) > 5) ||
|
||||||
|
((power_history[i] - power_history[i+1]) < -5)) {
|
||||||
|
long_delta = 777777;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(i = CHARGE_END_LONGD - 11; i < CHARGE_END_LONGD - 1 ; i++) {
|
||||||
if(((power_history[i] - power_history[i+1]) > 5) ||
|
if(((power_history[i] - power_history[i+1]) > 5) ||
|
||||||
((power_history[i] - power_history[i+1]) < -5)) {
|
((power_history[i] - power_history[i+1]) < -5)) {
|
||||||
long_delta = 888888;
|
long_delta = 888888;
|
||||||
|
|
@ -727,21 +761,26 @@ static void power_thread(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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):
|
* End of charge criteria (any qualify):
|
||||||
* 1) Charged a long time
|
* 1) Charged a long time
|
||||||
* 2) DeltaV went negative for a short time
|
* 2) DeltaV went negative for a short time ( & long delta static)
|
||||||
* 3) DeltaV was close to zero for a long time
|
* 3) DeltaV was negative over a longer period (no disk use only)
|
||||||
* Note: short_delta and long_delta are centivolts
|
* Note: short_delta and long_delta are centivolts
|
||||||
*/
|
*/
|
||||||
if ((powermgmt_last_cycle_startstop_min > charge_max_time_now) ||
|
if ((powermgmt_last_cycle_startstop_min >= charge_max_time_now) ||
|
||||||
(short_delta <= -5) || (long_delta < 5))
|
(short_delta <= -5 && long_delta < 5 ) || (long_delta < -2 &&
|
||||||
{
|
last_disk_activity > CHARGE_END_LONGD)) {
|
||||||
if (powermgmt_last_cycle_startstop_min > charge_max_time_now) {
|
if (powermgmt_last_cycle_startstop_min > charge_max_time_now) {
|
||||||
DEBUGF("power: powermgmt_last_cycle_startstop_min > charge_max_time_now, "
|
DEBUGF("power: powermgmt_last_cycle_startstop_min > charge_max_time_now, "
|
||||||
"enough!\n");
|
"enough!\n");
|
||||||
/* have charged too long and deltaV detection did not
|
/*
|
||||||
work! */
|
*have charged too long and deltaV detection did not
|
||||||
|
*work!
|
||||||
|
*/
|
||||||
snprintf(power_message, POWER_MESSAGE_LEN,
|
snprintf(power_message, POWER_MESSAGE_LEN,
|
||||||
"Chg tmout %d min", charge_max_time_now);
|
"Chg tmout %d min", charge_max_time_now);
|
||||||
/*
|
/*
|
||||||
|
|
@ -753,6 +792,16 @@ static void power_thread(void)
|
||||||
powermgmt_last_cycle_level = battery_percent;
|
powermgmt_last_cycle_level = battery_percent;
|
||||||
powermgmt_last_cycle_startstop_min = 0;
|
powermgmt_last_cycle_startstop_min = 0;
|
||||||
charge_state = TRICKLE;
|
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] - 15;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if(short_delta <= -5) {
|
if(short_delta <= -5) {
|
||||||
DEBUGF("power: short-term negative"
|
DEBUGF("power: short-term negative"
|
||||||
|
|
@ -760,12 +809,16 @@ static void power_thread(void)
|
||||||
snprintf(power_message, POWER_MESSAGE_LEN,
|
snprintf(power_message, POWER_MESSAGE_LEN,
|
||||||
"end negd %d %dmin", short_delta,
|
"end negd %d %dmin", short_delta,
|
||||||
powermgmt_last_cycle_startstop_min);
|
powermgmt_last_cycle_startstop_min);
|
||||||
|
target_voltage = power_history[CHARGE_END_SHORTD - 1]
|
||||||
|
- 5;
|
||||||
} else {
|
} else {
|
||||||
DEBUGF("power: long-term small "
|
DEBUGF("power: long-term small "
|
||||||
"positive delta, enough!\n");
|
"positive delta, enough!\n");
|
||||||
snprintf(power_message, POWER_MESSAGE_LEN,
|
snprintf(power_message, POWER_MESSAGE_LEN,
|
||||||
"end lowd %d %dmin", long_delta,
|
"end lowd %d %dmin", long_delta,
|
||||||
powermgmt_last_cycle_startstop_min);
|
powermgmt_last_cycle_startstop_min);
|
||||||
|
target_voltage = power_history[CHARGE_END_LONGD - 1]
|
||||||
|
- 5;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Switch to top-off charging.
|
* Switch to top-off charging.
|
||||||
|
|
@ -778,7 +831,8 @@ static void power_thread(void)
|
||||||
}
|
}
|
||||||
else if (charge_state > CHARGING) /* top off or trickle */
|
else if (charge_state > CHARGING) /* top off or trickle */
|
||||||
{
|
{
|
||||||
/* Time to switch from topoff to trickle?
|
/*
|
||||||
|
*Time to switch from topoff to trickle?
|
||||||
*/
|
*/
|
||||||
if ((charge_state == TOPOFF) &&
|
if ((charge_state == TOPOFF) &&
|
||||||
(powermgmt_last_cycle_startstop_min > TOPOFF_MAX_TIME))
|
(powermgmt_last_cycle_startstop_min > TOPOFF_MAX_TIME))
|
||||||
|
|
@ -786,6 +840,7 @@ static void power_thread(void)
|
||||||
powermgmt_last_cycle_level = battery_percent;
|
powermgmt_last_cycle_level = battery_percent;
|
||||||
powermgmt_last_cycle_startstop_min = 0;
|
powermgmt_last_cycle_startstop_min = 0;
|
||||||
charge_state = TRICKLE;
|
charge_state = TRICKLE;
|
||||||
|
target_voltage = target_voltage - 10;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Adjust trickle charge time (proportional and integral terms).
|
* Adjust trickle charge time (proportional and integral terms).
|
||||||
|
|
@ -793,10 +848,6 @@ static void power_thread(void)
|
||||||
* plugged in, but it doesn't appear to be necessary and will
|
* plugged in, but it doesn't appear to be necessary and will
|
||||||
* generate more heat [gvb].
|
* generate more heat [gvb].
|
||||||
*/
|
*/
|
||||||
if(charge_state == TOPOFF)
|
|
||||||
target_voltage = TOPOFF_VOLTAGE;
|
|
||||||
else
|
|
||||||
target_voltage = TRICKLE_VOLTAGE;
|
|
||||||
|
|
||||||
pid_p = target_voltage - battery_centivolts;
|
pid_p = target_voltage - battery_centivolts;
|
||||||
if((pid_p > PID_DEADZONE) || (pid_p < -PID_DEADZONE))
|
if((pid_p > PID_DEADZONE) || (pid_p < -PID_DEADZONE))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue