Unverified Commit 576f8941 authored by Earle F. Philhower, III's avatar Earle F. Philhower, III Committed by GitHub

Add setFIFOSize to UART Serial ports (#410)

Allow setting the size of the receive buffer by the application using a
call to Serial1/2.setFIFOSize(xxx) before the begin() call.
parent 039cbcf2
...@@ -127,7 +127,7 @@ void __not_in_flash_func(SerialPIO::_handleIRQ)() { ...@@ -127,7 +127,7 @@ void __not_in_flash_func(SerialPIO::_handleIRQ)() {
SerialPIO::SerialPIO(pin_size_t tx, pin_size_t rx, size_t fifosize) { SerialPIO::SerialPIO(pin_size_t tx, pin_size_t rx, size_t fifosize) {
_tx = tx; _tx = tx;
_rx = rx; _rx = rx;
_fifosize = fifosize; _fifosize = fifosize + 1; // Always one unused entry
_queue = new uint8_t[_fifosize]; _queue = new uint8_t[_fifosize];
mutex_init(&_mutex); mutex_init(&_mutex);
} }
......
...@@ -65,6 +65,14 @@ bool SerialUART::setTX(pin_size_t pin) { ...@@ -65,6 +65,14 @@ bool SerialUART::setTX(pin_size_t pin) {
return false; return false;
} }
bool SerialUART::setFIFOSize(size_t size) {
if (!size || _running) {
return false;
}
_fifoSize = size + 1; // Always 1 unused entry
return true;
}
SerialUART::SerialUART(uart_inst_t *uart, pin_size_t tx, pin_size_t rx) { SerialUART::SerialUART(uart_inst_t *uart, pin_size_t tx, pin_size_t rx) {
_uart = uart; _uart = uart;
_tx = tx; _tx = tx;
...@@ -76,6 +84,7 @@ static void _uart0IRQ(); ...@@ -76,6 +84,7 @@ static void _uart0IRQ();
static void _uart1IRQ(); static void _uart1IRQ();
void SerialUART::begin(unsigned long baud, uint16_t config) { void SerialUART::begin(unsigned long baud, uint16_t config) {
_queue = new uint8_t[_fifoSize];
_baud = baud; _baud = baud;
uart_init(_uart, baud); uart_init(_uart, baud);
int bits, stop; int bits, stop;
...@@ -140,6 +149,7 @@ void SerialUART::end() { ...@@ -140,6 +149,7 @@ void SerialUART::end() {
irq_set_enabled(UART1_IRQ, false); irq_set_enabled(UART1_IRQ, false);
} }
uart_deinit(_uart); uart_deinit(_uart);
delete[] _queue;
_running = false; _running = false;
} }
...@@ -170,7 +180,7 @@ int SerialUART::read() { ...@@ -170,7 +180,7 @@ int SerialUART::read() {
while ((now - start) < _timeout) { while ((now - start) < _timeout) {
if (_writer != _reader) { if (_writer != _reader) {
auto ret = _queue[_reader]; auto ret = _queue[_reader];
_reader = (_reader + 1) % sizeof(_queue); _reader = (_reader + 1) % _fifoSize;
return ret; return ret;
} }
delay(1); delay(1);
...@@ -184,7 +194,7 @@ int SerialUART::available() { ...@@ -184,7 +194,7 @@ int SerialUART::available() {
if (!_running || !m) { if (!_running || !m) {
return 0; return 0;
} }
return (_writer - _reader) % sizeof(_queue); return (_writer - _reader) % _fifoSize;
} }
int SerialUART::availableForWrite() { int SerialUART::availableForWrite() {
...@@ -250,10 +260,10 @@ void __not_in_flash_func(SerialUART::_handleIRQ)() { ...@@ -250,10 +260,10 @@ void __not_in_flash_func(SerialUART::_handleIRQ)() {
uart_get_hw(_uart)->icr |= UART_UARTICR_RTIC_BITS | UART_UARTICR_RXIC_BITS; uart_get_hw(_uart)->icr |= UART_UARTICR_RTIC_BITS | UART_UARTICR_RXIC_BITS;
while (uart_is_readable(_uart)) { while (uart_is_readable(_uart)) {
auto val = uart_getc(_uart); auto val = uart_getc(_uart);
if ((_writer + 1) % sizeof(_queue) != _reader) { if ((_writer + 1) % _fifoSize != _reader) {
_queue[_writer] = val; _queue[_writer] = val;
asm volatile("" ::: "memory"); // Ensure the queue is written before the written count advances asm volatile("" ::: "memory"); // Ensure the queue is written before the written count advances
_writer = (_writer + 1) % sizeof(_queue); _writer = (_writer + 1) % _fifoSize;
} else { } else {
// TODO: Overflow // TODO: Overflow
} }
......
...@@ -40,6 +40,7 @@ public: ...@@ -40,6 +40,7 @@ public:
ret &= setTX(tx); ret &= setTX(tx);
return ret; return ret;
} }
bool setFIFOSize(size_t size);
void begin(unsigned long baud = 115200) override { void begin(unsigned long baud = 115200) override {
begin(baud, SERIAL_8N1); begin(baud, SERIAL_8N1);
...@@ -70,7 +71,8 @@ private: ...@@ -70,7 +71,8 @@ private:
// Lockless, IRQ-handled circular queue // Lockless, IRQ-handled circular queue
uint32_t _writer; uint32_t _writer;
uint32_t _reader; uint32_t _reader;
uint8_t _queue[32]; size_t _fifoSize = 32;
uint8_t *_queue;
}; };
extern SerialUART Serial1; // HW UART 0 extern SerialUART Serial1; // HW UART 0
......
...@@ -24,5 +24,12 @@ Configure their pins using the ``setXXX`` calls prior to calling ``begin()`` ...@@ -24,5 +24,12 @@ Configure their pins using the ``setXXX`` calls prior to calling ``begin()``
Serial1.setTX(pin); Serial1.setTX(pin);
Serial1.begin(baud); Serial1.begin(baud);
The size of the receive FIFO may also be adjusted from the default 32 bytes by
using the ``setFIFOSize`` call prior to calling ``begin()``
.. code:: cpp
Serial1.setFIFOSize(128);
Serial1.begin(baud);
For detailed information about the Serial ports, see the For detailed information about the Serial ports, see the
Arduino `Serial Reference <https://www.arduino.cc/reference/en/language/functions/communication/serial/>`_ . Arduino `Serial Reference <https://www.arduino.cc/reference/en/language/functions/communication/serial/>`_ .
...@@ -34,3 +34,4 @@ resumeOtherCore KEYWORD2 ...@@ -34,3 +34,4 @@ resumeOtherCore KEYWORD2
PIOProgram KEYWORD2 PIOProgram KEYWORD2
prepare KEYWORD2 prepare KEYWORD2
SerialPIO KEYWORD2 SerialPIO KEYWORD2
setFIFOSize KEYWORD2
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment