aboutsummaryrefslogtreecommitdiff
path: root/cores
diff options
context:
space:
mode:
authorJohn Holman <john.g.holman@gmail.com>2017-10-25 10:38:23 +0100
committerMartino Facchin <m.facchin@arduino.cc>2017-11-13 17:46:47 +0100
commit99c294c5a251cffe84a51d474ec5275bd1a8311c (patch)
tree2cd43b73e0f978be56d5ce239f123b37627fef64 /cores
parente9e43cf58302a16b606ed6fd0b5b2c73efc2ada2 (diff)
Improve how TXCn bit is cleared in USCRnA register
Preserve values of configuration bits MPCMn and U2Xn. Avoid setting other read-only bits for datasheet conformance. See #3745
Diffstat (limited to 'cores')
-rw-r--r--cores/arduino/HardwareSerial.cpp8
1 files changed, 5 insertions, 3 deletions
diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp
index 560ef3a..e6ccdef 100644
--- a/cores/arduino/HardwareSerial.cpp
+++ b/cores/arduino/HardwareSerial.cpp
@@ -97,8 +97,10 @@ void HardwareSerial::_tx_udr_empty_irq(void)
// clear the TXC bit -- "can be cleared by writing a one to its bit
// location". This makes sure flush() won't return until the bytes
- // actually got written
- sbi(*_ucsra, TXC0);
+ // actually got written. Other r/w bits are preserved, and zeroes
+ // written to the rest.
+
+ *_ucsra = ((*_ucsra) & ((1 << U2X0) | (1 << MPCM0))) | (1 << TXC0);
if (_tx_buffer_head == _tx_buffer_tail) {
// Buffer empty, so disable interrupts
@@ -225,7 +227,7 @@ size_t HardwareSerial::write(uint8_t c)
// 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);
+ *_ucsra = ((*_ucsra) & ((1 << U2X0) | (1 << MPCM0))) | (1 << TXC0);
return 1;
}
tx_buffer_index_t i = (_tx_buffer_head + 1) % SERIAL_TX_BUFFER_SIZE;