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

How to add app_fifo with LIBUARTE ?

Hi All,

I used app_uart_fifo.c and it worked however RX is not good so I switched to LIBUARTE.

The RX part is good with LIBUARTE however when TX traffic is high nrf_libuarte_async_tx might skip data I need.

Any good idea to integrate app_fifo with LIBUARTE for TX and is there blocking API of nrf_libuarte_async_tx ?

BR,

Sam

Parents
  • Hi,

    It is not possible to run two different libraries on a single UART instance, this would require you to run libUARTE on UARTE0 for TX on GPIO P0.06 and app_uart_fifo on UARTE1 for RX on GPIO P0.08 or similar.

    What baudrate are you running at, and are you using HW flow control pins? I'm not sure that running two different libraries is the best solution to your issues. Are you checking error codes when calling nrf_libuarte_async_tx? This function should return NRF_ERROR_BUSY if a transfer is ongoing. You can then buffer the message in your application and start a new transfer as soon as you receive the NRF_LIBUARTE_ASYNC_EVT_TX_DONE event.

    Best regards,
    Jørgen

  • LibUARTE does not use the UART driver, it uses the UARTE HAL layer directly. Have you considered the Serial port library?

  • Hi Sir,

    Serial port library doesn't work for RX case.

    I managed to use app_fifo with libuarte like this.

    void uart_event_handler(void * context, nrf_libuarte_async_evt_t * p_evt)
    {
        nrf_libuarte_async_t * p_libuarte = (nrf_libuarte_async_t *)context;
        static uint8_t ch = 0;
        ret_code_t ret;
    
        static uint16_t idx = 0;
        uint16_t to_read;
        uint16_t to_write;
    
    
        switch (p_evt->type)
        {
        case NRF_LIBUARTE_ASYNC_EVT_ERROR:
            bsp_board_led_invert(1);
            app_sched_event_put(NULL, 0, uart_evt_recover);
    
            break;
        case NRF_LIBUARTE_ASYNC_EVT_RX_DATA:
            // ch = p_evt->data.rxtx.p_data[0];
            // igs_printf("<%s>(%d)", p_evt->data.rxtx.p_data, p_evt->data.rxtx.length);
            // ret = nrf_libuarte_async_tx(p_libuarte, p_evt->data.rxtx.p_data, p_evt->data.rxtx.length);
    
            to_read = RX_LINE_BUF_SIZE - idx;
            if (to_read > p_evt->data.rxtx.length) {
                to_read = p_evt->data.rxtx.length;
            }
    
            strncpy(m_data_array + idx, p_evt->data.rxtx.p_data, to_read);
            idx += (to_read);
            m_data_array[idx] = 0;
            // igs_printf("[%s](%d)",m_data_array, idx);
    
            if ((m_data_array[idx - 1] == '\n') || (idx >= (RX_LINE_BUF_SIZE - 1))) {
                app_sched_event_put(NULL, 0, uart_evt_get);
                idx = 0;
            }
    
            nrf_libuarte_async_rx_free(p_libuarte, p_evt->data.rxtx.p_data, p_evt->data.rxtx.length);
    //            ret = nrf_libuarte_async_tx(p_libuarte, &ch, 1);
    //            APP_ERROR_CHECK(ret);
            // bsp_board_led_invert(1);
            break;
        case NRF_LIBUARTE_ASYNC_EVT_TX_DONE:
            // app_sched_event_put(NULL, 0, uart_evt_tx);
        if (!nrf_libuarte_async_tx_in_progress(&libuarte))
        {
            to_write = UART_TX_BUF_SIZE;
            if (app_fifo_read(&m_tx_fifo, tx_buffer, &to_write) == NRF_SUCCESS)
            {
                ret = nrf_libuarte_async_tx(&libuarte, tx_buffer, to_write);
                // if (ret !=  NRF_SUCCESS) {
                if (ret ==  NRF_ERROR_BUSY) {
    
                    bsp_board_led_invert(0);
                    // uart_evt_recover(NULL, 0);
                    // app_sched_event_put(NULL, 0, uart_evt_recover);
                }
            }
        }
            bsp_board_led_invert(1);
            break;
        default:
            break;
        }
    }
    

    I suggest to add API nrf_libuarte_async_tx_in_progress(&libuarte) officially for this usage.

    BR,

    Sam

Reply
  • Hi Sir,

    Serial port library doesn't work for RX case.

    I managed to use app_fifo with libuarte like this.

    void uart_event_handler(void * context, nrf_libuarte_async_evt_t * p_evt)
    {
        nrf_libuarte_async_t * p_libuarte = (nrf_libuarte_async_t *)context;
        static uint8_t ch = 0;
        ret_code_t ret;
    
        static uint16_t idx = 0;
        uint16_t to_read;
        uint16_t to_write;
    
    
        switch (p_evt->type)
        {
        case NRF_LIBUARTE_ASYNC_EVT_ERROR:
            bsp_board_led_invert(1);
            app_sched_event_put(NULL, 0, uart_evt_recover);
    
            break;
        case NRF_LIBUARTE_ASYNC_EVT_RX_DATA:
            // ch = p_evt->data.rxtx.p_data[0];
            // igs_printf("<%s>(%d)", p_evt->data.rxtx.p_data, p_evt->data.rxtx.length);
            // ret = nrf_libuarte_async_tx(p_libuarte, p_evt->data.rxtx.p_data, p_evt->data.rxtx.length);
    
            to_read = RX_LINE_BUF_SIZE - idx;
            if (to_read > p_evt->data.rxtx.length) {
                to_read = p_evt->data.rxtx.length;
            }
    
            strncpy(m_data_array + idx, p_evt->data.rxtx.p_data, to_read);
            idx += (to_read);
            m_data_array[idx] = 0;
            // igs_printf("[%s](%d)",m_data_array, idx);
    
            if ((m_data_array[idx - 1] == '\n') || (idx >= (RX_LINE_BUF_SIZE - 1))) {
                app_sched_event_put(NULL, 0, uart_evt_get);
                idx = 0;
            }
    
            nrf_libuarte_async_rx_free(p_libuarte, p_evt->data.rxtx.p_data, p_evt->data.rxtx.length);
    //            ret = nrf_libuarte_async_tx(p_libuarte, &ch, 1);
    //            APP_ERROR_CHECK(ret);
            // bsp_board_led_invert(1);
            break;
        case NRF_LIBUARTE_ASYNC_EVT_TX_DONE:
            // app_sched_event_put(NULL, 0, uart_evt_tx);
        if (!nrf_libuarte_async_tx_in_progress(&libuarte))
        {
            to_write = UART_TX_BUF_SIZE;
            if (app_fifo_read(&m_tx_fifo, tx_buffer, &to_write) == NRF_SUCCESS)
            {
                ret = nrf_libuarte_async_tx(&libuarte, tx_buffer, to_write);
                // if (ret !=  NRF_SUCCESS) {
                if (ret ==  NRF_ERROR_BUSY) {
    
                    bsp_board_led_invert(0);
                    // uart_evt_recover(NULL, 0);
                    // app_sched_event_put(NULL, 0, uart_evt_recover);
                }
            }
        }
            bsp_board_led_invert(1);
            break;
        default:
            break;
        }
    }
    

    I suggest to add API nrf_libuarte_async_tx_in_progress(&libuarte) officially for this usage.

    BR,

    Sam

Children
No Data
Related