From b1b62286db7396e2079ea3d8523cd5c97d659471 Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia Date: Thu, 1 Aug 2024 06:09:59 -0300 Subject: [PATCH] fix(uart): Sets XTAL as clock source for uart (#10087) * fix(uart): Sets XTAL as clock source for uart C6 and H2 have problems after returning from light sleep. The baud rate seems to be off when APB is used as clock source. This fix solves the issue using a steady clock source. * fix(typo): Typo and commentaries Adds C2 in the XTAL list. * fix(uart): adjust get/set baudrate Fixes the functions for reading/writing UART baudrate by using IDF functions instead of HAL/LL. * fix(uart): uses REF_TICK for ESP32/S2 * fix(uart): esp32/s2 baudrate > 1MHz Fixes the baudrate for ESP32 and ESP32-S2 when the baud rate is higher than 1MHz. REF_TICK is just 2MHZ and can handle up to 1MHZ baudrate. * fix(uart): rxTimeout minimum Default RxTimeout changed to the minimum = 1. When TICK_REF is used as clock source, this is mandatory, * ci(pre-commit): Apply automatic fixes --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- cores/esp32/HardwareSerial.cpp | 2 +- cores/esp32/esp32-hal-uart.c | 30 +++++++++++++++++++++--------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/cores/esp32/HardwareSerial.cpp b/cores/esp32/HardwareSerial.cpp index 3d7c70687..1f064faad 100644 --- a/cores/esp32/HardwareSerial.cpp +++ b/cores/esp32/HardwareSerial.cpp @@ -96,7 +96,7 @@ void serialEventRun(void) { #endif HardwareSerial::HardwareSerial(uint8_t uart_nr) - : _uart_nr(uart_nr), _uart(NULL), _rxBufferSize(256), _txBufferSize(0), _onReceiveCB(NULL), _onReceiveErrorCB(NULL), _onReceiveTimeout(false), _rxTimeout(2), + : _uart_nr(uart_nr), _uart(NULL), _rxBufferSize(256), _txBufferSize(0), _onReceiveCB(NULL), _onReceiveErrorCB(NULL), _onReceiveTimeout(false), _rxTimeout(1), _rxFIFOFull(0), _eventTask(NULL) #if !CONFIG_DISABLE_HAL_LOCKS , diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index f87775a83..a33345daa 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -503,8 +503,20 @@ uart_t *uartBegin( uart_config.flow_ctrl = UART_HW_FLOWCTRL_DISABLE; uart_config.rx_flow_ctrl_thresh = rxfifo_full_thrhd; uart_config.baud_rate = baudrate; - // CLK_APB for ESP32|S2|S3|C3 -- CLK_PLL_F40M for C2 -- CLK_PLL_F48M for H2 -- CLK_PLL_F80M for C6 - uart_config.source_clk = UART_SCLK_DEFAULT; + // there is an issue when returning from light sleep with the C6 and H2: the uart baud rate is not restored + // therefore, uart clock source will set to XTAL for all SoC that support it. This fix solves the C6|H2 issue. +#if SOC_UART_SUPPORT_XTAL_CLK + uart_config.source_clk = UART_SCLK_XTAL; // valid for C2, S3, C3, C6, H2 and P4 +#elif SOC_UART_SUPPORT_REF_TICK + if (baudrate <= 1000000) { + uart_config.source_clk = UART_SCLK_REF_TICK; // valid for ESP32, S2 - MAX supported baud rate is 1MHz + } else { + uart_config.source_clk = UART_SCLK_APB; // baudrate may change with the APB Frequency! + } +#else + // Default CLK Source: CLK_APB for ESP32|S2|S3|C3 -- CLK_PLL_F40M for C2 -- CLK_PLL_F48M for H2 -- CLK_PLL_F80M for C6 + uart_config.source_clk = UART_SCLK_DEFAULT; // baudrate may change with the APB Frequency! +#endif UART_MUTEX_LOCK(); bool retCode = ESP_OK == uart_driver_install(uart_nr, rx_buffer_size, tx_buffer_size, 20, &(uart->uart_event_queue), 0); @@ -778,25 +790,25 @@ void uartSetBaudRate(uart_t *uart, uint32_t baud_rate) { return; } UART_MUTEX_LOCK(); - uint32_t sclk_freq; - if (uart_get_sclk_freq(UART_SCLK_DEFAULT, &sclk_freq) == ESP_OK) { - uart_ll_set_baudrate(UART_LL_GET_HW(uart->num), baud_rate, sclk_freq); + if (uart_set_baudrate(uart->num, baud_rate) == ESP_OK) { + uart->_baudrate = baud_rate; + } else { + log_e("Setting UART%d baud rate to %d has failed.", uart->num, baud_rate); } - uart->_baudrate = baud_rate; UART_MUTEX_UNLOCK(); } uint32_t uartGetBaudRate(uart_t *uart) { uint32_t baud_rate = 0; - uint32_t sclk_freq; if (uart == NULL) { return 0; } UART_MUTEX_LOCK(); - if (uart_get_sclk_freq(UART_SCLK_DEFAULT, &sclk_freq) == ESP_OK) { - baud_rate = uart_ll_get_baudrate(UART_LL_GET_HW(uart->num), sclk_freq); + if (uart_get_baudrate(uart->num, &baud_rate) != ESP_OK) { + log_e("Getting UART%d baud rate has failed.", uart->num); + baud_rate = (uint32_t)-1; // return value when failed } UART_MUTEX_UNLOCK(); return baud_rate;