Skip to content

Commit 4055ac1

Browse files
committed
Applied HardwareSerial updates to robot's core.
1 parent ae4427f commit 4055ac1

File tree

3 files changed

+67
-86
lines changed

3 files changed

+67
-86
lines changed

hardware/arduino/avr/cores/robot/HardwareSerial.cpp

Lines changed: 41 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -49,55 +49,17 @@
4949
#endif
5050
#endif
5151

52-
// Define constants and variables for buffering incoming serial data. We're
53-
// using a ring buffer (I think), in which head is the index of the location
54-
// to which to write the next incoming character and tail is the index of the
55-
// location from which to read.
56-
#if (RAMEND < 1000)
57-
#define SERIAL_BUFFER_SIZE 16
58-
#else
59-
#define SERIAL_BUFFER_SIZE 64
60-
#endif
61-
62-
struct ring_buffer
52+
inline void store_char(unsigned char c, HardwareSerial *s)
6353
{
64-
unsigned char buffer[SERIAL_BUFFER_SIZE];
65-
volatile unsigned int head;
66-
volatile unsigned int tail;
67-
};
68-
69-
#if defined(USBCON)
70-
ring_buffer rx_buffer = { { 0 }, 0, 0};
71-
ring_buffer tx_buffer = { { 0 }, 0, 0};
72-
#endif
73-
#if defined(UBRRH) || defined(UBRR0H)
74-
ring_buffer rx_buffer = { { 0 }, 0, 0 };
75-
ring_buffer tx_buffer = { { 0 }, 0, 0 };
76-
#endif
77-
#if defined(UBRR1H)
78-
ring_buffer rx_buffer1 = { { 0 }, 0, 0 };
79-
ring_buffer tx_buffer1 = { { 0 }, 0, 0 };
80-
#endif
81-
#if defined(UBRR2H)
82-
ring_buffer rx_buffer2 = { { 0 }, 0, 0 };
83-
ring_buffer tx_buffer2 = { { 0 }, 0, 0 };
84-
#endif
85-
#if defined(UBRR3H)
86-
ring_buffer rx_buffer3 = { { 0 }, 0, 0 };
87-
ring_buffer tx_buffer3 = { { 0 }, 0, 0 };
88-
#endif
89-
90-
inline void store_char(unsigned char c, ring_buffer *buffer)
91-
{
92-
int i = (unsigned int)(buffer->head + 1) % SERIAL_BUFFER_SIZE;
54+
int i = (unsigned int)(s->_rx_buffer_head + 1) % SERIAL_BUFFER_SIZE;
9355

9456
// if we should be storing the received character into the location
9557
// just before the tail (meaning that the head would advance to the
9658
// current location of the tail), we're about to overflow the buffer
9759
// and so we don't write the character or advance the head.
98-
if (i != buffer->tail) {
99-
buffer->buffer[buffer->head] = c;
100-
buffer->head = i;
60+
if (i != s->_rx_buffer_tail) {
61+
s->_rx_buffer[s->_rx_buffer_head] = c;
62+
s->_rx_buffer_head = i;
10163
}
10264
}
10365

@@ -122,7 +84,7 @@ inline void store_char(unsigned char c, ring_buffer *buffer)
12284
#if defined(UDR0)
12385
if (bit_is_clear(UCSR0A, UPE0)) {
12486
unsigned char c = UDR0;
125-
store_char(c, &rx_buffer);
87+
store_char(c, &Serial);
12688
} else {
12789
unsigned char c = UDR0;
12890
};
@@ -148,7 +110,7 @@ inline void store_char(unsigned char c, ring_buffer *buffer)
148110
{
149111
if (bit_is_clear(UCSR1A, UPE1)) {
150112
unsigned char c = UDR1;
151-
store_char(c, &rx_buffer1);
113+
store_char(c, &Serial1);
152114
} else {
153115
unsigned char c = UDR1;
154116
};
@@ -163,7 +125,7 @@ inline void store_char(unsigned char c, ring_buffer *buffer)
163125
{
164126
if (bit_is_clear(UCSR2A, UPE2)) {
165127
unsigned char c = UDR2;
166-
store_char(c, &rx_buffer2);
128+
store_char(c, &Serial2);
167129
} else {
168130
unsigned char c = UDR2;
169131
};
@@ -178,7 +140,7 @@ inline void store_char(unsigned char c, ring_buffer *buffer)
178140
{
179141
if (bit_is_clear(UCSR3A, UPE3)) {
180142
unsigned char c = UDR3;
181-
store_char(c, &rx_buffer3);
143+
store_char(c, &Serial3);
182144
} else {
183145
unsigned char c = UDR3;
184146
};
@@ -218,7 +180,7 @@ ISR(USART0_UDRE_vect)
218180
ISR(USART_UDRE_vect)
219181
#endif
220182
{
221-
if (tx_buffer.head == tx_buffer.tail) {
183+
if (Serial._tx_buffer_head == Serial._tx_buffer_tail) {
222184
// Buffer empty, so disable interrupts
223185
#if defined(UCSR0B)
224186
cbi(UCSR0B, UDRIE0);
@@ -228,8 +190,8 @@ ISR(USART_UDRE_vect)
228190
}
229191
else {
230192
// There is more data in the output buffer. Send the next byte
231-
unsigned char c = tx_buffer.buffer[tx_buffer.tail];
232-
tx_buffer.tail = (tx_buffer.tail + 1) % SERIAL_BUFFER_SIZE;
193+
unsigned char c = Serial._tx_buffer[Serial._tx_buffer_tail];
194+
Serial._tx_buffer_tail = (Serial._tx_buffer_tail + 1) % SERIAL_BUFFER_SIZE;
233195

234196
#if defined(UDR0)
235197
UDR0 = c;
@@ -246,14 +208,14 @@ ISR(USART_UDRE_vect)
246208
#ifdef USART1_UDRE_vect
247209
ISR(USART1_UDRE_vect)
248210
{
249-
if (tx_buffer1.head == tx_buffer1.tail) {
211+
if (Serial1._tx_buffer_head == Serial1._tx_buffer_tail) {
250212
// Buffer empty, so disable interrupts
251213
cbi(UCSR1B, UDRIE1);
252214
}
253215
else {
254216
// There is more data in the output buffer. Send the next byte
255-
unsigned char c = tx_buffer1.buffer[tx_buffer1.tail];
256-
tx_buffer1.tail = (tx_buffer1.tail + 1) % SERIAL_BUFFER_SIZE;
217+
unsigned char c = Serial1._tx_buffer[Serial1._tx_buffer_tail];
218+
Serial1._tx_buffer_tail = (Serial1._tx_buffer_tail + 1) % SERIAL_BUFFER_SIZE;
257219

258220
UDR1 = c;
259221
}
@@ -263,14 +225,14 @@ ISR(USART1_UDRE_vect)
263225
#ifdef USART2_UDRE_vect
264226
ISR(USART2_UDRE_vect)
265227
{
266-
if (tx_buffer2.head == tx_buffer2.tail) {
228+
if (Serial2._tx_buffer_head == Serial2._tx_buffer_tail) {
267229
// Buffer empty, so disable interrupts
268230
cbi(UCSR2B, UDRIE2);
269231
}
270232
else {
271233
// There is more data in the output buffer. Send the next byte
272-
unsigned char c = tx_buffer2.buffer[tx_buffer2.tail];
273-
tx_buffer2.tail = (tx_buffer2.tail + 1) % SERIAL_BUFFER_SIZE;
234+
unsigned char c = Serial2._tx_buffer[Serial2._tx_buffer_tail];
235+
Serial2._tx_buffer_tail = (Serial2._tx_buffer_tail + 1) % SERIAL_BUFFER_SIZE;
274236

275237
UDR2 = c;
276238
}
@@ -280,31 +242,30 @@ ISR(USART2_UDRE_vect)
280242
#ifdef USART3_UDRE_vect
281243
ISR(USART3_UDRE_vect)
282244
{
283-
if (tx_buffer3.head == tx_buffer3.tail) {
245+
if (Serial3._tx_buffer_head == Serial3._tx_buffer_tail) {
284246
// Buffer empty, so disable interrupts
285247
cbi(UCSR3B, UDRIE3);
286248
}
287249
else {
288250
// There is more data in the output buffer. Send the next byte
289-
unsigned char c = tx_buffer3.buffer[tx_buffer3.tail];
290-
tx_buffer3.tail = (tx_buffer3.tail + 1) % SERIAL_BUFFER_SIZE;
251+
unsigned char c = Serial3._tx_buffer[Serial3._tx_buffer_tail];
252+
Serial3._tx_buffer_tail = (Serial3._tx_buffer_tail + 1) % SERIAL_BUFFER_SIZE;
291253

292254
UDR3 = c;
293255
}
294256
}
295257
#endif
296258

297-
298259
// Constructors ////////////////////////////////////////////////////////////////
299260

300-
HardwareSerial::HardwareSerial(ring_buffer *rx_buffer, ring_buffer *tx_buffer,
261+
HardwareSerial::HardwareSerial(
301262
volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
302263
volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
303264
volatile uint8_t *ucsrc, volatile uint8_t *udr,
304265
uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udrie, uint8_t u2x)
305266
{
306-
_rx_buffer = rx_buffer;
307-
_tx_buffer = tx_buffer;
267+
_tx_buffer_head = _tx_buffer_tail = 0;
268+
_rx_buffer_head = _rx_buffer_tail = 0;
308269
_ubrrh = ubrrh;
309270
_ubrrl = ubrrl;
310271
_ucsra = ucsra;
@@ -412,7 +373,7 @@ void HardwareSerial::begin(unsigned long baud, byte config)
412373
void HardwareSerial::end()
413374
{
414375
// wait for transmission of outgoing data
415-
while (_tx_buffer->head != _tx_buffer->tail)
376+
while (_tx_buffer_head != _tx_buffer_tail)
416377
;
417378

418379
cbi(*_ucsrb, _rxen);
@@ -421,31 +382,31 @@ void HardwareSerial::end()
421382
cbi(*_ucsrb, _udrie);
422383

423384
// clear any received data
424-
_rx_buffer->head = _rx_buffer->tail;
385+
_rx_buffer_head = _rx_buffer_tail;
425386
}
426387

427388
int HardwareSerial::available(void)
428389
{
429-
return (unsigned int)(SERIAL_BUFFER_SIZE + _rx_buffer->head - _rx_buffer->tail) % SERIAL_BUFFER_SIZE;
390+
return (unsigned int)(SERIAL_BUFFER_SIZE + _rx_buffer_head - _rx_buffer_tail) % SERIAL_BUFFER_SIZE;
430391
}
431392

432393
int HardwareSerial::peek(void)
433394
{
434-
if (_rx_buffer->head == _rx_buffer->tail) {
395+
if (_rx_buffer_head == _rx_buffer_tail) {
435396
return -1;
436397
} else {
437-
return _rx_buffer->buffer[_rx_buffer->tail];
398+
return _rx_buffer[_rx_buffer_tail];
438399
}
439400
}
440401

441402
int HardwareSerial::read(void)
442403
{
443404
// if the head isn't ahead of the tail, we don't have any characters
444-
if (_rx_buffer->head == _rx_buffer->tail) {
405+
if (_rx_buffer_head == _rx_buffer_tail) {
445406
return -1;
446407
} else {
447-
unsigned char c = _rx_buffer->buffer[_rx_buffer->tail];
448-
_rx_buffer->tail = (unsigned int)(_rx_buffer->tail + 1) % SERIAL_BUFFER_SIZE;
408+
unsigned char c = _rx_buffer[_rx_buffer_tail];
409+
_rx_buffer_tail = (unsigned int)(_rx_buffer_tail + 1) % SERIAL_BUFFER_SIZE;
449410
return c;
450411
}
451412
}
@@ -459,16 +420,16 @@ void HardwareSerial::flush()
459420

460421
size_t HardwareSerial::write(uint8_t c)
461422
{
462-
int i = (_tx_buffer->head + 1) % SERIAL_BUFFER_SIZE;
423+
int i = (_tx_buffer_head + 1) % SERIAL_BUFFER_SIZE;
463424

464425
// If the output buffer is full, there's nothing for it other than to
465426
// wait for the interrupt handler to empty it a bit
466427
// ???: return 0 here instead?
467-
while (i == _tx_buffer->tail)
428+
while (i == _tx_buffer_tail)
468429
;
469430

470-
_tx_buffer->buffer[_tx_buffer->head] = c;
471-
_tx_buffer->head = i;
431+
_tx_buffer[_tx_buffer_head] = c;
432+
_tx_buffer_head = i;
472433

473434
sbi(*_ucsrb, _udrie);
474435
// clear the TXC bit -- "can be cleared by writing a one to its bit location"
@@ -485,23 +446,23 @@ HardwareSerial::operator bool() {
485446
// Preinstantiate Objects //////////////////////////////////////////////////////
486447

487448
#if defined(UBRRH) && defined(UBRRL)
488-
HardwareSerial Serial(&rx_buffer, &tx_buffer, &UBRRH, &UBRRL, &UCSRA, &UCSRB, &UCSRC, &UDR, RXEN, TXEN, RXCIE, UDRIE, U2X);
449+
HardwareSerial Serial(&UBRRH, &UBRRL, &UCSRA, &UCSRB, &UCSRC, &UDR, RXEN, TXEN, RXCIE, UDRIE, U2X);
489450
#elif defined(UBRR0H) && defined(UBRR0L)
490-
HardwareSerial Serial(&rx_buffer, &tx_buffer, &UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UCSR0C, &UDR0, RXEN0, TXEN0, RXCIE0, UDRIE0, U2X0);
451+
HardwareSerial Serial(&UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UCSR0C, &UDR0, RXEN0, TXEN0, RXCIE0, UDRIE0, U2X0);
491452
#elif defined(USBCON)
492453
// do nothing - Serial object and buffers are initialized in CDC code
493454
#else
494455
#error no serial port defined (port 0)
495456
#endif
496457

497458
#if defined(UBRR1H)
498-
HardwareSerial Serial1(&rx_buffer1, &tx_buffer1, &UBRR1H, &UBRR1L, &UCSR1A, &UCSR1B, &UCSR1C, &UDR1, RXEN1, TXEN1, RXCIE1, UDRIE1, U2X1);
459+
HardwareSerial Serial1(&UBRR1H, &UBRR1L, &UCSR1A, &UCSR1B, &UCSR1C, &UDR1, RXEN1, TXEN1, RXCIE1, UDRIE1, U2X1);
499460
#endif
500461
#if defined(UBRR2H)
501-
HardwareSerial Serial2(&rx_buffer2, &tx_buffer2, &UBRR2H, &UBRR2L, &UCSR2A, &UCSR2B, &UCSR2C, &UDR2, RXEN2, TXEN2, RXCIE2, UDRIE2, U2X2);
462+
HardwareSerial Serial2(&UBRR2H, &UBRR2L, &UCSR2A, &UCSR2B, &UCSR2C, &UDR2, RXEN2, TXEN2, RXCIE2, UDRIE2, U2X2);
502463
#endif
503464
#if defined(UBRR3H)
504-
HardwareSerial Serial3(&rx_buffer3, &tx_buffer3, &UBRR3H, &UBRR3L, &UCSR3A, &UCSR3B, &UCSR3C, &UDR3, RXEN3, TXEN3, RXCIE3, UDRIE3, U2X3);
465+
HardwareSerial Serial3(&UBRR3H, &UBRR3L, &UCSR3A, &UCSR3B, &UCSR3C, &UDR3, RXEN3, TXEN3, RXCIE3, UDRIE3, U2X3);
505466
#endif
506467

507468
#endif // whole file

hardware/arduino/avr/cores/robot/HardwareSerial.h

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,19 @@
2727

2828
#include "Stream.h"
2929

30-
struct ring_buffer;
30+
// Define constants and variables for buffering incoming serial data. We're
31+
// using a ring buffer (I think), in which head is the index of the location
32+
// to which to write the next incoming character and tail is the index of the
33+
// location from which to read.
34+
#if (RAMEND < 1000)
35+
#define SERIAL_BUFFER_SIZE 16
36+
#else
37+
#define SERIAL_BUFFER_SIZE 64
38+
#endif
3139

3240
class HardwareSerial : public Stream
3341
{
34-
private:
35-
ring_buffer *_rx_buffer;
36-
ring_buffer *_tx_buffer;
42+
protected:
3743
volatile uint8_t *_ubrrh;
3844
volatile uint8_t *_ubrrl;
3945
volatile uint8_t *_ucsra;
@@ -46,8 +52,20 @@ class HardwareSerial : public Stream
4652
uint8_t _udrie;
4753
uint8_t _u2x;
4854
bool transmitting;
55+
4956
public:
50-
HardwareSerial(ring_buffer *rx_buffer, ring_buffer *tx_buffer,
57+
volatile uint8_t _rx_buffer_head;
58+
volatile uint8_t _rx_buffer_tail;
59+
volatile uint8_t _tx_buffer_head;
60+
volatile uint8_t _tx_buffer_tail;
61+
62+
// Don't put any members after these buffers, since only the first
63+
// 32 bytes of this struct can be accessed quickly using the ldd
64+
// instruction.
65+
unsigned char _rx_buffer[SERIAL_BUFFER_SIZE];
66+
unsigned char _tx_buffer[SERIAL_BUFFER_SIZE];
67+
68+
HardwareSerial(
5169
volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
5270
volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
5371
volatile uint8_t *ucsrc, volatile uint8_t *udr,

hardware/arduino/avr/cores/robot/USBAPI.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ extern USBDevice_ USBDevice;
2525
//================================================================================
2626
// Serial over CDC (Serial1 is the physical port)
2727

28+
struct ring_buffer;
29+
2830
class Serial_ : public Stream
2931
{
3032
private:
@@ -193,4 +195,4 @@ void USB_Flush(uint8_t ep);
193195

194196
#endif
195197

196-
#endif /* if defined(USBCON) */
198+
#endif /* if defined(USBCON) */

0 commit comments

Comments
 (0)