Просмотр исходного кода

feat(uart): spilt LP and HP uart set_baudrate function

gaoxu 2 лет назад
Родитель
Сommit
bc2a6bd730

+ 10 - 9
components/driver/include/esp_private/uart_private.h

@@ -7,27 +7,28 @@
 
 #pragma once
 
-#include "sdkconfig.h"
+#include "soc/soc_caps.h"
 #include "esp_private/periph_ctrl.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#if (SOC_UART_LP_NUM >= 1)
-#define LP_UART_CLK_ATOMIC()    PERIPH_RCC_ATOMIC()
-#endif
-
 #if SOC_PERIPH_CLK_CTRL_SHARED
-#define UART_SCLK_ATOMIC()      PERIPH_RCC_ATOMIC()
+#define HP_UART_SRC_CLK_ATOMIC()       PERIPH_RCC_ATOMIC()
 #else
-#define UART_SCLK_ATOMIC()
+#define HP_UART_SRC_CLK_ATOMIC()
 #endif
 
 #if SOC_RCC_IS_INDEPENDENT
-#define UART_CLK_ATOMIC()
+#define HP_UART_BUS_CLK_ATOMIC()
 #else
-#define UART_CLK_ATOMIC()       PERIPH_RCC_ATOMIC()
+#define HP_UART_BUS_CLK_ATOMIC()       PERIPH_RCC_ATOMIC()
+#endif
+
+#if (SOC_UART_LP_NUM >= 1)
+#define LP_UART_SRC_CLK_ATOMIC()    PERIPH_RCC_ATOMIC()
+#define LP_UART_BUS_CLK_ATOMIC()    PERIPH_RCC_ATOMIC()
 #endif
 
 #ifdef __cplusplus

+ 23 - 15
components/driver/uart/uart.c

@@ -179,24 +179,24 @@ static void uart_module_enable(uart_port_t uart_num)
     UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
     if (uart_context[uart_num].hw_enabled != true) {
         if (uart_num < SOC_UART_HP_NUM) {
-            UART_CLK_ATOMIC() {
+            HP_UART_BUS_CLK_ATOMIC() {
                 uart_ll_enable_bus_clock(uart_num, true);
             }
             if (uart_num != CONFIG_ESP_CONSOLE_UART_NUM) {
                 // Workaround for ESP32C3/S3: enable core reset before enabling uart module clock to prevent uart output
                 // garbage value.
 #if SOC_UART_REQUIRE_CORE_RESET
-                UART_SCLK_ATOMIC(){
+                HP_UART_SRC_CLK_ATOMIC(){
                     uart_hal_set_reset_core(&(uart_context[uart_num].hal), true);
                 }
-                UART_CLK_ATOMIC() {
+                HP_UART_BUS_CLK_ATOMIC() {
                     uart_ll_reset_register(uart_num);
                 }
-                UART_SCLK_ATOMIC(){
+                HP_UART_SRC_CLK_ATOMIC(){
                     uart_hal_set_reset_core(&(uart_context[uart_num].hal), false);
                 }
 #else
-                UART_CLK_ATOMIC() {
+                HP_UART_BUS_CLK_ATOMIC() {
                     uart_ll_reset_register(uart_num);
                 }
 #endif
@@ -204,7 +204,7 @@ static void uart_module_enable(uart_port_t uart_num)
         }
 #if (SOC_UART_LP_NUM >= 1)
         else {
-            LP_UART_CLK_ATOMIC() {
+            LP_UART_BUS_CLK_ATOMIC() {
                 lp_uart_ll_enable_bus_clock(uart_num - SOC_UART_HP_NUM, true);
                 lp_uart_ll_reset_register(uart_num - SOC_UART_HP_NUM);
             }
@@ -220,13 +220,13 @@ static void uart_module_disable(uart_port_t uart_num)
     UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
     if (uart_context[uart_num].hw_enabled != false) {
         if (uart_num != CONFIG_ESP_CONSOLE_UART_NUM && uart_num < SOC_UART_HP_NUM) {
-            UART_CLK_ATOMIC() {
+            HP_UART_BUS_CLK_ATOMIC() {
                 uart_ll_enable_bus_clock(uart_num, false);
             }
         }
 #if (SOC_UART_LP_NUM >= 1)
         else if (uart_num >= SOC_UART_HP_NUM) {
-            LP_UART_CLK_ATOMIC() {
+            LP_UART_BUS_CLK_ATOMIC() {
                 lp_uart_ll_enable_bus_clock(uart_num - SOC_UART_HP_NUM, false);
             }
         }
@@ -306,9 +306,18 @@ esp_err_t uart_set_baudrate(uart_port_t uart_num, uint32_t baud_rate)
     ESP_RETURN_ON_ERROR(esp_clk_tree_src_get_freq_hz(src_clk, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &sclk_freq), UART_TAG, "Invalid src_clk");
 
     UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
-    UART_SCLK_ATOMIC() {
-        uart_hal_set_baudrate(&(uart_context[uart_num].hal), baud_rate, sclk_freq);
+
+    if (uart_num < SOC_UART_HP_NUM) {
+        HP_UART_SRC_CLK_ATOMIC() {
+            uart_hal_set_baudrate(&(uart_context[uart_num].hal), baud_rate, sclk_freq);
+        }
     }
+#if (SOC_UART_LP_NUM >= 1)
+    else {
+        lp_uart_ll_set_baudrate(uart_context[uart_num].hal.dev, baud_rate, sclk_freq);
+    }
+#endif
+
     UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock));
     return ESP_OK;
 }
@@ -818,20 +827,19 @@ esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_conf
     UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
     uart_hal_init(&(uart_context[uart_num].hal), uart_num);
     if (uart_num < SOC_UART_HP_NUM) {
-        UART_SCLK_ATOMIC() {
+        HP_UART_SRC_CLK_ATOMIC() {
             uart_hal_set_sclk(&(uart_context[uart_num].hal), uart_sclk_sel);
+            uart_hal_set_baudrate(&(uart_context[uart_num].hal), uart_config->baud_rate, sclk_freq);
         }
     }
 #if (SOC_UART_LP_NUM >= 1)
     else {
-        LP_UART_CLK_ATOMIC() {
+        LP_UART_SRC_CLK_ATOMIC() {
             lp_uart_ll_set_source_clk(uart_context[uart_num].hal.dev, (soc_periph_lp_uart_clk_src_t)uart_sclk_sel);
         }
+        lp_uart_ll_set_baudrate(uart_context[uart_num].hal.dev, uart_config->baud_rate, sclk_freq);
     }
 #endif
-    UART_SCLK_ATOMIC() {
-        uart_hal_set_baudrate(&(uart_context[uart_num].hal), uart_config->baud_rate, sclk_freq);
-    }
     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);

+ 2 - 3
components/esp_pm/pm_impl.c

@@ -43,7 +43,6 @@
 #include "esp_private/sleep_cpu.h"
 #include "esp_private/sleep_gpio.h"
 #include "esp_private/sleep_modem.h"
-#include "esp_private/periph_ctrl.h"
 #include "esp_sleep.h"
 
 #include "sdkconfig.h"
@@ -742,13 +741,13 @@ void esp_pm_impl_init(void)
         ;
     }
     /* When DFS is enabled, override system setting and use REFTICK as UART clock source */
-    UART_SCLK_ATOMIC() {
+    HP_UART_SRC_CLK_ATOMIC() {
         uart_ll_set_sclk(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), (soc_module_clk_t)clk_source);
     }
     uint32_t sclk_freq;
     esp_err_t err = uart_get_sclk_freq(clk_source, &sclk_freq);
     assert(err == ESP_OK);
-    UART_SCLK_ATOMIC() {
+    HP_UART_SRC_CLK_ATOMIC() {
         uart_ll_set_baudrate(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), CONFIG_ESP_CONSOLE_UART_BAUDRATE, sclk_freq);
     }
 #endif // CONFIG_ESP_CONSOLE_UART

+ 2 - 0
components/esp_rom/include/esp_rom_uart.h

@@ -34,6 +34,8 @@ void esp_rom_uart_tx_wait_idle(uint8_t uart_no);
  * @param uart_no UART port number
  * @param clock_hz Source clock (in Hz)
  * @param baud_rate Baud rate to set
+ *
+ * @note Only for HP UART
  */
 #define esp_rom_uart_set_clock_baudrate(uart_no, clock_hz, baud_rate) uart_ll_set_baudrate(UART_LL_GET_HW(uart_no), baud_rate, clock_hz)
 

+ 0 - 1
components/esp_system/port/cpu_start.c

@@ -91,7 +91,6 @@
 #include "esp_cpu.h"
 #include "esp_private/esp_clk.h"
 #include "spi_flash_mmap.h"
-#include "esp_private/periph_ctrl.h"
 
 #if CONFIG_ESP32_TRAX || CONFIG_ESP32S2_TRAX || CONFIG_ESP32S3_TRAX
 #include "esp_private/trax.h"

+ 2 - 2
components/esp_system/test_apps/esp_system_unity_tests/main/test_sleep.c

@@ -230,12 +230,12 @@ TEST_CASE("light sleep and frequency switching", "[deepsleep]")
 #elif SOC_UART_SUPPORT_XTAL_CLK
     clk_source = UART_SCLK_XTAL;
 #endif
-    UART_SCLK_ATOMIC() {
+    HP_UART_SRC_CLK_ATOMIC() {
         uart_ll_set_sclk(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), (soc_module_clk_t)clk_source);
     }
     uint32_t sclk_freq;
     TEST_ESP_OK(uart_get_sclk_freq(clk_source, &sclk_freq));
-    UART_SCLK_ATOMIC() {
+    HP_UART_SRC_CLK_ATOMIC() {
         uart_ll_set_baudrate(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), CONFIG_ESP_CONSOLE_UART_BAUDRATE, sclk_freq);
     }
 #endif

+ 2 - 6
components/hal/esp32/include/hal/uart_ll.h

@@ -11,7 +11,6 @@
 #pragma once
 
 #include <stdlib.h>
-#include "hal/assert.h"
 #include "hal/misc.h"
 #include "esp_attr.h"
 #include "soc/uart_reg.h"
@@ -66,7 +65,6 @@ typedef enum {
  */
 FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
 {
-    HAL_ASSERT(uart_num < SOC_UART_HP_NUM);
     uint32_t uart_rst_bit = ((uart_num == 0) ? DPORT_UART_RST :
                             (uart_num == 1) ? DPORT_UART1_RST :
                             (uart_num == 2) ? DPORT_UART2_RST : 0);
@@ -85,8 +83,7 @@ FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
 static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
 {
     uint32_t reg_val = DPORT_READ_PERI_REG(DPORT_PERIP_CLK_EN_REG);
-    switch (uart_num)
-    {
+    switch (uart_num) {
     case 0:
         reg_val = reg_val & (~DPORT_UART_CLK_EN);
         reg_val = reg_val | (enable << 2);
@@ -113,8 +110,7 @@ static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
  */
 static inline void uart_ll_reset_register(uart_port_t uart_num)
 {
-    switch (uart_num)
-    {
+    switch (uart_num) {
     case 0:
         DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART_RST);
         DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART_RST);

+ 2 - 6
components/hal/esp32c2/include/hal/uart_ll.h

@@ -12,7 +12,6 @@
 #include <stdlib.h>
 #include "hal/uart_types.h"
 #include "hal/misc.h"
-#include "hal/assert.h"
 #include "soc/uart_reg.h"
 #include "soc/uart_struct.h"
 #include "soc/clk_tree_defs.h"
@@ -69,7 +68,6 @@ typedef enum {
  */
 FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
 {
-    HAL_ASSERT(uart_num < SOC_UART_HP_NUM);
     uint32_t uart_rst_bit = ((uart_num == 0) ? SYSTEM_UART_RST :
                             (uart_num == 1) ? SYSTEM_UART1_RST : 0);
     uint32_t uart_en_bit  = ((uart_num == 0) ? SYSTEM_UART_CLK_EN :
@@ -85,8 +83,7 @@ FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
  */
 static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
 {
-    switch (uart_num)
-    {
+    switch (uart_num) {
     case 0:
         SYSTEM.perip_clk_en0.uart_clk_en = enable;
         break;
@@ -107,8 +104,7 @@ static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
  */
 static inline void uart_ll_reset_register(uart_port_t uart_num)
 {
-    switch (uart_num)
-    {
+    switch (uart_num) {
     case 0:
         SYSTEM.perip_rst_en0.uart_rst = 1;
         SYSTEM.perip_rst_en0.uart_rst = 0;

+ 2 - 6
components/hal/esp32c3/include/hal/uart_ll.h

@@ -11,7 +11,6 @@
 #pragma once
 
 #include <stdlib.h>
-#include "hal/assert.h"
 #include "hal/misc.h"
 #include "hal/uart_types.h"
 #include "soc/uart_reg.h"
@@ -69,7 +68,6 @@ typedef enum {
  */
 FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
 {
-    HAL_ASSERT(uart_num < SOC_UART_HP_NUM);
     uint32_t uart_rst_bit = ((uart_num == 0) ? SYSTEM_UART_RST :
                             (uart_num == 1) ? SYSTEM_UART1_RST : 0);
     uint32_t uart_en_bit  = ((uart_num == 0) ? SYSTEM_UART_CLK_EN :
@@ -85,8 +83,7 @@ FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
  */
 static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
 {
-    switch (uart_num)
-    {
+    switch (uart_num) {
     case 0:
         SYSTEM.perip_clk_en0.reg_uart_clk_en = enable;
         break;
@@ -107,8 +104,7 @@ static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
  */
 static inline void uart_ll_reset_register(uart_port_t uart_num)
 {
-    switch (uart_num)
-    {
+    switch (uart_num) {
     case 0:
         SYSTEM.perip_rst_en0.reg_uart_rst = 1;
         SYSTEM.perip_rst_en0.reg_uart_rst = 0;

+ 42 - 18
components/hal/esp32c6/include/hal/uart_ll.h

@@ -85,6 +85,19 @@ typedef enum {
     UART_INTR_WAKEUP           = (0x1 << 19),
 } uart_intr_t;
 
+/**
+ * @brief Sync the update to UART core clock domain
+ *
+ * @param hw Beginning address of the peripheral registers.
+ *
+ * @return None.
+ */
+FORCE_INLINE_ATTR void uart_ll_update(uart_dev_t *hw)
+{
+    hw->reg_update.reg_update = 1;
+    while (hw->reg_update.reg_update);
+}
+
 /****************************************** LP_UART Specific ********************************************/
 /**
  * @brief  Get the LP_UART source clock.
@@ -131,6 +144,32 @@ static inline void lp_uart_ll_set_source_clk(uart_dev_t *hw, soc_periph_lp_uart_
 /// LP_CLKRST.lpperi is a shared register, so this function must be used in an atomic way
 #define lp_uart_ll_set_source_clk(...) (void)__DECLARE_RCC_ATOMIC_ENV; lp_uart_ll_set_source_clk(__VA_ARGS__)
 
+/**
+ * @brief  Configure the lp uart baud-rate.
+ *
+ * @param  hw Beginning address of the peripheral registers.
+ * @param  baud The baud rate to be set.
+ * @param  sclk_freq Frequency of the clock source of UART, in Hz.
+ *
+ * @return None
+ */
+FORCE_INLINE_ATTR void lp_uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint32_t sclk_freq)
+{
+#define DIV_UP(a, b)    (((a) + (b) - 1) / (b))
+    const uint32_t max_div = BIT(12) - 1;   // UART divider integer part only has 12 bits
+    uint32_t sclk_div = DIV_UP(sclk_freq, (uint64_t)max_div * baud);
+
+    if (sclk_div == 0) abort();
+
+    uint32_t clk_div = ((sclk_freq) << 4) / (baud * sclk_div);
+    // The baud rate configuration register is divided into
+    // an integer part and a fractional part.
+    hw->clkdiv_sync.clkdiv_int = clk_div >> 4;
+    hw->clkdiv_sync.clkdiv_frag = clk_div & 0xf;
+    HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clk_conf, sclk_div_num, sclk_div - 1);
+    uart_ll_update(hw);
+}
+
 /**
  * @brief Enable bus clock for the LP UART module
  *
@@ -190,8 +229,7 @@ FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
  */
 static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
 {
-    switch (uart_num)
-    {
+    switch (uart_num) {
     case 0:
         PCR.uart0_conf.uart0_clk_en = enable;
         break;
@@ -211,8 +249,7 @@ static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
  */
 static inline void uart_ll_reset_register(uart_port_t uart_num)
 {
-    switch (uart_num)
-    {
+    switch (uart_num) {
     case 0:
         PCR.uart0_conf.uart0_rst_en = 1;
         PCR.uart0_conf.uart0_rst_en = 0;
@@ -228,19 +265,6 @@ static inline void uart_ll_reset_register(uart_port_t uart_num)
     }
 }
 
-/**
- * @brief Sync the update to UART core clock domain
- *
- * @param hw Beginning address of the peripheral registers.
- *
- * @return None.
- */
-FORCE_INLINE_ATTR void uart_ll_update(uart_dev_t *hw)
-{
-    hw->reg_update.reg_update = 1;
-    while (hw->reg_update.reg_update);
-}
-
 /**
  * @brief  Configure the UART core reset.
  *
@@ -382,7 +406,7 @@ FORCE_INLINE_ATTR void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint3
     hw->clkdiv_sync.clkdiv_int = clk_div >> 4;
     hw->clkdiv_sync.clkdiv_frag = clk_div & 0xf;
     if ((hw) == &LP_UART) {
-        HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clk_conf, sclk_div_num, sclk_div - 1);
+        abort();
     } else {
         UART_LL_PCR_REG_U32_SET(hw, sclk_conf, sclk_div_num, sclk_div - 1);
     }

+ 2 - 6
components/hal/esp32h2/include/hal/uart_ll.h

@@ -12,7 +12,6 @@
 
 #include <stdlib.h>
 #include "esp_attr.h"
-#include "hal/assert.h"
 #include "hal/misc.h"
 #include "hal/uart_types.h"
 #include "soc/uart_reg.h"
@@ -91,7 +90,6 @@ typedef enum {
  */
 FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
 {
-    HAL_ASSERT(uart_num < SOC_UART_HP_NUM);
     uint32_t uart_clk_config_reg = ((uart_num == 0) ? PCR_UART0_CONF_REG :
                                     (uart_num == 1) ? PCR_UART1_CONF_REG : 0);
     uint32_t uart_rst_bit = ((uart_num == 0) ? PCR_UART0_RST_EN :
@@ -109,8 +107,7 @@ FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
  */
 static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
 {
-    switch (uart_num)
-    {
+    switch (uart_num) {
     case 0:
         PCR.uart0_conf.uart0_clk_en = enable;
         break;
@@ -129,8 +126,7 @@ static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
  */
 static inline void uart_ll_reset_register(uart_port_t uart_num)
 {
-    switch (uart_num)
-    {
+    switch (uart_num) {
     case 0:
         PCR.uart0_conf.uart0_rst_en = 1;
         PCR.uart0_conf.uart0_rst_en = 0;

+ 50 - 26
components/hal/esp32p4/include/hal/uart_ll.h

@@ -69,6 +69,19 @@ typedef enum {
     UART_INTR_WAKEUP           = (0x1 << 19),
 } uart_intr_t;
 
+/**
+ * @brief Sync the update to UART core clock domain
+ *
+ * @param hw Beginning address of the peripheral registers.
+ *
+ * @return None.
+ */
+FORCE_INLINE_ATTR void uart_ll_update(uart_dev_t *hw)
+{
+    hw->reg_update.reg_update = 1;
+    while (hw->reg_update.reg_update);
+}
+
 /****************************************** LP_UART Specific ********************************************/
 /**
  * @brief  Get the LP_UART source clock.
@@ -99,7 +112,7 @@ FORCE_INLINE_ATTR void lp_uart_ll_get_sclk(uart_dev_t *hw, soc_module_clk_t *sou
  * @param  hw Address offset of the LP UART peripheral registers
  * @param  src_clk Source clock for the LP UART peripheral
  */
-FORCE_INLINE_ATTR void lp_uart_ll_set_source_clk(uart_dev_t *hw, soc_periph_lp_uart_clk_src_t src_clk)
+static inline void lp_uart_ll_set_source_clk(uart_dev_t *hw, soc_periph_lp_uart_clk_src_t src_clk)
 {
     (void)hw;
     switch (src_clk) {
@@ -121,13 +134,40 @@ FORCE_INLINE_ATTR void lp_uart_ll_set_source_clk(uart_dev_t *hw, soc_periph_lp_u
 // LPPERI.core_clk_sel is a shared register, so this function must be used in an atomic way
 #define lp_uart_ll_set_source_clk(...) (void)__DECLARE_RCC_ATOMIC_ENV; lp_uart_ll_set_source_clk(__VA_ARGS__)
 
+/**
+ * @brief  Configure the lp uart baud-rate.
+ *
+ * @param  hw Beginning address of the peripheral registers.
+ * @param  baud The baud rate to be set.
+ * @param  sclk_freq Frequency of the clock source of UART, in Hz.
+ *
+ * @return None
+ */
+FORCE_INLINE_ATTR void lp_uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint32_t sclk_freq)
+{
+#define DIV_UP(a, b)    (((a) + (b) - 1) / (b))
+    const uint32_t max_div = BIT(12) - 1;   // UART divider integer part only has 12 bits
+    uint32_t sclk_div = DIV_UP(sclk_freq, (uint64_t)max_div * baud);
+    if (sclk_div == 0) abort();
+
+    uint32_t clk_div = ((sclk_freq) << 4) / (baud * sclk_div);
+    // The baud rate configuration register is divided into
+    // an integer part and a fractional part.
+    hw->clkdiv_sync.clkdiv = clk_div >> 4;
+    hw->clkdiv_sync.clkdiv_frag = clk_div & 0xf;
+    //needs force u32 write
+    HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clk_conf, sclk_div_num, sclk_div - 1);
+#undef DIV_UP
+    uart_ll_update(hw);
+}
+
 /**
  * @brief Enable bus clock for the LP UART module
  *
  * @param hw_id LP UART instance ID
  * @param enable True to enable, False to disable
  */
-FORCE_INLINE_ATTR void lp_uart_ll_enable_bus_clock(int hw_id, bool enable)
+static inline void lp_uart_ll_enable_bus_clock(int hw_id, bool enable)
 {
     (void)hw_id;
     LPPERI.clk_en.ck_en_lp_uart = enable;
@@ -141,7 +181,7 @@ FORCE_INLINE_ATTR void lp_uart_ll_enable_bus_clock(int hw_id, bool enable)
  *
  * @param hw_id LP UART instance ID
  */
-FORCE_INLINE_ATTR void lp_uart_ll_reset_register(int hw_id)
+static inline void lp_uart_ll_reset_register(int hw_id)
 {
     (void)hw_id;
     LPPERI.reset_en.rst_en_lp_uart = 1;
@@ -166,8 +206,7 @@ FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
     bool uart_rst_en = false;
     bool uart_apb_en = false;
     bool uart_sys_en = false;
-    switch (uart_num)
-    {
+    switch (uart_num) {
     case 0:
         uart_rst_en = HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_uart0_apb;
         uart_apb_en = HP_SYS_CLKRST.soc_clk_ctrl2.reg_uart0_apb_clk_en;
@@ -204,10 +243,9 @@ FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
  * @param uart_num UART port number, the max port number is (UART_NUM_MAX -1).
  * @param enable true to enable, false to disable
  */
-FORCE_INLINE_ATTR void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
+static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
 {
-    switch (uart_num)
-    {
+    switch (uart_num) {
     case 0:
         HP_SYS_CLKRST.soc_clk_ctrl2.reg_uart0_apb_clk_en = enable;
         HP_SYS_CLKRST.soc_clk_ctrl1.reg_uart0_sys_clk_en = enable;
@@ -243,10 +281,9 @@ FORCE_INLINE_ATTR void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enabl
  * @brief Reset UART module
  * @param uart_num UART port number, the max port number is (UART_NUM_MAX -1).
  */
-FORCE_INLINE_ATTR void uart_ll_reset_register(uart_port_t uart_num)
+static inline void uart_ll_reset_register(uart_port_t uart_num)
 {
-    switch (uart_num)
-    {
+    switch (uart_num) {
     case 0:
         HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_uart0_apb = 1;
         HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_uart0_apb = 0;
@@ -278,19 +315,6 @@ FORCE_INLINE_ATTR void uart_ll_reset_register(uart_port_t uart_num)
 //  HP_SYS_CLKRST.hp_rst_en1 is a shared register, so this function must be used in an atomic way
 #define uart_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; uart_ll_reset_register(__VA_ARGS__)
 
-/**
- * @brief Sync the update to UART core clock domain
- *
- * @param hw Beginning address of the peripheral registers.
- *
- * @return None.
- */
-FORCE_INLINE_ATTR void uart_ll_update(uart_dev_t *hw)
-{
-    hw->reg_update.reg_update = 1;
-    while (hw->reg_update.reg_update);
-}
-
 /**
  * @brief  Configure the UART core reset.
  *
@@ -490,8 +514,8 @@ FORCE_INLINE_ATTR void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint3
         HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl114, reg_uart3_sclk_div_num, sclk_div - 1);
     } else if ((hw) == &UART4) {
         HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl115, reg_uart4_sclk_div_num, sclk_div - 1);
-    } else if ((hw) == &LP_UART) {
-        HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clk_conf, sclk_div_num, sclk_div - 1);
+    } else {
+        abort();
     }
 #undef DIV_UP
     uart_ll_update(hw);

+ 2 - 6
components/hal/esp32s2/include/hal/uart_ll.h

@@ -11,7 +11,6 @@
 #pragma once
 
 #include <stdlib.h>
-#include "hal/assert.h"
 #include "hal/misc.h"
 #include "hal/uart_types.h"
 #include "soc/uart_reg.h"
@@ -65,7 +64,6 @@ typedef enum {
  */
 FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
 {
-    HAL_ASSERT(uart_num < SOC_UART_HP_NUM);
     uint32_t uart_rst_bit = ((uart_num == 0) ? DPORT_UART_RST :
                             (uart_num == 1) ? DPORT_UART1_RST : 0);
     uint32_t uart_en_bit  = ((uart_num == 0) ? DPORT_UART_CLK_EN :
@@ -82,8 +80,7 @@ FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
 static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
 {
     uint32_t reg_val = READ_PERI_REG(DPORT_PERIP_CLK_EN0_REG);
-    switch (uart_num)
-    {
+    switch (uart_num) {
     case 0:
         reg_val = reg_val & (~DPORT_UART_CLK_EN);
         reg_val = reg_val | (enable << DPORT_UART_CLK_EN_S);
@@ -106,8 +103,7 @@ static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
  */
 static inline void uart_ll_reset_register(uart_port_t uart_num)
 {
-    switch (uart_num)
-    {
+    switch (uart_num) {
     case 0:
         DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART_RST);
         DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART_RST);

+ 2 - 6
components/hal/esp32s3/include/hal/uart_ll.h

@@ -11,7 +11,6 @@
 #pragma once
 
 #include <stdlib.h>
-#include "hal/assert.h"
 #include "hal/misc.h"
 #include "hal/uart_types.h"
 #include "soc/uart_reg.h"
@@ -69,7 +68,6 @@ typedef enum {
  */
 FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
 {
-    HAL_ASSERT(uart_num < SOC_UART_HP_NUM);
     uint32_t uart_rst_bit = ((uart_num == 0) ? SYSTEM_UART_RST :
                             (uart_num == 1) ? SYSTEM_UART1_RST :
                             (uart_num == 2) ? SYSTEM_UART2_RST : 0);
@@ -87,8 +85,7 @@ FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
  */
 static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
 {
-    switch (uart_num)
-    {
+    switch (uart_num) {
     case 0:
         SYSTEM.perip_clk_en0.uart_clk_en = enable;
         break;
@@ -112,8 +109,7 @@ static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable)
  */
 static inline void uart_ll_reset_register(uart_port_t uart_num)
 {
-    switch (uart_num)
-    {
+    switch (uart_num) {
     case 0:
         SYSTEM.perip_rst_en0.uart_rst = 1;
         SYSTEM.perip_rst_en0.uart_rst = 0;

+ 6 - 1
components/soc/esp32p4/include/soc/clk_tree_defs.h

@@ -278,7 +278,12 @@ typedef enum {
     LP_UART_SCLK_LP_FAST = SOC_MOD_CLK_RTC_FAST,        /*!< LP_UART source clock is LP(RTC)_FAST */
     LP_UART_SCLK_XTAL_D2 = SOC_MOD_CLK_XTAL_D2,         /*!< LP_UART source clock is XTAL_D2 */
     LP_UART_SCLK_LP_PLL  = SOC_MOD_CLK_LP_PLL,          /*!< LP_UART source clock is LP_PLL (8M PLL) */
-    LP_UART_SCLK_DEFAULT = SOC_MOD_CLK_XTAL_D2,        /*!< LP_UART source clock default choice is XTAL_D2 */
+#if SOC_CLK_TREE_SUPPORTED
+    LP_UART_SCLK_DEFAULT = SOC_MOD_CLK_RTC_FAST,
+#else
+    LP_UART_SCLK_DEFAULT = SOC_MOD_CLK_XTAL_D2,         /*!< LP_UART source clock default choice is XTAL_D2 */
+#endif
+
 } soc_periph_lp_uart_clk_src_t;
 
 //////////////////////////////////////////////////MCPWM/////////////////////////////////////////////////////////////////

+ 2 - 4
components/ulp/lp_core/lp_core_uart.c

@@ -48,14 +48,12 @@ static esp_err_t lp_core_uart_param_config(const lp_core_uart_cfg_t *cfg)
     }
 
     // LP UART clock source is mixed with other peripherals in the same register
-    PERIPH_RCC_ATOMIC() {
+    LP_UART_SRC_CLK_ATOMIC() {
         lp_uart_ll_set_source_clk(hal.dev, clk_src);
     }
 
     /* Override protocol parameters from the configuration */
-    UART_SCLK_ATOMIC() {
-        uart_hal_set_baudrate(&hal, cfg->uart_proto_cfg.baud_rate, sclk_freq);
-    }
+    lp_uart_ll_set_baudrate(hal.dev, cfg->uart_proto_cfg.baud_rate, sclk_freq);
     uart_hal_set_parity(&hal, cfg->uart_proto_cfg.parity);
     uart_hal_set_data_bit_num(&hal, cfg->uart_proto_cfg.data_bits);
     uart_hal_set_stop_bits(&hal, cfg->uart_proto_cfg.stop_bits);

+ 4 - 4
examples/system/.build-test-rules.yml

@@ -204,12 +204,12 @@ examples/system/ulp/lp_core/lp_i2c:
     - if: SOC_LP_I2C_SUPPORTED == 1
 
 examples/system/ulp/lp_core/lp_uart/lp_uart_echo:
-  enable:
-    - if: SOC_ULP_LP_UART_SUPPORTED == 1
+  disable:
+    - if: SOC_ULP_LP_UART_SUPPORTED != 1
 
 examples/system/ulp/lp_core/lp_uart/lp_uart_print:
-  enable:
-    - if: SOC_ULP_LP_UART_SUPPORTED == 1
+  disable:
+    - if: SOC_ULP_LP_UART_SUPPORTED != 1
 
 examples/system/ulp/ulp_fsm/ulp:
   disable: