diff -urN --exclude=CVS --exclude=*~ orig/firmware/powermgmt.c firmware/powermgmt.c --- orig/firmware/powermgmt.c Thu Jan 1 02:00:00 1970 +++ firmware/powermgmt.c Wed Jul 24 11:11:21 2002 @@ -0,0 +1,95 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * 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 "powermgmt.h" + +#ifndef SIMULATOR +#ifdef ARCHOS_RECORDER + +static char power_stack[DEFAULT_STACK_SIZE]; +static char power_thread_name[] = "power"; + +unsigned short power_history[POWER_HISTORY_LEN]; + +/* + * 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) + */ + +#define POWER_AVG 3 /* how many samples to take for each measurement */ + +static void power_thread(void) +{ + int i; + int avg; + + while(1) + { + /* 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(2); + } + 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; + + /* sleep for a minute... to get a better idea how backlights, disk + spinning etc change the voltage, try sleeping for 2 seconds + instead (and setting POWER_AVG to 1) */ + sleep(HZ*(60-POWER_AVG*2)); + } +} + +void power_init(void) +{ + /* init history to 0 */ + memset(power_history, 0x00, sizeof(power_history)); + + create_thread(power_thread, power_stack, sizeof(power_stack), power_thread_name); +} + +#endif +#endif diff -urN --exclude=CVS --exclude=*~ orig/firmware/powermgmt.h firmware/powermgmt.h --- orig/firmware/powermgmt.h Thu Jan 1 02:00:00 1970 +++ firmware/powermgmt.h Tue Jul 23 17:22:21 2002 @@ -0,0 +1,34 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * 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 +#ifdef ARCHOS_RECORDER + +#define POWER_HISTORY_LEN 2*60 /* 2 hours of samples, one per minute */ + +extern unsigned short power_history[POWER_HISTORY_LEN]; + +void power_init(void); + +#endif +#endif + +#endif diff -urN --exclude=CVS --exclude=*~ orig/apps/debug_menu.c apps/debug_menu.c --- orig/apps/debug_menu.c Tue Jul 23 12:58:26 2002 +++ apps/debug_menu.c Tue Jul 23 17:16:52 2002 @@ -33,6 +33,8 @@ #include "rtc.h" #include "debug.h" #include "thread.h" +#include "powermgmt.h" +#include "system.h" /*---------------------------------------------------*/ /* SPECIAL DEBUG STUFF */ @@ -414,6 +416,65 @@ } } } + +/* + * view_battery() shows a automatically scaled graph of the battery voltage + * over time. Usable for estimating battery life / charging rate. + * The power_history array is updated in power_thread of powermgmt.c. + */ + +#define BAT_FIRST_VAL MAX(POWER_HISTORY_LEN - LCD_WIDTH - 1, 0) +#define BAT_YSPACE (LCD_HEIGHT - 20) + +void view_battery(void) +{ + int button; + int i, x, y; + int maxv, minv; + char buf[32]; + + while(1) + { + /* Find maximum and minimum voltage for scaling */ + maxv = minv = 0; + for (i = BAT_FIRST_VAL; i < POWER_HISTORY_LEN; i++) { + if (power_history[i] > maxv) + maxv = power_history[i]; + if ((minv == 0) || ((power_history[i]) && (power_history[i] < minv)) ) + minv = power_history[i]; + } + if (minv < 1) + minv = 1; + if (maxv < 2) + maxv = 2; + + lcd_clear_display(); + lcd_puts(0, 0, "Battery voltage:"); + snprintf(buf, 30, "scale %d.%02d-%d.%02d V", minv / 100, minv % 100, maxv / 100, maxv % 100); + lcd_puts(0, 1, buf); + + x = 0; + for (i = BAT_FIRST_VAL+1; i < POWER_HISTORY_LEN; i++) { + y = (power_history[i] - minv) * BAT_YSPACE / (maxv - minv); + lcd_clearline(x, LCD_HEIGHT-1, x, 20); + lcd_drawline(x, LCD_HEIGHT-1, x, MIN(MAX(LCD_HEIGHT-1 - y, 20), LCD_HEIGHT-1)); + x++; + } + + lcd_update(); + sleep(HZ/2); + + button = button_get(false); + + switch(button) + { + case BUTTON_LEFT: + case BUTTON_OFF: + return; + } + } +} + #endif void debug_menu(void) @@ -431,6 +492,7 @@ { "View MAS regs", dbg_mas }, #ifdef ARCHOS_RECORDER { "View MAS codec", dbg_mas_codec }, + { "View battery", view_battery }, #endif }; diff -urN --exclude=CVS --exclude=*~ orig/apps/main.c apps/main.c --- orig/apps/main.c Tue Jul 23 12:58:26 2002 +++ apps/main.c Tue Jul 23 14:13:55 2002 @@ -30,6 +30,7 @@ #include "menu.h" #include "system.h" #include "usb.h" +#include "powermgmt.h" #include "adc.h" #include "i2c.h" #ifndef SIMULATOR @@ -156,7 +155,6 @@ status_init(); usb_start_monitoring(); - power_init(); } int main(void)