diff --git a/components/esp32s2beta/panic.c b/components/esp32s2beta/panic.c index f68c37941..0082e0a85 100644 --- a/components/esp32s2beta/panic.c +++ b/components/esp32s2beta/panic.c @@ -470,32 +470,6 @@ static inline void disableAllWdts(void) TIMERG1.wdt_wprotect = 0; } -static void esp_panic_wdt_start(void) -{ - if (REG_GET_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_EN)) { - return; - } - WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, RTC_CNTL_WDT_WKEY_VALUE); - WRITE_PERI_REG(RTC_CNTL_WDTFEED_REG, 1); - REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_SYS_RESET_LENGTH, 7); - REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_CPU_RESET_LENGTH, 7); - REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_STG0, RTC_WDT_STG_SEL_RESET_SYSTEM); - // 64KB of core dump data (stacks of about 30 tasks) will produce ~85KB base64 data. - // @ 115200 UART speed it will take more than 6 sec to print them out. - WRITE_PERI_REG(RTC_CNTL_WDTCONFIG1_REG, rtc_clk_slow_freq_get_hz() * 7); - REG_SET_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_EN); - WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, 0); -} - -void esp_panic_wdt_stop(void) -{ - WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, RTC_CNTL_WDT_WKEY_VALUE); - WRITE_PERI_REG(RTC_CNTL_WDTFEED_REG, 1); - REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_STG0, RTC_WDT_STG_SEL_OFF); - REG_CLR_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_EN); - WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, 0); -} - #if CONFIG_ESP32S2_PANIC_PRINT_REBOOT || CONFIG_ESP32S2_PANIC_SILENT_REBOOT static void esp_panic_dig_reset(void) __attribute__((noreturn)); @@ -628,7 +602,18 @@ static __attribute__((noreturn)) void commonErrorHandler(XtExcFrame *frame) int core_id = xPortGetCoreID(); // start panic WDT to restart system if we hang in this handler - esp_panic_wdt_start(); + if (!rtc_wdt_is_on()) { + rtc_wdt_protect_off(); + rtc_wdt_disable(); + rtc_wdt_set_length_of_reset_signal(RTC_WDT_SYS_RESET_SIG, RTC_WDT_LENGTH_3_2us); + rtc_wdt_set_length_of_reset_signal(RTC_WDT_CPU_RESET_SIG, RTC_WDT_LENGTH_3_2us); + rtc_wdt_set_stage(RTC_WDT_STAGE0, RTC_WDT_STAGE_ACTION_RESET_SYSTEM); + // 64KB of core dump data (stacks of about 30 tasks) will produce ~85KB base64 data. + // @ 115200 UART speed it will take more than 6 sec to print them out. + rtc_wdt_set_time(RTC_WDT_STAGE0, 7000); + rtc_wdt_enable(); + rtc_wdt_protect_on(); + } //Feed the watchdogs, so they will give us time to print out debug info reconfigureAllWdts(); @@ -653,7 +638,7 @@ static __attribute__((noreturn)) void commonErrorHandler(XtExcFrame *frame) #if CONFIG_ESP32S2_PANIC_GDBSTUB disableAllWdts(); - esp_panic_wdt_stop(); + rtc_wdt_disable(); panicPutStr("Entering gdb stub now.\r\n"); esp_gdbstub_panic_handler(frame); #else @@ -674,7 +659,7 @@ static __attribute__((noreturn)) void commonErrorHandler(XtExcFrame *frame) reconfigureAllWdts(); } #endif /* CONFIG_ESP32_ENABLE_COREDUMP */ - esp_panic_wdt_stop(); + rtc_wdt_disable(); #if CONFIG_ESP32S2_PANIC_PRINT_REBOOT || CONFIG_ESP32S2_PANIC_SILENT_REBOOT panicPutStr("Rebooting...\r\n"); if (frame->exccause != PANIC_RSN_CACHEERR) { diff --git a/components/esp32s2beta/sleep_modes.c b/components/esp32s2beta/sleep_modes.c index 5e723f755..f0c5bd24d 100644 --- a/components/esp32s2beta/sleep_modes.c +++ b/components/esp32s2beta/sleep_modes.c @@ -34,6 +34,7 @@ #include "soc/spi_mem_reg.h" #include "soc/sens_reg.h" #include "soc/dport_reg.h" +#include "soc/rtc_wdt.h" #include "driver/rtc_io.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -218,27 +219,6 @@ void IRAM_ATTR esp_deep_sleep_start(void) } } -static void rtc_wdt_enable(int time_ms) -{ - WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, RTC_CNTL_WDT_WKEY_VALUE); - WRITE_PERI_REG(RTC_CNTL_WDTFEED_REG, 1); - REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_SYS_RESET_LENGTH, 7); - REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_CPU_RESET_LENGTH, 7); - REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_STG0, RTC_WDT_STG_SEL_RESET_RTC); - WRITE_PERI_REG(RTC_CNTL_WDTCONFIG1_REG, rtc_clk_slow_freq_get_hz() * time_ms / 1000); - SET_PERI_REG_MASK(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_EN | RTC_CNTL_WDT_PAUSE_IN_SLP); - WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, 0); -} - -static void rtc_wdt_disable(void) -{ - WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, RTC_CNTL_WDT_WKEY_VALUE); - WRITE_PERI_REG(RTC_CNTL_WDTFEED_REG, 1); - REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_STG0, RTC_WDT_STG_SEL_OFF); - REG_CLR_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_EN); - WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, 0); -} - /** * Helper function which handles entry to and exit from light sleep * Placed into IRAM as flash may need some time to be powered on. @@ -305,7 +285,17 @@ esp_err_t esp_light_sleep_start(void) rtc_vddsdio_config_t vddsdio_config = rtc_vddsdio_get_config(); // Safety net: enable WDT in case exit from light sleep fails - rtc_wdt_enable(1000); + bool wdt_was_enabled = rtc_wdt_is_on(); // If WDT was enabled in the user code, then do not change it here. + if (!wdt_was_enabled) { + rtc_wdt_protect_off(); + rtc_wdt_disable(); + rtc_wdt_set_length_of_reset_signal(RTC_WDT_SYS_RESET_SIG, RTC_WDT_LENGTH_3_2us); + rtc_wdt_set_length_of_reset_signal(RTC_WDT_CPU_RESET_SIG, RTC_WDT_LENGTH_3_2us); + rtc_wdt_set_stage(RTC_WDT_STAGE0, RTC_WDT_STAGE_ACTION_RESET_RTC); + rtc_wdt_set_time(RTC_WDT_STAGE0, 1000); + rtc_wdt_enable(); + rtc_wdt_protect_on(); + } // Enter sleep, then wait for flash to be ready on wakeup esp_err_t err = esp_light_sleep_inner(pd_flags, @@ -331,7 +321,9 @@ esp_err_t esp_light_sleep_start(void) esp_timer_impl_unlock(); DPORT_STALL_OTHER_CPU_END(); - rtc_wdt_disable(); + if (!wdt_was_enabled) { + rtc_wdt_disable(); + } portEXIT_CRITICAL(&light_sleep_lock); return err; } diff --git a/components/esp32s2beta/system_api.c b/components/esp32s2beta/system_api.c index c27b9bebf..285a83ef6 100644 --- a/components/esp32s2beta/system_api.c +++ b/components/esp32s2beta/system_api.c @@ -31,6 +31,7 @@ #include "soc/timer_group_struct.h" #include "soc/cpu.h" #include "soc/rtc.h" +#include "soc/rtc_wdt.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/xtensa_api.h" @@ -254,14 +255,14 @@ void IRAM_ATTR esp_restart_noos(void) xt_ints_off(0xFFFFFFFF); // Enable RTC watchdog for 1 second - REG_WRITE(RTC_CNTL_WDTWPROTECT_REG, RTC_CNTL_WDT_WKEY_VALUE); - REG_WRITE(RTC_CNTL_WDTCONFIG0_REG, - RTC_CNTL_WDT_FLASHBOOT_MOD_EN_M | - (RTC_WDT_STG_SEL_RESET_SYSTEM << RTC_CNTL_WDT_STG0_S) | - (RTC_WDT_STG_SEL_RESET_RTC << RTC_CNTL_WDT_STG1_S) | - (1 << RTC_CNTL_WDT_SYS_RESET_LENGTH_S) | - (1 << RTC_CNTL_WDT_CPU_RESET_LENGTH_S) ); - REG_WRITE(RTC_CNTL_WDTCONFIG1_REG, rtc_clk_slow_freq_get_hz() * 1); + rtc_wdt_protect_off(); + rtc_wdt_disable(); + rtc_wdt_set_stage(RTC_WDT_STAGE0, RTC_WDT_STAGE_ACTION_RESET_RTC); + rtc_wdt_set_stage(RTC_WDT_STAGE1, RTC_WDT_STAGE_ACTION_RESET_SYSTEM); + rtc_wdt_set_length_of_reset_signal(RTC_WDT_SYS_RESET_SIG, RTC_WDT_LENGTH_200ns); + rtc_wdt_set_length_of_reset_signal(RTC_WDT_CPU_RESET_SIG, RTC_WDT_LENGTH_200ns); + rtc_wdt_set_time(RTC_WDT_STAGE0, 1000); + rtc_wdt_flashboot_mode_enable(); // Reset and stall the other CPU. // CPU must be reset before stalling, in case it was running a s32c1i