nRF5 SDK v15.2.0
UART

The UART driver includes two layers: the hardware access layer (HAL) and the driver layer (DRV).

The hardware access layer provides basic APIs for accessing the registers of the UART and UARTE peripherals. See the API documentation for the UART HAL and UARTE HAL for details.

The driver layer provides APIs on a higher level than the HAL. See the API documentation for the UART driver - legacy layer for details.

Key features include:

Note that peripherals using EasyDMA can work only with buffers that are placed in the Data RAM region. Under certain circumstances, compilers might choose to use a different region for data placement and, for example, place a constant buffer in the code FLASH. In such a case, the UARTE peripheral cannot be used to transfer data from the buffer.

Driver configuration

The UART driver can use multiple instances of the UART/UARTE peripherals, and it provides a common API for both peripheral types. The instances of the peripherals that are to be assigned to the driver must be selected statically in sdk_config.h. In the same way, you configure whether a given instance uses EasyDMA.

The UART default configuration is located in sdk_config.h. If UARTE is present on the chip, the driver can be configured at runtime to support UART mode, UARTE mode, or both. The following example shows how to configure the driver to support both modes in runtime and have legacy mode as the default:

#ifdef NRF52
#define UART0_USE_EASY_DMA false
#define UART_EASY_DMA_SUPPORT 1
#define UART_LEGACY_SUPPORT 1
#endif //NRF52

If only one mode is used in the application, disable the second mode in sdk_config.h to achieve a lower memory footprint and better performance.

Call nrf_drv_uart_init with the p_config argument set to NULL to use the default configuration. To use a custom configuration, provide a user configuration structure, for example:

nrf_drv_uart_t uart_driver_instance = NRF_DRV_UART_INSTANCE(UART0_INSTANCE_INDEX);
config.use_easy_dma = true;
ret_code = nrf_drv_uart_init(&uart_driver_instance, &config, NULL);

Using the UART driver

Blocking mode

If no event handler is provided during the initialization of the driver, the driver will operate in blocking mode. In this case, nrf_drv_uart_tx and nrf_drv_uart_rx will not return until the requested transfer is completed, nrf_drv_uart_rx_abort or nrf_drv_uart_tx_abort is called from a different context, or an error is detected. When an abort function is called, nrf_drv_uart_tx or nrf_drv_uart_rx returns with an error code. When an error is reported by the peripheral,nrf_drv_uart_rx returns with an error code.

In blocking mode, the driver does not use a peripheral interrupt, and there is no context switching inside the driver.

Non-blocking mode

If an event handler (nrf_uart_event_handler_t) is provided during the initialization of the driver, the driver will operate in non-blocking mode. In this case, nrf_drv_uart_tx and nrf_drv_uart_rx will return immediately after transfer is started. Completion will be notified to the user by the event handler that was provided during initialization. The event handler is called in the context of the UART/UARTE interrupt. If an error is reported by the peripheral, it is also reported by the event handler. The error event contains information about the amount of data that was transferred before the error occurred.

If nrf_drv_uart_rx_abort or nrf_drv_uart_tx_abort is called, the event handler notifies that the transfer is completed, but the length field is set to the amount of data that was transferred before the abort function was called.

Enabling RX without providing data buffer

You can enable RX without providing a buffer for incoming data. In this case, incoming data (up to 6 bytes) stays in the hardware FIFO. If more than 6 bytes are received, an overrun error condition occurs. This condition will be reported by the event handler or at the next nrf_drv_uart_rx call.

Note
This functionality is provided only for UART mode.
nrf_drv_uart_t uart_driver_instance = NRF_DRV_UART_INSTANCE(UART0_INSTANCE_INDEX);
ret_code = nrf_drv_uart_init(&uart_driver_instance, NULL, NULL);
nrf_drv_uart_rx_enable(&uart_driver_instance);
//UART RX is enabled
nrf_drv_uart_rx(&uart_driver_instance, buffer, 2);
//UART RX is still enabled.
nrf_drv_uart_rx_disable(&uart_driver_instance);

Documentation feedback | Developer Zone | Subscribe | Updated