I’m working with nRF9151 + Toolchain 2.9.0 and wanted to share my experience & issue while sending ~7kB data over UART. I’ve tried both DMA & FIFO-based approaches — here’s what I learned, and where I need help.
DMA-Based UART (Async API)
To achieve high-speed transfer, I first used the async UART API with DMA:
prj.conf:
CONFIG_SERIAL=y CONFIG_UART_ASYNC_API=y CONFIG_UART_0_INTERRUPT_DRIVEN=y CONFIG_UART_0_ASYNC=y CONFIG_NRFX_UARTE0=y
Init:
uart_callback_set(dev, siwg917y_uart_response_handler, &siwg917y_Udata); uart_rx_enable(dev, siwg917y_Udata.user_rx_buf, siwg917y_Udata.user_rx_len, siwg917y_Udata.user_rx_timeout);
Handler:
static void siwg917y_uart_response_handler(const struct device *dev, struct uart_event *evt, void *user_data)
{
switch (evt->type) {
case UART_RX_RDY:
// buffer handling logic
break;
case UART_RX_DISABLED:
uart_rx_enable(dev, data->user_rx_buf, data->user_rx_len, data->user_rx_timeout);
break;
}
}
Transmit:
uart_tx(dev, cmd, strlen(cmd), SYS_FOREVER_US); // Works perfectly!
With this setup, I can send 7kB in ~1 second.
2) FIFO-Based UART (Interrupt-Driven)
To improve stability and explore classic UART FIFO, I switched to interrupt-driven mode:
prj.conf:
CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y
init:
uart_irq_callback_user_data_set(dev, siwg917y_uart_response_handler, &siwg917y_Udata); uart_irq_rx_enable(dev);
FIFO Handler:
while (uart_fifo_read(dev, &c, 1) == 1) {
if ((c == '\n' || c == '\r') && rx_buf_pos > 0) {
// Copy into user buffer & queue
k_msgq_put(&siwg917y_rx_queue, data, K_NO_WAIT);
rx_buf_pos = 0;
} else {
rx_buf[rx_buf_pos++] = c;
}
}
Transmit:
for (int i = 0; i < strlen(cmd); i++) {
uart_poll_out(dev, cmd[i]);
}
This method takes 5–6 seconds for the same 7kB.
Issue:
When using FIFO mode, uart_tx() does not work — but it's fast and DMA-friendly in async mode.
Goal:
Use a fast transmit method (like uart_tx) with FIFO / interrupt mode — is this possible?
Question to the community:
Is there a way to use uart_tx() or any DMA-based high-speed send method with FIFO config?
Any ideas, configs, or driver-level tricks to enable uart_tx or DMA in interrupt mode?
Let me know what worked for you!