diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp index 561127f9f..b43052f6c 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 23 November 2019 by Georg Icking-Konert */ #include @@ -84,6 +86,9 @@ void serialEventRun(void) #define TX_BUFFER_ATOMIC #endif +// dummy custom function for TxC interrupt. Is faster than check if(fct==NULL) +void dummyTxFct(void) { /* dummy */} + // Actual interrupt handlers ////////////////////////////////////////////////////////////// void HardwareSerial::_tx_udr_empty_irq(void) @@ -147,6 +152,7 @@ void HardwareSerial::begin(unsigned long baud, byte config) sbi(*_ucsrb, TXEN0); sbi(*_ucsrb, RXCIE0); cbi(*_ucsrb, UDRIE0); + //cbi(*_ucsrb, TXCIE0); } void HardwareSerial::end() @@ -158,6 +164,7 @@ void HardwareSerial::end() cbi(*_ucsrb, TXEN0); cbi(*_ucsrb, RXCIE0); cbi(*_ucsrb, UDRIE0); + cbi(*_ucsrb, TXCIE0); // clear any received data _rx_buffer_head = _rx_buffer_tail; @@ -278,4 +285,30 @@ size_t HardwareSerial::write(uint8_t c) return 1; } +void HardwareSerial::attachInterrupt_Receive( isrRx_t fn, void* args ) +{ + uint8_t oldSREG = SREG; + cli(); + _isrRx = fn; + _rxArg = args; + SREG = oldSREG; +} + +void HardwareSerial::attachInterrupt_Send( isrTx_t fn ) +{ + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { + _isrTx = fn; // set custom function + sbi(*_ucsra, TXC0); // clear TXC status + sbi(*_ucsrb, TXCIE0); // activate TXC interrupt + } +} + +void HardwareSerial::detachInterrupt_Send() +{ + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { + _isrTx = dummyTxFct; // restore dummy function + cbi(*_ucsrb, TXCIE0); // deactivate TXC interrupt + } +} + #endif // whole file diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h index 6ff29d0b9..7d1c9c91b 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 23 November 2019 by Georg Icking-Konert */ #ifndef HardwareSerial_h @@ -90,6 +92,9 @@ typedef uint8_t rx_buffer_index_t; #define SERIAL_7O2 0x3C #define SERIAL_8O2 0x3E +// dummy custom function for TxC interrupt. Is faster than check if(fct==NULL) +void dummyTxFct(void); + class HardwareSerial : public Stream { protected: @@ -112,6 +117,13 @@ class HardwareSerial : public Stream // instruction. unsigned char _rx_buffer[SERIAL_RX_BUFFER_SIZE]; unsigned char _tx_buffer[SERIAL_TX_BUFFER_SIZE]; + + // custom handlers for RX and TXC interrupts + typedef void (* isrRx_t)( uint8_t data, uint8_t status, void* args ); + typedef void (* isrTx_t)( void ); + isrRx_t _isrRx; + isrTx_t _isrTx; + void* _rxArg; public: inline HardwareSerial( @@ -137,6 +149,18 @@ class HardwareSerial : public Stream // Interrupt handlers - Not intended to be called externally inline void _rx_complete_irq(void); void _tx_udr_empty_irq(void); + inline void _tx_complete_irq(void); + + // attach custom handlers for RX and TXC interrupts + void attachInterrupt_Receive( isrRx_t fn, void *args = NULL ); + void detachInterrupt_Receive( void ) { attachInterrupt_Receive( (isrRx_t) NULL ); }; + void attachInterrupt_Send( isrTx_t fn ); + void detachInterrupt_Send( void ); + + private: + + 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 7d47ed2f6..ab2120560 100644 --- a/cores/arduino/HardwareSerial0.cpp +++ b/cores/arduino/HardwareSerial0.cpp @@ -20,6 +20,7 @@ Modified 28 September 2010 by Mark Sproul Modified 14 August 2012 by Alarus Modified 3 December 2013 by Matthijs Kooijman + Modified 23 November 2019 by Georg Icking-Konert */ #include "Arduino.h" @@ -64,6 +65,19 @@ ISR(USART_UDRE_vect) Serial._tx_udr_empty_irq(); } +#if defined(UART0_TX_vect) +ISR(UART0_TX_vect) +#elif defined(USART0_TX_vect) +ISR(USART0_TX_vect) +#elif defined(USART_TX_vect) +ISR(USART_TX_vect) +#else + #error "Don't know what the Transmission Complete vector is called for Serial" +#endif +{ + Serial._tx_complete_irq(); +} + #if defined(UBRRH) && defined(UBRRL) HardwareSerial Serial(&UBRRH, &UBRRL, &UCSRA, &UCSRB, &UCSRC, &UDR); #else diff --git a/cores/arduino/HardwareSerial1.cpp b/cores/arduino/HardwareSerial1.cpp index a345cdbbc..02e988a67 100644 --- a/cores/arduino/HardwareSerial1.cpp +++ b/cores/arduino/HardwareSerial1.cpp @@ -20,6 +20,7 @@ Modified 28 September 2010 by Mark Sproul Modified 14 August 2012 by Alarus Modified 3 December 2013 by Matthijs Kooijman + Modified 23 November 2019 by Georg Icking-Konert */ #include "Arduino.h" @@ -58,6 +59,17 @@ ISR(USART1_UDRE_vect) Serial1._tx_udr_empty_irq(); } +#if defined(UART1_TX_vect) +ISR(UART1_TX_vect) +#elif defined(USART1_TX_vect) +ISR(USART1_TX_vect) +#else + #error "Don't know what the Transmission Complete vector is called for Serial1" +#endif +{ + Serial1._tx_complete_irq(); +} + HardwareSerial Serial1(&UBRR1H, &UBRR1L, &UCSR1A, &UCSR1B, &UCSR1C, &UDR1); // Function that can be weakly referenced by serialEventRun to prevent diff --git a/cores/arduino/HardwareSerial2.cpp b/cores/arduino/HardwareSerial2.cpp index 8e433b6fc..265cc3845 100644 --- a/cores/arduino/HardwareSerial2.cpp +++ b/cores/arduino/HardwareSerial2.cpp @@ -20,6 +20,7 @@ Modified 28 September 2010 by Mark Sproul Modified 14 August 2012 by Alarus Modified 3 December 2013 by Matthijs Kooijman + Modified 23 November 2019 by Georg Icking-Konert */ #include "Arduino.h" @@ -46,6 +47,11 @@ ISR(USART2_UDRE_vect) Serial2._tx_udr_empty_irq(); } +ISR(USART2_TX_vect) +{ + Serial2._tx_complete_irq(); +} + HardwareSerial Serial2(&UBRR2H, &UBRR2L, &UCSR2A, &UCSR2B, &UCSR2C, &UDR2); // Function that can be weakly referenced by serialEventRun to prevent diff --git a/cores/arduino/HardwareSerial3.cpp b/cores/arduino/HardwareSerial3.cpp index 26aaee81d..2b37c7529 100644 --- a/cores/arduino/HardwareSerial3.cpp +++ b/cores/arduino/HardwareSerial3.cpp @@ -20,6 +20,7 @@ Modified 28 September 2010 by Mark Sproul Modified 14 August 2012 by Alarus Modified 3 December 2013 by Matthijs Kooijman + Modified 23 November 2019 by Georg Icking-Konert */ #include "Arduino.h" @@ -46,6 +47,11 @@ ISR(USART3_UDRE_vect) Serial3._tx_udr_empty_irq(); } +ISR(USART3_TX_vect) +{ + Serial3._tx_complete_irq(); +} + HardwareSerial Serial3(&UBRR3H, &UBRR3L, &UCSR3A, &UCSR3B, &UCSR3C, &UDR3); // Function that can be weakly referenced by serialEventRun to prevent diff --git a/cores/arduino/HardwareSerial_private.h b/cores/arduino/HardwareSerial_private.h index 2e23cec0c..ad5354789 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 23 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), + _isrRx(NULL), _isrTx(dummyTxFct), _rxArg(NULL) { } @@ -100,24 +103,41 @@ 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; - - // 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; - }; + // user receive function was attached -> call it with data, status byte and optional argument pointer + if (_isrRx) { + unsigned char status = *_ucsra; + unsigned char data = *_udr; + _isrRx( data, status, _rxArg ); + } + + // 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; + }; + } +} + +void HardwareSerial::_tx_complete_irq(void) +{ + // user send function was attached -> call it + _isrTx(); } #endif // whole file pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy