avr-libc-dev
[Top][All Lists]
Advanced

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

Re: [avr-libc-dev] wdt_enable may fail to enable the watchdog onATmega12


From: Danjel McGougan
Subject: Re: [avr-libc-dev] wdt_enable may fail to enable the watchdog onATmega1281
Date: Tue, 01 Sep 2009 09:11:54 +0200
User-agent: Thunderbird 2.0.0.23 (Windows/20090812)

Weddington, Eric wrote:
>> This macro seems to depend on the fact that at least one more
>> instruction will be executed after global interrupts are enabled
>> before an actual interrupt can happen. But this fact seems only to be
>> true for instructions using only one instruction word (16 bits).
>> Instructions such as sts that use two words (32 bits) are not
>> guaranteed to be executed before an interrupt may fire. I have learned
>> this the hard way after trying to optimize interrupt latency in my
>> application for ATmega1281. It does not seem to be documented by
>> Atmel.
> 
> Have you tested this on the ATmega1281? Have you tested this on any other 
> ATmega device?

Hi,

I tried to reproduce this using simpler code since posting and I can not 
trigger it again. It seems the construct that confused me was this little piece 
in my application:

This is the start of the USART0_RX_vect interrupt routine:

        push    r29                             ; save r29
        in      r29, _SFR_IO_ADDR(SREG)
        push    r29                             ; save SREG
        lds     r29, _SFR_MEM_ADDR(UCSR0B)
        andi    r29, ~_BV(RXCIE0)
        sts     _SFR_MEM_ADDR(UCSR0B), r29      ; clear RXCIE0 in UCSR0B
        sei

Here I disable the RXC-interrupt and then enable global interrupts to allow 
nested interrupts in my application. If I move sei one instruction up (to 
reduce interrupt latency) the code does not work anymore:

        push    r29                             ; save r29
        in      r29, _SFR_IO_ADDR(SREG)
        push    r29                             ; save SREG
        lds     r29, _SFR_MEM_ADDR(UCSR0B)
        andi    r29, ~_BV(RXCIE0)
        sei
        sts     _SFR_MEM_ADDR(UCSR0B), r29      ; clear RXCIE0 in UCSR0B
---> RXC interrupt fires here

It seems the CPU schedules an RXC interrupt when sei is executed and it doesn't 
matter that we then clear the RXCIE0 bit in the next instruction (which should 
always be executed). The RXC interrupt fires before the next instruction anyway.

So to conclude I don't think there is a problem in avr-libc. I was too quick to 
post.

BR,
Danjel McGougan





reply via email to

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