OpenThread UARTE0

Hi,

I am trying to integrate an UARTE application code with OpenThread example(thread_mqtt_sn_client_publisher_pca10056) on my nRF52840. My application code uses UARTE0 to communicate with other system.

Here are some of the problems I am encountering:

  • If I use 
    NRF_LIBUARTE_ASYNC_DEFINE(UARTE0, 0, 0, 0, NRF_LIBUARTE_PERIPHERAL_NOT_USED, 255, 3);
    , I will get an error saying "multiple definition of `UARTE0_UART0_IRQHandler'; Output/PD52840V1R1_Thread Release/Obj/nrf_libuarte_drv.o:xx:\xxxxx\xxxx\xxxxx\nRF52840\Nordic\SDK\nRF5_SDK_for_Thread_and_Zigbee_v4.0.0_dc7186b\components\libraries\libuarte/nrf_libuarte_drv.c:826: first defined here".
    1. For this error, I tried the following:
    2. Enabled NRFX_PRS_ENABLED and checked NRFX_PRS_BOX_2_ENABLED
    3. Disabled UART_LEGACY_SUPPORT and UART_EASY_DMA_SUPPORT in sdk_config.h

However, I still get the multiple definitions for "UARTE0_UART0_IRQHandler" error.

When I changed the definition to 

NRF_LIBUARTE_ASYNC_DEFINE(UARTE0, 1, 0, 0, NRF_LIBUARTE_PERIPHERAL_NOT_USED, 255, 3);
, I can successfully transmit the message. I see some response on the Rx line on the scope. However, the control in the code isn't going to "NRF_LIBUARTE_ASYNC_EVT_RX_DATA". I can see that I am getting NRF_LIBUARTE_ASYNC_EVT_TX_DONE event in the event handler.

I am trying to understand the following:

  1. Why am I getting the UARTE0_UART0_IRQHandler error and how to fix that?
  2. Why is the control not going to the NRF_LIBUARTE_ASYNC_EVT_RX_DATA part of the event handler even after me seeing Rx pulses on the scope?(If I just run the application without thread, everything's working the way it should)


Can you please help me understand the above questions? Here's the UART Code:

/*
 * PD_UARTE.c
 * Created on: Feb 05, 2020
 * Author: Teja Chintalapati
 * Contact: teja@precisedraft.com
 * Description: Contains code to handle UARTE module.

 /**************************************************
 * INCLUDES
 **************************************************/

#include "nrf_libuarte_async.h"
#include "nrf_queue.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include <bsp.h>

/***** PRECISE INCLUDES *****/
#include "PD_Application.h"
#include "PD_Responses.h"
#include "PD_Timers.h"
#include "PD_UARTE.h"

/**************************************************
 * GLOBALS
 **************************************************/

typedef struct {
  uint8_t *p_data;
  uint32_t length;
} UARTERxBuffer;

/***** EXTERN GLOBALS *****/

extern volatile bool JetFile2UARTReceiveTimedout;

/**************************************************
 * DEFINES
 **************************************************/

NRF_LIBUARTE_ASYNC_DEFINE(UARTE0, 1, 0, 0, NRF_LIBUARTE_PERIPHERAL_NOT_USED, 255, 3);
NRF_QUEUE_DEF(UARTERxBuffer, UARTE0RxBufferQueue, 4, NRF_QUEUE_MODE_NO_OVERFLOW);

/**************************************************
 * FUNCTION DEFINITIONS
 **************************************************/

/*
 * Function: JetFile2UARTInitialisation
 * Params: nrf_libuarte_async_config_t - (Please refer to nRF documentation)
 * returns: None
 * Description: Initialises UARTE0 Module used for JetFile2 Communication
 */

void JetFile2UARTInitialisation(nrf_libuarte_async_config_t nrf_libuarte_async_config) {
  ret_code_t err_code = nrf_libuarte_async_init(&UARTE0, &nrf_libuarte_async_config, UARTE0EventHandler, (void *)&UARTE0);
  APP_ERROR_CHECK(err_code);

  nrf_libuarte_async_enable(&UARTE0);
  NRF_LOG_DEBUG("JetFile2 UART Initialisation complete.")
  NRF_LOG_FLUSH();
}

/*
 * Function: JetFile2UARTTransmitData
 * Params:
          UARTE0TxDataPtr: Pointer to the data that is to be transmitted.
          UARTE0TxDataLength: Length of data to be transmitted.
          expectingResponse: Set to "true" if you're expecting response to your transmission.
          responseBuffer[out]: Buffer in which response data is stored.
          responseBufferSize[out]: Length of the received buffer.
          receiveTimeout: Timeout for response.
 * returns: Response to Tx
 * Description: Initialises UARTE0 Module
 */

ret_code_t JetFile2UARTTransmitData(uint8_t *UARTE0TxDataPtr, size_t UARTE0TxDataLength, bool expectingResponse, uint8_t *responseBuffer, size_t *responseBufferSize, uint16_t receiveTimeout) {
  NRF_LOG_DEBUG("Transmitting data on JetFile2 UART. Data:");
  NRF_LOG_HEXDUMP_DEBUG(UARTE0TxDataPtr, UARTE0TxDataLength);
  NRF_LOG_FLUSH();

  ret_code_t responseCode = nrf_libuarte_async_tx(&UARTE0, UARTE0TxDataPtr, UARTE0TxDataLength);
  if (responseCode == NRF_SUCCESS) {
    //Data transmission successful
    if (expectingResponse) {
      //We're expecting a response after transmission.

      //Start the timeout timer
      startJetFile2UARTTimeoutTimer(receiveTimeout);
      while ((getNewDataOnJetFile2UART(responseBuffer, responseBufferSize) != JETFILE2UART_NEW_DATA_AVAILABLE) && JetFile2UARTReceiveTimedout == false);
      if (JetFile2UARTReceiveTimedout) {
        //Operation timedout.
        NRF_LOG_WARNING("Didn't receive acknowledgement for JetFile2 transmission.")
        NRF_LOG_FLUSH();

        return RSP_NO_RESPONSE_FOR_TRANSMISSION;
      } else {
        //Response received for a transmission.

        //Stop timer.
        stopJetFile2UARTTimeoutTimer();

        NRF_LOG_DEBUG("Response received for a JetFile2 transmission. Data: ")
        NRF_LOG_HEXDUMP_DEBUG(responseBuffer, *responseBufferSize);
        NRF_LOG_FLUSH();

        return RSP_PD_SUCCESS;
      }
    }
  } else {
    NRF_LOG_WARNING("JetFile2 UART Transmission Failed. NRF Error code: %d", responseCode);
    NRF_LOG_FLUSH();
    return responseCode;
  }

  return RSP_PD_SUCCESS;
}

/*
 * Function: UARTE0EventHandler
 * Params: (Please refer to nRF documentation)
 * returns: None
 * Description: Handle for all UARTE events.
 */

void UARTE0EventHandler(void *context, nrf_libuarte_async_evt_t *p_evt) {
  nrf_libuarte_async_t *p_libuarte = (nrf_libuarte_async_t *)context;
  ret_code_t ret;

  switch (p_evt->type) {
  case NRF_LIBUARTE_ASYNC_EVT_ERROR:
    break;
  case NRF_LIBUARTE_ASYNC_EVT_RX_DATA:
    //Data received on UART. If a queue is available, "push" the Rx data into that queue.
    if (nrf_queue_available_get(&UARTE0RxBufferQueue) > 0) {
      UARTERxBuffer pushBuffer;
      pushBuffer.length = p_evt->data.rxtx.length;
      pushBuffer.p_data = p_evt->data.rxtx.p_data;

      //Push the data into the queue
      ret = nrf_queue_push(&UARTE0RxBufferQueue, &pushBuffer);
      APP_ERROR_CHECK(ret);
    }

    //As recommended by nRF(Infocenter -> nRF52 Series -> nRF52840 -> Specs -> Peripherals -> UARTE -> Reception), release the data.
    nrf_libuarte_async_rx_free(p_libuarte, p_evt->data.rxtx.p_data, p_evt->data.rxtx.length);
    break;
  case NRF_LIBUARTE_ASYNC_EVT_TX_DONE:
    break;
  case NRF_LIBUARTE_ASYNC_EVT_OVERRUN_ERROR:
    break;
  default:
    break;
  }
}

Related