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

Dubble buffered UARTE reception

Hi NordicSemi

I have a project where we receive data via the UARTE. To avoid missing data caused by higher prioritized tasks we want to use the DMA facilities. 

nrf52832 with softdevice and SDK version 15.2

But as we do not know how many bytes we receive we want to use the double buffered facilities, allowing us to process one buffer while the other are used for reception.

But we are not always receiving data, and we still not know how many data are going to be received, therefore we want to periodically forcefully swap from one buffer to the other.

Is this possible.

I have tried with the following (only relevant code snippets shown):

static void FpiUartEventHandler(nrf_drv_uart_event_t * p_event, void * p_context)
{
  uint8_t *p = p_event->data.rxtx.p_data;
  uint32_t l = p_event->data.rxtx.bytes;
  switch(p_event->type)
  {
  case NRFX_UARTE_EVT_ERROR:
    while(l--)
      FifoPut(&fifoRxUart, *p++);

/* Restart reception */
    nrf_drv_uart_rx(&m_uart, bufferRx[0], FPI_UART_MAX_LENGTH);
    nrf_drv_uart_rx(&m_uart, bufferRx[1], FPI_UART_MAX_LENGTH);
    break;
  case NRF_DRV_UART_EVT_TX_DONE:
  {
    FpiUartTransmitNext();
    break;
  }
  case NRF_DRV_UART_EVT_RX_DONE:
  {
    while(l--)
      FifoPut(&fifoRxUart, *p++);

    ret = nrf_drv_uart_rx(&m_uart, p_event->data.rxtx.p_data, FPI_UART_MAX_LENGTH);

    break;
  }
  default:
    break;
  }
}

static void FpiPoll(void * p_context)
{
/* Used as timeout, to ensure that data is not left in receive buffer too long */
  nrf_drv_uart_rx_abort(&m_uart); /* end receiving on primary buffer, automatically switching to secondary buffer */
}

void FpiInit(void)
{
  nrf_drv_uart_config_t config = NRF_DRV_UART_DEFAULT_CONFIG;
  config.pseltxd = HAL_UART_TX_PIN;
  config.pselrxd = HAL_UART_RX_PIN;
  APP_ERROR_CHECK(nrf_drv_uart_init(&m_uart, &config, FpiUartEventHandler));
  APP_ERROR_CHECK(nrf_drv_uart_rx(&m_uart, bufferRx[0], FPI_UART_MAX_LENGTH));
  APP_ERROR_CHECK(nrf_drv_uart_rx(&m_uart, bufferRx[1], FPI_UART_MAX_LENGTH)); // Do not use double buffering at the time.

  APP_ERROR_CHECK(app_timer_create(&m_fpi_timer_id, APP_TIMER_MODE_REPEATED,  FpiPoll));
  APP_ERROR_CHECK(app_timer_start(m_fpi_timer_id, APP_TIMER_TICKS(FPI_TIMER_PERIOD), NULL));
}

The nrf_drv_uart_rx_abort does trigger the TO event on the UART receiver and the FpiUartEventHandler is called. But in the driver the secondary buffer is forcefully canceled.

Therefore it seems to be impossible to use the double buffered feature together with the nrf_drv_uart_rx_abort. 

Did I miss something?

BR and thanks in advance.

Parents Reply Children
No Data
Related