aboutsummaryrefslogtreecommitdiff
path: root/cores/arduino/HardwareSerial.h
diff options
context:
space:
mode:
Diffstat (limited to 'cores/arduino/HardwareSerial.h')
-rw-r--r--cores/arduino/HardwareSerial.h43
1 files changed, 35 insertions, 8 deletions
diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h
index 226bf57..1beafc5 100644
--- a/cores/arduino/HardwareSerial.h
+++ b/cores/arduino/HardwareSerial.h
@@ -32,10 +32,36 @@
// using a ring buffer (I think), in which head is the index of the location
// to which to write the next incoming character and tail is the index of the
// location from which to read.
+// NOTE: a "power of 2" buffer size is reccomended to dramatically
+// optimize all the modulo operations for ring buffers.
+// WARNING: When buffer sizes are increased to > 256, the buffer index
+// variables are automatically increased in size, but the extra
+// atomicity guards needed for that are not implemented. This will
+// often work, but occasionally a race condition can occur that makes
+// Serial behave erratically. See https://github.com/arduino/Arduino/issues/2405
+#if !defined(SERIAL_TX_BUFFER_SIZE)
#if (RAMEND < 1000)
- #define SERIAL_BUFFER_SIZE 16
+#define SERIAL_TX_BUFFER_SIZE 16
#else
- #define SERIAL_BUFFER_SIZE 64
+#define SERIAL_TX_BUFFER_SIZE 64
+#endif
+#endif
+#if !defined(SERIAL_RX_BUFFER_SIZE)
+#if (RAMEND < 1000)
+#define SERIAL_RX_BUFFER_SIZE 16
+#else
+#define SERIAL_RX_BUFFER_SIZE 64
+#endif
+#endif
+#if (SERIAL_TX_BUFFER_SIZE>256)
+typedef uint16_t tx_buffer_index_t;
+#else
+typedef uint8_t tx_buffer_index_t;
+#endif
+#if (SERIAL_RX_BUFFER_SIZE>256)
+typedef uint16_t rx_buffer_index_t;
+#else
+typedef uint8_t rx_buffer_index_t;
#endif
// Define config for Serial.begin(baud, config);
@@ -76,16 +102,16 @@ class HardwareSerial : public Stream
// Has any byte been written to the UART since begin()
bool _written;
- volatile uint8_t _rx_buffer_head;
- volatile uint8_t _rx_buffer_tail;
- volatile uint8_t _tx_buffer_head;
- volatile uint8_t _tx_buffer_tail;
+ volatile rx_buffer_index_t _rx_buffer_head;
+ volatile rx_buffer_index_t _rx_buffer_tail;
+ volatile tx_buffer_index_t _tx_buffer_head;
+ volatile tx_buffer_index_t _tx_buffer_tail;
// Don't put any members after these buffers, since only the first
// 32 bytes of this struct can be accessed quickly using the ldd
// instruction.
- unsigned char _rx_buffer[SERIAL_BUFFER_SIZE];
- unsigned char _tx_buffer[SERIAL_BUFFER_SIZE];
+ unsigned char _rx_buffer[SERIAL_RX_BUFFER_SIZE];
+ unsigned char _tx_buffer[SERIAL_TX_BUFFER_SIZE];
public:
inline HardwareSerial(
@@ -98,6 +124,7 @@ class HardwareSerial : public Stream
virtual int available(void);
virtual int peek(void);
virtual int read(void);
+ int availableForWrite(void);
virtual void flush(void);
virtual size_t write(uint8_t);
inline size_t write(unsigned long n) { return write((uint8_t)n); }