From 43be9d0710fa678bb6c2295313e055fe65077d4c Mon Sep 17 00:00:00 2001 From: Roger Clark Date: Tue, 25 Nov 2014 21:11:04 +1100 Subject: [PATCH] Added support for serial functions in 1.0 and 1.5, specificaally Serial.peek and also Serial.find. Updated HardwareSerial class so it inhetits from Stream instead of Print, to confirm with Arduino 1.0 structure --- STM32F1XX/cores/maple/HardwareSerial.cpp | 21 +++++- STM32F1XX/cores/maple/HardwareSerial.h | 72 ++++++++++++++++--- .../libmaple/include/libmaple/ring_buffer.h | 20 ++++++ .../system/libmaple/include/libmaple/usart.h | 12 ++++ 4 files changed, 115 insertions(+), 10 deletions(-) diff --git a/STM32F1XX/cores/maple/HardwareSerial.cpp b/STM32F1XX/cores/maple/HardwareSerial.cpp index 5c9b0ec..f58abdf 100644 --- a/STM32F1XX/cores/maple/HardwareSerial.cpp +++ b/STM32F1XX/cores/maple/HardwareSerial.cpp @@ -137,17 +137,34 @@ void HardwareSerial::end(void) { * I/O */ -uint8 HardwareSerial::read(void) { +int HardwareSerial::read(void) { // Block until a byte becomes available, to save user confusion. while (!this->available()) ; return usart_getc(this->usart_device); } -uint32 HardwareSerial::available(void) { +int HardwareSerial::available(void) { return usart_data_available(this->usart_device); } +/* Roger Clark. Added function missing from LibMaple code */ + +int HardwareSerial::peek(void) +{ + return usart_getc(this->usart_device); +} + +int HardwareSerial::availableForWrite(void) +{ +/* Roger Clark. + * Currently there isn't an output ring buffer, chars are sent straight to the hardware. + * so just return 1, meaning that 1 char can be written + * This will be slower than a ring buffer implementation, but it should at least work ! + */ + return 1; +} + size_t HardwareSerial::write(unsigned char ch) { usart_putc(this->usart_device, ch); diff --git a/STM32F1XX/cores/maple/HardwareSerial.h b/STM32F1XX/cores/maple/HardwareSerial.h index 9f2ba13..4b0f2ac 100644 --- a/STM32F1XX/cores/maple/HardwareSerial.h +++ b/STM32F1XX/cores/maple/HardwareSerial.h @@ -48,9 +48,40 @@ * the documentation accordingly. */ + + +// 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 + struct usart_dev; -class HardwareSerial : public Print { +/* Roger clark. Changed class inheritance from Print to Stream. + * Also added new functions for peek() and availableForWrite() + * Note. AvailableForWrite is only a stub function in the cpp + */ +class HardwareSerial : public Stream { + public: HardwareSerial(struct usart_dev *usart_device, uint8 tx_pin, @@ -58,13 +89,17 @@ public: /* Set up/tear down */ void begin(uint32 baud); - void end(void); - - /* I/O */ - uint32 available(void); - uint8 read(void); - void flush(void); - virtual size_t write(unsigned char); + 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; /* Pin accessors */ @@ -80,6 +115,27 @@ private: struct usart_dev *usart_device; uint8 tx_pin; uint8 rx_pin; + protected: +#if 0 + 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]; +#endif }; #ifdef BOOTLOADER_maple diff --git a/STM32F1XX/system/libmaple/include/libmaple/ring_buffer.h b/STM32F1XX/system/libmaple/include/libmaple/ring_buffer.h index e02e6e7..eb38634 100644 --- a/STM32F1XX/system/libmaple/include/libmaple/ring_buffer.h +++ b/STM32F1XX/system/libmaple/include/libmaple/ring_buffer.h @@ -126,6 +126,26 @@ static inline uint8 rb_remove(ring_buffer *rb) { return ch; } +/* + * Roger Clark. 20141125, + * added peek function. + * @brief Return the first item from a ring buffer, without removing it + * @param rb Buffer to remove from, must contain at least one element. + */ + +static inline int rb_peek(ring_buffer *rb) +{ + if (rb->head == rb->tail) + { + return -1; + } + else + { + return rb->buf[rb->head]; + } +} + + /** * @brief Attempt to remove the first item from a ring buffer. * diff --git a/STM32F1XX/system/libmaple/include/libmaple/usart.h b/STM32F1XX/system/libmaple/include/libmaple/usart.h index 7d89a14..c85980c 100644 --- a/STM32F1XX/system/libmaple/include/libmaple/usart.h +++ b/STM32F1XX/system/libmaple/include/libmaple/usart.h @@ -473,6 +473,18 @@ static inline uint8 usart_getc(usart_dev *dev) { return rb_remove(dev->rb); } +/* + * Roger Clark. 20141125, + * added peek function. + * @param dev Serial port to read from + * @return byte read + */ +static inline int usart_peek(usart_dev *dev) +{ + return rb_peek(dev->rb); +} + + /** * @brief Return the amount of data available in a serial port's RX buffer. * @param dev Serial port to check