]> git.donarmstrong.com Git - tmk_firmware.git/blobdiff - keyboard/hhkb_rn42/rn42/rn42_task.c
Monitor battery and alert low voltage
[tmk_firmware.git] / keyboard / hhkb_rn42 / rn42 / rn42_task.c
index 2bc1c7fd0452b0fe9b5b20e5335258b93dbfebc2..30914452e530296afcac18e7c45c3da5b2eb7b25 100644 (file)
@@ -9,44 +9,25 @@
 #include "print.h"
 #include "timer.h"
 #include "command.h"
+#include "battery.h"
 
 static bool config_mode = false;
 static bool force_usb = false;
 
-static void battery_adc_init(void)
+static void status_led(bool on)
 {
-    ADMUX = (1<<REFS1) | (1<<REFS0);                // Ref:2.56V band-gap, Input:ADC0(PF0)
-    ADCSRA = (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);  // Prescale:128 16MHz/128=125KHz
-    ADCSRA |= (1<<ADEN);                            // enable ADC
-}
-
-static uint16_t battery_adc(void)
-{
-    volatile uint16_t bat;
-    ADCSRA |= (1<<ADEN);
-
-    // discard first result
-    ADCSRA |= (1<<ADSC);
-    while (ADCSRA & (1<<ADSC)) ;
-    bat = ADC;
-
-    // discard second result
-    ADCSRA |= (1<<ADSC);
-    while (ADCSRA & (1<<ADSC)) ;
-    bat = ADC;
-
-    ADCSRA |= (1<<ADSC);
-    while (ADCSRA & (1<<ADSC)) ;
-    bat = ADC;
-
-    ADCSRA &= ~(1<<ADEN);
-    return bat;
+    if (on) {
+        DDRE  |=  (1<<6);
+        PORTE &= ~(1<<6);
+    } else {
+        DDRE  |=  (1<<6);
+        PORTE |=  (1<<6);
+    }
 }
 
-
 void rn42_task_init(void)
 {
-    battery_adc_init();
+    battery_init();
 }
 
 void rn42_task(void)
@@ -99,6 +80,57 @@ void rn42_task(void)
             host_set_driver(&lufa_driver);
         }
     }
+
+
+    static uint16_t prev_timer = 0;
+    static uint8_t sec = 0;
+    // NOTE: not exact 1 sec
+    if (timer_elapsed(prev_timer) > 1000) {
+        /* every second */
+        prev_timer = timer_read();
+
+        /* Low voltage alert */
+        uint8_t bs = battery_status();
+        if (bs == LOW_VOLTAGE) {
+            battery_led(LED_ON);
+        } else {
+            battery_led(LED_CHARGER);
+        }
+
+        static uint8_t prev_status = UNKNOWN;
+        if (bs != prev_status) {
+            prev_status = bs;
+            switch (bs) {
+                case FULL_CHARGED:  xprintf("FULL_CHARGED\n"); break;
+                case CHARGING:      xprintf("CHARGING\n"); break;
+                case DISCHARGING:   xprintf("DISCHARGING\n"); break;
+                case LOW_VOLTAGE:   xprintf("LOW_VOLTAGE\n"); break;
+                default:            xprintf("UNKNOWN STATUS\n"); break;
+            };
+        }
+
+        /* every minute */
+        if (sec == 0) {
+            uint32_t t = timer_read32()/1000;
+            uint16_t v = battery_voltage();
+            uint8_t h = t/3600;
+            uint8_t m = t%3600/60;
+            uint8_t s = t%60;
+            xprintf("%02u:%02u:%02u\t%umV\n", h, m, s, v);
+            /* TODO: xprintf doesn't work for this.
+            xprintf("%02u:%02u:%02u\t%umV\n", (t/3600), (t%3600/60), (t%60), v);
+            */
+        }
+        sec++; sec = sec%60;
+    }
+
+
+    /* Connection monitor */
+    if (rn42_linked()) {
+        status_led(true);
+    } else {
+        status_led(false);
+    }
 }
 
 
@@ -108,6 +140,8 @@ void rn42_task(void)
  ******************************************************************************/
 bool command_extra(uint8_t code)
 {
+    uint32_t t;
+    uint16_t b;
     static host_driver_t *prev_driver = &rn42_driver;
     switch (code) {
         case KC_H:
@@ -162,12 +196,21 @@ bool command_extra(uint8_t code)
             xprintf("protocol: %s\n", (host_get_driver() == &rn42_driver) ? "RN-42" : "LUFA");
             xprintf("force_usb: %X\n", force_usb);
             xprintf("rn42_autoconnecting(): %X\n", rn42_autoconnecting());
+            xprintf("rn42_linked(): %X\n", rn42_linked());
             xprintf("rn42_rts(): %X\n", rn42_rts());
             xprintf("config_mode: %X\n", config_mode);
+            xprintf("VBUS: %X\n", USBSTA&(1<<VBUS));
+            xprintf("battery_charging: %X\n", battery_charging());
+            xprintf("battery_status: %X\n", battery_status());
             return true;
         case KC_B:
             // battery monitor
-            xprintf("BAT: %04X(%08lX)\n",  battery_adc(), timer_read32());
+            t = timer_read32()/1000;
+            b = battery_voltage();
+            xprintf("BAT: %umV\t", b);
+            xprintf("%02u:",   t/3600);
+            xprintf("%02u:",   t%3600/60);
+            xprintf("%02u\n",  t%60);
             return true;
         default:
             if (config_mode)