avr-chat
[Top][All Lists]
Advanced

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

Re: [avr-chat] wdt_disable bug found


From: Michael Hennebry
Subject: Re: [avr-chat] wdt_disable bug found
Date: Mon, 20 Dec 2010 11:29:42 -0600 (CST)
User-agent: Alpine 1.00 (DEB 882 2007-12-20)

On Mon, 20 Dec 2010, KL wrote:

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

Preservation isn't necessary.
Setting the prescale bits to the slowest available would also do the trick.
It has the advantage of allowing a constant.

--
Michael   address@hidden
"Pessimist: The glass is half empty.
Optimist:   The glass is half full.
Engineer:   The glass is twice as big as it needs to be."



reply via email to

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