Check UART errors when calling "uart_read_bytes"

carlessolegrau
Posts: 3
Joined: Tue Jun 22, 2021 12:54 pm

Check UART errors when calling "uart_read_bytes"

Postby carlessolegrau » Tue Jun 22, 2021 1:02 pm

Hello,
For a project I'm interested in detecting when some errros exist in the UART.

I have found this struct:

Code: Select all

typedef enum {
    UART_DATA,              /*!< UART data event*/
    UART_BREAK,             /*!< UART break event*/
    UART_BUFFER_FULL,       /*!< UART RX buffer full event*/
    UART_FIFO_OVF,          /*!< UART FIFO overflow event*/
    UART_FRAME_ERR,         /*!< UART RX frame error event*/
    UART_PARITY_ERR,        /*!< UART RX parity event*/
    UART_DATA_BREAK,        /*!< UART TX data and break event*/
    UART_PATTERN_DET,       /*!< UART pattern detected */
    UART_EVENT_MAX,         /*!< UART event max index*/
} uart_event_type_t;
That I can use to detect for example Parity Error or others.

But I just finding that this struct is accessible only when using UART through events(https://github.com/espressif/esp-idf/tr ... art_events).

So, is there a way to get if UART has Parity Error (for example) on polling? Or at the same time that uart_read_bytes is called?

Thanks

carlessolegrau
Posts: 3
Joined: Tue Jun 22, 2021 12:54 pm

Re: Check UART errors when calling "uart_read_bytes"

Postby carlessolegrau » Wed Jun 30, 2021 9:30 am

I manage to do something that works for me, so I share it.

When installing the driver I set the event queue:

Code: Select all

esp_err_t err = uart_driver_install(m_uart_device.uartInstance, k_uart_buf_size, k_uart_buf_size, 25, &m_uart_queue, 0);
And then when reading the data:

Code: Select all

/**
 * @brief Read bytes from UART buffer
 * @param frame pointer to the buffer to place the data
 * @param statics UART statics pointer destination. Null for don't get the statics
 * @return
 *     - (-1) Error
 *     - OTHERS (>=0) The number of bytes read from UART FIFO
 */
int32_t Uart::getFrame(uint8_t **frame, Statics *statics)
{
    int32_t rsp = UART_ERR;

    if (m_rx_buff != NULL)
    {
        memset(m_rx_buff, 0x00, m_rx_buff_size);
        rsp = uart_read_bytes(m_uart_device.uartInstance, m_rx_buff, m_frame_size,
                              (m_interFrame_tout_us / 1000) / portTICK_RATE_MS);

        (*frame) = m_rx_buff;

        // If 'm_max_frame_size' is reached, internal rx buffer will keep the pending bytes for the next
        // 'uart_read_bytes'

        // And now check all the UART events
        check_uart_events(statics);

        if (rsp > 0)
        {
            if (m_rx_data_inverted)
            {
                invertData(m_rx_buff, rsp);
            }
        }
    }

    return rsp;
}
I called "check_uart_events" function:

Code: Select all

/**
 * @brief Get UART events and fill statics struct accordingly
 * @param statics UART statics pointer destination. Null for don't get the statics
 * @return
 */
uart_func_rsp_t Uart::check_uart_events(Statics *statics)
{
    uart_func_rsp_t rsp = UART_ERR;

    if (statics != NULL)
    {
        statics->INTERRUPTS = 0;
        statics->RX_BREAKS = 0;
        statics->RX_CHARS = 0;
        statics->RX_DROPPED_INPUT = 0;
        statics->RX_FRAMING_ERRORS = 0;
        statics->RX_NOISE_ERRORS = 0;
        statics->RX_OVERRUNS = 0;
        statics->RX_PARITY_ERRORS = 0;
        statics->TX_CHARS = 0;
    }

    do
    {
        uart_event_t uart_event;
        // We must not wait here, but in 'uart_read_bytes' function to keep the compatibility with old/inherited code
        if (xQueueReceive(m_uart_queue, (void *)&uart_event, 0x00))
        {
            switch (uart_event.type)
            {
                case UART_DATA:
                    // We will always read the data, no matter the event type.
                    printf("UART#%u: UART_DATA\r\n", m_uart_device.uartInstance);
                    break;
                // Event of UART parity check error
                case UART_PARITY_ERR:
                    printf("UART#%u: UART_PARITY_ERR\r\n", m_uart_device.uartInstance);
                    if (statics != NULL)
                    {
                        statics->RX_PARITY_ERRORS++;
                    }
                    break;
                // Event of UART frame error
                case UART_FRAME_ERR:
                    printf("UART#%u: UART_FRAME_ERR\r\n", m_uart_device.uartInstance);
                    if (statics != NULL)
                    {
                        statics->RX_FRAMING_ERRORS++;
                    }
                    break;
                // Other events
                default:
                    printf("UART#%u: OTHER_UART_EVENT\r\n", m_uart_device.uartInstance);
                    break;
            }
        }
    } while (uxQueueMessagesWaiting(m_uart_queue));

    return rsp;
}

Who is online

Users browsing this forum: Majestic-12 [Bot] and 59 guests