diff --git a/components/esp_system/port/soc/esp32c3/system_internal.c b/components/esp_system/port/soc/esp32c3/system_internal.c index 2dd27c0bf6..d915c769ae 100644 --- a/components/esp_system/port/soc/esp32c3/system_internal.c +++ b/components/esp_system/port/soc/esp32c3/system_internal.c @@ -30,6 +30,7 @@ #include "soc/rtc_periph.h" #include "soc/syscon_reg.h" #include "soc/system_reg.h" +#include "soc/uart_reg.h" #include "hal/wdt_hal.h" #include "cache_err_int.h" @@ -103,6 +104,10 @@ void IRAM_ATTR esp_restart_noos(void) REG_WRITE(SYSTEM_CORE_RST_EN_REG, 0); + // Reset uart0 core first, then reset apb side. + // rom will clear this bit, as well as SYSTEM_UART_RST + SET_PERI_REG_MASK(UART_CLK_CONF_REG(0), UART_RST_CORE_M); + // Reset timer/spi/uart SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG, SYSTEM_TIMERS_RST | SYSTEM_SPI01_RST | SYSTEM_UART_RST); diff --git a/components/hal/esp32c3/include/hal/clk_gate_ll.h b/components/hal/esp32c3/include/hal/clk_gate_ll.h index f7382650d5..db38299d6a 100644 --- a/components/hal/esp32c3/include/hal/clk_gate_ll.h +++ b/components/hal/esp32c3/include/hal/clk_gate_ll.h @@ -24,6 +24,7 @@ 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) { @@ -208,6 +209,12 @@ 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)); } @@ -226,6 +233,12 @@ 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)); }