Hello!
I'm using Zepyhr OS with nrf connect SDK v3.2.3 and the NRF54L15 hardware.
I am using UARTE with the async driver (direct memory access). This is my uart configuration (compiled dts):
uart20: uart@c6000 {
compatible = "nordic,nrf-uarte";
reg = < 0xc6000 0x1000 >;
interrupts = < 0xc6 0x1 >;
endtx-stoptx-supported;
frame-timeout-supported;
status = "okay";
current-speed = < 0x4b0 >;
parity = "even";
stop-bits = "1";
data-bits = < 0x7 >;
pinctrl-0 = < &uart20_default >;
pinctrl-1 = < &uart20_sleep >;
pinctrl-names = "default",
"sleep";
phandle = < 0x16 >;
};
I'm using two single byte buffers*...
static uint8_t rx_dma_buf_a[1]; static uint8_t rx_dma_buf_b[1]; static uint8_t* rx_dma_next_buf = rx_dma_buf_b;
...that are delivered through the uart callback:
case UART_RX_BUF_REQUEST: {
uint8_t* next_buf = rx_dma_next_buf;
int err = uart_rx_buf_rsp(dev, next_buf, 1);
#ifdef CONFIG_UART_EXTENSIVE_LOGGING
if (err) {
LOG_ERR("Failed to provide next UART RX buffer, error %d", err);
} else {
LOG_INF("Provided buffer %c", (next_buf == rx_dma_buf_a) ? 'A' : 'B');
}
#endif
break;
}
case UART_RX_BUF_RELEASED:
#ifdef CONFIG_UART_EXTENSIVE_LOGGING
LOG_INF("UART RX buffer released: %c",
(evt->data.rx_buf.buf == rx_dma_buf_a) ? 'A' : 'B');
#endif
rx_dma_next_buf = evt->data.rx_buf.buf;
break;
I start UART using:
uart_rx_enable(data->active_uart, rx_dma_next_buf, 1,
SDI12_UART_RX_TIMEOUT_US);
In normal operation this is working perfectly fine! I receive byte after byte and can process it in the UART_RX_RDY case.
Once an error happens, UART_RX_STOPPED is called (e.g. FRAME + BREAK error) and the driver is disabled automatically as documented. But theoretically it should be possible to restart the driver using uart_rx_enable again (exactly with the same parameters as before) inside of the UART_RX_DISABLED case (in the async callback). But this does not seem to work. It does restart, but no buffer requests are following... The buffer overruns and UART is automatically disabled again. This leads to a ERROR->DISABLE->ENABLE->DISABLE->ENABLE->... loop for me on every received character. I also tried restarting using rx_enable in another thread (after UART_RX_DISABLED event) but this also does not seem to help. I also tried calling uart_rx_buf_rsp right after reenabling rx with an irq lock. Is there something wrong with the driver or am I understanding something wrong here? Shoudn't restarting in the callback work?
*:
I had to use two single byte buffers because passing a byte time to uart_rx_enable is not working for me, the data takes 50-60ms to arrive in the callback without the 1 byte buffer setup.