Skip to content

Commit 8447da1

Browse files
committed
added optional custom handler to Serial interrupt
added optional custom handler to Serial interrupt. Is similar to NeoHWSerial by SlashDevin (https://github.com/SlashDevin/NeoHWSerial), but: - user function also gets UART status as parameter to e.g. detect LIN break in user routine. - ported to Arduino Due Added as core extension because AFAIK cannot be implemented as library for Due. Also note similar pull request for AVR (arduino/ArduinoCore-avr#297)
1 parent eed66e7 commit 8447da1

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

cores/arduino/UARTClass.cpp

+20-3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ UARTClass::UARTClass( Uart *pUart, IRQn_Type dwIrq, uint32_t dwId, RingBuffer *p
3131
_pUart=pUart;
3232
_dwIrq=dwIrq;
3333
_dwId=dwId;
34+
35+
_isr = NULL;
3436
}
3537

3638
// Public Methods //////////////////////////////////////////////////////////////
@@ -166,13 +168,28 @@ size_t UARTClass::write( const uint8_t uc_data )
166168
return 1;
167169
}
168170

171+
void UARTClass::attachInterrupt( USART_isr_t fn )
172+
{
173+
_isr = fn;
174+
}
175+
169176
void UARTClass::IrqHandler( void )
170177
{
171178
uint32_t status = _pUart->UART_SR;
172179

173180
// Did we receive data?
174-
if ((status & UART_SR_RXRDY) == UART_SR_RXRDY)
175-
_rx_buffer->store_char(_pUart->UART_RHR);
181+
if ((status & UART_SR_RXRDY) == UART_SR_RXRDY) {
182+
183+
// user function was attached -> call it with data and status byte
184+
if (_isr) {
185+
_isr(_pUart->UART_RHR, status);
186+
}
187+
// no user function attached -> store in ring buffer
188+
else {
189+
_rx_buffer->store_char(_pUart->UART_RHR);
190+
}
191+
192+
}
176193

177194
// Do we need to keep sending data?
178195
if ((status & UART_SR_TXRDY) == UART_SR_TXRDY)
@@ -189,7 +206,7 @@ void UARTClass::IrqHandler( void )
189206
}
190207

191208
// Acknowledge errors
192-
if ((status & UART_SR_OVRE) == UART_SR_OVRE || (status & UART_SR_FRAME) == UART_SR_FRAME)
209+
if ((status & UART_SR_OVRE) == UART_SR_OVRE || (status & UART_SR_FRAME) == UART_SR_FRAME || (status & UART_SR_RXBRK) == UART_SR_RXBRK)
193210
{
194211
// TODO: error reporting outside ISR
195212
_pUart->UART_CR |= UART_CR_RSTSTA;

cores/arduino/UARTClass.h

+8
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131
#define SERIAL_8M1 UARTClass::Mode_8M1
3232
#define SERIAL_8S1 UARTClass::Mode_8S1
3333

34+
// missing in CMSIS
35+
#define UART_SR_RXBRK (0x1u << 2)
36+
3437

3538
class UARTClass : public HardwareSerial
3639
{
@@ -60,6 +63,10 @@ class UARTClass : public HardwareSerial
6063

6164
void IrqHandler(void);
6265

66+
typedef void (*USART_isr_t)(uint8_t data, uint32_t status);
67+
void attachInterrupt( USART_isr_t fn );
68+
void detachInterrupt() { attachInterrupt( (USART_isr_t) NULL ); };
69+
6370
operator bool() { return true; }; // UART always active
6471

6572
protected:
@@ -72,6 +79,7 @@ class UARTClass : public HardwareSerial
7279
IRQn_Type _dwIrq;
7380
uint32_t _dwId;
7481

82+
USART_isr_t _isr;
7583
};
7684

7785
#endif // _UART_CLASS_

0 commit comments

Comments
 (0)