From 24484887a90e7769e1b869ae8d7bd49aca940ae4 Mon Sep 17 00:00:00 2001 From: Gustavo Henrique Nihei Date: Fri, 24 Feb 2023 09:23:30 -0300 Subject: [PATCH 1/2] esp_system: Ensure TIMG0 clock is always enabled during normal operation If the TimerGroup 0 clock is disabled and then reenabled, the watchdog registers (Flashboot protection included) will be re-enabled, and some seconds later, will trigger an unintended reset. Signed-off-by: Gustavo Henrique Nihei --- components/driver/gptimer.c | 5 +---- components/esp_system/port/soc/esp32/clk.c | 9 +++++++++ components/esp_system/port/soc/esp32c2/clk.c | 9 +++++++++ components/esp_system/port/soc/esp32c3/clk.c | 9 +++++++++ components/esp_system/port/soc/esp32h2/clk.c | 9 +++++++++ components/esp_system/port/soc/esp32s2/clk.c | 9 +++++++++ components/esp_system/port/soc/esp32s3/clk.c | 9 +++++++++ 7 files changed, 55 insertions(+), 4 deletions(-) diff --git a/components/driver/gptimer.c b/components/driver/gptimer.c index d0591c6b57..d58460ce33 100644 --- a/components/driver/gptimer.c +++ b/components/driver/gptimer.c @@ -417,10 +417,7 @@ static void gptimer_release_group_handle(gptimer_group_t *group) assert(s_platform.groups[group_id]); do_deinitialize = true; s_platform.groups[group_id] = NULL; - // Theoretically we need to disable the peripheral clock for the timer group - // However, next time when we enable the peripheral again, the registers will be reset to default value, including the watchdog registers inside the group - // Then the watchdog will go into reset state, e.g. the flash boot watchdog is enabled again and reset the system very soon - // periph_module_disable(timer_group_periph_signals.groups[group_id].module); + periph_module_disable(timer_group_periph_signals.groups[group_id].module); } _lock_release(&s_platform.mutex); diff --git a/components/esp_system/port/soc/esp32/clk.c b/components/esp_system/port/soc/esp32/clk.c index fef50f109a..5ec87cca7f 100644 --- a/components/esp_system/port/soc/esp32/clk.c +++ b/components/esp_system/port/soc/esp32/clk.c @@ -300,6 +300,15 @@ __attribute__((weak)) void esp_perip_clk_init(void) /* Enable RNG clock. */ periph_module_enable(PERIPH_RNG_MODULE); + + /* Enable TimerGroup 0 clock to ensure its reference counter will never + * be decremented to 0 during normal operation and preventing it from + * being disabled. + * If the TimerGroup 0 clock is disabled and then reenabled, the watchdog + * registers (Flashboot protection included) will be reenabled, and some + * seconds later, will trigger an unintended reset. + */ + periph_module_enable(PERIPH_TIMG0_MODULE); } void rtc_clk_select_rtc_slow_clk(void) diff --git a/components/esp_system/port/soc/esp32c2/clk.c b/components/esp_system/port/soc/esp32c2/clk.c index ebc800e576..d22dc4ceaf 100644 --- a/components/esp_system/port/soc/esp32c2/clk.c +++ b/components/esp_system/port/soc/esp32c2/clk.c @@ -251,4 +251,13 @@ __attribute__((weak)) void esp_perip_clk_init(void) /* Enable RNG clock. */ periph_module_enable(PERIPH_RNG_MODULE); + + /* Enable TimerGroup 0 clock to ensure its reference counter will never + * be decremented to 0 during normal operation and preventing it from + * being disabled. + * If the TimerGroup 0 clock is disabled and then reenabled, the watchdog + * registers (Flashboot protection included) will be reenabled, and some + * seconds later, will trigger an unintended reset. + */ + periph_module_enable(PERIPH_TIMG0_MODULE); } diff --git a/components/esp_system/port/soc/esp32c3/clk.c b/components/esp_system/port/soc/esp32c3/clk.c index 3f044443c1..87f8b1c04b 100644 --- a/components/esp_system/port/soc/esp32c3/clk.c +++ b/components/esp_system/port/soc/esp32c3/clk.c @@ -295,4 +295,13 @@ __attribute__((weak)) void esp_perip_clk_init(void) /* Enable RNG clock. */ periph_module_enable(PERIPH_RNG_MODULE); + + /* Enable TimerGroup 0 clock to ensure its reference counter will never + * be decremented to 0 during normal operation and preventing it from + * being disabled. + * If the TimerGroup 0 clock is disabled and then reenabled, the watchdog + * registers (Flashboot protection included) will be reenabled, and some + * seconds later, will trigger an unintended reset. + */ + periph_module_enable(PERIPH_TIMG0_MODULE); } diff --git a/components/esp_system/port/soc/esp32h2/clk.c b/components/esp_system/port/soc/esp32h2/clk.c index de5612b7c2..839a3f3f6c 100644 --- a/components/esp_system/port/soc/esp32h2/clk.c +++ b/components/esp_system/port/soc/esp32h2/clk.c @@ -274,4 +274,13 @@ __attribute__((weak)) void esp_perip_clk_init(void) /* Enable RNG clock. */ periph_module_enable(PERIPH_RNG_MODULE); + + /* Enable TimerGroup 0 clock to ensure its reference counter will never + * be decremented to 0 during normal operation and preventing it from + * being disabled. + * If the TimerGroup 0 clock is disabled and then reenabled, the watchdog + * registers (Flashboot protection included) will be reenabled, and some + * seconds later, will trigger an unintended reset. + */ + periph_module_enable(PERIPH_TIMG0_MODULE); } diff --git a/components/esp_system/port/soc/esp32s2/clk.c b/components/esp_system/port/soc/esp32s2/clk.c index 8461d16c83..dda6cd264b 100644 --- a/components/esp_system/port/soc/esp32s2/clk.c +++ b/components/esp_system/port/soc/esp32s2/clk.c @@ -312,4 +312,13 @@ __attribute__((weak)) void esp_perip_clk_init(void) /* Enable RNG clock. */ periph_module_enable(PERIPH_RNG_MODULE); + + /* Enable TimerGroup 0 clock to ensure its reference counter will never + * be decremented to 0 during normal operation and preventing it from + * being disabled. + * If the TimerGroup 0 clock is disabled and then reenabled, the watchdog + * registers (Flashboot protection included) will be reenabled, and some + * seconds later, will trigger an unintended reset. + */ + periph_module_enable(PERIPH_TIMG0_MODULE); } diff --git a/components/esp_system/port/soc/esp32s3/clk.c b/components/esp_system/port/soc/esp32s3/clk.c index 5df6e1ae8c..8d25f506ec 100644 --- a/components/esp_system/port/soc/esp32s3/clk.c +++ b/components/esp_system/port/soc/esp32s3/clk.c @@ -314,4 +314,13 @@ __attribute__((weak)) void esp_perip_clk_init(void) /* Enable RNG clock. */ periph_module_enable(PERIPH_RNG_MODULE); + + /* Enable TimerGroup 0 clock to ensure its reference counter will never + * be decremented to 0 during normal operation and preventing it from + * being disabled. + * If the TimerGroup 0 clock is disabled and then reenabled, the watchdog + * registers (Flashboot protection included) will be reenabled, and some + * seconds later, will trigger an unintended reset. + */ + periph_module_enable(PERIPH_TIMG0_MODULE); } From aab0a5a4a85d7f355ad9687e156a1aff47c5bfe4 Mon Sep 17 00:00:00 2001 From: Gustavo Henrique Nihei Date: Thu, 23 Feb 2023 08:59:59 -0300 Subject: [PATCH 2/2] esp_system: Fix TIMG0 still enabled after Timer is freed Signed-off-by: Gustavo Henrique Nihei --- components/esp_system/task_wdt/task_wdt_impl_timergroup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp_system/task_wdt/task_wdt_impl_timergroup.c b/components/esp_system/task_wdt/task_wdt_impl_timergroup.c index 57af2cd7e0..817aa08199 100644 --- a/components/esp_system/task_wdt/task_wdt_impl_timergroup.c +++ b/components/esp_system/task_wdt/task_wdt_impl_timergroup.c @@ -105,7 +105,7 @@ void esp_task_wdt_impl_timer_free(twdt_ctx_t obj) ESP_ERROR_CHECK(esp_intr_disable(ctx->intr_handle)); /* Disable the Timer Group module */ - periph_module_enable(TWDT_PERIPH_MODULE); + periph_module_disable(TWDT_PERIPH_MODULE); /* Deregister interrupt */ ESP_ERROR_CHECK(esp_intr_free(ctx->intr_handle));