From 291b7f7b8a19c43e267ab01b32fdaa9204b14c70 Mon Sep 17 00:00:00 2001 From: Georg Icking-Konert Date: Fri, 8 Nov 2019 06:06:04 +0100 Subject: [PATCH 1/8] added optional custom handler to Serial interrupt added optional custom handler to Serial interrupt. Is minor enhancement of NeoHWSerial by SlashDevin (https://github.com/SlashDevin/NeoHWSerial), as user function also gets UART status as parameter to e.g. detect LIN break in user routine. Added as core extension instead of library due to similar extension for Due (https://github.com/gicking/ArduinoCore-sam) which AFAIK cannot be implemented as library. --- cores/arduino/HardwareSerial.cpp | 10 ++++++ cores/arduino/HardwareSerial.h | 11 ++++++ cores/arduino/HardwareSerial0.cpp | 2 ++ cores/arduino/HardwareSerial1.cpp | 2 ++ cores/arduino/HardwareSerial2.cpp | 2 ++ cores/arduino/HardwareSerial3.cpp | 2 ++ cores/arduino/HardwareSerial_private.h | 50 ++++++++++++++++---------- 7 files changed, 61 insertions(+), 18 deletions(-) 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..1bb395d8a 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=0x00, uint8_t s=0x00 ); + 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 From e5fd810fc507217143ad93fe92b70abb9ba73aea Mon Sep 17 00:00:00 2001 From: Georg Icking-Konert Date: Sat, 9 Nov 2019 18:00:59 +0100 Subject: [PATCH 2/8] fixed compiler warnings fixed compiler warnings when compiling with max. waring level --- cores/arduino/HardwareSerial.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h index 1bb395d8a..f8a3bc65b 100644 --- a/cores/arduino/HardwareSerial.h +++ b/cores/arduino/HardwareSerial.h @@ -140,7 +140,7 @@ class HardwareSerial : public Stream inline void _rx_complete_irq(void); void _tx_udr_empty_irq(void); - typedef void (* isr_t)( uint8_t d=0x00, uint8_t s=0x00 ); + typedef void (* isr_t)( uint8_t d, uint8_t s ); void attachInterrupt( isr_t fn ); void detachInterrupt() { attachInterrupt( (isr_t) NULL ); }; private: From 8665c0367d9fddffdfa1777a7cdda0fa6bd8427c Mon Sep 17 00:00:00 2001 From: Georg Icking-Konert Date: Sun, 17 Nov 2019 09:08:23 +0100 Subject: [PATCH 3/8] add Serial.attachInterrupt_Send() add Serial.attachInterrupt_Send() rename Serial.attachInterrupt() to Serial.attachInterrupt_Receive() --- cores/arduino/HardwareSerial.cpp | 31 ++++++++++++++++++++++++-- cores/arduino/HardwareSerial.h | 15 ++++++++----- cores/arduino/HardwareSerial0.cpp | 16 +++++++++++-- cores/arduino/HardwareSerial1.cpp | 14 ++++++++++-- cores/arduino/HardwareSerial2.cpp | 17 ++++++++++++-- cores/arduino/HardwareSerial3.cpp | 8 +++++-- cores/arduino/HardwareSerial_private.h | 10 ++++----- 7 files changed, 91 insertions(+), 20 deletions(-) diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp index 56eb744fa..417e77af1 100644 --- a/cores/arduino/HardwareSerial.cpp +++ b/cores/arduino/HardwareSerial.cpp @@ -114,6 +114,14 @@ void HardwareSerial::_tx_udr_empty_irq(void) } } +void HardwareSerial::_tx_complete_irq(void) +{ + // user send function was attached -> call it + if (_isrTx) { + _isrTx(); + } +} + // Public Methods ////////////////////////////////////////////////////////////// void HardwareSerial::begin(unsigned long baud, byte config) @@ -160,6 +168,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; @@ -280,11 +289,29 @@ size_t HardwareSerial::write(uint8_t c) return 1; } -void HardwareSerial::attachInterrupt( isr_t fn ) +void HardwareSerial::attachInterrupt_Receive( isrRx_t fn ) +{ + uint8_t oldSREG = SREG; + cli(); + _isrRx = fn; + SREG = oldSREG; +} + +void HardwareSerial::attachInterrupt_Send( isrTx_t fn ) +{ + uint8_t oldSREG = SREG; + cli(); + _isrTx = fn; + sbi(*_ucsrb, TXCIE0); + SREG = oldSREG; +} + +void HardwareSerial::detachInterrupt_Send() { uint8_t oldSREG = SREG; cli(); - _isr = fn; + _isrTx = NULL; + cbi(*_ucsrb, TXCIE0); SREG = oldSREG; } diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h index f8a3bc65b..1e3de78a7 100644 --- a/cores/arduino/HardwareSerial.h +++ b/cores/arduino/HardwareSerial.h @@ -139,12 +139,17 @@ 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 ); }; + void _tx_complete_irq(void); + + typedef void (* isrRx_t)( uint8_t d, uint8_t s ); + void attachInterrupt_Receive( isrRx_t fn ); + void detachInterrupt_Receive() { attachInterrupt_Receive( (isrRx_t) NULL ); }; + typedef void (* isrTx_t)( void ); + void attachInterrupt_Send( isrTx_t fn ); + void detachInterrupt_Send( void ); private: - isr_t _isr; + isrRx_t _isrRx; + isrTx_t _isrTx; HardwareSerial( const HardwareSerial & ); HardwareSerial & operator =( const HardwareSerial &); diff --git a/cores/arduino/HardwareSerial0.cpp b/cores/arduino/HardwareSerial0.cpp index ece78a636..9f507b6c2 100644 --- a/cores/arduino/HardwareSerial0.cpp +++ b/cores/arduino/HardwareSerial0.cpp @@ -20,8 +20,7 @@ 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 + Modified 17 November 2019 by Georg Icking-Konert */ #include "Arduino.h" @@ -66,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 c436e1690..800191700 100644 --- a/cores/arduino/HardwareSerial1.cpp +++ b/cores/arduino/HardwareSerial1.cpp @@ -20,8 +20,7 @@ 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 + Modified 17 November 2019 by Georg Icking-Konert */ #include "Arduino.h" @@ -60,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 5558b17d1..c87607a47 100644 --- a/cores/arduino/HardwareSerial2.cpp +++ b/cores/arduino/HardwareSerial2.cpp @@ -20,8 +20,7 @@ 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 + Modified 17 November 2019 by Georg Icking-Konert */ #include "Arduino.h" @@ -38,6 +37,9 @@ #if defined(HAVE_HWSERIAL2) +// xxx +extern int count; + ISR(USART2_RX_vect) { Serial2._rx_complete_irq(); @@ -45,9 +47,20 @@ ISR(USART2_RX_vect) ISR(USART2_UDRE_vect) { + // xxx + Serial.println(++count); + digitalWrite(LED_BUILTIN, HIGH); + delayMicroseconds(50); + digitalWrite(LED_BUILTIN, LOW); + 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 f6ba55460..aaac520a5 100644 --- a/cores/arduino/HardwareSerial3.cpp +++ b/cores/arduino/HardwareSerial3.cpp @@ -20,8 +20,7 @@ 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 + Modified 17 November 2019 by Georg Icking-Konert */ #include "Arduino.h" @@ -48,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 72a9063b3..ac61bed20 100644 --- a/cores/arduino/HardwareSerial_private.h +++ b/cores/arduino/HardwareSerial_private.h @@ -20,7 +20,7 @@ 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 + Modified 17 November 2019 by Georg Icking-Konert */ #include "wiring_private.h" @@ -95,7 +95,7 @@ HardwareSerial::HardwareSerial( _udr(udr), _rx_buffer_head(0), _rx_buffer_tail(0), _tx_buffer_head(0), _tx_buffer_tail(0), - _isr(0) + _isrRx(0), _isrTx(0) { } @@ -103,11 +103,11 @@ HardwareSerial::HardwareSerial( void HardwareSerial::_rx_complete_irq(void) { - // user function was attached -> call it with data and status byte - if (_isr) { + // user receive function was attached -> call it with data and status byte + if (_isrRx) { unsigned char status = *_ucsra; unsigned char data = *_udr; - _isr( data, status ); + _isrRx( data, status ); } // default: save data in ring buffer From f7f584b1ba5078517e391fad8a3da1c627ad6960 Mon Sep 17 00:00:00 2001 From: Georg Icking-Konert Date: Mon, 18 Nov 2019 18:26:43 +0100 Subject: [PATCH 4/8] add Serial.attachInterrupt_Send() --- cores/arduino/HardwareSerial.cpp | 1 + cores/arduino/HardwareSerial2.cpp | 9 --------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp index 417e77af1..ffabbb735 100644 --- a/cores/arduino/HardwareSerial.cpp +++ b/cores/arduino/HardwareSerial.cpp @@ -120,6 +120,7 @@ void HardwareSerial::_tx_complete_irq(void) if (_isrTx) { _isrTx(); } + } // Public Methods ////////////////////////////////////////////////////////////// diff --git a/cores/arduino/HardwareSerial2.cpp b/cores/arduino/HardwareSerial2.cpp index c87607a47..1a3b7d754 100644 --- a/cores/arduino/HardwareSerial2.cpp +++ b/cores/arduino/HardwareSerial2.cpp @@ -37,9 +37,6 @@ #if defined(HAVE_HWSERIAL2) -// xxx -extern int count; - ISR(USART2_RX_vect) { Serial2._rx_complete_irq(); @@ -47,12 +44,6 @@ ISR(USART2_RX_vect) ISR(USART2_UDRE_vect) { - // xxx - Serial.println(++count); - digitalWrite(LED_BUILTIN, HIGH); - delayMicroseconds(50); - digitalWrite(LED_BUILTIN, LOW); - Serial2._tx_udr_empty_irq(); } From 307a108582edf6786a0e8d8c7fa4c6d4f78143e4 Mon Sep 17 00:00:00 2001 From: Georg Icking-Konert Date: Sat, 23 Nov 2019 09:11:38 +0100 Subject: [PATCH 5/8] optimized runtime for TXC custom function optimized runtime for TXC custom function --- cores/arduino/HardwareSerial.cpp | 32 +++++++++++--------------- cores/arduino/HardwareSerial.h | 14 +++++++---- cores/arduino/HardwareSerial_private.h | 11 ++++++++- 3 files changed, 32 insertions(+), 25 deletions(-) diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp index ffabbb735..74ee0040a 100644 --- a/cores/arduino/HardwareSerial.cpp +++ b/cores/arduino/HardwareSerial.cpp @@ -79,6 +79,9 @@ void serialEventRun(void) #endif } +// dummy function attached to TxC interrupt. Is faster than if(NULL) check +void dummyFct(void) { /* dummy */} + // macro to guard critical sections when needed for large TX buffer sizes #if (SERIAL_TX_BUFFER_SIZE>256) #define TX_BUFFER_ATOMIC ATOMIC_BLOCK(ATOMIC_RESTORESTATE) @@ -114,15 +117,6 @@ void HardwareSerial::_tx_udr_empty_irq(void) } } -void HardwareSerial::_tx_complete_irq(void) -{ - // user send function was attached -> call it - if (_isrTx) { - _isrTx(); - } - -} - // Public Methods ////////////////////////////////////////////////////////////// void HardwareSerial::begin(unsigned long baud, byte config) @@ -158,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() @@ -300,20 +295,19 @@ void HardwareSerial::attachInterrupt_Receive( isrRx_t fn ) void HardwareSerial::attachInterrupt_Send( isrTx_t fn ) { - uint8_t oldSREG = SREG; - cli(); - _isrTx = fn; - sbi(*_ucsrb, TXCIE0); - SREG = oldSREG; + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { + _isrTx = fn; + sbi(*_ucsra, TXC0); // clear TXC status + sbi(*_ucsrb, TXCIE0); // activate TXC interrupt + } } void HardwareSerial::detachInterrupt_Send() { - uint8_t oldSREG = SREG; - cli(); - _isrTx = NULL; - cbi(*_ucsrb, TXCIE0); - SREG = oldSREG; + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { + _isrTx = NULL; + cbi(*_ucsrb, TXCIE0); // deactivate TXC interrupt + } } #endif // whole file diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h index 1e3de78a7..a9354877b 100644 --- a/cores/arduino/HardwareSerial.h +++ b/cores/arduino/HardwareSerial.h @@ -114,6 +114,12 @@ 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 d, uint8_t s ); + typedef void (* isrTx_t)( void ); + isrRx_t _isrRx; + isrTx_t _isrTx; public: inline HardwareSerial( @@ -139,17 +145,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); - void _tx_complete_irq(void); + inline void _tx_complete_irq(void); - typedef void (* isrRx_t)( uint8_t d, uint8_t s ); + // attach custom handlers for RX and TXC interrupts void attachInterrupt_Receive( isrRx_t fn ); void detachInterrupt_Receive() { attachInterrupt_Receive( (isrRx_t) NULL ); }; - typedef void (* isrTx_t)( void ); void attachInterrupt_Send( isrTx_t fn ); void detachInterrupt_Send( void ); + private: - isrRx_t _isrRx; - isrTx_t _isrTx; HardwareSerial( const HardwareSerial & ); HardwareSerial & operator =( const HardwareSerial &); diff --git a/cores/arduino/HardwareSerial_private.h b/cores/arduino/HardwareSerial_private.h index ac61bed20..575d519f4 100644 --- a/cores/arduino/HardwareSerial_private.h +++ b/cores/arduino/HardwareSerial_private.h @@ -84,6 +84,9 @@ #error "Not all bit positions for UART3 are the same as for UART0" #endif +// dummy custom function attached and TXC interrupt. Is faster than if(NULL) check +void dummyFct(void); + // Constructors //////////////////////////////////////////////////////////////// HardwareSerial::HardwareSerial( @@ -95,7 +98,7 @@ HardwareSerial::HardwareSerial( _udr(udr), _rx_buffer_head(0), _rx_buffer_tail(0), _tx_buffer_head(0), _tx_buffer_tail(0), - _isrRx(0), _isrTx(0) + _isrRx(dummyFct), _isrTx(dummyFct) { } @@ -134,4 +137,10 @@ void HardwareSerial::_rx_complete_irq(void) } } +void HardwareSerial::_tx_complete_irq(void) +{ + // user send function was attached -> call it + _isrTx(); +} + #endif // whole file From cbcc356652ec3c5be1ae07df87311fafee1ecd67 Mon Sep 17 00:00:00 2001 From: Georg Icking-Konert Date: Sat, 23 Nov 2019 13:57:38 +0100 Subject: [PATCH 6/8] minor cosmetics minor cosmetics --- cores/arduino/HardwareSerial.cpp | 10 +++++----- cores/arduino/HardwareSerial.h | 5 ++++- cores/arduino/HardwareSerial_private.h | 5 +---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp index 74ee0040a..fc3716bc4 100644 --- a/cores/arduino/HardwareSerial.cpp +++ b/cores/arduino/HardwareSerial.cpp @@ -79,9 +79,6 @@ void serialEventRun(void) #endif } -// dummy function attached to TxC interrupt. Is faster than if(NULL) check -void dummyFct(void) { /* dummy */} - // macro to guard critical sections when needed for large TX buffer sizes #if (SERIAL_TX_BUFFER_SIZE>256) #define TX_BUFFER_ATOMIC ATOMIC_BLOCK(ATOMIC_RESTORESTATE) @@ -89,6 +86,9 @@ void dummyFct(void) { /* dummy */} #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) @@ -296,7 +296,7 @@ void HardwareSerial::attachInterrupt_Receive( isrRx_t fn ) void HardwareSerial::attachInterrupt_Send( isrTx_t fn ) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { - _isrTx = fn; + _isrTx = fn; // set custom function sbi(*_ucsra, TXC0); // clear TXC status sbi(*_ucsrb, TXCIE0); // activate TXC interrupt } @@ -305,7 +305,7 @@ void HardwareSerial::attachInterrupt_Send( isrTx_t fn ) void HardwareSerial::detachInterrupt_Send() { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { - _isrTx = NULL; + _isrTx = dummyTxFct; // restore dummy function cbi(*_ucsrb, TXCIE0); // deactivate TXC interrupt } } diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h index a9354877b..b39590496 100644 --- a/cores/arduino/HardwareSerial.h +++ b/cores/arduino/HardwareSerial.h @@ -92,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: @@ -149,7 +152,7 @@ class HardwareSerial : public Stream // attach custom handlers for RX and TXC interrupts void attachInterrupt_Receive( isrRx_t fn ); - void detachInterrupt_Receive() { attachInterrupt_Receive( (isrRx_t) NULL ); }; + void detachInterrupt_Receive( void ) { attachInterrupt_Receive( (isrRx_t) NULL ); }; void attachInterrupt_Send( isrTx_t fn ); void detachInterrupt_Send( void ); diff --git a/cores/arduino/HardwareSerial_private.h b/cores/arduino/HardwareSerial_private.h index 575d519f4..5446ab619 100644 --- a/cores/arduino/HardwareSerial_private.h +++ b/cores/arduino/HardwareSerial_private.h @@ -84,9 +84,6 @@ #error "Not all bit positions for UART3 are the same as for UART0" #endif -// dummy custom function attached and TXC interrupt. Is faster than if(NULL) check -void dummyFct(void); - // Constructors //////////////////////////////////////////////////////////////// HardwareSerial::HardwareSerial( @@ -98,7 +95,7 @@ HardwareSerial::HardwareSerial( _udr(udr), _rx_buffer_head(0), _rx_buffer_tail(0), _tx_buffer_head(0), _tx_buffer_tail(0), - _isrRx(dummyFct), _isrTx(dummyFct) + _isrRx(NULL), _isrTx(dummyTxFct) { } From b4f39848dd457d7e5342295fcbd98d6153ee297e Mon Sep 17 00:00:00 2001 From: Georg Icking-Konert Date: Sat, 23 Nov 2019 14:14:39 +0100 Subject: [PATCH 7/8] updated modification date - updated modification date to sync with SAM core - no functional change --- cores/arduino/HardwareSerial.cpp | 2 +- cores/arduino/HardwareSerial.h | 2 +- cores/arduino/HardwareSerial0.cpp | 2 +- cores/arduino/HardwareSerial1.cpp | 2 +- cores/arduino/HardwareSerial2.cpp | 2 +- cores/arduino/HardwareSerial3.cpp | 2 +- cores/arduino/HardwareSerial_private.h | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp index fc3716bc4..39984fc36 100644 --- a/cores/arduino/HardwareSerial.cpp +++ b/cores/arduino/HardwareSerial.cpp @@ -21,7 +21,7 @@ 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 + Modified 23 November 2019 by Georg Icking-Konert */ #include diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h index b39590496..b7368ccc5 100644 --- a/cores/arduino/HardwareSerial.h +++ b/cores/arduino/HardwareSerial.h @@ -20,7 +20,7 @@ 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 + Modified 23 November 2019 by Georg Icking-Konert */ #ifndef HardwareSerial_h diff --git a/cores/arduino/HardwareSerial0.cpp b/cores/arduino/HardwareSerial0.cpp index 9f507b6c2..33810d21d 100644 --- a/cores/arduino/HardwareSerial0.cpp +++ b/cores/arduino/HardwareSerial0.cpp @@ -20,7 +20,7 @@ Modified 28 September 2010 by Mark Sproul Modified 14 August 2012 by Alarus Modified 3 December 2013 by Matthijs Kooijman - Modified 17 November 2019 by Georg Icking-Konert + Modified 23 November 2019 by Georg Icking-Konert */ #include "Arduino.h" diff --git a/cores/arduino/HardwareSerial1.cpp b/cores/arduino/HardwareSerial1.cpp index 800191700..2dbad872d 100644 --- a/cores/arduino/HardwareSerial1.cpp +++ b/cores/arduino/HardwareSerial1.cpp @@ -20,7 +20,7 @@ Modified 28 September 2010 by Mark Sproul Modified 14 August 2012 by Alarus Modified 3 December 2013 by Matthijs Kooijman - Modified 17 November 2019 by Georg Icking-Konert + Modified 23 November 2019 by Georg Icking-Konert */ #include "Arduino.h" diff --git a/cores/arduino/HardwareSerial2.cpp b/cores/arduino/HardwareSerial2.cpp index 1a3b7d754..a06569a37 100644 --- a/cores/arduino/HardwareSerial2.cpp +++ b/cores/arduino/HardwareSerial2.cpp @@ -20,7 +20,7 @@ Modified 28 September 2010 by Mark Sproul Modified 14 August 2012 by Alarus Modified 3 December 2013 by Matthijs Kooijman - Modified 17 November 2019 by Georg Icking-Konert + Modified 23 November 2019 by Georg Icking-Konert */ #include "Arduino.h" diff --git a/cores/arduino/HardwareSerial3.cpp b/cores/arduino/HardwareSerial3.cpp index aaac520a5..b010858ba 100644 --- a/cores/arduino/HardwareSerial3.cpp +++ b/cores/arduino/HardwareSerial3.cpp @@ -20,7 +20,7 @@ Modified 28 September 2010 by Mark Sproul Modified 14 August 2012 by Alarus Modified 3 December 2013 by Matthijs Kooijman - Modified 17 November 2019 by Georg Icking-Konert + Modified 23 November 2019 by Georg Icking-Konert */ #include "Arduino.h" diff --git a/cores/arduino/HardwareSerial_private.h b/cores/arduino/HardwareSerial_private.h index 5446ab619..ee1dd611d 100644 --- a/cores/arduino/HardwareSerial_private.h +++ b/cores/arduino/HardwareSerial_private.h @@ -20,7 +20,7 @@ Modified 28 September 2010 by Mark Sproul Modified 14 August 2012 by Alarus Modified 2 November 2015 by SlashDev - Modified 17 November 2019 by Georg Icking-Konert + Modified 23 November 2019 by Georg Icking-Konert */ #include "wiring_private.h" From eb648c1efd108f01c189193d33700a9259626fa3 Mon Sep 17 00:00:00 2001 From: Georg Icking-Konert Date: Fri, 24 Dec 2021 09:28:45 +0100 Subject: [PATCH 8/8] added optional argument pointer added optional argument pointer, see https://github.com/arduino/ArduinoCore-sam/pull/95#issuecomment-999825944 --- cores/arduino/HardwareSerial.cpp | 3 ++- cores/arduino/HardwareSerial.h | 5 +++-- cores/arduino/HardwareSerial_private.h | 6 +++--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp index 39984fc36..e8eae9524 100644 --- a/cores/arduino/HardwareSerial.cpp +++ b/cores/arduino/HardwareSerial.cpp @@ -285,11 +285,12 @@ size_t HardwareSerial::write(uint8_t c) return 1; } -void HardwareSerial::attachInterrupt_Receive( isrRx_t fn ) +void HardwareSerial::attachInterrupt_Receive( isrRx_t fn, void* args ) { uint8_t oldSREG = SREG; cli(); _isrRx = fn; + _rxArg = args; SREG = oldSREG; } diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h index b7368ccc5..14c29c2ce 100644 --- a/cores/arduino/HardwareSerial.h +++ b/cores/arduino/HardwareSerial.h @@ -119,10 +119,11 @@ class HardwareSerial : public Stream unsigned char _tx_buffer[SERIAL_TX_BUFFER_SIZE]; // custom handlers for RX and TXC interrupts - typedef void (* isrRx_t)( uint8_t d, uint8_t s ); + 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( @@ -151,7 +152,7 @@ class HardwareSerial : public Stream inline void _tx_complete_irq(void); // attach custom handlers for RX and TXC interrupts - void attachInterrupt_Receive( isrRx_t fn ); + 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 ); diff --git a/cores/arduino/HardwareSerial_private.h b/cores/arduino/HardwareSerial_private.h index ee1dd611d..652622508 100644 --- a/cores/arduino/HardwareSerial_private.h +++ b/cores/arduino/HardwareSerial_private.h @@ -95,7 +95,7 @@ HardwareSerial::HardwareSerial( _udr(udr), _rx_buffer_head(0), _rx_buffer_tail(0), _tx_buffer_head(0), _tx_buffer_tail(0), - _isrRx(NULL), _isrTx(dummyTxFct) + _isrRx(NULL), _isrTx(dummyTxFct), _rxArg(NULL) { } @@ -103,11 +103,11 @@ HardwareSerial::HardwareSerial( void HardwareSerial::_rx_complete_irq(void) { - // user receive function was attached -> call it with data and status byte + // 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 ); + _isrRx( data, status, _rxArg ); } // default: save data in ring buffer 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