From a366ae18debc6e73c4946aa6290ed37c49bb1fc0 Mon Sep 17 00:00:00 2001 From: "Jan \"Yenya\" Kasprzak" Date: Fri, 7 Jun 2013 17:42:10 +0200 Subject: [PATCH] Disable WDT as early as possible 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 | 2 +- firmware/lights.h | 6 +++--- firmware/logging.c | 5 ++--- firmware/main.c | 21 ++++++++++++++++++--- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/firmware/buttons.c b/firmware/buttons.c index 20d28a5..f611c27 100644 --- a/firmware/buttons.c +++ b/firmware/buttons.c @@ -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; } diff --git a/firmware/lights.h b/firmware/lights.h index 5d1b6e5..7e7e2a4 100644 --- a/firmware/lights.h +++ b/firmware/lights.h @@ -11,13 +11,13 @@ /* 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__ */ diff --git a/firmware/logging.c b/firmware/logging.c index 2b8d242..31329f8 100644 --- a/firmware/logging.c +++ b/firmware/logging.c @@ -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); diff --git a/firmware/main.c b/firmware/main.c index a83884b..0fbdb1e 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -3,6 +3,7 @@ #include #include #include +#include #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 -- 2.43.5