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