litex
litex copied to clipboard
UART RXEMPTY register does not clear when last character is read
A simple loop of:
while (1) {
while (rd32(UART0_RXEMPTY) != 0) ;
printf("rx %02x\n", rd32(UART0_RXTX);
};
Will wait until one character arrives and then spin printing the same rx'd character over and over again.
To get RXEMPTY to reflect the new state one has to clear the RX bit in EV_PENDING.
Is this intentional? It's relatively unusual peripheral behavior for the state/status registers to not reflect current status.
Expected behaviour (assuming the rx fifo is initially empty):
When a character arrives:
- RXEMPTY becomes nonzero
- EV_STATUS.RX becomes set
- EV_PENDING.RX becomes set
- the IRQ is asserted if EV_ENABLE.RX is set
When that character is read from RXTX and the fifo is again empty:
- RXEMPTY becomes zero
- EV_STATUS.RX becomes cleared
- EV_PENDING.RX remains set (and IRQ asserted) until cleared by a software write
Thanks for the feedback @swetland, setting rx_fifo_rx_we to True here: https://github.com/enjoy-digital/litex/blob/master/litex/soc/cores/uart.py#L219 should provide the behaviour you are expecting, could you do a test?
I can confirm that this does indeed result in RXEMPTY becoming nonzero when the last character is read from the fifo. Thanks!
The bios firmware does not appear to be impacted by the change (probably because it's doing interrupt driven UART io rather than polling, so I suspect it never looks at RXEMPTY). Serial console and serial boot continue to work as expected.
Good, thanks. I'll have a closer look at this to see this if this could make sense to default to this behaviour.