Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UART interrupts incompletely enabled for FIFO mode #500

Closed
MustBeArt opened this issue Jun 29, 2021 · 3 comments · Fixed by #504
Closed

UART interrupts incompletely enabled for FIFO mode #500

MustBeArt opened this issue Jun 29, 2021 · 3 comments · Fixed by #504

Comments

@MustBeArt
Copy link

Using the SDK interface routines to the UART, enabling FIFO mode doesn't work correctly on receive.

Symptom: the last few characters of a burst are not received promptly.

Explanation: uart_set_irq_enables() only enables the receive data ready interrupt for receive. In FIFO mode, that interrupt only fires when the receive FIFO fills up to the threshold. If a few more characters are received, but not enough to reach the FIFO threshold, that does not trigger another receive data ready interrupt (see 4.2.6.2 of the RP2040 data sheet). In order to get an interrupt for those last few characters, we also need to enable the receive timeout interrupt (see 4.2.6.4).

Proposed solution: in uart_set_irq_enables():

    uart_get_hw(uart)->imsc = (!!tx_needs_data << UART_UARTIMSC_TXIM_LSB) |
                              (!!rx_has_data << UART_UARTIMSC_RXIM_LSB) |
                              (!!rx_has_data << UART_UARTIMSC_RTIM_LSB);  // <--- there it is
@lurch
Copy link
Contributor

lurch commented Jun 29, 2021

Interesting...
4.2.7. in the RP2040 datasheet shows that the FIFOs are enabled, https://github.com/raspberrypi/pico-sdk/blob/develop/src/rp2_common/hardware_uart/include/hardware/uart.h#L216 shows that the UARTIFLS_RXIFLSEL is set to 0, the register-description for UARTIFLS says that a RXIFSEL of 0 triggers the receive interrupt when "Receive FIFO
becomes >= 1 / 8 full", and the UART introduction says "Separate 32x8 Tx and 32x12 Rx FIFOs".

All of which combined (using my naive understanding), suggests that the receive interrupt will only trigger when the receive fifo contains at least 32 / 8 (i.e. 4) characters?

@kilograham Maybe we want a test similar to https://github.com/raspberrypi/pico-examples/blob/master/uart/uart_advanced/uart_advanced.c but which doesn't turn off the FIFOs?

@kilograham
Copy link
Contributor

cc @liamfraser @Wren6991

@Wren6991
Copy link
Contributor

Wren6991 commented Jul 9, 2021

4.2.6.4. UARTRTINTR The receive timeout interrupt is asserted when the receive FIFO is not empty, and no more data is received during a 32-bit period. The receive timeout interrupt is cleared either when the FIFO becomes empty through reading all the data (or by reading the holding register), or when a 1 is written to the corresponding bit of the Interrupt Clear Register, UARTICR

That does sound like what we want! Thanks, I'll open a PR.

MustBeArt added a commit to MustBeArt/SlowSoftSerial that referenced this issue Jul 28, 2021
Fixing this bug allows us to enable the FIFO on the UART

See raspberrypi/pico-sdk#500
Fixed in the SDK by raspberrypi/pico-sdk#504
Scheduled for merge in SDK 1.2.1.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants