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)
