diff --git a/cores/rp2040/SerialPIO.cpp b/cores/rp2040/SerialPIO.cpp index b8a09de..a024d52 100644 --- a/cores/rp2040/SerialPIO.cpp +++ b/cores/rp2040/SerialPIO.cpp @@ -127,7 +127,7 @@ void __not_in_flash_func(SerialPIO::_handleIRQ)() { SerialPIO::SerialPIO(pin_size_t tx, pin_size_t rx, size_t fifosize) { _tx = tx; _rx = rx; - _fifosize = fifosize; + _fifosize = fifosize + 1; // Always one unused entry _queue = new uint8_t[_fifosize]; mutex_init(&_mutex); } diff --git a/cores/rp2040/SerialUART.cpp b/cores/rp2040/SerialUART.cpp index c87d01b..f695e36 100644 --- a/cores/rp2040/SerialUART.cpp +++ b/cores/rp2040/SerialUART.cpp @@ -65,6 +65,14 @@ bool SerialUART::setTX(pin_size_t pin) { 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) { _uart = uart; _tx = tx; @@ -76,6 +84,7 @@ static void _uart0IRQ(); static void _uart1IRQ(); void SerialUART::begin(unsigned long baud, uint16_t config) { + _queue = new uint8_t[_fifoSize]; _baud = baud; uart_init(_uart, baud); int bits, stop; @@ -140,6 +149,7 @@ void SerialUART::end() { irq_set_enabled(UART1_IRQ, false); } uart_deinit(_uart); + delete[] _queue; _running = false; } @@ -170,7 +180,7 @@ int SerialUART::read() { while ((now - start) < _timeout) { if (_writer != _reader) { auto ret = _queue[_reader]; - _reader = (_reader + 1) % sizeof(_queue); + _reader = (_reader + 1) % _fifoSize; return ret; } delay(1); @@ -184,7 +194,7 @@ int SerialUART::available() { if (!_running || !m) { return 0; } - return (_writer - _reader) % sizeof(_queue); + return (_writer - _reader) % _fifoSize; } int SerialUART::availableForWrite() { @@ -250,10 +260,10 @@ void __not_in_flash_func(SerialUART::_handleIRQ)() { uart_get_hw(_uart)->icr |= UART_UARTICR_RTIC_BITS | UART_UARTICR_RXIC_BITS; while (uart_is_readable(_uart)) { auto val = uart_getc(_uart); - if ((_writer + 1) % sizeof(_queue) != _reader) { + if ((_writer + 1) % _fifoSize != _reader) { _queue[_writer] = val; asm volatile("" ::: "memory"); // Ensure the queue is written before the written count advances - _writer = (_writer + 1) % sizeof(_queue); + _writer = (_writer + 1) % _fifoSize; } else { // TODO: Overflow } diff --git a/cores/rp2040/SerialUART.h b/cores/rp2040/SerialUART.h index f5a8099..e6c2357 100644 --- a/cores/rp2040/SerialUART.h +++ b/cores/rp2040/SerialUART.h @@ -40,6 +40,7 @@ public: ret &= setTX(tx); return ret; } + bool setFIFOSize(size_t size); void begin(unsigned long baud = 115200) override { begin(baud, SERIAL_8N1); @@ -70,7 +71,8 @@ private: // Lockless, IRQ-handled circular queue uint32_t _writer; uint32_t _reader; - uint8_t _queue[32]; + size_t _fifoSize = 32; + uint8_t *_queue; }; extern SerialUART Serial1; // HW UART 0 diff --git a/docs/serial.rst b/docs/serial.rst index b8be658..7ef5b23 100644 --- a/docs/serial.rst +++ b/docs/serial.rst @@ -24,5 +24,12 @@ Configure their pins using the ``setXXX`` calls prior to calling ``begin()`` Serial1.setTX(pin); 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 Arduino `Serial Reference `_ . diff --git a/keywords.txt b/keywords.txt index 5aa6337..f6f4d83 100644 --- a/keywords.txt +++ b/keywords.txt @@ -34,3 +34,4 @@ resumeOtherCore KEYWORD2 PIOProgram KEYWORD2 prepare KEYWORD2 SerialPIO KEYWORD2 +setFIFOSize KEYWORD2