diff --git a/components/esp_system/include/esp_private/system_internal.h b/components/esp_system/include/esp_private/system_internal.h index 984e98129b..9a8989bba0 100644 --- a/components/esp_system/include/esp_private/system_internal.h +++ b/components/esp_system/include/esp_private/system_internal.h @@ -63,6 +63,11 @@ int64_t esp_system_get_time(void); */ uint32_t esp_system_get_time_resolution(void); +/** + * @brief Before the system exit (e.g. panic, brownout, restart, etc.), this function is to be called to reset all necessary peripherals. + */ +void esp_system_reset_modules_on_exit(void); + #ifdef __cplusplus } #endif diff --git a/components/esp_system/panic.c b/components/esp_system/panic.c index d9db16dda9..1804e84f0f 100644 --- a/components/esp_system/panic.c +++ b/components/esp_system/panic.c @@ -428,6 +428,7 @@ void esp_panic_handler(panic_info_t *info) #else /* CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT || CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT */ disable_all_wdts(); panic_print_str("CPU halted.\r\n"); + esp_system_reset_modules_on_exit(); while (1); #endif /* CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT || CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT */ #endif /* CONFIG_ESP_SYSTEM_PANIC_GDBSTUB */ diff --git a/components/esp_system/port/soc/esp32/system_internal.c b/components/esp_system/port/soc/esp32/system_internal.c index 693426001a..96a55e5287 100644 --- a/components/esp_system/port/soc/esp32/system_internal.c +++ b/components/esp_system/port/soc/esp32/system_internal.c @@ -29,6 +29,29 @@ #include "esp32/rom/cache.h" #include "esp32/rom/rtc.h" +void IRAM_ATTR esp_system_reset_modules_on_exit(void) +{ + // Flush any data left in UART FIFOs before reset the UART peripheral + esp_rom_uart_tx_wait_idle(0); + esp_rom_uart_tx_wait_idle(1); + esp_rom_uart_tx_wait_idle(2); + + // Reset wifi/bluetooth/ethernet/sdio (bb/mac) + DPORT_SET_PERI_REG_MASK(DPORT_CORE_RST_EN_REG, + DPORT_WIFIBB_RST | DPORT_FE_RST | DPORT_WIFIMAC_RST | DPORT_BTBB_RST | + DPORT_BTMAC_RST | DPORT_SDIO_RST | DPORT_SDIO_HOST_RST | DPORT_EMAC_RST | + DPORT_MACPWR_RST | DPORT_RW_BTMAC_RST | DPORT_RW_BTLP_RST); + DPORT_REG_WRITE(DPORT_CORE_RST_EN_REG, 0); + + // Reset timer, spi, uart, mcpwm + DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, + //UART TX FIFO cannot be reset correctly on ESP32, so reset the UART memory by DPORT here. + DPORT_TIMERS_RST | DPORT_SPI01_RST | DPORT_SPI2_RST | DPORT_SPI3_RST | + DPORT_SPI_DMA_RST | DPORT_UART_RST | DPORT_UART1_RST | DPORT_UART2_RST | + DPORT_UART_MEM_RST | DPORT_PWM0_RST | DPORT_PWM1_RST); + DPORT_REG_WRITE(DPORT_PERIP_RST_EN_REG, 0); +} + /* "inner" restart function for after RTOS, interrupts & anything else on this * core are already stopped. Stalls other core, resets hardware, * triggers restart. @@ -73,11 +96,6 @@ void IRAM_ATTR esp_restart_noos(void) wdt_hal_disable(&wdt1_context); wdt_hal_write_protect_enable(&wdt1_context); - // Flush any data left in UART FIFOs - esp_rom_uart_tx_wait_idle(0); - esp_rom_uart_tx_wait_idle(1); - esp_rom_uart_tx_wait_idle(2); - #ifdef CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY if (esp_ptr_external_ram(esp_cpu_get_sp())) { // If stack_addr is from External Memory (CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY is used) @@ -101,25 +119,8 @@ void IRAM_ATTR esp_restart_noos(void) WRITE_PERI_REG(GPIO_FUNC4_IN_SEL_CFG_REG, 0x30); WRITE_PERI_REG(GPIO_FUNC5_IN_SEL_CFG_REG, 0x30); - // Reset wifi/bluetooth/ethernet/sdio (bb/mac) - DPORT_SET_PERI_REG_MASK(DPORT_CORE_RST_EN_REG, DPORT_WIFIBB_RST | \ - DPORT_FE_RST | \ - DPORT_WIFIMAC_RST | \ - DPORT_BTBB_RST | \ - DPORT_BTMAC_RST | \ - DPORT_SDIO_RST | \ - DPORT_SDIO_HOST_RST | \ - DPORT_EMAC_RST | \ - DPORT_MACPWR_RST | \ - DPORT_RW_BTMAC_RST | \ - DPORT_RW_BTLP_RST); - DPORT_REG_WRITE(DPORT_CORE_RST_EN_REG, 0); - - // Reset timer/spi/uart - DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, - //UART TX FIFO cannot be reset correctly on ESP32, so reset the UART memory by DPORT here. - DPORT_TIMERS_RST | DPORT_SPI01_RST | DPORT_SPI2_RST | DPORT_SPI3_RST | DPORT_SPI_DMA_RST | DPORT_UART_RST | DPORT_UART1_RST | DPORT_UART2_RST | DPORT_UART_MEM_RST); - DPORT_REG_WRITE(DPORT_PERIP_RST_EN_REG, 0); + // reset necessary peripheral modules + esp_system_reset_modules_on_exit(); // Set CPU back to XTAL source, same as hard reset. PLL keeps on to match the behavior with chips. rtc_clk_cpu_set_to_default_config(); @@ -139,7 +140,7 @@ void IRAM_ATTR esp_restart_noos(void) esp_cpu_unstall(0); esp_rom_software_reset_cpu(1); } - while(true) { + while (true) { ; } } diff --git a/components/esp_system/port/soc/esp32c2/system_internal.c b/components/esp_system/port/soc/esp32c2/system_internal.c index 9584433a1b..bff2149fae 100644 --- a/components/esp_system/port/soc/esp32c2/system_internal.c +++ b/components/esp_system/port/soc/esp32c2/system_internal.c @@ -27,6 +27,25 @@ #include "esp32c2/rom/cache.h" #include "esp32c2/rom/rtc.h" +void IRAM_ATTR esp_system_reset_modules_on_exit(void) +{ + // Flush any data left in UART FIFOs before reset the UART peripheral + esp_rom_uart_tx_wait_idle(0); + esp_rom_uart_tx_wait_idle(1); + + // Reset wifi/bluetooth/ethernet/sdio (bb/mac) + + REG_WRITE(SYSTEM_CORE_RST_EN_REG, 0); + + // Reset timer/spi/uart + SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG, + SYSTEM_SPI01_RST | SYSTEM_UART_RST | SYSTEM_SYSTIMER_RST); + REG_WRITE(SYSTEM_PERIP_RST_EN0_REG, 0); + // Reset dma + SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_DMA_RST); + REG_WRITE(SYSTEM_PERIP_RST_EN1_REG, 0); +} + /* "inner" restart function for after RTOS, interrupts & anything else on this * core are already stopped. Stalls other core, resets hardware, * triggers restart. @@ -52,9 +71,6 @@ void IRAM_ATTR esp_restart_noos(void) wdt_hal_disable(&wdt0_context); wdt_hal_write_protect_enable(&wdt0_context); - // Flush any data left in UART FIFOs - esp_rom_uart_tx_wait_idle(0); - esp_rom_uart_tx_wait_idle(1); // Disable cache Cache_Disable_ICache(); @@ -67,17 +83,7 @@ void IRAM_ATTR esp_restart_noos(void) WRITE_PERI_REG(GPIO_FUNC4_IN_SEL_CFG_REG, 0x30); WRITE_PERI_REG(GPIO_FUNC5_IN_SEL_CFG_REG, 0x30); - // Reset wifi/bluetooth/ethernet/sdio (bb/mac) - - REG_WRITE(SYSTEM_CORE_RST_EN_REG, 0); - - // Reset timer/spi/uart - SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG, - SYSTEM_SPI01_RST | SYSTEM_UART_RST | SYSTEM_SYSTIMER_RST); - REG_WRITE(SYSTEM_PERIP_RST_EN0_REG, 0); - // Reset dma - SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_DMA_RST); - REG_WRITE(SYSTEM_PERIP_RST_EN1_REG, 0); + esp_system_reset_modules_on_exit(); // Set CPU back to XTAL source, same as hard reset. PLL keeps on to match the behavior with chips. #if !CONFIG_IDF_ENV_FPGA diff --git a/components/esp_system/port/soc/esp32c3/system_internal.c b/components/esp_system/port/soc/esp32c3/system_internal.c index be0d8de075..9372edd56f 100644 --- a/components/esp_system/port/soc/esp32c3/system_internal.c +++ b/components/esp_system/port/soc/esp32c3/system_internal.c @@ -28,6 +28,32 @@ #include "esp32c3/rom/cache.h" #include "esp32c3/rom/rtc.h" +void IRAM_ATTR esp_system_reset_modules_on_exit(void) +{ + // Flush any data left in UART FIFOs before reset the UART peripheral + esp_rom_uart_tx_wait_idle(0); + esp_rom_uart_tx_wait_idle(1); + + // Reset wifi/bluetooth/ethernet/sdio (bb/mac) + SET_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG, + SYSTEM_WIFIBB_RST | SYSTEM_FE_RST | SYSTEM_WIFIMAC_RST | SYSTEM_SDIO_RST | + SYSTEM_EMAC_RST | SYSTEM_MACPWR_RST | SYSTEM_BTBB_RST | SYSTEM_BTBB_REG_RST | + SYSTEM_RW_BTMAC_RST | SYSTEM_RW_BTLP_RST | SYSTEM_RW_BTMAC_REG_RST | SYSTEM_RW_BTLP_REG_RST); + 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 | SYSTEM_SYSTIMER_RST); + REG_WRITE(SYSTEM_PERIP_RST_EN0_REG, 0); + // Reset dma + SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_DMA_RST); + REG_WRITE(SYSTEM_PERIP_RST_EN1_REG, 0); +} + /* "inner" restart function for after RTOS, interrupts & anything else on this * core are already stopped. Stalls other core, resets hardware, * triggers restart. @@ -58,9 +84,6 @@ void IRAM_ATTR esp_restart_noos(void) wdt_hal_disable(&wdt1_context); wdt_hal_write_protect_enable(&wdt1_context); - // Flush any data left in UART FIFOs - esp_rom_uart_tx_wait_idle(0); - esp_rom_uart_tx_wait_idle(1); // Disable cache Cache_Disable_ICache(); @@ -73,25 +96,7 @@ void IRAM_ATTR esp_restart_noos(void) WRITE_PERI_REG(GPIO_FUNC4_IN_SEL_CFG_REG, 0x30); WRITE_PERI_REG(GPIO_FUNC5_IN_SEL_CFG_REG, 0x30); - // Reset wifi/bluetooth/ethernet/sdio (bb/mac) - SET_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG, - SYSTEM_WIFIBB_RST | SYSTEM_FE_RST | SYSTEM_WIFIMAC_RST | - SYSTEM_SDIO_RST | SYSTEM_EMAC_RST | SYSTEM_MACPWR_RST | - SYSTEM_BTBB_RST | SYSTEM_BTBB_REG_RST | - SYSTEM_RW_BTMAC_RST | SYSTEM_RW_BTLP_RST | SYSTEM_RW_BTMAC_REG_RST | SYSTEM_RW_BTLP_REG_RST); - 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 | SYSTEM_SYSTIMER_RST); - REG_WRITE(SYSTEM_PERIP_RST_EN0_REG, 0); - // Reset dma - SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_DMA_RST); - REG_WRITE(SYSTEM_PERIP_RST_EN1_REG, 0); + esp_system_reset_modules_on_exit(); // Set CPU back to XTAL source, same as hard reset, but keep BBPLL on so that USB Serial JTAG can log at 1st stage bootloader. #if !CONFIG_IDF_ENV_FPGA diff --git a/components/esp_system/port/soc/esp32c6/system_internal.c b/components/esp_system/port/soc/esp32c6/system_internal.c index 2d8b0183f4..75e43bf2d1 100644 --- a/components/esp_system/port/soc/esp32c6/system_internal.c +++ b/components/esp_system/port/soc/esp32c6/system_internal.c @@ -28,6 +28,36 @@ #include "esp32c6/rom/rtc.h" #include "soc/pcr_reg.h" +void IRAM_ATTR esp_system_reset_modules_on_exit(void) +{ + // Flush any data left in UART FIFOs before reset the UART peripheral + esp_rom_uart_tx_wait_idle(0); + esp_rom_uart_tx_wait_idle(1); + + modem_syscon_ll_reset_all(&MODEM_SYSCON); + modem_lpcon_ll_reset_all(&MODEM_LPCON); + + // Set Peripheral clk rst + SET_PERI_REG_MASK(PCR_MSPI_CONF_REG, PCR_MSPI_RST_EN); + SET_PERI_REG_MASK(PCR_UART0_CONF_REG, PCR_UART0_RST_EN); + SET_PERI_REG_MASK(PCR_UART1_CONF_REG, PCR_UART1_RST_EN); + SET_PERI_REG_MASK(PCR_SYSTIMER_CONF_REG, PCR_SYSTIMER_RST_EN); + SET_PERI_REG_MASK(PCR_GDMA_CONF_REG, PCR_GDMA_RST_EN); + SET_PERI_REG_MASK(PCR_SDIO_SLAVE_CONF_REG, PCR_SDIO_SLAVE_RST_EN); + SET_PERI_REG_MASK(PCR_MODEM_APB_CONF_REG, PCR_MODEM_RST_EN); + SET_PERI_REG_MASK(PCR_PWM_CONF_REG, PCR_PWM_RST_EN); + + // Clear Peripheral clk rst + CLEAR_PERI_REG_MASK(PCR_MSPI_CONF_REG, PCR_MSPI_RST_EN); + CLEAR_PERI_REG_MASK(PCR_UART0_CONF_REG, PCR_UART0_RST_EN); + CLEAR_PERI_REG_MASK(PCR_UART1_CONF_REG, PCR_UART1_RST_EN); + CLEAR_PERI_REG_MASK(PCR_SYSTIMER_CONF_REG, PCR_SYSTIMER_RST_EN); + CLEAR_PERI_REG_MASK(PCR_GDMA_CONF_REG, PCR_GDMA_RST_EN); + CLEAR_PERI_REG_MASK(PCR_SDIO_SLAVE_CONF_REG, PCR_SDIO_SLAVE_RST_EN); + CLEAR_PERI_REG_MASK(PCR_MODEM_APB_CONF_REG, PCR_MODEM_RST_EN); + CLEAR_PERI_REG_MASK(PCR_PWM_CONF_REG, PCR_PWM_RST_EN); +} + /* "inner" restart function for after RTOS, interrupts & anything else on this * core are already stopped. Stalls other core, resets hardware, * triggers restart. @@ -60,9 +90,6 @@ void IRAM_ATTR esp_restart_noos(void) wdt_hal_disable(&wdt1_context); wdt_hal_write_protect_enable(&wdt1_context); - // Flush any data left in UART FIFOs - esp_rom_uart_tx_wait_idle(0); - esp_rom_uart_tx_wait_idle(1); // Disable cache Cache_Disable_ICache(); @@ -73,30 +100,7 @@ void IRAM_ATTR esp_restart_noos(void) // SYSTEM_EMAC_RST | SYSTEM_MACPWR_RST | // TODO: IDF-5325 (ethernet) // REG_WRITE(SYSTEM_CORE_RST_EN_REG, 0); - modem_syscon_ll_reset_all(&MODEM_SYSCON); - modem_lpcon_ll_reset_all(&MODEM_LPCON); - - // Set Peripheral clk rst - SET_PERI_REG_MASK(PCR_TIMERGROUP0_CONF_REG, PCR_TG0_RST_EN); - SET_PERI_REG_MASK(PCR_TIMERGROUP1_CONF_REG, PCR_TG1_RST_EN); - SET_PERI_REG_MASK(PCR_MSPI_CONF_REG, PCR_MSPI_RST_EN); - SET_PERI_REG_MASK(PCR_UART0_CONF_REG, PCR_UART0_RST_EN); - SET_PERI_REG_MASK(PCR_UART1_CONF_REG, PCR_UART1_RST_EN); - SET_PERI_REG_MASK(PCR_SYSTIMER_CONF_REG, PCR_SYSTIMER_RST_EN); - SET_PERI_REG_MASK(PCR_GDMA_CONF_REG, PCR_GDMA_RST_EN); - SET_PERI_REG_MASK(PCR_SDIO_SLAVE_CONF_REG, PCR_SDIO_SLAVE_RST_EN); - SET_PERI_REG_MASK(PCR_MODEM_APB_CONF_REG, PCR_MODEM_RST_EN); - - // Clear Peripheral clk rst - CLEAR_PERI_REG_MASK(PCR_TIMERGROUP0_CONF_REG, PCR_TG0_RST_EN); - CLEAR_PERI_REG_MASK(PCR_TIMERGROUP1_CONF_REG, PCR_TG1_RST_EN); - CLEAR_PERI_REG_MASK(PCR_MSPI_CONF_REG, PCR_MSPI_RST_EN); - CLEAR_PERI_REG_MASK(PCR_UART0_CONF_REG, PCR_UART0_RST_EN); - CLEAR_PERI_REG_MASK(PCR_UART1_CONF_REG, PCR_UART1_RST_EN); - CLEAR_PERI_REG_MASK(PCR_SYSTIMER_CONF_REG, PCR_SYSTIMER_RST_EN); - CLEAR_PERI_REG_MASK(PCR_GDMA_CONF_REG, PCR_GDMA_RST_EN); - CLEAR_PERI_REG_MASK(PCR_SDIO_SLAVE_CONF_REG, PCR_SDIO_SLAVE_RST_EN); - CLEAR_PERI_REG_MASK(PCR_MODEM_APB_CONF_REG, PCR_MODEM_RST_EN); + esp_system_reset_modules_on_exit(); // Set CPU back to XTAL source, same as hard reset, but keep BBPLL on so that USB Serial JTAG can log at 1st stage bootloader. #if !CONFIG_IDF_ENV_FPGA diff --git a/components/esp_system/port/soc/esp32h2/system_internal.c b/components/esp_system/port/soc/esp32h2/system_internal.c index 62037572d6..bc4aecd271 100644 --- a/components/esp_system/port/soc/esp32h2/system_internal.c +++ b/components/esp_system/port/soc/esp32h2/system_internal.c @@ -29,6 +29,31 @@ #include "esp32h2/rom/rtc.h" #include "soc/pcr_reg.h" +void IRAM_ATTR esp_system_reset_modules_on_exit(void) +{ + // Flush any data left in UART FIFOs before reset the UART peripheral + esp_rom_uart_tx_wait_idle(0); + esp_rom_uart_tx_wait_idle(1); + + // Set Peripheral clk rst + SET_PERI_REG_MASK(PCR_MSPI_CONF_REG, PCR_MSPI_RST_EN); + SET_PERI_REG_MASK(PCR_UART0_CONF_REG, PCR_UART0_RST_EN); + SET_PERI_REG_MASK(PCR_UART1_CONF_REG, PCR_UART1_RST_EN); + SET_PERI_REG_MASK(PCR_SYSTIMER_CONF_REG, PCR_SYSTIMER_RST_EN); + SET_PERI_REG_MASK(PCR_GDMA_CONF_REG, PCR_GDMA_RST_EN); + SET_PERI_REG_MASK(PCR_MODEM_CONF_REG, PCR_MODEM_RST_EN); + SET_PERI_REG_MASK(PCR_PWM_CONF_REG, PCR_PWM_RST_EN); + + // Clear Peripheral clk rst + CLEAR_PERI_REG_MASK(PCR_MSPI_CONF_REG, PCR_MSPI_RST_EN); + CLEAR_PERI_REG_MASK(PCR_UART0_CONF_REG, PCR_UART0_RST_EN); + CLEAR_PERI_REG_MASK(PCR_UART1_CONF_REG, PCR_UART1_RST_EN); + CLEAR_PERI_REG_MASK(PCR_SYSTIMER_CONF_REG, PCR_SYSTIMER_RST_EN); + CLEAR_PERI_REG_MASK(PCR_GDMA_CONF_REG, PCR_GDMA_RST_EN); + CLEAR_PERI_REG_MASK(PCR_MODEM_CONF_REG, PCR_MODEM_RST_EN); + CLEAR_PERI_REG_MASK(PCR_PWM_CONF_REG, PCR_PWM_RST_EN); +} + /* "inner" restart function for after RTOS, interrupts & anything else on this * core are already stopped. Stalls other core, resets hardware, * triggers restart. @@ -59,9 +84,6 @@ void IRAM_ATTR esp_restart_noos(void) wdt_hal_disable(&wdt1_context); wdt_hal_write_protect_enable(&wdt1_context); - // Flush any data left in UART FIFOs - esp_rom_uart_tx_wait_idle(0); - esp_rom_uart_tx_wait_idle(1); // Disable cache Cache_Disable_ICache(); @@ -69,25 +91,7 @@ void IRAM_ATTR esp_restart_noos(void) // Reset them to the defaults expected by ROM. WRITE_PERI_REG(GPIO_FUNC0_IN_SEL_CFG_REG, 0x30); - // Set Peripheral clk rst - SET_PERI_REG_MASK(PCR_TIMERGROUP0_CONF_REG, PCR_TG0_RST_EN); - SET_PERI_REG_MASK(PCR_TIMERGROUP1_CONF_REG, PCR_TG1_RST_EN); - SET_PERI_REG_MASK(PCR_MSPI_CONF_REG, PCR_MSPI_RST_EN); - SET_PERI_REG_MASK(PCR_UART0_CONF_REG, PCR_UART0_RST_EN); - SET_PERI_REG_MASK(PCR_UART1_CONF_REG, PCR_UART1_RST_EN); - SET_PERI_REG_MASK(PCR_SYSTIMER_CONF_REG, PCR_SYSTIMER_RST_EN); - SET_PERI_REG_MASK(PCR_GDMA_CONF_REG, PCR_GDMA_RST_EN); - SET_PERI_REG_MASK(PCR_MODEM_CONF_REG, PCR_MODEM_RST_EN); - - // Clear Peripheral clk rst - CLEAR_PERI_REG_MASK(PCR_TIMERGROUP0_CONF_REG, PCR_TG0_RST_EN); - CLEAR_PERI_REG_MASK(PCR_TIMERGROUP1_CONF_REG, PCR_TG1_RST_EN); - CLEAR_PERI_REG_MASK(PCR_MSPI_CONF_REG, PCR_MSPI_RST_EN); - CLEAR_PERI_REG_MASK(PCR_UART0_CONF_REG, PCR_UART0_RST_EN); - CLEAR_PERI_REG_MASK(PCR_UART1_CONF_REG, PCR_UART1_RST_EN); - CLEAR_PERI_REG_MASK(PCR_SYSTIMER_CONF_REG, PCR_SYSTIMER_RST_EN); - CLEAR_PERI_REG_MASK(PCR_GDMA_CONF_REG, PCR_GDMA_RST_EN); - CLEAR_PERI_REG_MASK(PCR_MODEM_CONF_REG, PCR_MODEM_RST_EN); + esp_system_reset_modules_on_exit(); // If we set mspi clock frequency to PLL, but ROM does not have such clock source option. So reset the clock to XTAL when software restart. spi_flash_set_clock_src(MSPI_CLK_SRC_ROM_DEFAULT); diff --git a/components/esp_system/port/soc/esp32s2/system_internal.c b/components/esp_system/port/soc/esp32s2/system_internal.c index 9d84c14d24..db71cf1feb 100644 --- a/components/esp_system/port/soc/esp32s2/system_internal.c +++ b/components/esp_system/port/soc/esp32s2/system_internal.c @@ -31,6 +31,26 @@ extern int _bss_end; +void IRAM_ATTR esp_system_reset_modules_on_exit(void) +{ + // Flush any data left in UART FIFOs before reset the UART peripheral + esp_rom_uart_tx_wait_idle(0); + esp_rom_uart_tx_wait_idle(1); + + // Reset wifi/bluetooth/ethernet/sdio (bb/mac) + DPORT_SET_PERI_REG_MASK(DPORT_CORE_RST_EN_REG, + DPORT_WIFIBB_RST | DPORT_FE_RST | DPORT_WIFIMAC_RST | DPORT_BTBB_RST | + DPORT_BTMAC_RST | DPORT_SDIO_RST | DPORT_EMAC_RST | DPORT_MACPWR_RST | + DPORT_RW_BTMAC_RST | DPORT_RW_BTLP_RST); + DPORT_REG_WRITE(DPORT_CORE_RST_EN_REG, 0); + + // Reset timer/spi/uart + DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, + DPORT_TIMERS_RST | DPORT_SPI01_RST | DPORT_SPI2_RST | DPORT_SPI3_RST | + DPORT_SPI2_DMA_RST | DPORT_SPI3_DMA_RST | DPORT_UART_RST); + DPORT_REG_WRITE(DPORT_PERIP_RST_EN_REG, 0); +} + /* "inner" restart function for after RTOS, interrupts & anything else on this * core are already stopped. Stalls other core, resets hardware, * triggers restart. @@ -63,10 +83,6 @@ void IRAM_ATTR esp_restart_noos(void) wdt_hal_disable(&wdt1_context); wdt_hal_write_protect_enable(&wdt1_context); - // Flush any data left in UART FIFOs - esp_rom_uart_tx_wait_idle(0); - esp_rom_uart_tx_wait_idle(1); - #ifdef CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY if (esp_ptr_external_ram(esp_cpu_get_sp())) { // If stack_addr is from External Memory (CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY is used) @@ -90,23 +106,7 @@ void IRAM_ATTR esp_restart_noos(void) WRITE_PERI_REG(GPIO_FUNC4_IN_SEL_CFG_REG, 0x30); WRITE_PERI_REG(GPIO_FUNC5_IN_SEL_CFG_REG, 0x30); - // Reset wifi/bluetooth/ethernet/sdio (bb/mac) - DPORT_SET_PERI_REG_MASK(DPORT_CORE_RST_EN_REG, DPORT_WIFIBB_RST | \ - DPORT_FE_RST | \ - DPORT_WIFIMAC_RST | \ - DPORT_BTBB_RST | \ - DPORT_BTMAC_RST | \ - DPORT_SDIO_RST | \ - DPORT_EMAC_RST | \ - DPORT_MACPWR_RST | \ - DPORT_RW_BTMAC_RST | \ - DPORT_RW_BTLP_RST); - DPORT_REG_WRITE(DPORT_CORE_RST_EN_REG, 0); - - // Reset timer/spi/uart - DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, - DPORT_TIMERS_RST | DPORT_SPI01_RST | DPORT_SPI2_RST | DPORT_SPI3_RST | DPORT_SPI2_DMA_RST | DPORT_SPI3_DMA_RST | DPORT_UART_RST); - DPORT_REG_WRITE(DPORT_PERIP_RST_EN_REG, 0); + esp_system_reset_modules_on_exit(); // Set CPU back to XTAL source, same as hard reset, but keep BBPLL on so that USB CDC can log at 1st stage bootloader. rtc_clk_cpu_set_to_default_config(); diff --git a/components/esp_system/port/soc/esp32s3/system_internal.c b/components/esp_system/port/soc/esp32s3/system_internal.c index 0f595df873..4748098e52 100644 --- a/components/esp_system/port/soc/esp32s3/system_internal.c +++ b/components/esp_system/port/soc/esp32s3/system_internal.c @@ -31,6 +31,34 @@ extern int _bss_end; +void IRAM_ATTR esp_system_reset_modules_on_exit(void) +{ + // Flush any data left in UART FIFOs before reset the UART peripheral + esp_rom_uart_tx_wait_idle(0); + esp_rom_uart_tx_wait_idle(1); + esp_rom_uart_tx_wait_idle(2); + + // Reset wifi/bluetooth/ethernet/sdio (bb/mac) + SET_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG, + SYSTEM_WIFIBB_RST | SYSTEM_FE_RST | SYSTEM_WIFIMAC_RST | SYSTEM_SDIO_RST | + SYSTEM_EMAC_RST | SYSTEM_MACPWR_RST | SYSTEM_BTBB_RST | SYSTEM_BTBB_REG_RST | + SYSTEM_RW_BTMAC_RST | SYSTEM_RW_BTLP_RST | SYSTEM_RW_BTMAC_REG_RST | SYSTEM_RW_BTLP_REG_RST); + REG_WRITE(SYSTEM_CORE_RST_EN_REG, 0); + + // Reset timer, systimer, spi, uart, mcpwm + SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG, + SYSTEM_TIMERS_RST | SYSTEM_SPI01_RST | SYSTEM_UART_RST | SYSTEM_SYSTIMER_RST | + SYSTEM_PWM0_RST | SYSTEM_PWM1_RST); + REG_WRITE(SYSTEM_PERIP_RST_EN0_REG, 0); + + // Reset dma + SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_DMA_RST); + REG_WRITE(SYSTEM_PERIP_RST_EN1_REG, 0); + + SET_PERI_REG_MASK(SYSTEM_EDMA_CTRL_REG, SYSTEM_EDMA_RESET); + CLEAR_PERI_REG_MASK(SYSTEM_EDMA_CTRL_REG, SYSTEM_EDMA_RESET); +} + /* "inner" restart function for after RTOS, interrupts & anything else on this * core are already stopped. Stalls other core, resets hardware, * triggers restart. @@ -63,10 +91,6 @@ void IRAM_ATTR esp_restart_noos(void) wdt_hal_disable(&wdt1_context); wdt_hal_write_protect_enable(&wdt1_context); - // Flush any data left in UART FIFOs - esp_rom_uart_tx_wait_idle(0); - esp_rom_uart_tx_wait_idle(1); - #ifdef CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY if (esp_ptr_external_ram(esp_cpu_get_sp())) { // If stack_addr is from External Memory (CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY is used) @@ -101,25 +125,8 @@ void IRAM_ATTR esp_restart_noos(void) WRITE_PERI_REG(GPIO_FUNC4_IN_SEL_CFG_REG, 0x30); WRITE_PERI_REG(GPIO_FUNC5_IN_SEL_CFG_REG, 0x30); - // Reset wifi/bluetooth/ethernet/sdio (bb/mac) - SET_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG, - SYSTEM_WIFIBB_RST | SYSTEM_FE_RST | SYSTEM_WIFIMAC_RST | - SYSTEM_SDIO_RST | SYSTEM_EMAC_RST | SYSTEM_MACPWR_RST | - SYSTEM_BTBB_RST | SYSTEM_BTBB_REG_RST | - SYSTEM_RW_BTMAC_RST | SYSTEM_RW_BTLP_RST | SYSTEM_RW_BTMAC_REG_RST | SYSTEM_RW_BTLP_REG_RST); - REG_WRITE(SYSTEM_CORE_RST_EN_REG, 0); - - // Reset timer/spi/uart - SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG, - SYSTEM_TIMERS_RST | SYSTEM_SPI01_RST | SYSTEM_UART_RST | SYSTEM_SYSTIMER_RST); - REG_WRITE(SYSTEM_PERIP_RST_EN0_REG, 0); - - // Reset dma - SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_DMA_RST); - REG_WRITE(SYSTEM_PERIP_RST_EN1_REG, 0); - - SET_PERI_REG_MASK(SYSTEM_EDMA_CTRL_REG, SYSTEM_EDMA_RESET); - CLEAR_PERI_REG_MASK(SYSTEM_EDMA_CTRL_REG, SYSTEM_EDMA_RESET); + // reset necessary peripheral modules + esp_system_reset_modules_on_exit(); // Set CPU back to XTAL source, same as hard reset, but keep BBPLL on so that USB Serial JTAG can log at 1st stage bootloader. #if !CONFIG_IDF_ENV_FPGA