MCUdude / MegaCoreX

An Arduino hardware package for ATmega4809, ATmega4808, ATmega3209, ATmega3208, ATmega1609, ATmega1608, ATmega809 and ATmega808
GNU Lesser General Public License v2.1
245 stars 49 forks source link

Ugly bug in serial transmit interrupt #26

Closed egilkv closed 5 years ago

egilkv commented 5 years ago

This bug is inherited from the Arduino megaavr package, it is not in the original avr. The offending line is this:

while(!((*_hwserial_module).STATUS & USART_DREIF_bm));

It causes the CPU to stay put in the interrupt handler until the character is actually transmitted. Not only does this waste a lot of CPU cycles needlessly, since further serial interrupts are disabled at this time, it can miss a lot of interrupts on other peripherals. It is more of a problem the lower the baudrate on the transmitting channel.

It is easily reproduced by transmitting continuously on a slow baudrate on one serial channels, while receiving at a higher baudrate on another channels. Also, when transmitting on slow baudrates, the available CPU capacity will also be significantly reduced.

I am surprised that such a bug slipped though 'the net'. There are also some other 'interesting' things with the new driver, so I plan to review and revise as needed. There is also an issue with critical regions in the old driver that is not resolved in the new.

But this one thing is urgent, and can and should be fixed first. I have created a branch called 'Upstream' for this: https://github.com/MCUdude/MegaCoreX/pull/25

MCUdude commented 5 years ago

25 merged!