diff --git a/libraries/SoftwareSerial/SoftwareSerial.cpp b/libraries/SoftwareSerial/SoftwareSerial.cpp index bee1107..d1d2008 100644 --- a/libraries/SoftwareSerial/SoftwareSerial.cpp +++ b/libraries/SoftwareSerial/SoftwareSerial.cpp @@ -237,6 +237,11 @@ void SoftwareSerial::recv() // so interrupt is probably not for us if (_inverse_logic ? rx_pin_read() : !rx_pin_read()) { + // Disable further interrupts during reception, this prevents + // triggering another interrupt directly after we return, which can + // cause problems at higher baudrates. + setRxIntMsk(false); + // Wait approximately 1/2 of a bit width to "center" the sample tunedDelay(_rx_delay_centering); DebugPulse(_DEBUG_PIN2, 1); @@ -255,6 +260,8 @@ void SoftwareSerial::recv() tunedDelay(_rx_delay_stopbit); DebugPulse(_DEBUG_PIN2, 1); + // Re-enable interrupts when we're sure to be inside the stop bit + setRxIntMsk(true); if (_inverse_logic) d = ~d; diff --git a/libraries/SoftwareSerial/SoftwareSerial.h b/libraries/SoftwareSerial/SoftwareSerial.h index 302a23b..2b12598 100644 --- a/libraries/SoftwareSerial/SoftwareSerial.h +++ b/libraries/SoftwareSerial/SoftwareSerial.h @@ -76,7 +76,7 @@ private: void tx_pin_write(uint8_t pin_state) __attribute__((__always_inline__)); void setTX(uint8_t transmitPin); void setRX(uint8_t receivePin); - void setRxIntMsk(bool enable); + void setRxIntMsk(bool enable) __attribute__((__always_inline__)); // private static method for timing static inline void tunedDelay(uint16_t delay);