I'm working on implementing asynchronous UART on a nRF52840dk but uart_callback_set() is returning -88 (ENOSYS), which according to the tutorial here means it's not supported by the device. According to the Product Specification the UART is asynchronous (via EasyDMA), so I must be doing something wrong.
My overlay:
&pinctrl {
uart1_default: uart1_default {
group1 {
psels = <NRF_PSEL(UART_TX, 1, 2)>,
<NRF_PSEL(UART_RX, 1, 1)>;
};
};
/* required if CONFIG_PM_DEVICE=y */
uart1_sleep: uart1_sleep {
group1 {
psels = <NRF_PSEL(UART_TX, 1, 2)>,
<NRF_PSEL(UART_RX, 1, 2)>;
low-power-enable;
};
};
};
&uart1 {
compatible = "nordic,nrf-uarte";
current-speed = <38400>;
status = "okay";
pinctrl-0 = <&uart1_default>;
pinctrl-1 = <&uart1_sleep>;
pinctrl-names = "default", "sleep";
};
My config:
# From prj.conf CONFIG_NCS_SAMPLES_DEFAULTS=y CONFIG_CONSOLE=y CONFIG_CONSOLE_SUBSYS=y CONFIG_CONSOLE_HANDLER=y CONFIG_CONSOLE_GETCHAR=y CONFIG_BT_CTLR_SDC_LLPM=y CONFIG_BT_DEVICE_NAME="Nordic_LLPM" CONFIG_BT=y CONFIG_BT_DEBUG_LOG=y CONFIG_BT_SMP=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_CENTRAL=y CONFIG_BT_MAX_CONN=2 CONFIG_BT_SCAN=y CONFIG_BT_SCAN_FILTER_ENABLE=y CONFIG_BT_SCAN_UUID_CNT=1 CONFIG_BT_LATENCY=y CONFIG_BT_LATENCY_CLIENT=y CONFIG_BT_LL_SOFTDEVICE=y CONFIG_BT_HCI_VS_EVT_USER=y CONFIG_HEAP_MEM_POOL_SIZE=2048 CONFIG_BT_GAP_PERIPHERAL_PREF_PARAMS=n CONFIG_GPIO=y CONFIG_UART_ASYNC_API=y # From nrf52840dk_nrf52840.conf CONFIG_USB_DEVICE_STACK=y CONFIG_USB_DEVICE_REMOTE_WAKEUP=n CONFIG_USB_DEVICE_PRODUCT="LLPM sample console" CONFIG_USB_CDC_ACM_LOG_LEVEL_OFF=y CONFIG_UART_CONSOLE=y #Tried commenting out CONFIG_UART_INTERRUPT_DRIVEN=y #Tried commenting out CONFIG_UART_LINE_CTRL=y #Tried commenting out # Since the default LOG_MODE_MINIMAL is synchronous, it will mess with the USB # driver/subsys. Use the deferred mode instead. CONFIG_LOG_MODE_DEFERRED=y
Relevant code:
printk("Starting Uart1\r\n");
struct device *uart
uart = DEVICE_DT_GET(DT_NODELABEL(uart1));
if (!device_is_ready(uart)) {
printk("Uart1 not ready!\r\n");
return;
}
const struct uart_config uart_cfg = {
.baudrate = 38400,
.parity = UART_CFG_PARITY_NONE,
.stop_bits = UART_CFG_STOP_BITS_1,
.data_bits = UART_CFG_DATA_BITS_7,
.flow_ctrl = UART_CFG_FLOW_CTRL_NONE
};
err = uart_configure(uart, &uart_cfg);
if (err == -ENOSYS) {
printk("Uart1 configure failure: %d\r\n", err);
return;
}
err = uart_callback_set(uart, uart_cb, NULL);
if (err) {
printk("Uart1 callback set failure: %d\r\n", err);
return;
}
err = uart_rx_enable(uart, rx_buf, RX_BUFF_SIZE, 50); // 50ms timeout
if (err) {
printk("Uart1 rx buffer enable failure: %d\r\n", err);
return;
}
I used the llpm application as a starting point while following the nordic academy lesson above, I'm wondering if there's maybe a conflict with the config values that were there initially? Or I've noticed that the .dts file for the nrf52840dk is quite busy, possibly something conflicts there? Fwiw I initially implemented polling and had it working well before I tried the asynchronous approach. For that reason I have some confidence in my device tree.
Other than above issue, a few questions also have come to mind:
- Should I be using drivers/uarte.h instead of drivers/uart.h because of the EasyDMA support of the chipset? Would that be a problem if I didn't? I only favored uart.h because most of the examples follow it
- Does it matter if I enable CONFIG_UART_INTERRUPT_DRIVEN with the asynchronous approach? I've tried it both ways
Thanks
