From e609067202d7ef4cf7b99476fa2c8fda413b42c2 Mon Sep 17 00:00:00 2001 From: Jake <jake.read@cba.mit.edu> Date: Wed, 3 Jan 2024 18:21:35 -0500 Subject: [PATCH] next... --- rp2040_uart/2024-03_rp2040-uart.md | 62 +++++++++++++++++++ .../uart_pio_earle_tx_rx.ino | 2 - 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/rp2040_uart/2024-03_rp2040-uart.md b/rp2040_uart/2024-03_rp2040-uart.md index 45fe1e4..577fc5e 100644 --- a/rp2040_uart/2024-03_rp2040-uart.md +++ b/rp2040_uart/2024-03_rp2040-uart.md @@ -73,6 +73,68 @@ OK, I have this up and running: I am streaming at a fixed BAUD, then counting th So, I'm not convinced that I haven't fuxd anything here... it seems wild that we would have such a bottleneck to performance, and there are a few red flags here; namely that we have a lower bound of 11us between transmits, which would also explain our increasing error rate when we surpass 1 Mbit/sec (as the byte-wise period there is 10us or so). +At this point, I'm tempted to return to my old SAMD51 friend, who I know can do things ~ of this nature, fully ISR-d out, with no Flash-Code-Confusion, etc. But I'm also convinced that something is totally broken with the code that I'm operating with at the moment. + +To start, there is this oddity in all of earle's code: + +```cpp +int SerialPIO::read() { + // THE MUTEX ????? + CoreMutex m(&_mutex); + if (!_running || !m || (_rx == NOPIN)) { + return -1; + } + if (_writer != _reader) { + auto ret = _queue[_reader]; + asm volatile("" ::: "memory"); // Ensure the value is read before advancing + auto next_reader = (_reader + 1) % _fifoSize; + asm volatile("" ::: "memory"); // Ensure the reader value is only written once, correctly + _reader = next_reader; + return ret; + } + return -1; +} +``` + +Esp. the `CoreMutex` instantation, but also just that it's pretty bloated. Also the TX line is blocking, unless the PIO put_blocking doesn't actually block until the tx FIFO is clear, + +```cpp +size_t SerialPIO::write(uint8_t c) { + CoreMutex m(&_mutex); + if (!_running || !m || (_tx == NOPIN)) { + return 0; + } + + uint32_t val = c; + if (_parity == UART_PARITY_NONE) { + val |= 7 << _bits; // Set 2 stop bits, the HW will only transmit the required number + } else if (_parity == UART_PARITY_EVEN) { + val |= ::_parity(_bits, c) << _bits; + val |= 7 << (_bits + 1); + } else { + val |= (1 ^ ::_parity(_bits, c)) << _bits; + val |= 7 << (_bits + 1); + } + val <<= 1; // Start bit = low + + pio_sm_put_blocking(_txPIO, _txSM, _txInverted ? ~val : val); + + return 1; +} +``` + +Well - this [only blocks if the FIFO is full](https://cec-code-lab.aps.edu/robotics/resources/pico-c-api/group__hardware__pio.html), but the mutex aught to be adding some pretty bogus time. + +In summary - I think it's other peoples' not-bespoke code hell again, and I want out of it. Abandoning this means falling back to the D51, which *I know* can do this, but it would mean that circuit building would get a lot more difficult, and basically the whole lab is on RP2040's. + +So, we should go a little more hardo at this. + +### UART TX/RX with Modified Earle Code + +I'll try it my copy-pasta'ing the earle code, to see if I can remove some of the layers-of-abstraction cruft. + + + --- ### Not in Flash diff --git a/rp2040_uart/code/uart_pio_earle_tx_rx/uart_pio_earle_tx_rx.ino b/rp2040_uart/code/uart_pio_earle_tx_rx/uart_pio_earle_tx_rx.ino index 6d34a41..575189e 100644 --- a/rp2040_uart/code/uart_pio_earle_tx_rx/uart_pio_earle_tx_rx.ino +++ b/rp2040_uart/code/uart_pio_earle_tx_rx/uart_pio_earle_tx_rx.ino @@ -78,8 +78,6 @@ void loop(void){ uint32_t txInterval = txTime - lastTx; lastTx = txTime; intervalEstimate = (float)txInterval * 0.01F + intervalEstimate * 0.99F; - // while(serial.availableForWrite()){ - // } } // ... -- GitLab