From e8ba294bd28e773b1698d8fd9cc8d0a6b7ae8bc7 Mon Sep 17 00:00:00 2001 From: Marius Vikhammer Date: Tue, 17 Mar 2026 12:00:13 +0800 Subject: [PATCH 1/2] fix(bootloader): enable super WDT auto-feed on ESP32-S31 The super WDT was firing during bootloader init because auto-feed was not enabled, causing continuous resets with rst:0x12 (SUPER_WDT_RESET). Made-with: Cursor --- .../src/esp32s31/bootloader_esp32s31.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/components/bootloader_support/src/esp32s31/bootloader_esp32s31.c b/components/bootloader_support/src/esp32s31/bootloader_esp32s31.c index 5b6807bc10..3908ea48e9 100644 --- a/components/bootloader_support/src/esp32s31/bootloader_esp32s31.c +++ b/components/bootloader_support/src/esp32s31/bootloader_esp32s31.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,15 +18,24 @@ #include "bootloader_flash_priv.h" #include "bootloader_soc.h" #include "esp_private/bootloader_flash_internal.h" +#include "soc/rtc_wdt_reg.h" +#include "hal/rwdt_ll.h" ESP_LOG_ATTR_TAG(TAG, "boot.esp32s31"); +static void bootloader_super_wdt_auto_feed(void) +{ + REG_WRITE(RTC_WDT_SWD_WPROTECT_REG, RTC_WDT_SWD_WKEY_VALUE); + REG_SET_BIT(RTC_WDT_SWD_CONFIG_REG, RTC_WDT_SWD_AUTO_FEED_EN); + REG_WRITE(RTC_WDT_SWD_WPROTECT_REG, 0); +} + esp_err_t bootloader_init(void) { esp_err_t ret = ESP_OK; // bootloader_hardware_init(); // TODO: IDF-14696 - // bootloader_super_wdt_auto_feed(); // TODO: IDF-14678 + bootloader_super_wdt_auto_feed(); // In RAM_APP, memory will be initialized in `call_start_cpu0` #if !CONFIG_APP_BUILD_TYPE_RAM From 4ab44312d4733ad9d8648ffa652ce736603b203e Mon Sep 17 00:00:00 2001 From: Marius Vikhammer Date: Wed, 18 Mar 2026 11:08:40 +0800 Subject: [PATCH 2/2] fix(esp_timer): enable systimer functional clock on ESP32-S31 ESP32-S31 has a separate functional clock gate for the systimer (reg_systimer_clk_en in HP_SYS_CLKRST) that defaults to off. Without it, the counter snapshot never completes, hanging execution inside esp_timer_init_nonos. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../esp32c2/include/hal/systimer_ll.h | 11 +++++++++++ .../esp32c3/include/hal/systimer_ll.h | 11 +++++++++++ .../esp32c5/include/hal/systimer_ll.h | 11 +++++++++++ .../esp32c6/include/hal/systimer_ll.h | 11 +++++++++++ .../esp32c61/include/hal/systimer_ll.h | 11 +++++++++++ .../esp32h2/include/hal/systimer_ll.h | 11 +++++++++++ .../esp32h21/include/hal/systimer_ll.h | 11 +++++++++++ .../esp32h4/include/hal/systimer_ll.h | 11 +++++++++++ .../esp32p4/include/hal/systimer_ll.h | 17 +++++++++++++++++ .../esp32s2/include/hal/systimer_ll.h | 11 +++++++++++ .../esp32s3/include/hal/systimer_ll.h | 11 +++++++++++ .../esp32s31/include/hal/systimer_ll.h | 1 - .../esp_timer/src/esp_timer_impl_systimer.c | 1 + 13 files changed, 128 insertions(+), 1 deletion(-) diff --git a/components/esp_hal_systimer/esp32c2/include/hal/systimer_ll.h b/components/esp_hal_systimer/esp32c2/include/hal/systimer_ll.h index c745ca6461..4e7927259a 100644 --- a/components/esp_hal_systimer/esp32c2/include/hal/systimer_ll.h +++ b/components/esp_hal_systimer/esp32c2/include/hal/systimer_ll.h @@ -62,6 +62,17 @@ static inline void systimer_ll_enable_bus_clock(bool enable) systimer_ll_enable_bus_clock(__VA_ARGS__); \ } while(0) +/** + * @brief Enable the sys clock for systimer module + * This chip does not have a separate sys clock gate, this is a no-op. + * + * @param enable true to enable, false to disable + */ +static inline void systimer_ll_enable_sys_clock(bool enable) +{ + (void)enable; +} + /** * @brief Reset the systimer module * diff --git a/components/esp_hal_systimer/esp32c3/include/hal/systimer_ll.h b/components/esp_hal_systimer/esp32c3/include/hal/systimer_ll.h index 01e8e9df77..b5291786ab 100644 --- a/components/esp_hal_systimer/esp32c3/include/hal/systimer_ll.h +++ b/components/esp_hal_systimer/esp32c3/include/hal/systimer_ll.h @@ -62,6 +62,17 @@ static inline void systimer_ll_enable_bus_clock(bool enable) systimer_ll_enable_bus_clock(__VA_ARGS__); \ } while(0) +/** + * @brief Enable the sys clock for systimer module + * This chip does not have a separate sys clock gate, this is a no-op. + * + * @param enable true to enable, false to disable + */ +static inline void systimer_ll_enable_sys_clock(bool enable) +{ + (void)enable; +} + /** * @brief Reset the systimer module * diff --git a/components/esp_hal_systimer/esp32c5/include/hal/systimer_ll.h b/components/esp_hal_systimer/esp32c5/include/hal/systimer_ll.h index d3212993a1..1a09c5c3af 100644 --- a/components/esp_hal_systimer/esp32c5/include/hal/systimer_ll.h +++ b/components/esp_hal_systimer/esp32c5/include/hal/systimer_ll.h @@ -63,6 +63,17 @@ static inline void systimer_ll_enable_bus_clock(bool enable) systimer_ll_enable_bus_clock(__VA_ARGS__); \ } while(0) +/** + * @brief Enable the sys clock for systimer module + * This chip does not have a separate sys clock gate, this is a no-op. + * + * @param enable true to enable, false to disable + */ +static inline void systimer_ll_enable_sys_clock(bool enable) +{ + (void)enable; +} + /** * @brief Reset the systimer module * diff --git a/components/esp_hal_systimer/esp32c6/include/hal/systimer_ll.h b/components/esp_hal_systimer/esp32c6/include/hal/systimer_ll.h index 7dfb7c0e86..6bb5c98757 100644 --- a/components/esp_hal_systimer/esp32c6/include/hal/systimer_ll.h +++ b/components/esp_hal_systimer/esp32c6/include/hal/systimer_ll.h @@ -63,6 +63,17 @@ static inline void systimer_ll_enable_bus_clock(bool enable) systimer_ll_enable_bus_clock(__VA_ARGS__); \ } while(0) +/** + * @brief Enable the sys clock for systimer module + * This chip does not have a separate sys clock gate, this is a no-op. + * + * @param enable true to enable, false to disable + */ +static inline void systimer_ll_enable_sys_clock(bool enable) +{ + (void)enable; +} + /** * @brief Reset the systimer module * diff --git a/components/esp_hal_systimer/esp32c61/include/hal/systimer_ll.h b/components/esp_hal_systimer/esp32c61/include/hal/systimer_ll.h index c3f1f39018..0b48a648c4 100644 --- a/components/esp_hal_systimer/esp32c61/include/hal/systimer_ll.h +++ b/components/esp_hal_systimer/esp32c61/include/hal/systimer_ll.h @@ -63,6 +63,17 @@ static inline void systimer_ll_enable_bus_clock(bool enable) systimer_ll_enable_bus_clock(__VA_ARGS__); \ } while(0) +/** + * @brief Enable the sys clock for systimer module + * This chip does not have a separate sys clock gate, this is a no-op. + * + * @param enable true to enable, false to disable + */ +static inline void systimer_ll_enable_sys_clock(bool enable) +{ + (void)enable; +} + /** * @brief Reset the systimer module * diff --git a/components/esp_hal_systimer/esp32h2/include/hal/systimer_ll.h b/components/esp_hal_systimer/esp32h2/include/hal/systimer_ll.h index 767afdb0b3..c750cda700 100644 --- a/components/esp_hal_systimer/esp32h2/include/hal/systimer_ll.h +++ b/components/esp_hal_systimer/esp32h2/include/hal/systimer_ll.h @@ -63,6 +63,17 @@ static inline void systimer_ll_enable_bus_clock(bool enable) systimer_ll_enable_bus_clock(__VA_ARGS__); \ } while(0) +/** + * @brief Enable the sys clock for systimer module + * This chip does not have a separate sys clock gate, this is a no-op. + * + * @param enable true to enable, false to disable + */ +static inline void systimer_ll_enable_sys_clock(bool enable) +{ + (void)enable; +} + /** * @brief Reset the systimer module * diff --git a/components/esp_hal_systimer/esp32h21/include/hal/systimer_ll.h b/components/esp_hal_systimer/esp32h21/include/hal/systimer_ll.h index cabb4e5863..7046b97a6e 100644 --- a/components/esp_hal_systimer/esp32h21/include/hal/systimer_ll.h +++ b/components/esp_hal_systimer/esp32h21/include/hal/systimer_ll.h @@ -63,6 +63,17 @@ static inline void systimer_ll_enable_bus_clock(bool enable) systimer_ll_enable_bus_clock(__VA_ARGS__); \ } while(0) +/** + * @brief Enable the sys clock for systimer module + * This chip does not have a separate sys clock gate, this is a no-op. + * + * @param enable true to enable, false to disable + */ +static inline void systimer_ll_enable_sys_clock(bool enable) +{ + (void)enable; +} + /** * @brief Reset the systimer module * diff --git a/components/esp_hal_systimer/esp32h4/include/hal/systimer_ll.h b/components/esp_hal_systimer/esp32h4/include/hal/systimer_ll.h index 1bcc2a7123..75928e877b 100644 --- a/components/esp_hal_systimer/esp32h4/include/hal/systimer_ll.h +++ b/components/esp_hal_systimer/esp32h4/include/hal/systimer_ll.h @@ -63,6 +63,17 @@ static inline void systimer_ll_enable_bus_clock(bool enable) systimer_ll_enable_bus_clock(__VA_ARGS__); \ } while(0) +/** + * @brief Enable the sys clock for systimer module + * This chip does not have a separate sys clock gate, this is a no-op. + * + * @param enable true to enable, false to disable + */ +static inline void systimer_ll_enable_sys_clock(bool enable) +{ + (void)enable; +} + /** * @brief Reset the systimer module * diff --git a/components/esp_hal_systimer/esp32p4/include/hal/systimer_ll.h b/components/esp_hal_systimer/esp32p4/include/hal/systimer_ll.h index c94ad596e9..066e73ab68 100644 --- a/components/esp_hal_systimer/esp32p4/include/hal/systimer_ll.h +++ b/components/esp_hal_systimer/esp32p4/include/hal/systimer_ll.h @@ -70,6 +70,23 @@ static inline void systimer_ll_enable_bus_clock(bool enable) systimer_ll_enable_bus_clock(__VA_ARGS__); \ } while(0) +/** + * @brief Enable the sys clock for systimer module + * + * @param enable true to enable, false to disable + */ +static inline void systimer_ll_enable_sys_clock(bool enable) +{ + HP_SYS_CLKRST.peri_clk_ctrl21.reg_systimer_clk_en = enable; +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance +#define systimer_ll_enable_sys_clock(...) do { \ + (void)__DECLARE_RCC_RC_ATOMIC_ENV; \ + systimer_ll_enable_sys_clock(__VA_ARGS__); \ + } while(0) + /** * @brief Reset the systimer module * diff --git a/components/esp_hal_systimer/esp32s2/include/hal/systimer_ll.h b/components/esp_hal_systimer/esp32s2/include/hal/systimer_ll.h index b77d200282..2e36e4f11b 100644 --- a/components/esp_hal_systimer/esp32s2/include/hal/systimer_ll.h +++ b/components/esp_hal_systimer/esp32s2/include/hal/systimer_ll.h @@ -62,6 +62,17 @@ static inline void systimer_ll_enable_bus_clock(bool enable) systimer_ll_enable_bus_clock(__VA_ARGS__); \ } while(0) +/** + * @brief Enable the sys clock for systimer module + * This chip does not have a separate sys clock gate, this is a no-op. + * + * @param enable true to enable, false to disable + */ +static inline void systimer_ll_enable_sys_clock(bool enable) +{ + (void)enable; +} + /** * @brief Reset the systimer module * diff --git a/components/esp_hal_systimer/esp32s3/include/hal/systimer_ll.h b/components/esp_hal_systimer/esp32s3/include/hal/systimer_ll.h index af918248b8..a51b0c3e22 100644 --- a/components/esp_hal_systimer/esp32s3/include/hal/systimer_ll.h +++ b/components/esp_hal_systimer/esp32s3/include/hal/systimer_ll.h @@ -62,6 +62,17 @@ static inline void systimer_ll_enable_bus_clock(bool enable) systimer_ll_enable_bus_clock(__VA_ARGS__); \ } while(0) +/** + * @brief Enable the sys clock for systimer module + * This chip does not have a separate sys clock gate, this is a no-op. + * + * @param enable true to enable, false to disable + */ +static inline void systimer_ll_enable_sys_clock(bool enable) +{ + (void)enable; +} + /** * @brief Reset the systimer module * diff --git a/components/esp_hal_systimer/esp32s31/include/hal/systimer_ll.h b/components/esp_hal_systimer/esp32s31/include/hal/systimer_ll.h index 382794cdb2..3ce56961c0 100644 --- a/components/esp_hal_systimer/esp32s31/include/hal/systimer_ll.h +++ b/components/esp_hal_systimer/esp32s31/include/hal/systimer_ll.h @@ -29,7 +29,6 @@ extern "C" { #define SYSTIMER_LL_INT_LEVEL 1 // Systimer peripheral uses level interrupt #define SYSTIMER_LL_ALARM_MISS_COMPENSATE 1 // Systimer peripheral can generate interrupt immediately if t(target) > t(current) #define SYSTIMER_LL_FIXED_DIVIDER 1 // Clock source divider is fixed: 2.5 - /******************* Clock *************************/ __attribute__((always_inline)) static inline void systimer_ll_enable_clock(systimer_dev_t *dev, bool en) diff --git a/components/esp_timer/src/esp_timer_impl_systimer.c b/components/esp_timer/src/esp_timer_impl_systimer.c index 3d67ba33ca..237a435061 100644 --- a/components/esp_timer/src/esp_timer_impl_systimer.c +++ b/components/esp_timer/src/esp_timer_impl_systimer.c @@ -153,6 +153,7 @@ esp_err_t esp_timer_impl_early_init(void) if (ref_count == 0) { systimer_ll_enable_bus_clock(true); systimer_ll_reset_register(); + systimer_ll_enable_sys_clock(true); } } systimer_hal_tick_rate_ops_t ops = {