This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF52840 UART libraries

Good day all,

I am trying to build a very simple UART connection between the nrf52840 DK and my computer through a UART dongle.

First, I saw the UART example in the peripherals folder and  I tested it in the Loopback mode with no problem.

When I tried to build my own example I noticed that there are 4 different UART library flavors located in different places in the SDK:

  • components> libraries > serial > nrf_serial.h
  • components > libraries > uart > app_uart.h
  • modules > nrfx > hal > nrf_uart.h
  • modules > nrfx > drivers > nrfx_uart.h

  I selected nrf_uart.h (modules > nrfx > hal) just because it was used in the example.

 I am confused with all the different implementations of UART library

Why are there four instead of one UART library?

Which one should I use?

Furthermore, when I run my custom example, nothing is transmitted from the Tx PIn (8) of the nRF52840 DK  when I test it with the oscilloscope.

I cannot understand what I am doing wrong here. I followed the transmission steps given in the nRF52840 datasheet.

The code that I have written is given below.

#include <stdio.h>
#include <stdlib.h>
#include <nrf_gpio.h>     //The GPIO Hardware Abstraction Layer (HAL)
#include <nrf_delay.h>   //For basic delaying functions
#include <pca10056.h>    //GPIO definitions for the nRF52840-DK (aka pca10056)
#include "sdk_config.h"
#include <nrf_uart.h>   // UART library (modules > nrfx > hal)

int main(void)
{
    /* Configure pin 13 as standard output. */
    nrf_gpio_cfg_output(BSP_LED_0); //BSP_LED_0 is pin 13 in the nRF52840-DK
    nrf_gpio_cfg_output(BSP_LED_1); //BSP_LED_0 is pin 13 in the nRF52840-DK
    nrf_gpio_pin_write(BSP_LED_0,1); // switch off the LED
    nrf_gpio_pin_write(BSP_LED_1,1); // switch off the LED

    /*Initialize the UART peripheral */
    nrf_uart_baudrate_set(NRF_UART0,NRF_UART_BAUDRATE_115200);  // set the baudrate
    nrf_uart_configure(NRF_UART0, NRF_UART_PARITY_EXCLUDED, NRF_UART_HWFC_DISABLED);      // set flowcontrol and parity bit
    nrf_uart_txrx_pins_set(NRF_UART0, 6, 8);   // set the Tx and Rx pins on nrf52840 DK
    
    nrf_uart_enable(NRF_UART0);              // Enable UART
    nrf_uart_task_trigger(NRF_UART0, NRF_UART0->TASKS_STARTTX);   // Start UART Transmission 
                                                                    
    nrf_gpio_pin_write(BSP_LED_0,0);        // blink once to indicate start
    nrf_delay_ms(1000);
    nrf_gpio_pin_write(BSP_LED_0,1);
    
    
    while (true){
    
            nrf_uart_txd_set(NRF_UART0,0xAA);                                           // send data to UART 
            while(nrf_uart_event_check(NRF_UART0, NRF_UART0->EVENTS_TXDRDY) == 0){     //blink until data has been sent
                nrf_gpio_pin_write(BSP_LED_0,0);      
                nrf_delay_ms(100);
                nrf_gpio_pin_write(BSP_LED_0,1);
                nrf_delay_ms(100);
            }
    }
   
}

Thank you for your time

Parents Reply Children
  • One last question though,

    in the nrf_uart_task_trigger() and nrf_uart_event_check() of my code, the parameters are nrf_uart_task_t and event_t. At least that is were UART0 is pointing in both cases. Should I put this without a pointer?

    Thank you

  • The parameters you use may point to the task and event address in the UART peripheral, but that is not what the function wants. Look at the function definition of nrf_uart_event_check() f.eks.:

    __STATIC_INLINE bool nrf_uart_event_check(NRF_UART_Type * p_reg, nrf_uart_event_t event)
    {
        return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
    }

    nrf_uart_task_t and event_t are enums with offset values relative to the UART base address:

    /**
     * @enum nrf_uart_task_t
     * @brief UART tasks.
     */
    typedef enum
    {
        /*lint -save -e30 -esym(628,__INTADDR__)*/
        NRF_UART_TASK_STARTRX = offsetof(NRF_UART_Type, TASKS_STARTRX), /**< Task for starting reception. */
        NRF_UART_TASK_STOPRX  = offsetof(NRF_UART_Type, TASKS_STOPRX),  /**< Task for stopping reception. */
        NRF_UART_TASK_STARTTX = offsetof(NRF_UART_Type, TASKS_STARTTX), /**< Task for starting transmission. */
        NRF_UART_TASK_STOPTX  = offsetof(NRF_UART_Type, TASKS_STOPTX),  /**< Task for stopping transmission. */
        NRF_UART_TASK_SUSPEND = offsetof(NRF_UART_Type, TASKS_SUSPEND), /**< Task for suspending UART. */
        /*lint -restore*/
    } nrf_uart_task_t;
    
    /**
     * @enum nrf_uart_event_t
     * @brief UART events.
     */
    typedef enum
    {
        /*lint -save -e30*/
        NRF_UART_EVENT_CTS    = offsetof(NRF_UART_Type, EVENTS_CTS),   /**< Event from CTS line activation. */
        NRF_UART_EVENT_NCTS   = offsetof(NRF_UART_Type, EVENTS_NCTS),  /**< Event from CTS line deactivation. */
        NRF_UART_EVENT_RXDRDY = offsetof(NRF_UART_Type, EVENTS_RXDRDY),/**< Event from data ready in RXD. */
        NRF_UART_EVENT_TXDRDY = offsetof(NRF_UART_Type, EVENTS_TXDRDY),/**< Event from data sent from TXD. */
        NRF_UART_EVENT_ERROR  = offsetof(NRF_UART_Type, EVENTS_ERROR), /**< Event from error detection. */
        NRF_UART_EVENT_RXTO   = offsetof(NRF_UART_Type, EVENTS_RXTO)   /**< Event from receiver timeout. */
        /*lint -restore*/
    } nrf_uart_event_t;

  • So,if  I understand right I can put NRF_UART_EVENT_TXDRDY directly inside the function without pointer? Or create an  nrf_uart_event_t instance and point to it with the dot operator?

    Thank you for your help

  • Yes, that is correct. And instead of : 

    nrf_uart_task_trigger(NRF_UART0, NRF_UART0->TASKS_STARTTX);

    you should use:

    nrf_uart_task_trigger(NRF_UART0, NRF_UART_TASK_STARTTX);

Related