arduino/Arduino — pull request #1456 by allesblinkt (2013-06-07 13:34:30+00:00)
Title: Fix for Serial::flush() deadlock with high baud rates

I am currently developing a couple of Arduino Pro Mini (Atmega 328 @16MHz) based motor controllers that get their commands via RS-485. For that reason I have to switch the bus transceiver to transmit whenever one of my nodes sends something back.

Everything works nicely, however `HardwareSerial::flush()` occasionally locks up when I am using high baudrates (1.000.000 Bit/s).

I am not evening using interrupts or interrupt timers, but have found the problem to be in `HardwareSerial::send()`. When sending bytes, the interrupt for `UDRE` is enabled before the `TXC0` is cleared (set to one). If the interrupt fires fast enough, consumes and shifts out the byte, the `TXC0` bit is cleared after it is set when the last byte has been shifted out. Calling `Serial.flush()` in a case like this causes the Arduino to lock up, because it is stuck in its `while` loop indefinitely.

Here is a small sketch that will crash an Atmega 328 @16MHz after a couple of seconds:

```

#define DIR_PIN 10
#define LED_PIN 13

#define MAX_DATA_LENGTH 6

byte data[] = {
0xFF, 0xFF, 0xAB, 0xCD, 0xDE, 0x66};

void setup() {
Serial.begin(1000000);

pinMode(DIR_PIN, OUTPUT);
pinMode(LED_PIN, OUTPUT);
digitalWrite(DIR_PIN, LOW); // receive
}

void loop() {
digitalWrite(LED_PIN, HIGH);

digitalWrite(DIR_PIN, HIGH); // send
Serial.write(data, MAX_DATA_LENGTH);
Serial.flush();
digitalWrite(DIR_PIN, LOW); // receive

delay(100);
digitalWrite(LED_PIN, LOW);
delay(100);
}
```

Clearing the `TXC0` bit before enabling the interrupt in `HardwareSerial::send` makes the problem go away (see commit).