avr-chat
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-chat] wdt_disable bug found


From: KL
Subject: [avr-chat] wdt_disable bug found
Date: Mon, 20 Dec 2010 11:13:08 +0300

.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.


Best regards,
{Kreyl}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]