diff options
Diffstat (limited to 'cores/arduino/HardwareSerial.h')
-rw-r--r-- | cores/arduino/HardwareSerial.h | 122 |
1 files changed, 79 insertions, 43 deletions
diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h index a73117f..7dc2aa9 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,31 @@ #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. +// NOTE: a "power of 2" buffer size is reccomended to dramatically +// optimize all the modulo operations for ring buffers. +#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 +80,70 @@ 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); + 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); } + 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)); |