Jelajahi Sumber

add uart core reset in uart_module_enable()

Chen Yi Qun 4 tahun lalu
induk
melakukan
6317f5b481

+ 10 - 1
components/driver/uart.c

@@ -187,10 +187,19 @@ 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) {
+        periph_module_enable(uart_periph_signal[uart_num].module);
         if (uart_num != CONFIG_ESP_CONSOLE_UART_NUM) {
+        // Workaround for ESP32C3: enable core reset
+        // before enabling uart module clock
+        // to prevent uart output garbage value.
+        #if SOC_UART_REQUIRE_CORE_RESET
+            uart_hal_set_reset_core(&(uart_context[uart_num].hal), true);
+            periph_module_reset(uart_periph_signal[uart_num].module);
+            uart_hal_set_reset_core(&(uart_context[uart_num].hal), false);
+        #else
             periph_module_reset(uart_periph_signal[uart_num].module);
+        #endif
         }
-        periph_module_enable(uart_periph_signal[uart_num].module);
         uart_context[uart_num].hw_enabled = true;
     }
     UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock));

+ 0 - 13
components/hal/esp32c3/include/hal/clk_gate_ll.h

@@ -24,7 +24,6 @@ extern "C" {
 #include "soc/system_reg.h"
 #include "soc/syscon_reg.h"
 #include "soc/dport_access.h"
-#include "soc/uart_reg.h"
 
 static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph)
 {
@@ -209,12 +208,6 @@ static inline void periph_ll_enable_clk_clear_rst(periph_module_t periph)
 
 static inline void periph_ll_disable_clk_set_rst(periph_module_t periph)
 {
-    // set UART_RST_CORE before setting SYSTEM_UART_RST on esp32c3
-    if (periph == PERIPH_UART0_MODULE) {
-        SET_PERI_REG_MASK(UART_CLK_CONF_REG(0), UART_RST_CORE_M);
-    } else if (periph == PERIPH_UART1_MODULE) {
-        SET_PERI_REG_MASK(UART_CLK_CONF_REG(1), UART_RST_CORE_M);
-    }
     DPORT_CLEAR_PERI_REG_MASK(periph_ll_get_clk_en_reg(periph), periph_ll_get_clk_en_mask(periph));
     DPORT_SET_PERI_REG_MASK(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, false));
 }
@@ -233,12 +226,6 @@ static inline void IRAM_ATTR periph_ll_wifi_bt_module_disable_clk_set_rst(void)
 
 static inline void periph_ll_reset(periph_module_t periph)
 {
-    // set UART_RST_CORE before setting SYSTEM_UART_RST on esp32c3
-    if (periph == PERIPH_UART0_MODULE) {
-        SET_PERI_REG_MASK(UART_CLK_CONF_REG(0), UART_RST_CORE_M);
-    } else if (periph == PERIPH_UART1_MODULE) {
-        SET_PERI_REG_MASK(UART_CLK_CONF_REG(1), UART_RST_CORE_M);
-    }
     DPORT_SET_PERI_REG_MASK(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, false));
     DPORT_CLEAR_PERI_REG_MASK(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, false));
 }

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

@@ -58,9 +58,8 @@ typedef enum {
     UART_INTR_CMD_CHAR_DET     = (0x1 << 18),
 } uart_intr_t;
 
-static inline void uart_ll_reset_core(uart_dev_t *hw) {
-    hw->clk_conf.rst_core = 1;
-    hw->clk_conf.rst_core = 0;
+static inline void uart_ll_set_reset_core(uart_dev_t *hw, bool core_rst_en) {
+    hw->clk_conf.rst_core = core_rst_en;
 }
 
 static inline void uart_ll_sclk_enable(uart_dev_t *hw) {

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

@@ -58,9 +58,8 @@ typedef enum {
     UART_INTR_CMD_CHAR_DET     = (0x1 << 18),
 } uart_intr_t;
 
-static inline void uart_ll_reset_core(uart_dev_t *hw) {
-    hw->clk_conf.rst_core = 1;
-    hw->clk_conf.rst_core = 0;
+static inline void uart_ll_set_reset_core(uart_dev_t *hw, bool core_rst_en) {
+    hw->clk_conf.rst_core = core_rst_en;
 }
 
 static inline void uart_ll_sclk_enable(uart_dev_t *hw) {

+ 10 - 0
components/hal/include/hal/uart_hal.h

@@ -124,6 +124,16 @@ typedef struct {
  */
 #define uart_hal_is_tx_idle(hal)  uart_ll_is_tx_idle((hal)->dev)
 
+/**
+ * @brief  Configure the UART core reset
+ *
+ * @param  hal Context of the HAL layer
+ * @param  Set true to enable the core reset, otherwise set it false
+ *
+ * @return None
+ */
+#define uart_hal_set_reset_core(hal, core_rst_en)  uart_ll_set_reset_core((hal)->dev, core_rst_en)
+
 /**
  * @brief  Read data from the UART rxfifo
  *

+ 1 - 0
components/soc/esp32c3/include/soc/soc_caps.h

@@ -244,6 +244,7 @@
 
 #define SOC_UART_SUPPORT_RTC_CLK    (1)
 #define SOC_UART_SUPPORT_XTAL_CLK   (1)
+#define SOC_UART_REQUIRE_CORE_RESET (1)
 
 // UART has an extra TX_WAIT_SEND state when the FIFO is not empty and XOFF is enabled
 #define SOC_UART_SUPPORT_FSM_TX_WAIT_SEND   (1)