Skip to content

Commit 307a108

Browse files
committed
optimized runtime for TXC custom function
optimized runtime for TXC custom function
1 parent f7f584b commit 307a108

File tree

3 files changed

+32
-25
lines changed

3 files changed

+32
-25
lines changed

Diff for: cores/arduino/HardwareSerial.cpp

+13-19
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ void serialEventRun(void)
7979
#endif
8080
}
8181

82+
// dummy function attached to TxC interrupt. Is faster than if(NULL) check
83+
void dummyFct(void) { /* dummy */}
84+
8285
// macro to guard critical sections when needed for large TX buffer sizes
8386
#if (SERIAL_TX_BUFFER_SIZE>256)
8487
#define TX_BUFFER_ATOMIC ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
@@ -114,15 +117,6 @@ void HardwareSerial::_tx_udr_empty_irq(void)
114117
}
115118
}
116119

117-
void HardwareSerial::_tx_complete_irq(void)
118-
{
119-
// user send function was attached -> call it
120-
if (_isrTx) {
121-
_isrTx();
122-
}
123-
124-
}
125-
126120
// Public Methods //////////////////////////////////////////////////////////////
127121

128122
void HardwareSerial::begin(unsigned long baud, byte config)
@@ -158,6 +152,7 @@ void HardwareSerial::begin(unsigned long baud, byte config)
158152
sbi(*_ucsrb, TXEN0);
159153
sbi(*_ucsrb, RXCIE0);
160154
cbi(*_ucsrb, UDRIE0);
155+
//cbi(*_ucsrb, TXCIE0);
161156
}
162157

163158
void HardwareSerial::end()
@@ -300,20 +295,19 @@ void HardwareSerial::attachInterrupt_Receive( isrRx_t fn )
300295

301296
void HardwareSerial::attachInterrupt_Send( isrTx_t fn )
302297
{
303-
uint8_t oldSREG = SREG;
304-
cli();
305-
_isrTx = fn;
306-
sbi(*_ucsrb, TXCIE0);
307-
SREG = oldSREG;
298+
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
299+
_isrTx = fn;
300+
sbi(*_ucsra, TXC0); // clear TXC status
301+
sbi(*_ucsrb, TXCIE0); // activate TXC interrupt
302+
}
308303
}
309304

310305
void HardwareSerial::detachInterrupt_Send()
311306
{
312-
uint8_t oldSREG = SREG;
313-
cli();
314-
_isrTx = NULL;
315-
cbi(*_ucsrb, TXCIE0);
316-
SREG = oldSREG;
307+
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
308+
_isrTx = NULL;
309+
cbi(*_ucsrb, TXCIE0); // deactivate TXC interrupt
310+
}
317311
}
318312

319313
#endif // whole file

Diff for: cores/arduino/HardwareSerial.h

+9-5
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,12 @@ class HardwareSerial : public Stream
114114
// instruction.
115115
unsigned char _rx_buffer[SERIAL_RX_BUFFER_SIZE];
116116
unsigned char _tx_buffer[SERIAL_TX_BUFFER_SIZE];
117+
118+
// custom handlers for RX and TXC interrupts
119+
typedef void (* isrRx_t)( uint8_t d, uint8_t s );
120+
typedef void (* isrTx_t)( void );
121+
isrRx_t _isrRx;
122+
isrTx_t _isrTx;
117123

118124
public:
119125
inline HardwareSerial(
@@ -139,17 +145,15 @@ class HardwareSerial : public Stream
139145
// Interrupt handlers - Not intended to be called externally
140146
inline void _rx_complete_irq(void);
141147
void _tx_udr_empty_irq(void);
142-
void _tx_complete_irq(void);
148+
inline void _tx_complete_irq(void);
143149

144-
typedef void (* isrRx_t)( uint8_t d, uint8_t s );
150+
// attach custom handlers for RX and TXC interrupts
145151
void attachInterrupt_Receive( isrRx_t fn );
146152
void detachInterrupt_Receive() { attachInterrupt_Receive( (isrRx_t) NULL ); };
147-
typedef void (* isrTx_t)( void );
148153
void attachInterrupt_Send( isrTx_t fn );
149154
void detachInterrupt_Send( void );
155+
150156
private:
151-
isrRx_t _isrRx;
152-
isrTx_t _isrTx;
153157

154158
HardwareSerial( const HardwareSerial & );
155159
HardwareSerial & operator =( const HardwareSerial &);

Diff for: cores/arduino/HardwareSerial_private.h

+10-1
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@
8484
#error "Not all bit positions for UART3 are the same as for UART0"
8585
#endif
8686

87+
// dummy custom function attached and TXC interrupt. Is faster than if(NULL) check
88+
void dummyFct(void);
89+
8790
// Constructors ////////////////////////////////////////////////////////////////
8891

8992
HardwareSerial::HardwareSerial(
@@ -95,7 +98,7 @@ HardwareSerial::HardwareSerial(
9598
_udr(udr),
9699
_rx_buffer_head(0), _rx_buffer_tail(0),
97100
_tx_buffer_head(0), _tx_buffer_tail(0),
98-
_isrRx(0), _isrTx(0)
101+
_isrRx(dummyFct), _isrTx(dummyFct)
99102
{
100103
}
101104

@@ -134,4 +137,10 @@ void HardwareSerial::_rx_complete_irq(void)
134137
}
135138
}
136139

140+
void HardwareSerial::_tx_complete_irq(void)
141+
{
142+
// user send function was attached -> call it
143+
_isrTx();
144+
}
145+
137146
#endif // whole file

0 commit comments

Comments
 (0)