diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp index e99d503d8..56eb744fa 100644 --- a/cores/arduino/HardwareSerial.cpp +++ b/cores/arduino/HardwareSerial.cpp @@ -20,6 +20,8 @@ Modified 28 September 2010 by Mark Sproul Modified 14 August 2012 by Alarus Modified 3 December 2013 by Matthijs Kooijman + Modified 2 November 2015 by SlashDev + Modified 7 November 2019 by Georg Icking-Konert */ #include @@ -278,4 +280,12 @@ size_t HardwareSerial::write(uint8_t c) return 1; } +void HardwareSerial::attachInterrupt( isr_t fn ) +{ + uint8_t oldSREG = SREG; + cli(); + _isr = fn; + SREG = oldSREG; +} + #endif // whole file diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h index 17000c2cc..f8a3bc65b 100644 --- a/cores/arduino/HardwareSerial.h +++ b/cores/arduino/HardwareSerial.h @@ -19,6 +19,8 @@ Modified 28 September 2010 by Mark Sproul Modified 14 August 2012 by Alarus Modified 3 December 2013 by Matthijs Kooijman + Modified 2 November 2015 by SlashDev + Modified 7 November 2019 by Georg Icking-Konert */ #ifndef HardwareSerial_h @@ -137,6 +139,15 @@ class HardwareSerial : public Stream // Interrupt handlers - Not intended to be called externally inline void _rx_complete_irq(void); void _tx_udr_empty_irq(void); + + typedef void (* isr_t)( uint8_t d, uint8_t s ); + void attachInterrupt( isr_t fn ); + void detachInterrupt() { attachInterrupt( (isr_t) NULL ); }; + private: + isr_t _isr; + + HardwareSerial( const HardwareSerial & ); + HardwareSerial & operator =( const HardwareSerial &); }; #if defined(UBRRH) || defined(UBRR0H) diff --git a/cores/arduino/HardwareSerial0.cpp b/cores/arduino/HardwareSerial0.cpp index 1146eebab..ece78a636 100644 --- a/cores/arduino/HardwareSerial0.cpp +++ b/cores/arduino/HardwareSerial0.cpp @@ -20,6 +20,8 @@ Modified 28 September 2010 by Mark Sproul Modified 14 August 2012 by Alarus Modified 3 December 2013 by Matthijs Kooijman + Modified 2 November 2015 by SlashDev + Modified 7 November 2019 by Georg Icking-Konert */ #include "Arduino.h" diff --git a/cores/arduino/HardwareSerial1.cpp b/cores/arduino/HardwareSerial1.cpp index 19625e235..c436e1690 100644 --- a/cores/arduino/HardwareSerial1.cpp +++ b/cores/arduino/HardwareSerial1.cpp @@ -20,6 +20,8 @@ Modified 28 September 2010 by Mark Sproul Modified 14 August 2012 by Alarus Modified 3 December 2013 by Matthijs Kooijman + Modified 2 November 2015 by SlashDev + Modified 7 November 2019 by Georg Icking-Konert */ #include "Arduino.h" diff --git a/cores/arduino/HardwareSerial2.cpp b/cores/arduino/HardwareSerial2.cpp index fd334ae15..5558b17d1 100644 --- a/cores/arduino/HardwareSerial2.cpp +++ b/cores/arduino/HardwareSerial2.cpp @@ -20,6 +20,8 @@ Modified 28 September 2010 by Mark Sproul Modified 14 August 2012 by Alarus Modified 3 December 2013 by Matthijs Kooijman + Modified 2 November 2015 by SlashDev + Modified 7 November 2019 by Georg Icking-Konert */ #include "Arduino.h" diff --git a/cores/arduino/HardwareSerial3.cpp b/cores/arduino/HardwareSerial3.cpp index a68095b37..f6ba55460 100644 --- a/cores/arduino/HardwareSerial3.cpp +++ b/cores/arduino/HardwareSerial3.cpp @@ -20,6 +20,8 @@ Modified 28 September 2010 by Mark Sproul Modified 14 August 2012 by Alarus Modified 3 December 2013 by Matthijs Kooijman + Modified 2 November 2015 by SlashDev + Modified 7 November 2019 by Georg Icking-Konert */ #include "Arduino.h" diff --git a/cores/arduino/HardwareSerial_private.h b/cores/arduino/HardwareSerial_private.h index 761a5e559..72a9063b3 100644 --- a/cores/arduino/HardwareSerial_private.h +++ b/cores/arduino/HardwareSerial_private.h @@ -19,6 +19,8 @@ Modified 23 November 2006 by David A. Mellis Modified 28 September 2010 by Mark Sproul Modified 14 August 2012 by Alarus + Modified 2 November 2015 by SlashDev + Modified 7 November 2019 by Georg Icking-Konert */ #include "wiring_private.h" @@ -92,7 +94,8 @@ HardwareSerial::HardwareSerial( _ucsra(ucsra), _ucsrb(ucsrb), _ucsrc(ucsrc), _udr(udr), _rx_buffer_head(0), _rx_buffer_tail(0), - _tx_buffer_head(0), _tx_buffer_tail(0) + _tx_buffer_head(0), _tx_buffer_tail(0), + _isr(0) { } @@ -100,24 +103,35 @@ HardwareSerial::HardwareSerial( void HardwareSerial::_rx_complete_irq(void) { - if (bit_is_clear(*_ucsra, UPE0)) { - // No Parity error, read byte and store it in the buffer if there is - // room - unsigned char c = *_udr; - rx_buffer_index_t i = (unsigned int)(_rx_buffer_head + 1) % SERIAL_RX_BUFFER_SIZE; + // user function was attached -> call it with data and status byte + if (_isr) { + unsigned char status = *_ucsra; + unsigned char data = *_udr; + _isr( data, status ); + } - // if we should be storing the received character into the location - // just before the tail (meaning that the head would advance to the - // current location of the tail), we're about to overflow the buffer - // and so we don't write the character or advance the head. - if (i != _rx_buffer_tail) { - _rx_buffer[_rx_buffer_head] = c; - _rx_buffer_head = i; - } - } else { - // Parity error, read byte but discard it - *_udr; - }; + // default: save data in ring buffer + else { + if (bit_is_clear(*_ucsra, UPE0)) { + unsigned char c = *_udr; + // No Parity error, read byte and store it in the buffer if there is + // room + rx_buffer_index_t i = (unsigned int)(_rx_buffer_head + 1) % SERIAL_RX_BUFFER_SIZE; + + // if we should be storing the received character into the location + // just before the tail (meaning that the head would advance to the + // current location of the tail), we're about to overflow the buffer + // and so we don't write the character or advance the head. + if (i != _rx_buffer_tail) { + _rx_buffer[_rx_buffer_head] = c; + _rx_buffer_head = i; + } + } + else { + // Parity error, read byte but discard it + *_udr; + }; + } } #endif // whole file