I am using the LPUART and running into an issue when the UART is disabled. The LPUART doesn't notify the user callback that the buffer can be released. In my case, I am using the modem_backend_uart_async
with Zephyr's cellular modem driver. The modem_backend_uart_async
will internally mark its RX buffer as used on a UART_RX_BUF_REQUEST
and clear that on a UART_RX_BUF_RELEASED
. With the LPUART driver, when disable is called, the current RX buffer is not released, which causes modem_backend_uart_async
to not clear the used flag for that buffer.
This seems to be caused by how the LPUART driver always requests the next buffer when it enters the RX_TO_IDLE
state, but never calls to release it.
If I apply the following patch to force a UART_RX_BUF_RELEASED
on a disable, I no longer see the issue, and the modem_backend_uart_async
is fully able to stop:
--- a/drivers/serial/uart_nrf_sw_lpuart.c
+++ b/drivers/serial/uart_nrf_sw_lpuart.c
@@ -768,6 +770,20 @@ static int api_rx_disable(const struct device *dev)
return -EFAULT;
}
+ if (data->rx_state == RX_IDLE) {
+ struct uart_event event = {
+ .type = UART_RX_BUF_RELEASED,
+ .data = {
+ .rx_buf = {
+ .buf = data->rx_buf,
+ }
+ }
+ };
+
+ data->rx_buf = NULL;
+ user_callback(dev, &event);
+ }
+
data->rx_state = RX_TO_OFF;
err = uart_rx_disable(data->uart);
Is this an issue of the LPUART driver or is the intention to have the user (modem_backend_uart_async in this case) know that all the RX buffers are free on the UART_RX_DISABLED event.
nrfConnect 2.6.1 SDK running on a nrf5340.