Multiple UART on NRF52833

Hello Everyone,

                   I am using NRF52833 in my project and I have my NRF module connected to 2 other microcontrollers on UART peripherals. The details are mentioned as below:-

1) NRF52833 connected to MCU A

   RX pin of nrf- P0.29

   TX pin of nrf- P0.28

2) NRF52833 connected to MCU B

   RX pin of nrf- P0.30

   TX pin of nrf- P0.31.

I have successfully configured connection to MCU and I am able to transmit data from NRF to MCU A and receive data on NRF from MCU A.

Now I have to add another UART in the code so as to communicate with MCU B. What will be the steps to add one more UART configuration?? What is the procedure to do so.

Thanks & Regards,

Snehal.

Parents
  • Hi,

    The nRF52833 has only 1 UART, but 2 UARTE. So you would have to add a UARTE peripheral to your project. To add the peripheral you need to:

    1. Enable the Instance in your sdk config file and add necessary files to your project. 
    2. Initialize the peripheral and instance
    3. Use the peripheral Slight smile

    You can follow the procedure as in the UART example. If you're already using the UART example, then you're actually using the UARTE peripheral. If so, then you need to make sure that you add instance 1 instead of 0, because the example already use instance 0. 

    regards

    Jared 

Reply
  • Hi,

    The nRF52833 has only 1 UART, but 2 UARTE. So you would have to add a UARTE peripheral to your project. To add the peripheral you need to:

    1. Enable the Instance in your sdk config file and add necessary files to your project. 
    2. Initialize the peripheral and instance
    3. Use the peripheral Slight smile

    You can follow the procedure as in the UART example. If you're already using the UART example, then you're actually using the UARTE peripheral. If so, then you need to make sure that you add instance 1 instead of 0, because the example already use instance 0. 

    regards

    Jared 

Children
  • Hi Jared,

                 Thanks for your reply. You mean to say I will have to edit in sdk_config.h from 

    #ifndef APP_UART_DRIVER_INSTANCE
    #define APP_UART_DRIVER_INSTANCE 0
    #endif

    to 

    #ifndef APP_UART_DRIVER_INSTANCE
    #define APP_UART_DRIVER_INSTANCE 1
    #endif

    ??

    Will this enable 2 uarts? As well as for uart1 i am using function below:-

    void sys_uart_init(void)
    {
    uint32_t err_code;
    const app_uart_comm_params_t comm_params =
    {
    UART_RX_PIN_NUMBER,
    UART_TX_PIN_NUMBER,
    UART_RTS_PIN_NUMBER,
    UART_CTS_PIN_NUMBER,
    APP_UART_FLOW_CONTROL_DISABLED,
    false,
    UART_BAUDRATE_BAUDRATE_Baud9600
    };

    APP_UART_FIFO_INIT(&comm_params,
    UART_RX_BUF_SIZE,
    UART_TX_BUF_SIZE,
    uart_event_handle,
    APP_IRQ_PRIORITY_LOWEST,
    err_code);


    APP_ERROR_CHECK(err_code);
    }

    will i have to creae another function for adding 2nd uart using the same method???

    Thanks & Regards,

    Snehal 

  • Hi,

    Assuming that you're using the UART hardware peripheral example. 

    You need to add this to the config file:

    // <e> UART1_ENABLED - Enable UART1 instance
    //==========================================================
    #ifndef UART1_ENABLED
    #define UART1_ENABLED 1
    #endif
    // <q> UART1_CONFIG_USE_EASY_DMA  - Default setting for using EasyDMA
     
    
    #ifndef UART1_CONFIG_USE_EASY_DMA
    #define UART1_CONFIG_USE_EASY_DMA 1
    #endif
    
    // </e>

    You also need to repeat the initialization routine that was done for UART0 for UART1. That includes initialize a new FIFO with new RX and TX buffers. 

    regards

    Jared

  • Hi Jared,

     I have created new functions for uart2. 

    //handler for uart1

    void uart_event_handle(app_uart_evt_t * p_event)
    {
    switch (p_event->evt_type)
    {
    case APP_UART_DATA_READY:
    UNUSED_VARIABLE(app_uart_get(&rx_byte));
    com_rx_byte(rx_byte);
    NRF_LOG_INFO("RECEIVED DATA %x",rx_byte);
    break;

    case APP_UART_COMMUNICATION_ERROR:
    // APP_ERROR_HANDLER(p_event->data.error_communication);
    break;

    case APP_UART_FIFO_ERROR:
    APP_ERROR_HANDLER(p_event->data.error_code);
    break;

    default:
    break;
    }
    }

    //handler for uart2
    void uart_2_event_handle(app_uart_evt_t * p_event)
    {
    switch (p_event->evt_type)
    {
    case APP_UART_2_DATA_READY:
    UNUSED_VARIABLE(app_uart_get(&rx_byte));
    com_rx_byte(rx_byte);
    NRF_LOG_INFO("RECEIVED DATA %x",rx_byte);
    break;

    case APP_UART_2_COMMUNICATION_ERROR:
    // APP_ERROR_HANDLER(p_event->data.error_communication);
    break;

    case APP_UART_2_FIFO_ERROR:
    APP_ERROR_HANDLER(p_event->data.error_code);
    break;

    default:
    break;
    }
    }

    //initialization for uart1

    void sys_uart_init(void)
    {
    uint32_t err_code;
    const app_uart_comm_params_t comm_params =
    {
    UART_RX_PIN_NUMBER,
    UART_TX_PIN_NUMBER,
    UART_RTS_PIN_NUMBER,
    UART_CTS_PIN_NUMBER,
    APP_UART_FLOW_CONTROL_DISABLED,
    false,
    UART_BAUDRATE_BAUDRATE_Baud9600
    };

    APP_UART_FIFO_INIT(&comm_params,
    UART_RX_BUF_SIZE,
    UART_TX_BUF_SIZE,
    uart_event_handle,
    APP_IRQ_PRIORITY_LOWEST,
    err_code);


    APP_ERROR_CHECK(err_code);
    }

    //initialization for uart1

    void sys_uart2_init(void)
    {
    uint32_t err_code;
    const app_uart_comm_params_t comm_params =
    {
    UART_RX_2_PIN_NUMBER,
    UART_TX_2_PIN_NUMBER,
    UART_RTS_2_PIN_NUMBER,
    UART_CTS_2_PIN_NUMBER,
    APP_UART_FLOW_CONTROL_DISABLED,
    false,
    UART_BAUDRATE_BAUDRATE_Baud9600
    };

    APP_UART_FIFO_INIT(&comm_params,
    UART_2_RX_BUF_SIZE,
    UART_2_TX_BUF_SIZE,
    uart_2_event_handle,
    APP_IRQ_PRIORITY_LOWEST,
    err_code);


    APP_ERROR_CHECK(err_code);
    }

    Now for receiving and transmitting data through Uart, I have these functions for uart1:-

    uint32_t uart_rxByte(uint8_t *byte)
    {
    return app_uart_get(byte);
    }

    uint32_t uart_txByte(uint8_t byte)
    {
    return app_uart_put(byte);
    }

    Do i need to create the same for uart2 or the same ones can be used? 

    Thanks & Regards,

    Snehal 

  • Also how will app_uart_put and app_uart_get know which uart to send data from??

  • Hi,

    You're absolutely right, the app_uart module does not work with multiple instances. It's hardcoded to use UART(E) instance 0. You can use one UART(E) peripheral with app_uart and another UART(E) peripheral with the libUARTE peripheral. 

    Steps:

    1. Modify the libUARTE example in the SDK so that it uses UARTE instance 1 instead of 0. You can do this by:
      1. setting #define NRF_LIBUARTE_DRV_UARTE1 to 1 in the sdk_configh.h file. 
      2. Initialize UARTE 1 in main.c by NRF_LIBUARTE_ASYNC_DEFINE(libuarte, 1, 00NRF_LIBUARTE_PERIPHERAL_NOT_USED, 255, 3);
      3. Build the example and see if it works as expected.
    2. Merge the modified libuarte example with the app_uart example. 
      1. Compare the two sdk_config.h files and include everything that is not already included in the app_uart config file. Use the compare option in VS code.
      2. Add all project source files and paths that hasn't already been included. See this.
    3. Test the example.

    regards

    Jared 

Related