From 232df37f5ce2531f2b65f92fa1338e04b511beab Mon Sep 17 00:00:00 2001 From: r4 Date: Mon, 18 Apr 2022 19:31:51 +0200 Subject: [PATCH] fix watchdog + library independence --- spybug/spybug.ino | 51 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/spybug/spybug.ino b/spybug/spybug.ino index 5b899b5..248b78b 100644 --- a/spybug/spybug.ino +++ b/spybug/spybug.ino @@ -29,12 +29,12 @@ */ #include -#include /* https://github.com/rocketscream/Low-Power */ #include #include #include #include #include +#include /************************ BEGIN USER CONFIGURATION @@ -61,6 +61,8 @@ END USER CONFIGURATION **********************/ +void (*full_reset)() = nullptr; + static int serial_putch(char c, FILE *f) { (void)f; return Serial.write(c) == 1 ? 0 : 1; @@ -117,20 +119,40 @@ static bool fstreq(const char *a, const __FlashStringHelper *b_fsh) { #define info(fmt, ...) { if (settings.serial_log) printf(fmt, ##__VA_ARGS__); } #define info_special(x) { if (settings.serial_log) Serial.print(x); } -static void low_power_sleep_minutes(unsigned long t) { - for (unsigned long i = 0; 8ul * i < 60ul * t; i++) { - /* Power down for 8s. */ - LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); - } +volatile bool wdt_int_sleep_mode = false; +ISR (WDT_vect) { + if (wdt_int_sleep_mode) + wdt_disable(); + else + full_reset(); } -static void start_watchdog_with_full_reset() { - MCUSR &= ~B00001000; /* Clear reset flag. */ - WDTCSR |= B00011000; /* Prepare prescaler change. */ - WDTCSR = B00100001; /* Set watchdog timeout to 8s. */ - // Enable Watchdog Timer - WDTCSR |= B01000000; - MCUSR = MCUSR & B11110111; +/* Based on https://github.com/rocketscream/Low-Power. */ +static void low_power_sleep_minutes(unsigned long t) { + wdt_int_sleep_mode = true; + ADCSRA &= ~(1 << ADEN); /* Disable ADC. */ + for (unsigned long i = 0; 8ul * i < 60ul * t; i++) { + // Power Down for 8s + wdt_enable(WDTO_8S); /* Start watchdog timer for 8s. */ + WDTCSR |= (1 << WDIE); /* Enable watchdog interrupt. */ + do { + set_sleep_mode(SLEEP_MODE_PWR_SAVE); + cli(); + sleep_enable(); + sleep_bod_disable(); + sei(); + sleep_cpu(); + sleep_disable(); + sei(); + } while (0); + } + ADCSRA |= (1 << ADEN); /* Re-enable ADC. */ + wdt_int_sleep_mode = false; +} + +static void wdt_enable_with_full_reset() { + wdt_enable(WDTO_8S); /* Start watchdog timer for 8s. */ + WDTCSR |= (1 << WDIE); /* Enable watchdog interrupt. */ } static inline void disable_recording_interrupts() { @@ -397,7 +419,7 @@ void setup() { delay(500); /* Wait for components to initialize. */ #endif // Start Watchdog (wdt_enable() doesn't fully reset) - start_watchdog_with_full_reset(); + wdt_enable_with_full_reset(); // SD Card Setup if (!SD.begin(PIN_SS)) die(F("Error initializing SD card!\n")); @@ -440,6 +462,7 @@ void setup() { | _BV(OCIE1B); /* Enable "Output Compare B Match Interrupt". */ } + void loop() { delay(2000); wdt_reset(); /* Reset watchdog timer. */