I'm writing a program for an ATtiny85. I want to use the watchdog to wake up from power down in certain intervals. It all works fine as long as the intervals for a watch dog event don't change within the program (i.e. I don't change bits WDP0-3 after they're set once).
As soon as I change the timeout of the watchdog, it does an unwanted reset. I don't have the WDTON fusebit enabled, so the whactdog is not always on but rather has to be enabled by software. (In fact the fuse bits are: Low=0xe2, High=0xdf and Extended= 0xff make the controller run at 8 Mhz from the internal oscillator).
Here is a snipplet of my code:
#include <avr/wdt.h>
#include <avr/power.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>
void Config_wdt(uint8_t timeout) {
cli();
wdt_reset(); // reset watchdog timer
MCUSR &= ~(1<<WDRF); // clear reset flag
WDTCR = (1<<WDE) | (1<<WDCE); // enable watchdog
WDTCR = (1<<WDIE) | timeout; // watchdog interrupt instead of reset
//+reset, timeout can be 15,30,60,120,250,500ms or 1,2,4,8s
sei();
}
EMPTY_INTERRUPT(WDT_vect)
void Sleep_now(uint8_t i, uint8_t timeout) {
Config_wdt(timeout);
for(i=i; i>0; --i) {
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // set type of sleepmode
power_all_disable(); // disable unneeded loads
wdt_reset(); // timer should start at zero
sleep_enable(); // approach sleep mode
sleep_mode(); // enter sleep mode (confirm)
sleep_disable(); // entrance point when woken up
// Another Config_wdt(timeout); here or re-enabling WDIE doesn't help either
power_all_enable(); // re-enable the loads
}
}
int main() {
Config_wdt(WDTO_500MS);
Do_some_stuff();
Sleep_now(5, WDTO_500MS); // WORKS AS EXPECTED, SLEEPS 5 TIMES 500ms = 2.5s
while(1) {
Make_other_things();
Sleep_now(3, WDTO_30MS); // DOES AN UNWANTED RESET, ...
\\+I.E. STARTS FROM THE BEGINNING BEFORE "Do_some_sfuff()"...
\\+IF I REPLACE "WDTO_30MS" HERE by "WDTO_500MS" FROM ABOVE...
\\+THE CODE WORKS FINE.
}
}
The datasheet has this to say:
If WDE is set, WDIE is automatically cleared by hardware when a time-out occurs. This is useful for keeping the Watchdog Reset security while using the interrupt. After the WDIE bit is cleared, the next time-out will generate a reset. To avoid the Watchdog Reset, WDIE must be set after each interrupt.
But even if I set the WDIE bit immediately after waking up from sleep mode, it still does the unwanted reset.
So how do I change the watchdog timeout in my code, without the unwanted reset?