Issue with uart_enable_pattern_det_baud_intr() on ESP32-C3

mschultz
Posts: 8
Joined: Mon Apr 26, 2021 6:41 pm

Issue with uart_enable_pattern_det_baud_intr() on ESP32-C3

Postby mschultz » Tue Jun 15, 2021 12:50 am

There's a bug in the implementing code for the uart_enable_pattern_det_baud_intr() function in the latest (master) version of ESP-IDF, in source file ./components/driver/uart.c

The gap_tout, pre_idle and post_idle fields of the local at_cmd struct are never set to their respective passed-in values when ESP-IDF is built for a ESP32-C3 target. Thus, the pattern detect function of the UART does not function.

Here's the source for this function, along with the fix I put in.
My fix starts on the #else clause and ends at the #endif.
The 4 lines of code (comment and 3 at_cmd.* assignments) is not present in the original version.

Code: Select all

esp_err_t uart_enable_pattern_det_baud_intr(uart_port_t uart_num, char pattern_chr, uint8_t chr_num, int chr_tout, int post_idle, int pre_idle)
{
    UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL);
    UART_CHECK(chr_tout >= 0 && chr_tout <= UART_RX_GAP_TOUT_V, "uart pattern set error\n", ESP_FAIL);
    UART_CHECK(post_idle >= 0 && post_idle <= UART_POST_IDLE_NUM_V, "uart pattern set error\n", ESP_FAIL);
    UART_CHECK(pre_idle >= 0 && pre_idle <= UART_PRE_IDLE_NUM_V, "uart pattern set error\n", ESP_FAIL);
    uart_at_cmd_t at_cmd = {0};
    at_cmd.cmd_char = pattern_chr;
    at_cmd.char_num = chr_num;

#if CONFIG_IDF_TARGET_ESP32
    int apb_clk_freq = 0;
    uint32_t uart_baud = 0;
    uint32_t uart_div = 0;
    uart_get_baudrate(uart_num, &uart_baud);
    apb_clk_freq = esp_clk_apb_freq();
    uart_div = apb_clk_freq / uart_baud;

    at_cmd.gap_tout = chr_tout * uart_div;
    at_cmd.pre_idle = pre_idle * uart_div;
    at_cmd.post_idle = post_idle * uart_div;
#elif CONFIG_IDF_TARGET_ESP32S2
    at_cmd.gap_tout = chr_tout;
    at_cmd.pre_idle = pre_idle;
    at_cmd.post_idle = post_idle;
#else
    /* mschultz fix 14 Jun 2021 */
    at_cmd.gap_tout = chr_tout;
    at_cmd.pre_idle = pre_idle;
    at_cmd.post_idle = post_idle;
#endif
    uart_hal_clr_intsts_mask(&(uart_context[uart_num].hal), UART_INTR_CMD_CHAR_DET);
    UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
    uart_hal_set_at_cmd_char(&(uart_context[uart_num].hal), &at_cmd);
    uart_hal_ena_intr_mask(&(uart_context[uart_num].hal), UART_INTR_CMD_CHAR_DET);
    UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock));
    return ESP_OK;
}

Who is online

Users browsing this forum: Slinisa and 108 guests