|
Rockbox mail archiveSubject: Re: firmware powermgmt.c,NONE,1.1 powermgmt.h,NONE,1.1 config-recorder.h,1.4,1.5Re: firmware powermgmt.c,NONE,1.1 powermgmt.h,NONE,1.1 config-recorder.h,1.4,1.5
From: George Styles <george_at_ripnet.co.uk>
Date: Tue, 6 Aug 2002 12:15:19 +0100 Wooo Hoooo :) this is the final barrier to the Rockbox being better in every way than the stock firmware. good stuff g ----- Original Message ----- From: "Heikki Hannikainen" <hessuh_at_users.sourceforge.net> To: <rockbox-cvs_at_cool.haxx.se> Sent: Tuesday, August 06, 2002 11:50 AM Subject: cvs: firmware powermgmt.c,NONE,1.1 powermgmt.h,NONE,1.1 config-recorder.h,1.4,1.5 > Update of /cvsroot/rockbox/firmware > In directory usw-pr-cvs1:/tmp/cvs-serv18777 > > Modified Files: > config-recorder.h > Added Files: > powermgmt.c powermgmt.h > Log Message: > Added battery charger code for the recorder and battery voltage statistics keeping for all platforms. > > > --- NEW FILE: powermgmt.c --- > /*************************************************************************** > * __________ __ ___. > * Open \______ \ ____ ____ | | _\_ |__ _______ ___ > * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / > * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < > * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ > * \/ \/ \/ \/ \/ > * $Id: powermgmt.c,v 1.1 2002/08/06 10:50:50 hessuh Exp $ > * > * Copyright (C) 2002 by Heikki Hannikainen > * > * All files in this archive are subject to the GNU General Public License. > * See the file COPYING in the source tree root for full license agreement. > * > * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY > * KIND, either express or implied. > * > **************************************************************************** / > #include "config.h" > #include "sh7034.h" > #include "kernel.h" > #include "thread.h" > #include "system.h" > #include "debug.h" > #include "panic.h" > #include "adc.h" > #include "string.h" > #include "power.h" > #include "powermgmt.h" > > #ifndef SIMULATOR > > static char power_stack[DEFAULT_STACK_SIZE]; > static char power_thread_name[] = "power"; > > unsigned short power_history[POWER_HISTORY_LEN]; > #ifdef HAVE_CHARGE_CTRL > char power_message[POWER_MESSAGE_LEN] = ""; > char charge_restart_level = CHARGE_RESTART_HI; > #endif > > /* > * This power thread maintains a history of battery voltage > * and should, in the future, enable charging when it's needed > * and power is available, and disable it when the battery is full. > * Battery 'fullness' can be determined by the voltage drop, see: > * > * http://www.nimhbattery.com/nimhbattery-faq.htm questions 3 & 4 > * http://www.powerpacks-uk.com/Charging%20NiMh%20Batteries.htm > * http://www.angelfire.com/electronic/hayles/charge1.html (soft start idea) > * http://www.powerstream.com/NiMH.htm (discouraging) > * http://www.panasonic.com/industrial/battery/oem/images/pdf/nimhchar.pdf > * http://www.duracell.com/oem/Pdf/others/nimh_5.pdf (discharging) > * http://www.duracell.com/oem/Pdf/others/nimh_6.pdf (charging) > * > * Charging logic which we're starting with (by Linus, Hes, Bagder): > * > * 1) max 16 hrs charge time (just in negative delta detection fails) > * 2) Stop at negative delta of 5 mins > * 3) Stop at 15 mins of zero-delta or below > * 4) minimum of 15 mins charge time before 2) is applied > * 5) after end of charging, wait for charge go down 80% > * before charging again if in 'no-use overnight charging mode' > * and down to 10% if in 'fixed-location mains-powered usage mode' > */ > > static void power_thread(void) > { > int i; > int avg; > #ifdef HAVE_CHARGE_CTRL > int delta; > int charged_time = 0; > #endif > > while (1) > { > DEBUGF("power_thread woke up\n"); > /* make POWER_AVG measurements and calculate an average of that to > * reduce the effect of backlights/disk spinning/other variation > */ > avg = 0; > for (i = 0; i < POWER_AVG; i++) { > avg += adc_read(ADC_UNREG_POWER); > sleep(15); > } > avg = avg / POWER_AVG; > > /* rotate the power history */ > for (i = 0; i < POWER_HISTORY_LEN-1; i++) > power_history[i] = power_history[i+1]; > > /* insert new value in the end, in decivolts 8-) */ > power_history[POWER_HISTORY_LEN-1] = (avg * BATTERY_SCALE_FACTOR) / 10000; > > #ifdef HAVE_CHARGE_CTRL > if (charger_inserted()) { > if (charger_enabled) { > /* charger inserted and enabled */ > charged_time++; > if (charged_time > CHARGE_MAX_TIME) { > DEBUGF("power: charged_time > CHARGE_MAX_TIME, enough!\n"); > /* have charged too long and deltaV detection did not work! */ > charger_enable(false); > snprintf(power_message, POWER_MESSAGE_LEN, "Chg tmout %d min", CHARGE_MAX_TIME); > /* Perhaps we should disable charging for several > hours from this point, just to be sure. */ > } else { > if (charged_time > CHARGE_MIN_TIME) { > /* have charged continuously over the minimum charging time, > * so we monitor for deltaV going negative. Multiply things > * by 100 to get more accuracy without floating point arithmetic. > * power_history[] contains decivolts. > */ > delta = 0; > for (i = 0; i < CHARGE_END_NEGD; i++) > delta += power_history[POWER_HISTORY_LEN-1-i]*100 - power_history[POWER_HISTORY_LEN-1-i-1]*100; > delta = delta / CHARGE_END_NEGD; > > if (delta < -50) { /* delta < -0.3 V */ > DEBUGF("power: short-term negative delta, enough!\n"); > charger_enable(false); > snprintf(power_message, POWER_MESSAGE_LEN, "end negd %d %dmin", delta, charged_time); > } else { > /* if we didn't disable the charger in the previous test, check for low positive delta */ > delta = 0; > for (i = 0; i < CHARGE_END_ZEROD; i++) > delta += power_history[POWER_HISTORY_LEN-1-i]*100 - power_history[POWER_HISTORY_LEN-1-i-1]*100; > delta = delta / CHARGE_END_ZEROD; > > if (delta <= 5) { /* delta of <= 0.005 V */ > DEBUGF("power: long-term small positive delta, enough!\n"); > charger_enable(false); > snprintf(power_message, POWER_MESSAGE_LEN, "end lowd %d %dmin", delta, charged_time); > } > } > } > } > } else { > /* charged inserted but not enabled */ > /* if battery is not full, enable charging */ > if (battery_level() < charge_restart_level) { > DEBUGF("power: charger inserted and battery not full, enabling\n"); > charger_enable(true); > charged_time = 0; > snprintf(power_message, POWER_MESSAGE_LEN, "Chg started at %d%%", battery_level()); > } > } > } else { > /* charger not inserted */ > if (charger_enabled) { > /* charger not inserted but was enabled */ > DEBUGF("power: charger disconnected, disabling\n"); > charger_enable(false); > snprintf(power_message, POWER_MESSAGE_LEN, "Charger disc"); > } > /* charger not inserted and disabled, so we're discharging */ > } > #endif /* HAVE_CHARGE_CTRL*/ > > /* sleep for roughly a minute */ > sleep(HZ*(60-POWER_AVG*15)); > } > } > > void power_init(void) > { > /* init history to 0 */ > memset(power_history, 0x00, sizeof(power_history)); > > #ifdef HAVE_CHARGE_CTRL > snprintf(power_message, POWER_MESSAGE_LEN, "Powermgmt started"); > #endif > create_thread(power_thread, power_stack, sizeof(power_stack), power_thread_name); > } > > #endif > > --- NEW FILE: powermgmt.h --- > /*************************************************************************** > * __________ __ ___. > * Open \______ \ ____ ____ | | _\_ |__ _______ ___ > * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / > * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < > * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ > * \/ \/ \/ \/ \/ > * $Id: powermgmt.h,v 1.1 2002/08/06 10:50:50 hessuh Exp $ > * > * Copyright (C) 2002 by Heikki Hannikainen > * > * All files in this archive are subject to the GNU General Public License. > * See the file COPYING in the source tree root for full license agreement. > * > * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY > * KIND, either express or implied. > * > **************************************************************************** / > #ifndef _POWERMGMT_H_ > #define _POWERMGMT_H_ > > #ifndef SIMULATOR > > #define POWER_HISTORY_LEN 2*60 /* 2 hours of samples, one per minute */ > #define POWER_AVG 3 /* how many samples to take for each measurement */ > > #define CHARGE_END_NEGD 6 /* stop when N minutes have passed with > * avg delta being < -0.3 V */ > #define CHARGE_END_ZEROD 30 /* stop when N minutes have passed with > * avg delta being < 0.005 V */ > > #ifdef HAVE_CHARGE_CTRL > #define POWER_MESSAGE_LEN 32 /* power thread status message */ > #define CHARGE_MAX_TIME 16*60 /* minutes: maximum charging time */ > #define CHARGE_MIN_TIME 10 /* minutes: minimum charging time */ > #define CHARGE_RESTART_HI 90 /* %: when to restart charging in 'charge' mode */ > #define CHARGE_RESTART_LO 10 /* %: when to restart charging in 'discharge' mode */ > > extern char power_message[POWER_MESSAGE_LEN]; > extern char charge_restart_level; > #endif /* HAVE_CHARGE_CTRL */ > > extern unsigned short power_history[POWER_HISTORY_LEN]; > > void power_init(void); > > #endif > > #endif > > Index: config-recorder.h > =================================================================== > RCS file: /cvsroot/rockbox/firmware/config-recorder.h,v > retrieving revision 1.4 > retrieving revision 1.5 > diff -u -b -r1.4 -r1.5 > --- config-recorder.h 29 Jul 2002 09:34:43 -0000 1.4 > +++ config-recorder.h 6 Aug 2002 10:50:50 -0000 1.5 > _at__at_ -12,3 +12,7 _at__at_ > > /* Define this if you have a MAS3587F */ > #define HAVE_MAS3587F > + > +/* Define this if you have charging control */ > +#define HAVE_CHARGE_CTRL > + > > Received on 2002-08-06 Page template was last modified "Tue Sep 7 00:00:02 2021" The Rockbox Crew -- Privacy Policy |