ArduinoCore-avr/cores/arduino
Matthijs Kooijman fa8df58c93 Fix HardwareSerial::flush() when interrupts are kept disabled for a while
It turns out there is an additional corner case. The analysis in the
previous commit wrt to flush() assumes that the data register is always
kept filled by the interrupt handler, so the TXC bit won't get set until
all the queued bytes have been transmitted. But, when interrupts are
disabled for a longer period (for example when an interrupt handler for
another device is running for longer than 1-2 byte times), it could
happen that the UART stops transmitting while there are still more bytes
queued (but these are in the buffer, not in the UDR register, so the
UART can't know about them).

In this case, the TXC bit would get set, but the transmission is not
complete yet. We can easily detect this case by looking at the head and
tail pointers, but it seems easier to instead look at the UDRIE bit
(the TX interrupt is enabled if and only if there are bytes in the
queue). To fix this corner case, this commit:
 - Checks the UDRIE bit and only if it is unset, looks at the TXC bit.
 - Moves the clearing of TXC from write() to the tx interrupt handler.
   This (still) causes the TXC bit to be cleared whenever a byte is
   queued when the buffer is empty (in this case the tx interrupt will
   trigger directly after write() is called). It also causes the TXC bit
   to be cleared whenever transmission is resumed after it halted
   because interrupts have been disabled for too long.

As a side effect, another race condition is prevented. This could occur
at very high bitrates, where the transmission would be completed before
the code got time to clear the TXC0 register, making the clear happen
_after_ the transmission was already complete. With the new code, the
clearing of TXC happens directly after writing to the UDR register,
while interrupts are disabled, and we can be certain the data
transmission needs more time than one instruction to complete. This
fixes #1463 and replaces #1456.
2014-01-22 09:38:04 +01:00
..
avr-libc Increased malloc margin to 128. 2013-03-29 11:48:35 +01:00
Arduino.h Define a _NOP() macro 2014-01-16 16:29:41 +01:00
CDC.cpp Merge branch 'master' into ide-1.5.x 2013-09-30 16:25:10 +02:00
Client.h Making Print::write(char *) non-virtual. 2011-09-07 18:41:05 -04:00
HID.cpp fixed logic error in Keyboard.release() - now removes every occurrence of a key if it's present more than once 2012-03-28 19:46:32 -04:00
HardwareSerial.cpp Fix HardwareSerial::flush() when interrupts are kept disabled for a while 2014-01-22 09:38:04 +01:00
HardwareSerial.h Improve HardwareSerial::flush() 2014-01-22 09:37:54 +01:00
IPAddress.cpp Make some operators in IPAddress const 2014-01-15 16:20:48 +01:00
IPAddress.h Make some operators in IPAddress const 2014-01-15 16:20:48 +01:00
Platform.h support for non-Leonardo boards is back! 2011-08-30 11:50:08 -04:00
Print.cpp Merge branch 'cast' of github.com:Lauszus/Arduino into Lauszus-cast 2013-12-31 20:11:08 +01:00
Print.h Add Print::write(const char *, size_t) 2013-12-24 13:22:42 +01:00
Printable.h Merge branch 'new-extension' of https://github.com/arduino/Arduino 2011-08-27 23:53:42 +01:00
Server.h Making Print::write(char *) non-virtual. 2011-09-07 18:41:05 -04:00
Stream.cpp Adding readString() and readStringUntil() to Stream (Adrian McEwen). 2012-05-16 15:39:34 -04:00
Stream.h Add uint8_t* versions of methods in Stream 2013-12-24 13:22:42 +01:00
Tone.cpp fixed permissions on a lot of text files. see #1116 2012-12-10 10:42:49 +01:00
USBAPI.h Merge branch 'master' into ide-1.5.x 2013-09-30 16:25:10 +02:00
USBCore.cpp Remove hardcoded product names (all provided for in boards.txt) 2013-07-17 14:38:05 +02:00
USBCore.h Serial via USB works 2011-08-14 16:59:34 -04:00
USBDesc.h sketch USB VID and PID values are passed in from boards.txt at compile time now. changed sketch PIDs to final values. also uncommented Micro section in boards.txt 2012-04-09 08:06:35 -04:00
Udp.h Making Print::write(char *) non-virtual. 2011-09-07 18:41:05 -04:00
WCharacter.h Replacing custom String.toInt() function with a call to atol(). 2010-12-03 23:12:41 -05:00
WInterrupts.c Added support to INT6 on Leonardo. 2013-05-13 21:22:59 +02:00
WMath.cpp Improving third-party hardware support: 2009-11-21 23:23:43 +00:00
WString.cpp Improved portability of String class (maniacbug) 2014-01-01 17:22:40 +01:00
WString.h Fixed String class regression after f80c6c5f35cddcf4761a3c97feb8504425e9d27d 2013-09-03 18:40:30 +02:00
binary.h Improving third-party hardware support: 2009-11-21 23:23:43 +00:00
hooks.c Added general yield()-hook for cooperative scheduling development (part 2) 2012-11-02 18:12:21 +01:00
main.cpp renamed Leonardo USB_ class to USBDevice_ to be unambiguous. renamed "USB" object to "USBDevice" to prevent conflict with USB Host library (thanks Massimo) 2012-05-01 11:18:15 -04:00
new.cpp Add trivial new[] and delete[] operators (Justin R. Cutler) 2012-12-16 14:30:12 +01:00
new.h Add trivial new[] and delete[] operators (Justin R. Cutler) 2012-12-16 14:30:12 +01:00
wiring.c Merged 1.0.5 2013-04-03 13:51:04 +02:00
wiring_analog.c Merge branch 'issue1366' of github.com:Lauszus/Arduino into Lauszus-issue1366 2013-07-31 17:22:12 +02:00
wiring_digital.c Merge branch 'master' of github.com:arduino/Arduino into new-extension 2012-01-10 12:02:27 -05:00
wiring_private.h Merged 1.0.5 2013-05-29 18:30:36 +02:00
wiring_pulse.c fixed permissions on a lot of text files. see #1116 2012-12-10 10:42:49 +01:00
wiring_shift.c fixed permissions on a lot of text files. see #1116 2012-12-10 10:42:49 +01:00