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;
}