From fb8b90553933be6492c3974c285d9fdd55f32a30 Mon Sep 17 00:00:00 2001 From: Armando Date: Thu, 19 Nov 2020 17:03:10 +0800 Subject: [PATCH 1/2] uart: add uart support on esp32s3 --- components/console/esp_console_repl.c | 6 +- components/driver/test/test_uart.c | 57 +++++++---- components/driver/uart.c | 1 + components/esp_pm/pm_impl.c | 9 +- components/hal/esp32/include/hal/uart_ll.h | 64 ++++++++---- components/hal/esp32s2/include/hal/uart_ll.h | 64 ++++++++---- components/hal/esp32s3/include/hal/uart_ll.h | 99 +++++++++++++++---- components/hal/include/hal/uart_hal.h | 31 +++--- components/hal/include/hal/uart_types.h | 12 ++- components/hal/uart_hal.c | 23 ++++- components/soc/esp32/include/soc/soc_caps.h | 8 +- components/soc/esp32s2/include/soc/soc_caps.h | 8 +- components/soc/esp32s3/include/soc/soc.h | 2 + components/soc/esp32s3/include/soc/soc_caps.h | 14 +-- .../soc/esp32s3/include/soc/uart_caps.h | 3 +- .../soc/esp32s3/include/soc/uart_struct.h | 1 + components/soc/esp32s3/uart_periph.c | 10 +- 17 files changed, 299 insertions(+), 113 deletions(-) diff --git a/components/console/esp_console_repl.c b/components/console/esp_console_repl.c index 080096b47a..19dd9d85ab 100644 --- a/components/console/esp_console_repl.c +++ b/components/console/esp_console_repl.c @@ -152,7 +152,7 @@ esp_err_t esp_console_new_repl_uart(const esp_console_dev_uart_config_t *dev_con /* Move the caret to the beginning of the next line on '\n' */ esp_vfs_dev_uart_port_set_tx_line_endings(dev_config->channel, ESP_LINE_ENDINGS_CRLF); - /* Configure UART. Note that REF_TICK is used so that the baud rate remains + /* Configure UART. Note that REF_TICK/XTAL is used so that the baud rate remains * correct while APB frequency is changing in light sleep mode. */ const uart_config_t uart_config = { @@ -160,7 +160,11 @@ esp_err_t esp_console_new_repl_uart(const esp_console_dev_uart_config_t *dev_con .data_bits = UART_DATA_8_BITS, .parity = UART_PARITY_DISABLE, .stop_bits = UART_STOP_BITS_1, +#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 .source_clk = UART_SCLK_REF_TICK, +#else + .source_clk = UART_SCLK_XTAL, +#endif }; uart_param_config(dev_config->channel, &uart_config); diff --git a/components/driver/test/test_uart.c b/components/driver/test/test_uart.c index 4a89854042..4ec10c2a00 100644 --- a/components/driver/test/test_uart.c +++ b/components/driver/test/test_uart.c @@ -5,8 +5,8 @@ #include "driver/uart.h" // for the uart driver access #include "esp_log.h" #include "esp_system.h" // for uint32_t esp_random() - -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3) +#include "esp_rom_gpio.h" +#include "soc/uart_periph.h" #define UART_TAG "Uart" #define UART_NUM1 (UART_NUM_1) @@ -17,6 +17,7 @@ #define UART_BAUD_115200 (115200) #define TOLERANCE (0.02) //baud rate error tolerance 2%. +#define UART1_CTS_PIN (13) // RTS for RS485 Half-Duplex Mode manages DE/~RE #define UART1_RTS_PIN (18) @@ -26,16 +27,19 @@ // Wait timeout for uart driver #define PACKET_READ_TICS (1000 / portTICK_RATE_MS) -static void uart_config(uint32_t baud_rate, bool use_ref_tick) +#define TEST_DEFAULT_CLK UART_SCLK_APB + +static void uart_config(uint32_t baud_rate, uart_sclk_t source_clk) { uart_config_t uart_config = { .baud_rate = baud_rate, + .source_clk = source_clk, .data_bits = UART_DATA_8_BITS, .parity = UART_PARITY_DISABLE, .stop_bits = UART_STOP_BITS_1, .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, }; - uart_config.source_clk = use_ref_tick ? UART_SCLK_REF_TICK : UART_SCLK_APB; + uart_driver_install(UART_NUM1, BUF_SIZE * 2, BUF_SIZE * 2, 20, NULL, 0); uart_param_config(UART_NUM1, &uart_config); TEST_ESP_OK(uart_set_loop_back(UART_NUM1, true)); @@ -71,7 +75,7 @@ static void test_task2(void *pvParameters) TEST_CASE("test uart_wait_tx_done is not blocked when ticks_to_wait=0", "[uart]") { - uart_config(UART_BAUD_11520, false); + uart_config(UART_BAUD_11520, TEST_DEFAULT_CLK); xSemaphoreHandle exit_sema = xSemaphoreCreateBinary(); exit_flag = false; @@ -93,19 +97,22 @@ TEST_CASE("test uart_wait_tx_done is not blocked when ticks_to_wait=0", "[uart]" TEST_CASE("test uart get baud-rate", "[uart]") { +#if SOC_UART_SUPPORT_REF_TICK uint32_t baud_rate1 = 0; - uint32_t baud_rate2 = 0; printf("init uart%d, use reftick, baud rate : %d\n", (int)UART_NUM1, (int)UART_BAUD_11520); - uart_config(UART_BAUD_11520, true); + uart_config(UART_BAUD_11520, UART_SCLK_REF_TICK); uart_get_baudrate(UART_NUM1, &baud_rate1); - printf("init uart%d, unuse reftick, baud rate : %d\n", (int)UART_NUM1, (int)UART_BAUD_115200); - uart_config(UART_BAUD_115200, false); - uart_get_baudrate(UART_NUM1, &baud_rate2); printf("get baud rate when use reftick: %d\n", (int)baud_rate1); - printf("get baud rate when don't use reftick: %d\n", (int)baud_rate2); - uart_driver_delete(UART_NUM1); TEST_ASSERT_UINT32_WITHIN(UART_BAUD_11520 * TOLERANCE, UART_BAUD_11520, baud_rate1); +#endif + uint32_t baud_rate2 = 0; + printf("init uart%d, unuse reftick, baud rate : %d\n", (int)UART_NUM1, (int)UART_BAUD_115200); + uart_config(UART_BAUD_115200, TEST_DEFAULT_CLK); + uart_get_baudrate(UART_NUM1, &baud_rate2); + printf("get baud rate when don't use reftick: %d\n", (int)baud_rate2); TEST_ASSERT_UINT32_WITHIN(UART_BAUD_115200 * TOLERANCE, UART_BAUD_115200, baud_rate2); + + uart_driver_delete(UART_NUM1); ESP_LOGI(UART_TAG, "get baud-rate test passed ....\n"); } @@ -117,7 +124,7 @@ TEST_CASE("test uart tx data with break", "[uart]") char *psend = (char *)malloc(buf_len); TEST_ASSERT_NOT_NULL(psend); memset(psend, '0', buf_len); - uart_config(UART_BAUD_115200, false); + uart_config(UART_BAUD_115200, TEST_DEFAULT_CLK); printf("Uart%d send %d bytes with break\n", UART_NUM1, send_len); uart_write_bytes_with_break(UART_NUM1, (const char *)psend, send_len, brk_len); uart_wait_tx_done(UART_NUM1, (portTickType)portMAX_DELAY); @@ -203,7 +210,7 @@ TEST_CASE("uart general API test", "[uart]") .parity = UART_PARITY_DISABLE, .stop_bits = UART_STOP_BITS_1, .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, - .source_clk = UART_SCLK_APB, + .source_clk = TEST_DEFAULT_CLK, }; uart_param_config(uart_num, &uart_config); uart_word_len_set_get_test(uart_num); @@ -234,6 +241,15 @@ static void uart_write_task(void *param) vTaskDelete(NULL); } +/** + * The following tests use loop back + * + * NOTE: In the following tests, because the internal loopback is enabled, the CTS signal is connected to + * the RTS signal internally. However, On ESP32S3, they are not, and the CTS keeps the default level (which + * is a high level). So the workaround is to map the CTS in_signal to a GPIO pin (here IO13 is used) and connect + * the RTS output_signal to this IO. + */ + TEST_CASE("uart read write test", "[uart]") { const int uart_num = UART_NUM1; @@ -247,12 +263,15 @@ TEST_CASE("uart read write test", "[uart]") .parity = UART_PARITY_DISABLE, .stop_bits = UART_STOP_BITS_1, .flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS, - .source_clk = UART_SCLK_APB, + .source_clk = TEST_DEFAULT_CLK, .rx_flow_ctrl_thresh = 120 }; TEST_ESP_OK(uart_driver_install(uart_num, BUF_SIZE * 2, 0, 20, NULL, 0)); TEST_ESP_OK(uart_param_config(uart_num, &uart_config)); TEST_ESP_OK(uart_set_loop_back(uart_num, true)); + TEST_ESP_OK(uart_set_pin(uart_num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART1_CTS_PIN)); + //Connect the RTS out_signal to the CTS pin (which is mapped to CTS in_signal) + esp_rom_gpio_connect_out_signal(UART1_CTS_PIN, uart_periph_signal[uart_num].rts_sig, 0, 0); TEST_ESP_OK(uart_wait_tx_done(uart_num, portMAX_DELAY)); vTaskDelay(1 / portTICK_PERIOD_MS); // make sure last byte has flushed from TX FIFO @@ -313,12 +332,16 @@ TEST_CASE("uart tx with ringbuffer test", "[uart]") .stop_bits = UART_STOP_BITS_1, .flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS, .rx_flow_ctrl_thresh = 120, - .source_clk = UART_SCLK_APB, + .source_clk = TEST_DEFAULT_CLK, }; uart_wait_tx_idle_polling(uart_num); TEST_ESP_OK(uart_param_config(uart_num, &uart_config)); TEST_ESP_OK(uart_driver_install(uart_num, 1024 * 2, 1024 *2, 20, NULL, 0)); TEST_ESP_OK(uart_set_loop_back(uart_num, true)); + TEST_ESP_OK(uart_set_pin(uart_num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART1_CTS_PIN)); + //Connect the RTS out_signal to the CTS pin (which is mapped to CTS in_signal) + esp_rom_gpio_connect_out_signal(UART1_CTS_PIN, uart_periph_signal[uart_num].rts_sig, 0, 0); + for (int i = 0; i < 1024; i++) { wr_data[i] = i; rd_data[i] = 0; @@ -331,5 +354,3 @@ TEST_CASE("uart tx with ringbuffer test", "[uart]") free(rd_data); free(wr_data); } - -#endif diff --git a/components/driver/uart.c b/components/driver/uart.c index 47a4081e66..49b718611d 100644 --- a/components/driver/uart.c +++ b/components/driver/uart.c @@ -628,6 +628,7 @@ esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_conf uart_module_enable(uart_num); UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); uart_hal_init(&(uart_context[uart_num].hal), uart_num); + uart_hal_set_sclk(&(uart_context[uart_num].hal), uart_config->source_clk); uart_hal_set_baudrate(&(uart_context[uart_num].hal), uart_config->source_clk, uart_config->baud_rate); uart_hal_set_parity(&(uart_context[uart_num].hal), uart_config->parity); uart_hal_set_data_bit_num(&(uart_context[uart_num].hal), uart_config->data_bits); diff --git a/components/esp_pm/pm_impl.c b/components/esp_pm/pm_impl.c index 85b51712d7..7a1990db0d 100644 --- a/components/esp_pm/pm_impl.c +++ b/components/esp_pm/pm_impl.c @@ -680,9 +680,16 @@ void esp_pm_impl_dump_stats(FILE* out) void esp_pm_impl_init(void) { #if defined(CONFIG_ESP_CONSOLE_UART) + //This clock source should be a source which won't be affected by DFS + uint32_t clk_source; +#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 + clk_source = UART_SCLK_REF_TICK; +#else + clk_source = UART_SCLK_XTAL; +#endif while(!uart_ll_is_tx_idle(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM))); /* When DFS is enabled, override system setting and use REFTICK as UART clock source */ - uart_ll_set_baudrate(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), UART_SCLK_REF_TICK, CONFIG_ESP_CONSOLE_UART_BAUDRATE); + uart_ll_set_baudrate(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), clk_source, CONFIG_ESP_CONSOLE_UART_BAUDRATE); #endif // CONFIG_ESP_CONSOLE_UART #ifdef CONFIG_PM_TRACE diff --git a/components/hal/esp32/include/hal/uart_ll.h b/components/hal/esp32/include/hal/uart_ll.h index 905c149c48..87cc42d80a 100644 --- a/components/hal/esp32/include/hal/uart_ll.h +++ b/components/hal/esp32/include/hal/uart_ll.h @@ -58,6 +58,44 @@ typedef enum { UART_INTR_CMD_CHAR_DET = (0x1<<18), } uart_intr_t; +/** + * @brief Set the UART source clock. + * + * @param hw Beginning address of the peripheral registers. + * @param source_clk The UART source clock. The source clock can be APB clock or REF_TICK. + * If the source clock is REF_TICK, the UART can still work when the APB changes. + * + * @return None. + */ +static inline void uart_ll_set_sclk(uart_dev_t *hw, uart_sclk_t source_clk) +{ + hw->conf0.tick_ref_always_on = (source_clk == UART_SCLK_APB) ? 1 : 0; +} + +/** + * @brief Get the UART source clock type. + * + * @param hw Beginning address of the peripheral registers. + * @param source_clk The pointer to accept the UART source clock type. + * + * @return None. + */ +static inline void uart_ll_get_sclk(uart_dev_t *hw, uart_sclk_t* source_clk) +{ + *source_clk = hw->conf0.tick_ref_always_on ? UART_SCLK_APB : UART_SCLK_REF_TICK; +} + +/** + * @brief Get the UART source clock frequency. + * + * @param hw Beginning address of the peripheral registers. + * + * @return Current source clock frequency + */ +static inline uint32_t uart_ll_get_sclk_freq(uart_dev_t *hw) +{ + return (hw->conf0.tick_ref_always_on) ? APB_CLK_FREQ : REF_CLK_FREQ; +} /** * @brief Configure the baud-rate. @@ -71,14 +109,15 @@ typedef enum { */ static inline void uart_ll_set_baudrate(uart_dev_t *hw, uart_sclk_t source_clk, uint32_t baud) { - uint32_t sclk_freq = (source_clk == UART_SCLK_APB) ? APB_CLK_FREQ : REF_CLK_FREQ; - uint32_t clk_div = ((sclk_freq) << 4) / baud; + uint32_t sclk_freq, clk_div; + + uart_ll_set_sclk(hw, source_clk); + sclk_freq = uart_ll_get_sclk_freq(hw); + clk_div = ((sclk_freq) << 4) / baud; // The baud-rate configuration register is divided into // an integer part and a fractional part. hw->clk_div.div_int = clk_div >> 4; hw->clk_div.div_frag = clk_div & 0xf; - // Configure the UART source clock. - hw->conf0.tick_ref_always_on = (source_clk == UART_SCLK_APB); } /** @@ -90,9 +129,9 @@ static inline void uart_ll_set_baudrate(uart_dev_t *hw, uart_sclk_t source_clk, */ static inline uint32_t uart_ll_get_baudrate(uart_dev_t *hw) { - uint32_t src_clk = hw->conf0.tick_ref_always_on ? APB_CLK_FREQ : REF_CLK_FREQ; + uint32_t sclk_freq = uart_ll_get_sclk_freq(hw); typeof(hw->clk_div) div_reg = hw->clk_div; - return ((src_clk << 4)) / ((div_reg.div_int << 4) | div_reg.div_frag); + return ((sclk_freq << 4)) / ((div_reg.div_int << 4) | div_reg.div_frag); } /** @@ -526,19 +565,6 @@ static inline void uart_ll_set_data_bit_num(uart_dev_t *hw, uart_word_length_t d hw->conf0.bit_num = data_bit; } -/** - * @brief Get the UART source clock. - * - * @param hw Beginning address of the peripheral registers. - * @param source_clk The pointer to accept the UART source clock configuration. - * - * @return None. - */ -static inline void uart_ll_get_sclk(uart_dev_t *hw, uart_sclk_t* source_clk) -{ - *source_clk = hw->conf0.tick_ref_always_on ? UART_SCLK_APB : UART_SCLK_REF_TICK; -} - /** * @brief Set the rts active level. * diff --git a/components/hal/esp32s2/include/hal/uart_ll.h b/components/hal/esp32s2/include/hal/uart_ll.h index 76d20093ec..c8a721b940 100644 --- a/components/hal/esp32s2/include/hal/uart_ll.h +++ b/components/hal/esp32s2/include/hal/uart_ll.h @@ -55,6 +55,44 @@ typedef enum { UART_INTR_CMD_CHAR_DET = (0x1<<18), } uart_intr_t; +/** + * @brief Set the UART source clock. + * + * @param hw Beginning address of the peripheral registers. + * @param source_clk The UART source clock. The source clock can be APB clock or REF_TICK. + * If the source clock is REF_TICK, the UART can still work when the APB changes. + * + * @return None. + */ +static inline void uart_ll_set_sclk(uart_dev_t *hw, uart_sclk_t source_clk) +{ + hw->conf0.tick_ref_always_on = (source_clk == UART_SCLK_APB) ? 1 : 0; +} + +/** + * @brief Get the UART source clock type. + * + * @param hw Beginning address of the peripheral registers. + * @param source_clk The pointer to accept the UART source clock type. + * + * @return None. + */ +static inline void uart_ll_get_sclk(uart_dev_t *hw, uart_sclk_t* source_clk) +{ + *source_clk = hw->conf0.tick_ref_always_on ? UART_SCLK_APB : UART_SCLK_REF_TICK; +} + +/** + * @brief Get the UART source clock frequency. + * + * @param hw Beginning address of the peripheral registers. + * + * @return Current source clock frequency + */ +static inline uint32_t uart_ll_get_sclk_freq(uart_dev_t *hw) +{ + return (hw->conf0.tick_ref_always_on) ? APB_CLK_FREQ : REF_CLK_FREQ; +} /** * @brief Configure the baud-rate. @@ -68,14 +106,15 @@ typedef enum { */ static inline void uart_ll_set_baudrate(uart_dev_t *hw, uart_sclk_t source_clk, uint32_t baud) { - uint32_t sclk_freq = (source_clk == UART_SCLK_APB) ? APB_CLK_FREQ : REF_CLK_FREQ; - uint32_t clk_div = ((sclk_freq) << 4) / baud; + uint32_t sclk_freq, clk_div; + + uart_ll_set_sclk(hw, source_clk); + sclk_freq = uart_ll_get_sclk_freq(hw); + clk_div = ((sclk_freq) << 4) / baud; // The baud rate configuration register is divided into // an integer part and a fractional part. hw->clk_div.div_int = clk_div >> 4; hw->clk_div.div_frag = clk_div & 0xf; - // Configure the UART source clock. - hw->conf0.tick_ref_always_on = (source_clk == UART_SCLK_APB); } /** @@ -87,9 +126,9 @@ static inline void uart_ll_set_baudrate(uart_dev_t *hw, uart_sclk_t source_clk, */ static inline uint32_t uart_ll_get_baudrate(uart_dev_t *hw) { - uint32_t src_clk = hw->conf0.tick_ref_always_on ? APB_CLK_FREQ : REF_CLK_FREQ; + uint32_t sclk_freq = uart_ll_get_sclk_freq(hw); typeof(hw->clk_div) div_reg = hw->clk_div; - return ((src_clk << 4)) / ((div_reg.div_int << 4) | div_reg.div_frag); + return ((sclk_freq << 4)) / ((div_reg.div_int << 4) | div_reg.div_frag); } /** @@ -476,19 +515,6 @@ static inline void uart_ll_set_data_bit_num(uart_dev_t *hw, uart_word_length_t d hw->conf0.bit_num = data_bit; } -/** - * @brief Get the UART source clock. - * - * @param hw Beginning address of the peripheral registers. - * @param source_clk The pointer to accept the UART source clock configuration. - * - * @return None. - */ -static inline void uart_ll_get_sclk(uart_dev_t *hw, uart_sclk_t* source_clk) -{ - *source_clk = hw->conf0.tick_ref_always_on ? UART_SCLK_APB : UART_SCLK_REF_TICK; -} - /** * @brief Set the rts active level. * diff --git a/components/hal/esp32s3/include/hal/uart_ll.h b/components/hal/esp32s3/include/hal/uart_ll.h index 22d6f24c8d..6a6be04c13 100644 --- a/components/hal/esp32s3/include/hal/uart_ll.h +++ b/components/hal/esp32s3/include/hal/uart_ll.h @@ -27,7 +27,7 @@ extern "C" { // The default fifo depth #define UART_LL_FIFO_DEF_LEN (SOC_UART_FIFO_LEN) // Get UART hardware instance with giving uart num -#define UART_LL_GET_HW(num) (((num) == 0) ? (&UART0) : (&UART1)) +#define UART_LL_GET_HW(num) (((num) == 0) ? (&UART0) : (((num) == 1) ? (&UART1) : (&UART2))) #define UART_LL_MIN_WAKEUP_THRESH (2) #define UART_LL_INTR_MASK (0x7ffff) //All interrupt mask @@ -56,20 +56,92 @@ typedef enum { } uart_intr_t; +/** + * @brief Set the UART source clock. + * + * @param hw Beginning address of the peripheral registers. + * @param source_clk The UART source clock. The source clock can be APB clock, RTC clock or XTAL clock. + * If the source clock is RTC/XTAL, the UART can still work when the APB changes. + * + * @return None. + */ +static inline void uart_ll_set_sclk(uart_dev_t *hw, uart_sclk_t source_clk) +{ + switch (source_clk) { + default: + case UART_SCLK_APB: + hw->clk_conf.sclk_sel = 1; + break; + case UART_SCLK_RTC: + hw->clk_conf.sclk_sel = 2; + break; + case UART_SCLK_XTAL: + hw->clk_conf.sclk_sel = 3; + break; + } +} + +/** + * @brief Get the UART source clock type. + * + * @param hw Beginning address of the peripheral registers. + * @param source_clk The pointer to accept the UART source clock type. + * + * @return None. + */ +static inline void uart_ll_get_sclk(uart_dev_t *hw, uart_sclk_t *source_clk) +{ + switch (hw->clk_conf.sclk_sel) { + default: + case 1: + *source_clk = UART_SCLK_APB; + break; + case 2: + *source_clk = UART_SCLK_RTC; + break; + case 3: + *source_clk = UART_SCLK_XTAL; + break; + } +} + +/** + * @brief Get the UART source clock frequency. + * + * @param hw Beginning address of the peripheral registers. + * + * @return Current source clock frequency + */ +static inline uint32_t uart_ll_get_sclk_freq(uart_dev_t *hw) +{ + switch (hw->clk_conf.sclk_sel) { + default: + case 1: + return APB_CLK_FREQ; + case 2: + return RTC_CLK_FREQ; + case 3: + return XTAL_CLK_FREQ; + } +} + /** * @brief Configure the baud-rate. * * @param hw Beginning address of the peripheral registers. + * @param source_clk The UART source clock. The source clock can be APB clock, RTC clock or XTAL clock. + * If the source clock is RTC/XTAL, the UART can still work when the APB changes. * @param baud The baud rate to be set. When the source clock is APB, the max baud rate is `UART_LL_BITRATE_MAX` - * @param source_clk The UART source clock. The source clock can be APB clock or REF_TICK. - * If the source clock is REF_TICK, the UART can still work when the APB changes. * * @return None */ static inline void uart_ll_set_baudrate(uart_dev_t *hw, uart_sclk_t source_clk, uint32_t baud) { - uint32_t sclk_freq = (source_clk == UART_SCLK_APB) ? APB_CLK_FREQ : REF_CLK_FREQ; - uint32_t clk_div = ((sclk_freq) << 4) / baud; + uint32_t sclk_freq, clk_div; + + uart_ll_set_sclk(hw, source_clk); + sclk_freq = uart_ll_get_sclk_freq(hw); + clk_div = ((sclk_freq) << 4) / baud; // The baud rate configuration register is divided into // an integer part and a fractional part. hw->clk_div.div_int = clk_div >> 4; @@ -85,9 +157,9 @@ static inline void uart_ll_set_baudrate(uart_dev_t *hw, uart_sclk_t source_clk, */ static inline uint32_t uart_ll_get_baudrate(uart_dev_t *hw) { - uint32_t src_clk = APB_CLK_FREQ; + uint32_t sclk_freq = uart_ll_get_sclk_freq(hw); typeof(hw->clk_div) div_reg = hw->clk_div; - return ((src_clk << 4)) / ((div_reg.div_int << 4) | div_reg.div_frag); + return ((sclk_freq << 4)) / ((div_reg.div_int << 4) | div_reg.div_frag); } /** @@ -473,19 +545,6 @@ static inline void uart_ll_set_data_bit_num(uart_dev_t *hw, uart_word_length_t d hw->conf0.bit_num = data_bit; } -/** - * @brief Get the UART source clock. - * - * @param hw Beginning address of the peripheral registers. - * @param source_clk The pointer to accept the UART source clock configuration. - * - * @return None. - */ -static inline void uart_ll_get_sclk(uart_dev_t *hw, uart_sclk_t *source_clk) -{ - *source_clk = UART_SCLK_APB; -} - /** * @brief Set the rts active level. * diff --git a/components/hal/include/hal/uart_hal.h b/components/hal/include/hal/uart_hal.h index 7cc52405a0..45ff08d53f 100644 --- a/components/hal/include/hal/uart_hal.h +++ b/components/hal/include/hal/uart_hal.h @@ -177,11 +177,30 @@ void uart_hal_rxfifo_rst(uart_hal_context_t *hal); */ void uart_hal_init(uart_hal_context_t *hal, uart_port_t uart_num); +/** + * @brief Set the UART source clock type + * @param hal Context of the HAL layer + * @param sclk The UART source clock type. + * + * @return None + */ +void uart_hal_set_sclk(uart_hal_context_t *hal, uart_sclk_t sclk); + +/** + * @brief Get the UART source clock type + * + * @param hal Context of the HAL layer + * @param sclk The poiter to accept the UART source clock type + * + * @return None + */ +void uart_hal_get_sclk(uart_hal_context_t *hal, uart_sclk_t *sclk); + /** * @brief Configure the UART baud-rate and select the source clock * * @param hal Context of the HAL layer - * @param source_clk The UART source clock. Support `UART_SCLK_REF_TICK` and `UART_SCLK_APB` + * @param source_clk The UART source clock. * @param baud_rate The baud-rate to be set * * @return None @@ -412,16 +431,6 @@ void uart_hal_get_hw_flow_ctrl(uart_hal_context_t *hal, uart_hw_flowcontrol_t *f */ bool uart_hal_is_hw_rts_en(uart_hal_context_t *hal); -/** - * @brief Get the UART source clock configuration - * - * @param hal Context of the HAL layer - * @param sclk The poiter to accept the UART source clock configuration - * - * @return None - */ -void uart_hal_get_sclk(uart_hal_context_t *hal, uart_sclk_t *sclk); - /** * @brief Configure TX signal loop back to RX module, just for the testing purposes * diff --git a/components/hal/include/hal/uart_types.h b/components/hal/include/hal/uart_types.h index 04ff86b323..1e1110f136 100644 --- a/components/hal/include/hal/uart_types.h +++ b/components/hal/include/hal/uart_types.h @@ -99,8 +99,16 @@ typedef enum { * @brief UART source clock */ typedef enum { - UART_SCLK_APB = 0x0, /*!< UART source clock from APB*/ - UART_SCLK_REF_TICK = 0x01, /*!< UART source clock from REF_TICK*/ + UART_SCLK_APB = 0x0, /*!< UART source clock from APB*/ +#if SOC_UART_SUPPORT_RTC_CLK + UART_SCLK_RTC = 0x1, /*!< UART source clock from RTC*/ +#endif +#if SOC_UART_SUPPORT_XTAL_CLK + UART_SCLK_XTAL = 0x2, /*!< UART source clock from XTAL*/ +#endif +#if SOC_UART_SUPPORT_REF_TICK + UART_SCLK_REF_TICK = 0x3, /*!< UART source clock from REF_TICK*/ +#endif } uart_sclk_t; /** diff --git a/components/hal/uart_hal.c b/components/hal/uart_hal.c index 742c3ad673..4f243fab08 100644 --- a/components/hal/uart_hal.c +++ b/components/hal/uart_hal.c @@ -14,7 +14,23 @@ // The HAL layer for UART (common part) #include "hal/uart_hal.h" +#include "soc/rtc_cntl_reg.h" +void uart_hal_set_sclk(uart_hal_context_t *hal, uart_sclk_t sclk) +{ + uart_ll_set_sclk(hal->dev, sclk); + +#if SOC_UART_SUPPORT_RTC_CLK + if (sclk == UART_SCLK_RTC) { + SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M); + } +#endif +} + +void uart_hal_get_sclk(uart_hal_context_t *hal, uart_sclk_t *sclk) +{ + uart_ll_get_sclk(hal->dev, sclk); +} void uart_hal_set_baudrate(uart_hal_context_t *hal, uart_sclk_t source_clk, uint32_t baud_rate) { @@ -76,11 +92,6 @@ void uart_hal_set_at_cmd_char(uart_hal_context_t *hal, uart_at_cmd_t *at_cmd) uart_ll_set_at_cmd_char(hal->dev, at_cmd); } -void uart_hal_get_sclk(uart_hal_context_t *hal, uart_sclk_t *sclk) -{ - uart_ll_get_sclk(hal->dev, sclk); -} - void uart_hal_set_tx_idle_num(uart_hal_context_t *hal, uint16_t idle_num) { uart_ll_set_tx_idle_num(hal->dev, idle_num); @@ -133,6 +144,8 @@ void uart_hal_set_loop_back(uart_hal_context_t *hal, bool loop_back_en) void uart_hal_init(uart_hal_context_t *hal, int uart_num) { + // Set clock source + uart_ll_set_sclk(hal->dev, UART_SCLK_APB); // Set default baud: 115200, use APB clock. const uint32_t baud_def = 115200; uart_ll_set_baudrate(hal->dev, UART_SCLK_APB, baud_def); diff --git a/components/soc/esp32/include/soc/soc_caps.h b/components/soc/esp32/include/soc/soc_caps.h index d547e725f7..45889d3f42 100644 --- a/components/soc/esp32/include/soc/soc_caps.h +++ b/components/soc/esp32/include/soc/soc_caps.h @@ -229,10 +229,10 @@ /*-------------------------- UART CAPS ---------------------------------------*/ // ESP32 have 3 UART. -#define SOC_UART_NUM (3) - -#define SOC_UART_FIFO_LEN (128) /*!< The UART hardware FIFO length */ -#define SOC_UART_BITRATE_MAX (5000000) /*!< Max bit rate supported by UART */ +#define SOC_UART_NUM (3) +#define SOC_UART_SUPPORT_REF_TICK (1) /*!< Support REF_TICK as the clock source */ +#define SOC_UART_FIFO_LEN (128) /*!< The UART hardware FIFO length */ +#define SOC_UART_BITRATE_MAX (5000000) /*!< Max bit rate supported by UART */ /*--------------------------- SHA CAPS ---------------------------------------*/ diff --git a/components/soc/esp32s2/include/soc/soc_caps.h b/components/soc/esp32s2/include/soc/soc_caps.h index f559b740b0..a25f4c75a8 100644 --- a/components/soc/esp32s2/include/soc/soc_caps.h +++ b/components/soc/esp32s2/include/soc/soc_caps.h @@ -221,10 +221,10 @@ /*-------------------------- UART CAPS ---------------------------------------*/ // ESP32-S2 have 2 UART. -#define SOC_UART_NUM (2) - -#define SOC_UART_FIFO_LEN (128) /*!< The UART hardware FIFO length */ -#define SOC_UART_BITRATE_MAX (5000000) /*!< Max bit rate supported by UART */ +#define SOC_UART_NUM (2) +#define SOC_UART_SUPPORT_REF_TICK (1) /*!< Support REF_TICK as the clock source */ +#define SOC_UART_FIFO_LEN (128) /*!< The UART hardware FIFO length */ +#define SOC_UART_BITRATE_MAX (5000000) /*!< Max bit rate supported by UART */ /*-------------------------- USB CAPS ----------------------------------------*/ #define SOC_USB_PERIPH_NUM 1 diff --git a/components/soc/esp32s3/include/soc/soc.h b/components/soc/esp32s3/include/soc/soc.h index fae2996288..a9d386b560 100644 --- a/components/soc/esp32s3/include/soc/soc.h +++ b/components/soc/esp32s3/include/soc/soc.h @@ -220,6 +220,8 @@ #define CPU_CLK_FREQ APB_CLK_FREQ #define APB_CLK_FREQ (80*1000000) #define REF_CLK_FREQ (1000000) +#define RTC_CLK_FREQ (20*1000000) +#define XTAL_CLK_FREQ (40*1000000) #define UART_CLK_FREQ APB_CLK_FREQ #define WDT_CLK_FREQ APB_CLK_FREQ #define TIMER_CLK_FREQ (80000000>>4) diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index 4e455694ed..7f70afb676 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -6,12 +6,12 @@ #pragma once /*-------------------------- COMMON CAPS ---------------------------------------*/ -#define SOC_PCNT_SUPPORTED 1 -#define SOC_TWAI_SUPPORTED 1 -#define SOC_GDMA_SUPPORTED 1 -#define SOC_DEDICATED_GPIO_SUPPORTED 1 -#define SOC_CPU_CORES_NUM 2 -#define SOC_CACHE_SUPPORT_WRAP 1 +#define SOC_PCNT_SUPPORTED 1 +#define SOC_TWAI_SUPPORTED 1 +#define SOC_GDMA_SUPPORTED 1 +#define SOC_DEDICATED_GPIO_SUPPORTED 1 +#define SOC_CACHE_SUPPORT_WRAP 1 +#define SOC_CPU_CORES_NUM 2 /*-------------------------- ADC CAPS ----------------------------------------*/ #include "adc_caps.h" @@ -93,6 +93,8 @@ /*-------------------------- UART CAPS ---------------------------------------*/ #include "uart_caps.h" +#define SOC_UART_SUPPORT_RTC_CLK (1) /*!< Support RTC clock as the clock source */ +#define SOC_UART_SUPPORT_XTAL_CLK (1) /*!< Support XTAL clock as the clock source */ /*--------------------------- SHA CAPS ---------------------------------------*/ /* Max amount of bytes in a single DMA operation is 4095, diff --git a/components/soc/esp32s3/include/soc/uart_caps.h b/components/soc/esp32s3/include/soc/uart_caps.h index 3691273a2e..2024c7a2e5 100644 --- a/components/soc/esp32s3/include/soc/uart_caps.h +++ b/components/soc/esp32s3/include/soc/uart_caps.h @@ -21,8 +21,7 @@ extern "C" { #define SOC_UART_FIFO_LEN (128) /*!< The UART hardware FIFO length */ #define SOC_UART_BITRATE_MAX (5000000) /*!< Max bit rate supported by UART */ -// ESP32-S3 have 2 UART -#define SOC_UART_NUM (2) +#define SOC_UART_NUM (3) #ifdef __cplusplus } diff --git a/components/soc/esp32s3/include/soc/uart_struct.h b/components/soc/esp32s3/include/soc/uart_struct.h index ba2efb33c9..d3564c8a6b 100644 --- a/components/soc/esp32s3/include/soc/uart_struct.h +++ b/components/soc/esp32s3/include/soc/uart_struct.h @@ -395,6 +395,7 @@ typedef volatile struct { extern uart_dev_t UART0; extern uart_dev_t UART1; +extern uart_dev_t UART2; #ifdef __cplusplus } diff --git a/components/soc/esp32s3/uart_periph.c b/components/soc/esp32s3/uart_periph.c index a2c8e1646f..78b8090b15 100644 --- a/components/soc/esp32s3/uart_periph.c +++ b/components/soc/esp32s3/uart_periph.c @@ -33,5 +33,13 @@ const uart_signal_conn_t uart_periph_signal[SOC_UART_NUM] = { .cts_sig = U1CTS_IN_IDX, .irq = ETS_UART1_INTR_SOURCE, .module = PERIPH_UART1_MODULE, - } + }, + { + .tx_sig = U2TXD_OUT_IDX, + .rx_sig = U2RXD_IN_IDX, + .rts_sig = U2RTS_OUT_IDX, + .cts_sig = U2CTS_IN_IDX, + .irq = ETS_UART2_INTR_SOURCE, + .module = PERIPH_UART2_MODULE, + }, }; From 05a4a8d8645c88bd5b1cee6c83782b853687e301 Mon Sep 17 00:00:00 2001 From: Armando Date: Mon, 23 Nov 2020 19:31:50 +0800 Subject: [PATCH 2/2] uart: seperate sclk and baudrate setting --- components/driver/uart.c | 52 ++++++++++++++++++-- components/esp32/test/test_dport.c | 6 ++- components/esp_pm/pm_impl.c | 3 +- components/esp_system/test/test_sleep.c | 3 +- components/hal/esp32/include/hal/uart_ll.h | 7 +-- components/hal/esp32s2/include/hal/uart_ll.h | 7 +-- components/hal/esp32s3/include/hal/uart_ll.h | 5 +- components/hal/include/hal/uart_hal.h | 3 +- components/hal/uart_hal.c | 15 ++---- 9 files changed, 66 insertions(+), 35 deletions(-) diff --git a/components/driver/uart.c b/components/driver/uart.c index 49b718611d..8ef0977859 100644 --- a/components/driver/uart.c +++ b/components/driver/uart.c @@ -24,6 +24,7 @@ #include "freertos/ringbuf.h" #include "hal/uart_hal.h" #include "soc/uart_periph.h" +#include "soc/rtc_cntl_reg.h" #include "driver/uart.h" #include "driver/gpio.h" #include "driver/uart_select.h" @@ -84,6 +85,10 @@ static const char* UART_TAG = "uart"; .hw_enabled = false,\ } +#if SOC_UART_SUPPORT_RTC_CLK +#define RTC_ENABLED(uart_num) (BIT(uart_num)) +#endif + typedef struct { uart_event_type_t type; /*!< UART TX data type */ struct { @@ -158,6 +163,34 @@ static uart_context_t uart_context[UART_NUM_MAX] = { static portMUX_TYPE uart_selectlock = portMUX_INITIALIZER_UNLOCKED; +#if SOC_UART_SUPPORT_RTC_CLK + +static uint8_t rtc_enabled = 0; +static portMUX_TYPE rtc_num_spinlock = portMUX_INITIALIZER_UNLOCKED; + +static void rtc_clk_enable(uart_port_t uart_num) +{ + portENTER_CRITICAL(&rtc_num_spinlock); + if (!(rtc_enabled & RTC_ENABLED(uart_num))) { + rtc_enabled |= RTC_ENABLED(uart_num); + } + SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M); + portEXIT_CRITICAL(&rtc_num_spinlock); +} + +static void rtc_clk_disable(uart_port_t uart_num) +{ + assert(rtc_enabled & RTC_ENABLED(uart_num)); + + portENTER_CRITICAL(&rtc_num_spinlock); + rtc_enabled &= ~RTC_ENABLED(uart_num); + if (rtc_enabled == 0) { + CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M); + } + portEXIT_CRITICAL(&rtc_num_spinlock); +} +#endif + static void uart_module_enable(uart_port_t uart_num) { UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); @@ -236,10 +269,8 @@ esp_err_t uart_get_parity(uart_port_t uart_num, uart_parity_t* parity_mode) esp_err_t uart_set_baudrate(uart_port_t uart_num, uint32_t baud_rate) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - uart_sclk_t source_clk = 0; UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); - uart_hal_get_sclk(&(uart_context[uart_num].hal), &source_clk); - uart_hal_set_baudrate(&(uart_context[uart_num].hal), source_clk, baud_rate); + uart_hal_set_baudrate(&(uart_context[uart_num].hal), baud_rate); UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock)); return ESP_OK; } @@ -626,10 +657,15 @@ esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_conf UART_CHECK((uart_config->flow_ctrl < UART_HW_FLOWCTRL_MAX), "hw_flowctrl mode error", ESP_FAIL); UART_CHECK((uart_config->data_bits < UART_DATA_BITS_MAX), "data bit error", ESP_FAIL); uart_module_enable(uart_num); +#if SOC_UART_SUPPORT_RTC_CLK + if (uart_config->source_clk == UART_SCLK_RTC) { + rtc_clk_enable(uart_num); + } +#endif UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); uart_hal_init(&(uart_context[uart_num].hal), uart_num); uart_hal_set_sclk(&(uart_context[uart_num].hal), uart_config->source_clk); - uart_hal_set_baudrate(&(uart_context[uart_num].hal), uart_config->source_clk, uart_config->baud_rate); + uart_hal_set_baudrate(&(uart_context[uart_num].hal), uart_config->baud_rate); uart_hal_set_parity(&(uart_context[uart_num].hal), uart_config->parity); uart_hal_set_data_bit_num(&(uart_context[uart_num].hal), uart_config->data_bits); uart_hal_set_stop_bits(&(uart_context[uart_num].hal), uart_config->stop_bits); @@ -1417,6 +1453,14 @@ esp_err_t uart_driver_delete(uart_port_t uart_num) heap_caps_free(p_uart_obj[uart_num]); p_uart_obj[uart_num] = NULL; +#if SOC_UART_SUPPORT_RTC_CLK + + uart_sclk_t sclk = 0; + uart_hal_get_sclk(&(uart_context[uart_num].hal), &sclk); + if (sclk == UART_SCLK_RTC) { + rtc_clk_disable(uart_num); + } +#endif uart_module_disable(uart_num); return ESP_OK; } diff --git a/components/esp32/test/test_dport.c b/components/esp32/test/test_dport.c index 84b62be367..c8719fcdb7 100644 --- a/components/esp32/test/test_dport.c +++ b/components/esp32/test/test_dport.c @@ -130,7 +130,8 @@ void run_tasks_with_change_freq_cpu(int cpu_freq_mhz) esp_rom_uart_tx_wait_idle(uart_num); rtc_clk_cpu_freq_set_config(&new_config); - uart_ll_set_baudrate(UART_LL_GET_HW(uart_num), UART_SCLK_APB, uart_baud); + uart_ll_set_sclk(UART_LL_GET_HW(uart_num), UART_SCLK_APB); + uart_ll_set_baudrate(UART_LL_GET_HW(uart_num), uart_baud); /* adjust RTOS ticks */ _xt_tick_divisor = cpu_freq_mhz * 1000000 / XT_TICK_PER_SEC; vTaskDelay(2); @@ -142,7 +143,8 @@ void run_tasks_with_change_freq_cpu(int cpu_freq_mhz) // return old freq. esp_rom_uart_tx_wait_idle(uart_num); rtc_clk_cpu_freq_set_config(&old_config); - uart_ll_set_baudrate(UART_LL_GET_HW(uart_num), UART_SCLK_APB, uart_baud); + uart_ll_set_sclk(UART_LL_GET_HW(uart_num), UART_SCLK_APB); + uart_ll_set_baudrate(UART_LL_GET_HW(uart_num), uart_baud); _xt_tick_divisor = old_config.freq_mhz * 1000000 / XT_TICK_PER_SEC; } diff --git a/components/esp_pm/pm_impl.c b/components/esp_pm/pm_impl.c index 7a1990db0d..92ab65347d 100644 --- a/components/esp_pm/pm_impl.c +++ b/components/esp_pm/pm_impl.c @@ -689,7 +689,8 @@ void esp_pm_impl_init(void) #endif while(!uart_ll_is_tx_idle(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM))); /* When DFS is enabled, override system setting and use REFTICK as UART clock source */ - uart_ll_set_baudrate(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), clk_source, CONFIG_ESP_CONSOLE_UART_BAUDRATE); + uart_ll_set_sclk(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), clk_source); + uart_ll_set_baudrate(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), CONFIG_ESP_CONSOLE_UART_BAUDRATE); #endif // CONFIG_ESP_CONSOLE_UART #ifdef CONFIG_PM_TRACE diff --git a/components/esp_system/test/test_sleep.c b/components/esp_system/test/test_sleep.c index e7b5d9a1f9..9c3e8d9ad2 100644 --- a/components/esp_system/test/test_sleep.c +++ b/components/esp_system/test/test_sleep.c @@ -191,7 +191,8 @@ TEST_CASE("light sleep duration is correct", "[deepsleep][ignore]") TEST_CASE("light sleep and frequency switching", "[deepsleep]") { #ifndef CONFIG_PM_ENABLE - uart_ll_set_baudrate(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), UART_SCLK_REF_TICK, CONFIG_ESP_CONSOLE_UART_BAUDRATE); + uart_ll_set_sclk(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), UART_SCLK_REF_TICK); + uart_ll_set_baudrate(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), CONFIG_ESP_CONSOLE_UART_BAUDRATE); #endif rtc_cpu_freq_config_t config_xtal, config_default; diff --git a/components/hal/esp32/include/hal/uart_ll.h b/components/hal/esp32/include/hal/uart_ll.h index 87cc42d80a..47ed21abf7 100644 --- a/components/hal/esp32/include/hal/uart_ll.h +++ b/components/hal/esp32/include/hal/uart_ll.h @@ -102,16 +102,13 @@ static inline uint32_t uart_ll_get_sclk_freq(uart_dev_t *hw) * * @param hw Beginning address of the peripheral registers. * @param baud The baud-rate to be set. When the source clock is APB, the max baud-rate is `UART_LL_BITRATE_MAX` - * @param source_clk The UART source clock. The source clock can be APB clock or REF_TICK. - * If the source clock is REF_TICK, the UART can still work when the APB changes. - * + * @return None */ -static inline void uart_ll_set_baudrate(uart_dev_t *hw, uart_sclk_t source_clk, uint32_t baud) +static inline void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud) { uint32_t sclk_freq, clk_div; - uart_ll_set_sclk(hw, source_clk); sclk_freq = uart_ll_get_sclk_freq(hw); clk_div = ((sclk_freq) << 4) / baud; // The baud-rate configuration register is divided into diff --git a/components/hal/esp32s2/include/hal/uart_ll.h b/components/hal/esp32s2/include/hal/uart_ll.h index c8a721b940..6bc3b120d1 100644 --- a/components/hal/esp32s2/include/hal/uart_ll.h +++ b/components/hal/esp32s2/include/hal/uart_ll.h @@ -99,16 +99,13 @@ static inline uint32_t uart_ll_get_sclk_freq(uart_dev_t *hw) * * @param hw Beginning address of the peripheral registers. * @param baud The baud rate to be set. When the source clock is APB, the max baud rate is `UART_LL_BITRATE_MAX` - * @param source_clk The UART source clock. The source clock can be APB clock or REF_TICK. - * If the source clock is REF_TICK, the UART can still work when the APB changes. - * + * @return None */ -static inline void uart_ll_set_baudrate(uart_dev_t *hw, uart_sclk_t source_clk, uint32_t baud) +static inline void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud) { uint32_t sclk_freq, clk_div; - uart_ll_set_sclk(hw, source_clk); sclk_freq = uart_ll_get_sclk_freq(hw); clk_div = ((sclk_freq) << 4) / baud; // The baud rate configuration register is divided into diff --git a/components/hal/esp32s3/include/hal/uart_ll.h b/components/hal/esp32s3/include/hal/uart_ll.h index 6a6be04c13..bd61350a3c 100644 --- a/components/hal/esp32s3/include/hal/uart_ll.h +++ b/components/hal/esp32s3/include/hal/uart_ll.h @@ -129,17 +129,14 @@ static inline uint32_t uart_ll_get_sclk_freq(uart_dev_t *hw) * @brief Configure the baud-rate. * * @param hw Beginning address of the peripheral registers. - * @param source_clk The UART source clock. The source clock can be APB clock, RTC clock or XTAL clock. - * If the source clock is RTC/XTAL, the UART can still work when the APB changes. * @param baud The baud rate to be set. When the source clock is APB, the max baud rate is `UART_LL_BITRATE_MAX` * * @return None */ -static inline void uart_ll_set_baudrate(uart_dev_t *hw, uart_sclk_t source_clk, uint32_t baud) +static inline void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud) { uint32_t sclk_freq, clk_div; - uart_ll_set_sclk(hw, source_clk); sclk_freq = uart_ll_get_sclk_freq(hw); clk_div = ((sclk_freq) << 4) / baud; // The baud rate configuration register is divided into diff --git a/components/hal/include/hal/uart_hal.h b/components/hal/include/hal/uart_hal.h index 45ff08d53f..d236431dca 100644 --- a/components/hal/include/hal/uart_hal.h +++ b/components/hal/include/hal/uart_hal.h @@ -200,12 +200,11 @@ void uart_hal_get_sclk(uart_hal_context_t *hal, uart_sclk_t *sclk); * @brief Configure the UART baud-rate and select the source clock * * @param hal Context of the HAL layer - * @param source_clk The UART source clock. * @param baud_rate The baud-rate to be set * * @return None */ -void uart_hal_set_baudrate(uart_hal_context_t *hal, uart_sclk_t source_clk, uint32_t baud_rate); +void uart_hal_set_baudrate(uart_hal_context_t *hal, uint32_t baud_rate); /** * @brief Configure the UART stop bit diff --git a/components/hal/uart_hal.c b/components/hal/uart_hal.c index 4f243fab08..9fa9725768 100644 --- a/components/hal/uart_hal.c +++ b/components/hal/uart_hal.c @@ -14,17 +14,10 @@ // The HAL layer for UART (common part) #include "hal/uart_hal.h" -#include "soc/rtc_cntl_reg.h" void uart_hal_set_sclk(uart_hal_context_t *hal, uart_sclk_t sclk) { uart_ll_set_sclk(hal->dev, sclk); - -#if SOC_UART_SUPPORT_RTC_CLK - if (sclk == UART_SCLK_RTC) { - SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M); - } -#endif } void uart_hal_get_sclk(uart_hal_context_t *hal, uart_sclk_t *sclk) @@ -32,9 +25,9 @@ void uart_hal_get_sclk(uart_hal_context_t *hal, uart_sclk_t *sclk) uart_ll_get_sclk(hal->dev, sclk); } -void uart_hal_set_baudrate(uart_hal_context_t *hal, uart_sclk_t source_clk, uint32_t baud_rate) +void uart_hal_set_baudrate(uart_hal_context_t *hal, uint32_t baud_rate) { - uart_ll_set_baudrate(hal->dev, source_clk, baud_rate); + uart_ll_set_baudrate(hal->dev, baud_rate); } void uart_hal_get_baudrate(uart_hal_context_t *hal, uint32_t *baud_rate) @@ -144,11 +137,11 @@ void uart_hal_set_loop_back(uart_hal_context_t *hal, bool loop_back_en) void uart_hal_init(uart_hal_context_t *hal, int uart_num) { - // Set clock source + // Set default clock source uart_ll_set_sclk(hal->dev, UART_SCLK_APB); // Set default baud: 115200, use APB clock. const uint32_t baud_def = 115200; - uart_ll_set_baudrate(hal->dev, UART_SCLK_APB, baud_def); + uart_ll_set_baudrate(hal->dev, baud_def); // Set UART mode. uart_ll_set_mode(hal->dev, UART_MODE_UART); // Disable UART parity