8484#error "Not all bit positions for UART3 are the same as for UART0"
8585#endif
8686
87- inline void store_char (unsigned char c, HardwareSerial *s)
88- {
89- int i = (unsigned int )(s->_rx_buffer_head + 1 ) % SERIAL_BUFFER_SIZE;
90-
91- // if we should be storing the received character into the location
92- // just before the tail (meaning that the head would advance to the
93- // current location of the tail), we're about to overflow the buffer
94- // and so we don't write the character or advance the head.
95- if (i != s->_rx_buffer_tail ) {
96- s->_rx_buffer [s->_rx_buffer_head ] = c;
97- s->_rx_buffer_head = i;
98- }
99- }
100-
10187#if !defined(USART0_RX_vect) && defined(USART1_RX_vect)
10288// do nothing - on the 32u4 the first USART is USART1
10389#else
@@ -116,23 +102,7 @@ inline void store_char(unsigned char c, HardwareSerial *s)
116102 ISR (USART_RXC_vect) // ATmega8
117103#endif
118104 {
119- #if defined(UDR0)
120- if (bit_is_clear (UCSR0A, UPE0)) {
121- unsigned char c = UDR0;
122- store_char (c, &Serial);
123- } else {
124- unsigned char c = UDR0;
125- };
126- #elif defined(UDR)
127- if (bit_is_clear (UCSRA, PE)) {
128- unsigned char c = UDR;
129- store_char (c, &Serial);
130- } else {
131- unsigned char c = UDR;
132- };
133- #else
134- #error UDR not defined
135- #endif
105+ Serial._rx_complete_irq ();
136106 }
137107#endif
138108#endif
@@ -143,12 +113,7 @@ inline void store_char(unsigned char c, HardwareSerial *s)
143113 #define serialEvent1_implemented
144114 ISR (USART1_RX_vect)
145115 {
146- if (bit_is_clear (UCSR1A, UPE1)) {
147- unsigned char c = UDR1;
148- store_char (c, &Serial1);
149- } else {
150- unsigned char c = UDR1;
151- };
116+ Serial1._rx_complete_irq ();
152117 }
153118#endif
154119
@@ -158,12 +123,7 @@ inline void store_char(unsigned char c, HardwareSerial *s)
158123 #define serialEvent2_implemented
159124 ISR (USART2_RX_vect)
160125 {
161- if (bit_is_clear (UCSR2A, UPE2)) {
162- unsigned char c = UDR2;
163- store_char (c, &Serial2);
164- } else {
165- unsigned char c = UDR2;
166- };
126+ Serial2._rx_complete_irq ();
167127 }
168128#endif
169129
@@ -173,12 +133,7 @@ inline void store_char(unsigned char c, HardwareSerial *s)
173133 #define serialEvent3_implemented
174134 ISR (USART3_RX_vect)
175135 {
176- if (bit_is_clear (UCSR3A, UPE3)) {
177- unsigned char c = UDR3;
178- store_char (c, &Serial3);
179- } else {
180- unsigned char c = UDR3;
181- };
136+ Serial3._rx_complete_irq ();
182137 }
183138#endif
184139
@@ -215,81 +170,71 @@ ISR(USART0_UDRE_vect)
215170ISR (USART_UDRE_vect)
216171#endif
217172{
218- if (Serial._tx_buffer_head == Serial._tx_buffer_tail ) {
219- // Buffer empty, so disable interrupts
220- #if defined(UCSR0B)
221- cbi (UCSR0B, UDRIE0);
222- #else
223- cbi (UCSRB, UDRIE);
224- #endif
225- }
226- else {
227- // There is more data in the output buffer. Send the next byte
228- unsigned char c = Serial._tx_buffer [Serial._tx_buffer_tail ];
229- Serial._tx_buffer_tail = (Serial._tx_buffer_tail + 1 ) % SERIAL_BUFFER_SIZE;
230-
231- #if defined(UDR0)
232- UDR0 = c;
233- #elif defined(UDR)
234- UDR = c;
235- #else
236- #error UDR not defined
237- #endif
238- }
173+ Serial._tx_udr_empty_irq ();
239174}
240175#endif
241176#endif
242177
243178#ifdef USART1_UDRE_vect
244179ISR (USART1_UDRE_vect)
245180{
246- if (Serial1._tx_buffer_head == Serial1._tx_buffer_tail ) {
247- // Buffer empty, so disable interrupts
248- cbi (UCSR1B, UDRIE1);
249- }
250- else {
251- // There is more data in the output buffer. Send the next byte
252- unsigned char c = Serial1._tx_buffer [Serial1._tx_buffer_tail ];
253- Serial1._tx_buffer_tail = (Serial1._tx_buffer_tail + 1 ) % SERIAL_BUFFER_SIZE;
254-
255- UDR1 = c;
256- }
181+ Serial1._tx_udr_empty_irq ();
257182}
258183#endif
259184
260185#ifdef USART2_UDRE_vect
261186ISR (USART2_UDRE_vect)
262187{
263- if (Serial2._tx_buffer_head == Serial2._tx_buffer_tail ) {
264- // Buffer empty, so disable interrupts
265- cbi (UCSR2B, UDRIE2);
266- }
267- else {
268- // There is more data in the output buffer. Send the next byte
269- unsigned char c = Serial2._tx_buffer [Serial2._tx_buffer_tail ];
270- Serial2._tx_buffer_tail = (Serial2._tx_buffer_tail + 1 ) % SERIAL_BUFFER_SIZE;
271-
272- UDR2 = c;
273- }
188+ Serial2._tx_udr_empty_irq ();
274189}
275190#endif
276191
277192#ifdef USART3_UDRE_vect
278193ISR (USART3_UDRE_vect)
279194{
280- if (Serial3._tx_buffer_head == Serial3._tx_buffer_tail ) {
281- // Buffer empty, so disable interrupts
282- cbi (UCSR3B, UDRIE3);
195+ Serial3._tx_udr_empty_irq ();
196+ }
197+ #endif
198+
199+
200+ // Actual interrupt handlers //////////////////////////////////////////////////////////////
201+
202+ void HardwareSerial::_rx_complete_irq (void )
203+ {
204+ if (bit_is_clear (*_ucsra, UPE0)) {
205+ // No Parity error, read byte and store it in the buffer if there is
206+ // room
207+ unsigned char c = *_udr;
208+ int i = (unsigned int )(_rx_buffer_head + 1 ) % SERIAL_BUFFER_SIZE;
209+
210+ // if we should be storing the received character into the location
211+ // just before the tail (meaning that the head would advance to the
212+ // current location of the tail), we're about to overflow the buffer
213+ // and so we don't write the character or advance the head.
214+ if (i != _rx_buffer_tail) {
215+ _rx_buffer[_rx_buffer_head] = c;
216+ _rx_buffer_head = i;
217+ }
218+ } else {
219+ // Parity error, read byte but discard it
220+ unsigned char c = *_udr;
221+ };
222+ }
223+
224+ void HardwareSerial::_tx_udr_empty_irq (void )
225+ {
226+ if (_tx_buffer_head == _tx_buffer_tail) {
227+ // Buffer empty, so disable interrupts
228+ cbi (*_ucsrb, UDRIE0);
283229 }
284230 else {
285231 // There is more data in the output buffer. Send the next byte
286- unsigned char c = Serial3. _tx_buffer [Serial3. _tx_buffer_tail ];
287- Serial3. _tx_buffer_tail = (Serial3. _tx_buffer_tail + 1 ) % SERIAL_BUFFER_SIZE;
288-
289- UDR3 = c;
232+ unsigned char c = _tx_buffer[_tx_buffer_tail];
233+ _tx_buffer_tail = (_tx_buffer_tail + 1 ) % SERIAL_BUFFER_SIZE;
234+
235+ *_udr = c;
290236 }
291237}
292- #endif
293238
294239// Constructors ////////////////////////////////////////////////////////////////
295240
0 commit comments