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.h119
1 files changed, 76 insertions, 43 deletions
diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h
index a73117f..b96e5d0 100644
--- a/cores/arduino/HardwareSerial.h
+++ b/cores/arduino/HardwareSerial.h
@@ -18,6 +18,7 @@
Modified 28 September 2010 by Mark Sproul
Modified 14 August 2012 by Alarus
+ Modified 3 December 2013 by Matthijs Kooijman
*/
#ifndef HardwareSerial_h
@@ -27,46 +28,29 @@
#include "Stream.h"
-struct ring_buffer;
-
-class HardwareSerial : public Stream
-{
- private:
- ring_buffer *_rx_buffer;
- ring_buffer *_tx_buffer;
- volatile uint8_t *_ubrrh;
- volatile uint8_t *_ubrrl;
- volatile uint8_t *_ucsra;
- volatile uint8_t *_ucsrb;
- volatile uint8_t *_ucsrc;
- volatile uint8_t *_udr;
- uint8_t _rxen;
- uint8_t _txen;
- uint8_t _rxcie;
- uint8_t _udrie;
- uint8_t _u2x;
- bool transmitting;
- public:
- HardwareSerial(ring_buffer *rx_buffer, ring_buffer *tx_buffer,
- volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
- volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
- volatile uint8_t *ucsrc, volatile uint8_t *udr,
- uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udrie, uint8_t u2x);
- void begin(unsigned long);
- void begin(unsigned long, uint8_t);
- void end();
- virtual int available(void);
- virtual int peek(void);
- virtual int read(void);
- virtual void flush(void);
- virtual size_t write(uint8_t);
- inline size_t write(unsigned long n) { return write((uint8_t)n); }
- inline size_t write(long n) { return write((uint8_t)n); }
- inline size_t write(unsigned int n) { return write((uint8_t)n); }
- inline size_t write(int n) { return write((uint8_t)n); }
- using Print::write; // pull in write(str) and write(buf, size) from Print
- operator bool();
-};
+// Define constants and variables for buffering incoming serial data. We're
+// 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.
+#if !(defined(SERIAL_TX_BUFFER_SIZE) && defined(SERIAL_RX_BUFFER_SIZE))
+#if (RAMEND < 1000)
+#define SERIAL_TX_BUFFER_SIZE 16
+#define SERIAL_RX_BUFFER_SIZE 16
+#else
+#define SERIAL_TX_BUFFER_SIZE 64
+#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);
#define SERIAL_5N1 0x00
@@ -94,20 +78,69 @@ class HardwareSerial : public Stream
#define SERIAL_7O2 0x3C
#define SERIAL_8O2 0x3E
+class HardwareSerial : public Stream
+{
+ protected:
+ volatile uint8_t * const _ubrrh;
+ volatile uint8_t * const _ubrrl;
+ volatile uint8_t * const _ucsra;
+ volatile uint8_t * const _ucsrb;
+ volatile uint8_t * const _ucsrc;
+ volatile uint8_t * const _udr;
+ // Has any byte been written to the UART since begin()
+ bool _written;
+
+ 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_RX_BUFFER_SIZE];
+ unsigned char _tx_buffer[SERIAL_TX_BUFFER_SIZE];
+
+ public:
+ inline HardwareSerial(
+ volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
+ volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
+ volatile uint8_t *ucsrc, volatile uint8_t *udr);
+ void begin(unsigned long baud) { begin(baud, SERIAL_8N1); }
+ void begin(unsigned long, uint8_t);
+ void end();
+ virtual int available(void);
+ virtual int peek(void);
+ virtual int read(void);
+ virtual void flush(void);
+ virtual size_t write(uint8_t);
+ inline size_t write(unsigned long n) { return write((uint8_t)n); }
+ inline size_t write(long n) { return write((uint8_t)n); }
+ inline size_t write(unsigned int n) { return write((uint8_t)n); }
+ inline size_t write(int n) { return write((uint8_t)n); }
+ using Print::write; // pull in write(str) and write(buf, size) from Print
+ operator bool() { return true; }
+
+ // Interrupt handlers - Not intended to be called externally
+ inline void _rx_complete_irq(void);
+ void _tx_udr_empty_irq(void);
+};
+
#if defined(UBRRH) || defined(UBRR0H)
extern HardwareSerial Serial;
-#elif defined(USBCON)
- #include "USBAPI.h"
-// extern HardwareSerial Serial_;
+ #define HAVE_HWSERIAL0
#endif
#if defined(UBRR1H)
extern HardwareSerial Serial1;
+ #define HAVE_HWSERIAL1
#endif
#if defined(UBRR2H)
extern HardwareSerial Serial2;
+ #define HAVE_HWSERIAL2
#endif
#if defined(UBRR3H)
extern HardwareSerial Serial3;
+ #define HAVE_HWSERIAL3
#endif
extern void serialEventRun(void) __attribute__((weak));