]> www.fi.muni.cz Git - bike-lights.git/commitdiff
Disable WDT as early as possible
authorJan "Yenya" Kasprzak <kas@fi.muni.cz>
Fri, 7 Jun 2013 15:42:10 +0000 (17:42 +0200)
committerJan "Yenya" Kasprzak <kas@fi.muni.cz>
Fri, 7 Jun 2013 15:46:22 +0000 (17:46 +0200)
Apparently, after WDT reset, WDT is still running, and has to be
disabled. Otherwise it will kick in again during the initialization.

We want to indicate the WDT reset contition somehow. We use the GPIO
LED 0 - we set it to on if the reset source was WDT.

Also, we want to read and reset MCUSR as early as possible. We do it
from main(), and we then send the saved value where needed (init_log()
and power_down()).

firmware/buttons.c
firmware/lights.h
firmware/logging.c
firmware/main.c

index 20d28a58915658b84dcfa723d66511743a9cfd46..f611c2725babe845a763911153215bb1baa91aa6 100644 (file)
@@ -111,7 +111,7 @@ static inline void short_press(unsigned char button)
 static inline void long_press(unsigned char button)
 {
        if (button == 0) {
-               power_down();
+               power_down(0);
                return;
        }
 
index 5d1b6e5ae61b43f6b03238e6c071347a0e087ade..7e7e2a4d850b18d46e469c8e75668b42f1ca1f32 100644 (file)
 
 /* logging.c */
 #ifdef USE_LOGGING
-void init_log();
+void init_log(unsigned char mcusr);
 void log_set_state(unsigned char val);
 void log_flush();
 void log_byte(unsigned char byte);
 void log_word(uint16_t word);
 #else
-void inline init_log() { }
+void inline init_log(unsigned char mcusr) { }
 void inline log_set_state(unsigned char val) { }
 void inline log_flush() { }
 void inline log_byte(unsigned char byte) { }
@@ -126,7 +126,7 @@ pattern_t *illumination_led_pattern_select();
 pattern_t *laser_pattern_select();
 
 /* main.c */
-void power_down();
+void power_down(unsigned char err);
 
 #endif /* !LIGHTS_H__ */
 
index 2b8d242e7156215af1284c1708e609e37d19ff98..31329f889ba6f860ad44e954480f959cf73c7a23 100644 (file)
@@ -21,7 +21,7 @@ void log_set_state(unsigned char val)
                eeprom_write_byte(&log_state, val);
 }
 
-void init_log()
+void init_log(unsigned char mcusr)
 {
        unsigned char r_count;
 
@@ -31,8 +31,7 @@ void init_log()
        if (r_count < 5) {
                r_count++;
                eeprom_write_byte(&reboot_count,
-                       (r_count << 4) | (MCUSR & 0xF));
-               MCUSR = 0;
+                       (r_count << 4) | (mcusr & 0xF));
                can_write_eeprom = 1;
        } else {
                //eeprom_write_byte(&log_state, 0xFF);
index a83884b86f9408101f9bbf3a2bc91fa010b7b1be..0fbdb1e9f804421fca1a07fe69f33d72bd0890a2 100644 (file)
@@ -3,6 +3,7 @@
 #include <avr/sleep.h>
 #include <avr/interrupt.h>
 #include <avr/power.h>
+#include <avr/wdt.h>
 
 #include "lights.h"
 
@@ -33,11 +34,14 @@ static void hw_suspend()
        susp_buttons();
 }
 
-void power_down()
+void power_down(unsigned char err)
 {
        hw_suspend();
 
        do {
+               if (err)
+                       gpio_set(0, 1);
+
                // G'night
                set_sleep_mode(SLEEP_MODE_PWR_DOWN);
                sleep_enable();
@@ -58,7 +62,18 @@ void power_down()
 
 int main(void)
 {
-       init_log();
+       unsigned char mcusr_save;
+
+       // disable the WDT if running
+       wdt_reset();
+       mcusr_save = MCUSR;
+       MCUSR = 0;
+       wdt_disable();
+
+       if (mcusr_save & _BV(WDRF)) // was watchdog reset?
+               gpio_set(0, 1);
+
+       init_log(mcusr_save);
 
        power_usi_disable(); // Once for lifetime
        ACSRA |= _BV(ACD);   // disable analog comparator
@@ -66,7 +81,7 @@ int main(void)
        log_set_state(3);
 
        hw_setup();
-       power_down();
+       power_down(mcusr_save & _BV(WDRF));
 
        sei();
 #if 1