Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

libuarte Unexpected RX free input parameter

Hi there,

several months ago I developed a usb to uart bridge based on the nRF52820. We've produced a hand full of those bridges for internal tests and the feedback showed some problems.

Right now the biggest problem is that sometimes the bridge stops responding when hitting it with a load from both sides. Right now DEBUG is set so an error results in an endless loop instead of a reset
So far I figured out that the problem lies within the nrf_libuarte_async_rx_free function. Here I run into the "Unexpected RX free input parameter" case. Debugging it shows that rx_free_cnt is 499968 and rx_buf_size is 0 ...

Here is my init function:

#define UART_RX_BUF_SIZE   256
#define UART_RX_BUF_NUM    8
#define UART_RX_PIN_NUMBER 30
#define UART_TX_PIN_NUMBER 29
#define UART_RX_TIMEOUT_US 100
NRF_LIBUARTE_ASYNC_DEFINE(libuarte, 0, 0, 0, 3, UART_RX_BUF_SIZE, UART_RX_BUF_NUM);

void uart_init(UART_init_struct_t* psInit)
{
  ret_code_t                  err_code;
  nrf_libuarte_async_config_t nrf_libuarte_async_config;

  nrf_libuarte_async_config.tx_pin     = UART_TX_PIN_NUMBER;
  nrf_libuarte_async_config.rx_pin     = UART_RX_PIN_NUMBER;
  nrf_libuarte_async_config.baudrate   = NRF_UARTE_BAUDRATE_1000000;
  nrf_libuarte_async_config.parity     = NRF_UARTE_PARITY_EXCLUDED;
  nrf_libuarte_async_config.timeout_us = UART_RX_TIMEOUT_US;
  nrf_libuarte_async_config.int_prio   = APP_IRQ_PRIORITY_HIGH;
  nrf_libuarte_async_config.pullup_rx  = true;
  nrf_libuarte_async_config.rts_pin    = UART_PIN_DISCONNECTED;
  nrf_libuarte_async_config.cts_pin    = UART_PIN_DISCONNECTED;
  nrf_libuarte_async_config.hwfc       = NRF_UARTE_HWFC_DISABLED;

  nrf_libuarte_async_uninit(&libuarte);
  err_code = nrf_libuarte_async_init(&libuarte, &nrf_libuarte_async_config, uart_event_handler, (void*)&libuarte);
  if(err_code != NRF_SUCCESS)
    NRF_LOG_ERROR("libuarte async init = %d", err_code);
  APP_ERROR_CHECK(err_code);

  nrf_libuarte_async_enable(&libuarte);
}

The uart events get handled via the scheduler:

static void uart_event_sched_handler(void* p_event_data, uint16_t event_size)
{
  nrf_libuarte_async_evt_t* p_evt = (nrf_libuarte_async_evt_t*) p_event_data;

  switch(p_evt->type)
  {
    case NRF_LIBUARTE_ASYNC_EVT_RX_DATA:
    {
      u8* pu8Data;
      u32 i;
      for(i = 0, pu8Data = p_evt->data.rxtx.p_data; i < p_evt->data.rxtx.length; i++, pu8Data++)
      {
        UART_RxProcess(*pu8Data);
      }
      nrf_libuarte_async_rx_free(&libuarte, p_evt->data.rxtx.p_data, p_evt->data.rxtx.length);
      break;
    }
    case NRF_LIBUARTE_ASYNC_EVT_TX_DONE:
    {
      UART_Tx(NULL, 0);
      break;
    }
    case NRF_LIBUARTE_ASYNC_EVT_ERROR:
    {
      NRF_LOG_INFO("UART Error: %d", p_evt->data.errorsrc);
      break;
    }
    default:
      NRF_LOG_INFO(" unexpected libuarte event: %d", p_evt->type);
      break;
  }
}

void uart_event_handler(void* context, nrf_libuarte_async_evt_t* p_evt)
{
  app_sched_event_put(p_evt, sizeof(nrf_libuarte_async_evt_t), uart_event_sched_handler);
}

I'm using the nRF5 SDK version 17.1.0 without softdevice.

Any idea what the problem could be?

Kind regards,
Johannes

Related