Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

NRF serial library error handling and nrf_serial_rx_drain purpose?

Hello, I'm currently evaluating NRF serial library for development.
I have 2 questions that is not clear for me in the library.

1. What is the purpose of nrf_serial_rx_drain ? It seems that it supposed to clean the queue, but it does not

2. How should I handle errors in event handler in particular NRF_SERIAL_EVENT_DRV_ERR and NRF_SERIAL_EVENT_FIFO_ERR.

With NRF_SERIAL_EVENT_DRV_ERR, I try to check for new line char of the message and signal that it has been received. However, after approximately 6 char the error occur. Why?

If there is some limit to reception, where is it defined? Also even if I got this error, how should it be handled, because currently driver seems to just stuck.

Here is the code:

/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
*/


#include "app_error.h"
#include "module_config.h"
#include "main.h"
#include "timer.h"
#include "nrf_delay.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#include "cm_jwt.h"
#include "nrf_serial.h"
#include "pca10056.h"
#include "nrf_drv_clock.h"

static bool rx_done = false;
static char rx_arr[20] = {0};
static void serial_evt_handler(struct nrf_serial_s const *p_serial, nrf_serial_event_t event);

static void sleep_handler(void)
{
  __WFE();
  __SEV();
  __WFE();
}

NRF_SERIAL_DRV_UART_CONFIG_DEF(m_uart0_drv_config,
        RX_PIN_NUMBER, TX_PIN_NUMBER,
        RTS_PIN_NUMBER, CTS_PIN_NUMBER,
        NRF_UART_HWFC_DISABLED, NRF_UART_PARITY_EXCLUDED,
        NRF_UART_BAUDRATE_115200,
UART_DEFAULT_CONFIG_IRQ_PRIORITY);

#define SERIAL_FIFO_TX_SIZE 32
#define SERIAL_FIFO_RX_SIZE 32

NRF_SERIAL_QUEUES_DEF(serial_queues, SERIAL_FIFO_TX_SIZE, SERIAL_FIFO_RX_SIZE);


#define SERIAL_BUFF_TX_SIZE 32
#define SERIAL_BUFF_RX_SIZE 1

NRF_SERIAL_BUFFERS_DEF(serial_buffs, SERIAL_BUFF_TX_SIZE, SERIAL_BUFF_RX_SIZE);

NRF_SERIAL_CONFIG_DEF(serial_config, NRF_SERIAL_MODE_IRQ,
&serial_queues, &serial_buffs, serial_evt_handler, sleep_handler);


NRF_SERIAL_UART_DEF(serial_uart, 0);

static void serial_evt_handler(struct nrf_serial_s const *p_serial, nrf_serial_event_t event)
{
  // NRF_LOG_INFO("Event %d", event);
  switch (event)
  {
    case NRF_SERIAL_EVENT_RX_DATA:
      NRF_LOG_INFO("Char %c, queue: %s, arr %s", ((char *)serial_buffs.p_rxb)[0], serial_queues.p_rxq->p_buffer, rx_arr);
      if(((char *)serial_buffs.p_rxb)[0] == '\n')
      {
        ((char *)serial_buffs.p_rxb)[0] = 0;
        rx_done = true;
        NRF_LOG_INFO("RX Done %d", nrf_serial_read(&serial_uart, &rx_arr, sizeof(rx_arr), NULL, 0));
      }

      break;

    case NRF_SERIAL_EVENT_TX_DONE:
      NRF_LOG_INFO("TX DONE");

      break;

    case NRF_SERIAL_EVENT_DRV_ERR:
      NRF_LOG_DEBUG("DRIVER ERR");

      break;

    case NRF_SERIAL_EVENT_FIFO_ERR:
      NRF_LOG_DEBUG("FIFO ERR");

      break;

    default:
      break;

  }
}


/**@brief Function for application main entry.
*/

int main(void)
{
    (void) NRF_LOG_INIT(NULL);
    NRF_LOG_DEFAULT_BACKENDS_INIT();

    NRF_LOG_INFO("\n\n\nInside main: %04x");
    start_up_reason();

  ret_code_t ret;

  ret = nrf_drv_clock_init();
  APP_ERROR_CHECK(ret);
  // ret = nrf_drv_power_init(NULL);
  // APP_ERROR_CHECK(ret);

  nrf_drv_clock_lfclk_request(NULL);
  ret = app_timer_init();
  APP_ERROR_CHECK(ret);

  ret = nrf_serial_init(&serial_uart, &m_uart0_drv_config, &serial_config);
  APP_ERROR_CHECK(ret);

  static char tx_message[] = "Hello nrf_serial!\r\n";

  ret = nrf_serial_write(&serial_uart,
                         tx_message,
                         strlen(tx_message),
                         NULL,
                         NRF_SERIAL_MAX_TIMEOUT);
  APP_ERROR_CHECK(ret);

  while (true)
  {
    if(rx_done)
    {
      (void)nrf_serial_write(&serial_uart, &rx_arr, strlen(rx_arr), NULL, 0);
      (void)nrf_serial_flush(&serial_uart, 0);
      rx_done = false;
      NRF_LOG_INFO("Drain result %d", nrf_serial_rx_drain(&serial_uart));
      NRF_LOG_INFO("queue %s", serial_queues.p_rxq->p_buffer);
      // ret = nrf_serial_read(&serial_uart, &rx_arr, sizeof(rx_arr), NULL, 0);
      // NRF_LOG_INFO("RX ret code: %02X", ret);
    }

  }
}

Note! SDK 15.3 is currently in use, and we do not plan to move to SDK 16, thus libuarte in not an option.
Currently I'm trying to choose between Serial, app_uart or low level UART_driver.

Related