]> www.fi.muni.cz Git - bike-lights.git/blobdiff - firmware/main.c
buttons.c: fix for setup timeout
[bike-lights.git] / firmware / main.c
index efebdabafb5d2aa30571b65e49ca1683b006a2c6..ea3bb69d1384dd5840c5e6a90066dda0807a229c 100644 (file)
@@ -2,12 +2,15 @@
 #include <util/delay.h>
 #include <avr/sleep.h>
 #include <avr/interrupt.h>
+#include <avr/power.h>
 #include <avr/wdt.h>
 
 #include "lights.h"
 
-void hw_setup()
+static void hw_setup()
 {
+       wdt_enable(WDTO_1S);
+       init_battery();
        init_pwm();
        init_adc();
        init_tmr();
@@ -21,17 +24,79 @@ void hw_setup()
        set_sleep_mode(SLEEP_MODE_IDLE);
 }
 
-int main(void)
+static void hw_suspend()
 {
-       log_init();
-       wdt_enable(WDTO_1S);
+       susp_pwm();
+       susp_adc();
+       susp_tmr();
+       susp_gpio();
+       wdt_disable();
+}
+
+
+void power_down()
+{
+       uint16_t wake_count = 0;
+       unsigned char btn;
+
+       hw_suspend();
+sleep_again:
+       // enable PCINT14, so that user can wake up later
+        GIMSK |= _BV(PCIE1);
+        PCMSK1 |= _BV(PCINT14);
+
+       // G'night
+        set_sleep_mode(SLEEP_MODE_PWR_DOWN);
+        sleep_enable();
+        sleep_bod_disable();
+        sei();
+        sleep_cpu();
+
+       // G'morning
+       cli();
+
+        sleep_disable();
+
+       // Disable PCINT14
+       GIMSK &= ~_BV(PCIE1);
+       PCMSK1 &= ~_BV(PCINT14);
 
-       _delay_ms(100);
+        // allow wakeup by long button-press only
+        for (btn = 0; btn < 5; btn++) {
+                if ((PINB & _BV(PB6)) != 0) {
+                        wake_count++;
+                        goto sleep_again;;
+                }
+                _delay_ms(100);
+        }
+
+       // ok, so I will wake up
+       log_byte(0xb1);
+       log_word(wake_count);
+       log_flush();
 
        hw_setup();
+}
+
+
+ISR(PCINT_vect)
+{
+       GIMSK &= ~_BV(PCIE1);
+       PCMSK1 &= ~_BV(PCINT14);
+}
+
+int main(void)
+{
+       log_init();
+
+       power_usi_disable(); // Once for lifetime
+       ACSRA |= _BV(ACD);   // disable analog comparator
 
        log_set_state(3);
 
+       hw_setup();
+       power_down();
+
        sei();
 #if 1
        while (1) {