.at least it looks like that.
Foreword: ATmega16A, 4 MHz, nothing special peripheral devices, just stupid
Nokia1100 display.
In my device, Watchdog disabling routine were used frequently enough (every
second). Sometimes device was reset. (Oh, that boring "sometimes".)
I found why.
wdt_disable routine (wdt.h) works like this:
1) Save SREG
2) cli
3) WD_CONTROL_REG = _BV(_WD_CHANGE_BIT) | _BV(WDE)
4) WD_CONTROL_REG = 0
5) Restore SREG
Looks like ok, yeah?
But look at (3). This line not only sets WD_CHANGE and WDE bits. In addition
it resets to zero WDT prescaler bits. This makes WD work at maximum speed.
If WDT_RESET was not performed recently enough, line (3) will reset device
immediately.
Even if I would write
wdt_reset();
wdt_disable();
I can stiil catch an interrupt right between reset and disable.
Sure, I can write ATOMIC_BLOCK, but all this becomes too bulky.
Workaround:
a) Add wdr between lines (2) and (3)
Or
b) Replace (3) to something that saves prescaler settings.