From 9ad14b2f0cb155993097e7ae25de9265e9964f23 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Wed, 18 Dec 2013 23:21:45 +0100 Subject: [PATCH] In HardwareSerial::write, bypass the queue when it's empty This helps improve the effective datarate on high (>500kbit/s) bitrates, by skipping the interrupt and associated overhead. At 1 Mbit/s the implementation previously got up to about 600-700 kbit/s, but now it actually gets up to the 1Mbit/s (values are rough estimates, though). --- hardware/arduino/avr/cores/arduino/HardwareSerial.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/hardware/arduino/avr/cores/arduino/HardwareSerial.cpp b/hardware/arduino/avr/cores/arduino/HardwareSerial.cpp index 5d622733e..9f0a2ec66 100644 --- a/hardware/arduino/avr/cores/arduino/HardwareSerial.cpp +++ b/hardware/arduino/avr/cores/arduino/HardwareSerial.cpp @@ -197,6 +197,15 @@ void HardwareSerial::flush() size_t HardwareSerial::write(uint8_t c) { + // If the buffer and the data register is empty, just write the byte + // to the data register and be done. This shortcut helps + // significantly improve the effective datarate at high (> + // 500kbit/s) bitrates, where interrupt overhead becomes a slowdown. + if (_tx_buffer_head == _tx_buffer_tail && bit_is_set(*_ucsra, UDRE0)) { + *_udr = c; + sbi(*_ucsra, TXC0); + return 1; + } int i = (_tx_buffer_head + 1) % SERIAL_BUFFER_SIZE; // If the output buffer is full, there's nothing for it other than to