libuarte+freertos receive wrong data

Hi there,

I used libuarte under FreeRTOS together with the SDK 17.1.0. When I test the application, I found that the data I received except some problem.

The baudrate is 921600, and I send the test data (abcdefg...), when i send about 10 pieces of data, the data I received was split into two parts.

i don't know what's going on.

uart.c is here.

NRF_LIBUARTE_ASYNC_DEFINE(libuarte, 0, 0, 0, NRF_LIBUARTE_PERIPHERAL_NOT_USED, 255, 3);

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:
            UART_PRINTF("NRF_LIBUARTE_ASYNC_EVT_ERROR = %d.", p_evt->data.errorsrc);
            break;
        case NRF_LIBUARTE_ASYNC_EVT_RX_DATA:
            m_loopback_phase = true;
            memcpy(data_array, p_evt->data.rxtx.p_data, p_evt->data.rxtx.length);
            UART_PRINTF("data_array = %s", data_array);
            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:
            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));
                }
            }
            break;
        default:
            UART_PRINTF("Unexpected LibUarte Event = %d.", p_evt->type);
            break;
    }
}


int main()
{
    uint8_t err_code;
    nrf_libuarte_async_config_t nrf_libuarte_async_config = {
            .tx_pin     = TX_PIN_NUMBER,
            .rx_pin     = RX_PIN_NUMBER,
            .baudrate   = NRF_UARTE_BAUDRATE_921600,
            .parity     = NRF_UARTE_PARITY_EXCLUDED,
            .hwfc       = NRF_UARTE_HWFC_DISABLED,
            .timeout_us = 100,
            .int_prio   = APP_IRQ_PRIORITY_HIGH,
            .pullup_rx  = 1
    };

    err_code = nrf_libuarte_async_init(&libuarte, &nrf_libuarte_async_config, uart_event_handler, (void *)&libuarte);
    if(err_code != NRF_SUCCESS)
    {
        UART_PRINTF("nrf_libuarte_async_init err_code = %d.", err_code);
    }
    APP_ERROR_CHECK(err_code);

    nrf_libuarte_async_enable(&libuarte);

}

BR,

Lurn

Parents Reply
  • Lurn_Z said:
    How should I do this?

    Or maybe you could do it much simpler.

    Maybe you could do as the SLIP packet framing as described in the Bluetooth Core Specification 4.0, Volume 4, Part D, Chapter 3 SLIP Layer.

    SLIP framing ensures that all packets sent on the UART are framed as:
    <0xC0> SLIP packet 1 <0xC0>
    <0xC0> SLIP packet 2 <0xC0>

    In your case replace "SLIP packet" with "your packet".

    Kenneth

Children
  • Hi Kenneth,

    I saw this link, and from my understanding of this question is when I want send n bytes, I need packet it and send 2*n+1 bytes?

    if my understanding is correct, I can't use it. cause my nrf device just receiver, the sender is another device that I can not control it.

    And I think this question maybe about the rx buffer, because when I change the RX buffer from 256 to 64, the data was be split earlier.

    NRF_LIBUARTE_ASYNC_DEFINE(libuarte, 0, 0, 0, NRF_LIBUARTE_PERIPHERAL_NOT_USED, 64, 3);
    

    Do you have any other solution?

    And I have another question that I need a frequency of 500 times per second, but when I test the application,I don't think it can reach this frequency. Because I get the logs in 9 second, it just 260 times data. Also I will check the sender frequency, and hope you can give me some suggestions.

    BR,

    Lurn

  • So, after my test, I send 32 bytes, the data head is A5 C5, and print 34 bytes so the last two data should be 0 (uint8_t data_array[256] = {0};).

    Here is 3 questions.

    1. When the sender sending data slowly, about 25 times per second, logs looks like that.

    After receiving several pieces of data, one of it was split into two parts

    2. When the sender sending data quickly, (250 times per second), data will be lost, Only 30 pieces of data are received per second.

    3. When the sender sending data quickly, (250 times per second), logs looks like that.

    There is an exception in the data format,

    Hope you can give me some suggestions.

    If you need my application, please tell me.

    BR,

    Lurn

  • Hi,

    It's quite normal in any communication that data is fragmented, how you solve this is up to your requirements, but I can only confirm that what you observe is normal. 

    Please have in mind that if you are also outputting the data to a log here, that may likely impact the throughput.

    Best regards,
    Kenneth

  • OK,

    NRF_LIBUARTE_ASYNC_DEFINE(_name, _uarte_idx, _timer0_idx,\
                                      _rtc1_idx, _timer1_idx,\
                                      _rx_buf_size, _rx_buf_cnt);

    So, how many _rx_buf_cnt can i set at most?

    and what is the maximum _rx_buf_size I can set?

    BR,

    Lurn

  • Out of curiosity, have you measured how long time your "UART_PRINTF("data_array = %s", data_array);" takes?

    Best regards,
    Kenneth

Related