drivers: serial: uart_liteuart: fix interrupt-driven mode

Interrupt-driven mode was not working, and disabled by default.
When it was forced on, the behavior was to only have a few bytes:
as many as min(CONFIG_SHELL_BACKEND_SERIAL_TX_RING_BUFFER_SIZE, 9).

After the hardware FIFO was filled by software and emptied by hardware,
no interrupt occured, and enqueuing more data did never happen.

By letting the events enabled for TX (only), then interrupts are still
generated after the first transfer, and the software can then add the
subsequent transfers until all data is print: the UART works.

It does not generate endless interrupts either, which was tested by
adding litex_write8('%', UART_RXTX_ADDR) in liteuart_uart_irq_handler()
to log all interrupts events, and when there is nothing to print, no
interrupt is fired.

It was tested with the Zephyr shell.

Fixes #63794

Signed-off-by: Josuah Demangeon <me@josuah.net>
This commit is contained in:
Josuah Demangeon 2023-10-12 12:58:40 +02:00 committed by Carles Cufí
commit 2dce408bc3

View file

@ -273,8 +273,8 @@ static void liteuart_uart_irq_handler(const struct device *dev)
data->callback(dev, data->cb_data);
}
/* clear events */
litex_write8(UART_EV_TX | UART_EV_RX, UART_EV_PENDING_ADDR);
/* Clear RX events, TX events still needed to enqueue the next transfer */
litex_write8(UART_EV_RX, UART_EV_PENDING_ADDR);
irq_unlock(key);
}