Bug in UART, UDRE interrupt

627 views
Skip to first unread message

Mirt

unread,
Jan 6, 2011, 5:21:28 PM1/6/11
to simavr
Greetings

I have been using simavr to simulate my hobby AVR projects lately.
simavr truly is a great library!

I possibly found a bug, i.e. the simulation of an Atmega 168 doesn't
act like its real-world counterpart.
When I enable the UDRE interrupt (USART data register empty) on a real
Atmega 168 before putting something in the USART data register (UDR),
the corresponding interrupt occurs immediately and the ISR is
executed. This is as expected because initially the UDR is empty.

In simavr though, the interrupt doesn't occur until I put something in
UDR. Maybe a flag isn't initialized properly?

Example code:


#define BAUD 19200 // bit/s
#include <util/setbaud.h>

#include "avr_mcu_section.h"
AVR_MCU(F_CPU, "atmega168");

int main(void)
{
// Set USART baud rate
UBRR0H = UBRRH_VALUE; // From header <util/setbaud.h>, see config.h
UBRR0L = UBRRL_VALUE;
// Set USART frame format to asynchronous 8N1
UCSR0C = (0<<UMSEL01)|(0<<UMSEL00) // asynchronous
|(0<<UCSZ02)|(1<<UCSZ01)|(1<<UCSZ00) // 8 databits
|(0<<UPM01)|(0<<UPM00) // no parity
|(0<<USBS0); // 1 stop bit
// Enable receiver, transmitter and receive interrupts
UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0);
// Set double USART transmission speed
UCSR0A |= (USE_2X << U2X0);

// enable interrupts
sei();

for(;;)
{
UCSR0B |= (1<<UDRIE0); // enable USART data register empty
interrupt
/*
UDRE ISR should be called immediately after enabling interrupt

it works after something has been put in the USART data register,
e.g.
UDR0 = 0x50;
*/
}

return 0;
}

// USART data register empty interrupt service routine
ISR(USART_UDRE_vect)
{
/*
This ISR is called immediately on a real Atmega 168 but not in
simavr
(only after something had been put in UDR0 before)
*/
}

Best wishes
Mirt

M P

unread,
Jan 7, 2011, 6:05:36 AM1/7/11
to sim...@googlegroups.com
It's bizarre, as I remember clearly being careful as to have /that/
behaviour. Must have read the datasheet the wrong way around or
something ? :-)

Michael

Mirt

unread,
Jan 7, 2011, 6:51:45 PM1/7/11
to simavr
Hi Michael

thank you for your reply.

No big deal! I discovered it when I tried to simulate a program that
uses interrupt-driven and buffered USART communication. I quadruple
checked and conclude that the real Atmega 168 definately fires the
interrupt right away.

Also the datasheet confirms this behavior [1, p. 182]:

"The Data Register Empty (UDREn) Flag indicates whether the transmit
buffer is ready to receive
new data. This bit is set when the transmit buffer is empty, and
cleared when the transmit buffer
contains data to be transmitted that has not yet been moved into the
Shift Register. For compatibility
with future devices, always write this bit to zero when writing the
UCSRnA Register.

When the Data Register Empty Interrupt Enable (UDRIEn) bit in UCSRnB
is written to one, the
USART Data Register Empty Interrupt will be executed as long as UDREn
is set (provided that
global interrupts are enabled). UDREn is cleared by writing UDRn. When
interrupt-driven data
transmission is used, the Data Register Empty interrupt routine must
either write new data to
UDRn in order to clear UDREn or disable the Data Register Empty
interrupt, otherwise a new
interrupt will occur once the interrupt routine terminates."

Maybe someone else can confirm this, too?

Best wishes
Mirt

[1] Atmel: ATmega48/88/168 datasheet, http://www.atmel.com/dyn/resources/prod_documents/doc2545.pdf

M P

unread,
Jan 14, 2011, 5:22:45 AM1/14/11
to sim...@googlegroups.com
Mirt,

I pushed a patch in the git tree with a "proper" fix, ie one that also
takes care of the behaviour when the UDR is not empty at the time you
set UDRE, this should solve your problem...

Michael

Mirt

unread,
Jan 14, 2011, 8:55:42 AM1/14/11
to simavr
Hi Michael

thank you for fixing it so quickly, it's working beautifully now. All
is well :)

Mirt

JAGANNATH SAHOO

unread,
Jan 11, 2017, 10:24:47 PM1/11/17
to simavr, sonntag...@googlemail.com
Can you give me your github link?

hovercraft-google

unread,
Jan 12, 2017, 3:40:00 AM1/12/17
to simavr, sonntag...@googlemail.com
Message has been deleted

tjwan

unread,
Jan 12, 2017, 6:55:44 PM1/12/17
to simavr
Hi,

when looking a https://github.com/buserror/simavr the latest commit is of Dec 13 2016. I must miss something. Where can I find your patch ?

Thanks Tjwan

hovercraft-google

unread,
Jan 12, 2017, 8:50:09 PM1/12/17
to simavr
Tjwan,

This particular topic is quite old and corresponding issue is fixed in the simavr master branch (notice buserror post as of 1/14/11 above).
Is it still (or again) actual?
Meanwhile, there is another UART issue. It is related with the reception FIFO pump.
As far as I know, there are two alternative attempts to fix it, no one yet merged into the simavr master.
Please see code here
and there .
Also look discussion here
and there

Al

hovercraft-google

unread,
Jan 12, 2017, 9:24:14 PM1/12/17
to simavr

tjwan

unread,
Jan 13, 2017, 10:56:44 AM1/13/17
to simavr
AI,
thanks for the hint. I just read the latest message of this thread and did not check the old dates.
Actually I have a problem with UART comm and will try the solutions you mentioned.
Reply all
Reply to author
Forward
0 new messages