diff --git a/hardware/arduino/avr/cores/arduino/HardwareSerial.cpp b/hardware/arduino/avr/cores/arduino/HardwareSerial.cpp index 5cd89e5e664..6f0c0beb535 100644 --- a/hardware/arduino/avr/cores/arduino/HardwareSerial.cpp +++ b/hardware/arduino/avr/cores/arduino/HardwareSerial.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include "Arduino.h" #include "HardwareSerial.h" @@ -178,13 +179,12 @@ int HardwareSerial::read(void) int HardwareSerial::availableForWrite(void) { #if (SERIAL_TX_BUFFER_SIZE>256) - uint8_t oldSREG = SREG; - cli(); + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { #endif tx_buffer_index_t head = _tx_buffer_head; tx_buffer_index_t tail = _tx_buffer_tail; #if (SERIAL_TX_BUFFER_SIZE>256) - SREG = oldSREG; + } #endif if (head >= tail) return SERIAL_TX_BUFFER_SIZE - 1 - head + tail; return tail - head - 1; @@ -217,9 +217,18 @@ size_t HardwareSerial::write(uint8_t c) // 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); +#if (SERIAL_TX_BUFFER_SIZE>256) + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { +#endif + bool emptyBuffer = _tx_buffer_head == _tx_buffer_tail; +#if (SERIAL_TX_BUFFER_SIZE>256) + } +#endif + if (emptyBuffer && bit_is_set(*_ucsra, UDRE0)) { + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { + *_udr = c; + sbi(*_ucsra, TXC0); + } return 1; } tx_buffer_index_t i = (_tx_buffer_head + 1) % SERIAL_TX_BUFFER_SIZE; @@ -240,9 +249,11 @@ size_t HardwareSerial::write(uint8_t c) } _tx_buffer[_tx_buffer_head] = c; - _tx_buffer_head = i; + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { + _tx_buffer_head = i; - sbi(*_ucsrb, UDRIE0); + sbi(*_ucsrb, UDRIE0); + } return 1; }