(Libuartes) Reset nRF when receive RX buffer from computer

Hi, I'm using the example libuartes of nrf5 sdk ver16. This example worked (receive data from computer(Hercules) and send it to back)
I have some customize that is when nRF received data from computer, it will send any data I want back to the computer.
Eg: my computer send "hello" and nrf after receive"hello" it will send to back "nice to meet you". 
But after I send some line "hello" from my computer and receive"nice to meet you" => nRF reset. I think TX (save in somewhere I don't know overflowed)

NRF_LIBUARTE_ASYNC_DEFINE(libuarte1, 0, 0, 0, NRF_LIBUARTE_PERIPHERAL_NOT_USED, 100, 3);
NRF_LIBUARTE_ASYNC_DEFINE(libuarte2, 1, 2, 2, NRF_LIBUARTE_PERIPHERAL_NOT_USED, 100, 3);

static uint8_t text[] = "nrf reset =============\r\n";
static uint8_t textAT1_Uart1[] = "nice to meet you\r\n";
static uint8_t textReceived[100];
static volatile bool m_loopback_phase;

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

NRF_QUEUE_DEF(buffer_t, m_buf_queue, 10, NRF_QUEUE_MODE_NO_OVERFLOW);

//Function to send via UART1
void send_UART_1(char *sdata, int len)
{
    ret_code_t ret;
    ret = nrf_libuarte_async_tx(&libuarte1, sdata, len);
    APP_ERROR_CHECK(ret);
}

void uart_event_handler(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:
        sprintf(textReceived, "%s", p_evt->data.rxtx.p_data);
        // send_UART_1(textAT1_Uart1, sizeof(textAT1_Uart1));
        // ret = nrf_libuarte_async_tx(p_libuarte, p_evt->data.rxtx.p_data, p_evt->data.rxtx.length);
        ret = nrf_libuarte_async_tx(p_libuarte, textAT1_Uart1, sizeof(textAT1_Uart1));
        if (ret == NRF_ERROR_BUSY)
        {
            buffer_t buf = {
                .p_data = p_evt->data.rxtx.p_data,
                .length = p_evt->data.rxtx.length,
            };

            ret = nrf_queue_push(&m_buf_queue, &buf);
            APP_ERROR_CHECK(ret);
        }
        else
        {
            APP_ERROR_CHECK(ret);
        }
        bsp_board_led_invert(1);
        m_loopback_phase = true;
        break;
    case NRF_LIBUARTE_ASYNC_EVT_TX_DONE:
        if (m_loopback_phase)
        {
            nrf_libuarte_async_rx_free(p_libuarte, p_evt->data.rxtx.p_data, p_evt->data.rxtx.length);
            if (!nrf_queue_is_empty(&m_buf_queue))
            {
                buffer_t buf;
                ret = nrf_queue_pop(&m_buf_queue, &buf);
                APP_ERROR_CHECK(ret);
                UNUSED_RETURN_VALUE(nrf_libuarte_async_tx(p_libuarte, buf.p_data, buf.length));
            }
        }
        bsp_board_led_invert(2);
        break;
    default:
        break;
    }
}

 int main(void)
  {
      bsp_board_init(BSP_INIT_LEDS);
      ret_code_t ret = nrf_drv_clock_init();
      APP_ERROR_CHECK(ret);
      nrf_drv_clock_lfclk_request(NULL);
      ret_code_t err_code = NRF_LOG_INIT(app_timer_cnt_get);
      APP_ERROR_CHECK(err_code);

      NRF_LOG_DEFAULT_BACKENDS_INIT();

      nrf_libuarte_async_config_t nrf_libuarte_async_config1 = {
          .tx_pin = TX_PIN_NUMBER1,
          .rx_pin = RX_PIN_NUMBER1,
          .baudrate = NRF_UARTE_BAUDRATE_115200,
          .parity = NRF_UARTE_PARITY_EXCLUDED,
          .hwfc = NRF_UARTE_HWFC_DISABLED,
          .timeout_us = 100,
          .int_prio = APP_IRQ_PRIORITY_LOW};

      nrf_libuarte_async_config_t nrf_libuarte_async_config2 = {
          .tx_pin = TX_PIN_NUMBER2,
          .rx_pin = RX_PIN_NUMBER2,
          .baudrate = NRF_UARTE_BAUDRATE_115200,
          .parity = NRF_UARTE_PARITY_EXCLUDED,
          .hwfc = NRF_UARTE_HWFC_DISABLED,
          .timeout_us = 100,
          .int_prio = APP_IRQ_PRIORITY_LOW};

      err_code = nrf_libuarte_async_init(&libuarte1, &nrf_libuarte_async_config1, uart_event_handler, (void *)&libuarte1);
      err_code = nrf_libuarte_async_init(&libuarte2, &nrf_libuarte_async_config2, uart_event_handler, (void *)&libuarte2);

      APP_ERROR_CHECK(err_code);
      nrf_libuarte_async_enable(&libuarte1);
      nrf_libuarte_async_enable(&libuarte2);
      APP_ERROR_CHECK(err_code);
      send_UART_1(text, sizeof(text));

      while (true)
      {
          NRF_LOG_FLUSH();
      }
  }


here is my code just edit line 37 into 38. But my code not work smoothy like the example. Please give me some hints. I really appreciate about that.
Best Regart,
Tam

Parents Reply
  • Hi,

    I'm glad to hear that it solved the problem.

    Pham Tam said:
    to check length of buffer before and after free but the length not change. I don't know what buffer which is freed  by

    "free" makes it so that the same memory can be re-used for the next transaction. You will eventually run out of buffers if you don't this. The event data (p_evt->data.rxtx.p_data and p_evt->data.rxtx.length) is however not updated after nrf_libuarte_async_rx_free();

Children
Related