Преглед на файлове

feat(gptimer): use RCC atomic block to enable/reset peripheral

morris преди 2 години
родител
ревизия
71cf16ec01
променени са 27 файла, в които са добавени 488 реда и са изтрити 113 реда
  1. 28 4
      components/driver/deprecated/timer_legacy.c
  2. 35 6
      components/driver/gptimer/gptimer.c
  3. 0 8
      components/esp_system/fpga_overrides.c
  4. 11 1
      components/esp_system/int_wdt.c
  5. 1 10
      components/esp_system/port/soc/esp32/clk.c
  6. 1 10
      components/esp_system/port/soc/esp32c2/clk.c
  7. 1 10
      components/esp_system/port/soc/esp32c3/clk.c
  8. 0 9
      components/esp_system/port/soc/esp32c6/clk.c
  9. 0 9
      components/esp_system/port/soc/esp32h2/clk.c
  10. 1 10
      components/esp_system/port/soc/esp32s2/clk.c
  11. 1 10
      components/esp_system/port/soc/esp32s3/clk.c
  12. 14 2
      components/esp_system/task_wdt/task_wdt_impl_timergroup.c
  13. 12 1
      components/esp_timer/src/esp_timer_impl_lac.c
  14. 51 1
      components/hal/esp32/include/hal/timer_ll.h
  15. 39 1
      components/hal/esp32c2/include/hal/timer_ll.h
  16. 47 1
      components/hal/esp32c3/include/hal/timer_ll.h
  17. 46 1
      components/hal/esp32c6/include/hal/timer_ll.h
  18. 45 0
      components/hal/esp32h2/include/hal/timer_ll.h
  19. 0 13
      components/hal/esp32p4/include/hal/clk_gate_ll.h
  20. 53 0
      components/hal/esp32p4/include/hal/timer_ll.h
  21. 51 1
      components/hal/esp32s2/include/hal/timer_ll.h
  22. 47 1
      components/hal/esp32s3/include/hal/timer_ll.h
  23. 0 4
      components/hal/timer_hal.c
  24. 1 0
      components/soc/esp32c2/include/soc/system_struct.h
  25. 1 0
      components/soc/esp32c2/ld/esp32c2.peripherals.ld
  26. 1 0
      components/soc/esp32c3/ld/esp32c3.peripherals.ld
  27. 1 0
      components/soc/esp32s3/ld/esp32s3.peripherals.ld

+ 28 - 4
components/driver/deprecated/timer_legacy.c

@@ -34,6 +34,12 @@ static const char *TIMER_TAG = "timer_group";
 #define TIMER_ENTER_CRITICAL(mux)      portENTER_CRITICAL_SAFE(mux);
 #define TIMER_EXIT_CRITICAL(mux)       portEXIT_CRITICAL_SAFE(mux);
 
+#if CONFIG_IDF_TARGET_ESP32P4
+#define GPTIMER_CLOCK_SRC_ATOMIC() PERIPH_RCC_ATOMIC()
+#else
+#define GPTIMER_CLOCK_SRC_ATOMIC()
+#endif
+
 typedef struct {
     timer_isr_t fn;  /*!< isr function */
     void *args;      /*!< isr function args */
@@ -305,7 +311,12 @@ esp_err_t timer_init(timer_group_t group_num, timer_idx_t timer_num, const timer
     }
     timer_hal_context_t *hal = &p_timer_obj[group_num][timer_num]->hal;
 
-    periph_module_enable(timer_group_periph_signals.groups[group_num].module);
+    PERIPH_RCC_ACQUIRE_ATOMIC(timer_group_periph_signals.groups[group_num].module, ref_count) {
+        if (ref_count == 0) {
+            timer_ll_enable_bus_clock(group_num, true);
+            timer_ll_reset_register(group_num);
+        }
+    }
 
     TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
     timer_hal_init(hal, group_num, timer_num);
@@ -315,9 +326,12 @@ esp_err_t timer_init(timer_group_t group_num, timer_idx_t timer_num, const timer
     if (config->clk_src) {
         clk_src = config->clk_src;
     }
-    // although `clk_src` is of `timer_src_clk_t` type, but it's binary compatible with `gptimer_clock_source_t`,
-    // as the underlying enum entries come from the same `soc_module_clk_t`
-    timer_ll_set_clock_source(p_timer_obj[group_num][timer_num]->hal.dev, timer_num, (gptimer_clock_source_t)clk_src);
+    GPTIMER_CLOCK_SRC_ATOMIC() {
+        // although `clk_src` is of `timer_src_clk_t` type, but it's binary compatible with `gptimer_clock_source_t`,
+        // as the underlying enum entries come from the same `soc_module_clk_t`
+        timer_ll_set_clock_source(p_timer_obj[group_num][timer_num]->hal.dev, timer_num, (gptimer_clock_source_t)clk_src);
+        timer_ll_enable_clock(hal->dev, timer_num, true);
+    }
     timer_ll_set_clock_prescale(hal->dev, timer_num, config->divider);
     timer_ll_set_count_direction(p_timer_obj[group_num][timer_num]->hal.dev, timer_num, config->counter_dir);
     timer_ll_enable_intr(hal->dev, TIMER_LL_EVENT_ALARM(timer_num), false);
@@ -343,12 +357,22 @@ esp_err_t timer_deinit(timer_group_t group_num, timer_idx_t timer_num)
     ESP_RETURN_ON_FALSE(p_timer_obj[group_num][timer_num] != NULL, ESP_ERR_INVALID_ARG, TIMER_TAG,  TIMER_NEVER_INIT_ERROR);
     timer_hal_context_t *hal = &p_timer_obj[group_num][timer_num]->hal;
 
+    // disable the source clock
+    GPTIMER_CLOCK_SRC_ATOMIC() {
+        timer_ll_enable_clock(hal->dev, hal->timer_id, false);
+    }
     TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]);
     timer_ll_enable_intr(hal->dev, TIMER_LL_EVENT_ALARM(timer_num), false);
     timer_ll_clear_intr_status(hal->dev, TIMER_LL_EVENT_ALARM(timer_num));
     timer_hal_deinit(hal);
     TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]);
 
+    PERIPH_RCC_RELEASE_ATOMIC(timer_group_periph_signals.groups[group_num].module, ref_count) {
+        if (ref_count == 0) {
+            timer_ll_enable_bus_clock(group_num, false);
+        }
+    }
+
     free(p_timer_obj[group_num][timer_num]);
     p_timer_obj[group_num][timer_num] = NULL;
 

+ 35 - 6
components/driver/gptimer/gptimer.c

@@ -32,6 +32,12 @@
 
 static const char *TAG = "gptimer";
 
+#if CONFIG_IDF_TARGET_ESP32P4
+#define GPTIMER_CLOCK_SRC_ATOMIC() PERIPH_RCC_ATOMIC()
+#else
+#define GPTIMER_CLOCK_SRC_ATOMIC()
+#endif
+
 typedef struct gptimer_platform_t {
     _lock_t mutex;                             // platform level mutex lock
     gptimer_group_t *groups[SOC_TIMER_GROUPS]; // timer group pool
@@ -163,8 +169,13 @@ esp_err_t gptimer_del_timer(gptimer_handle_t timer)
     gptimer_clock_source_t clk_src = timer->clk_src;
     int group_id = group->group_id;
     int timer_id = timer->timer_id;
+    timer_hal_context_t *hal = &timer->hal;
     ESP_LOGD(TAG, "del timer (%d,%d)", group_id, timer_id);
-    timer_hal_deinit(&timer->hal);
+    // disable the source clock
+    GPTIMER_CLOCK_SRC_ATOMIC() {
+        timer_ll_enable_clock(hal->dev, hal->timer_id, false);
+    }
+    timer_hal_deinit(hal);
     // recycle memory resource
     ESP_RETURN_ON_ERROR(gptimer_destroy(timer), TAG, "destroy gptimer failed");
 
@@ -382,8 +393,6 @@ static gptimer_group_t *gptimer_acquire_group_handle(int group_id)
             // initialize timer group members
             group->group_id = group_id;
             group->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED;
-            // enable APB access timer registers
-            periph_module_enable(timer_group_periph_signals.groups[group_id].module);
         }
     } else {
         group = s_platform.groups[group_id];
@@ -395,6 +404,15 @@ static gptimer_group_t *gptimer_acquire_group_handle(int group_id)
     _lock_release(&s_platform.mutex);
 
     if (new_group) {
+        // !!! HARDWARE SHARED RESOURCE !!!
+        // the gptimer and watchdog reside in the same the timer group
+        // we need to increase/decrease the reference count before enable/disable/reset the peripheral
+        PERIPH_RCC_ACQUIRE_ATOMIC(timer_group_periph_signals.groups[group_id].module, ref_count) {
+            if (ref_count == 0) {
+                timer_ll_enable_bus_clock(group_id, true);
+                timer_ll_reset_register(group_id);
+            }
+        }
         ESP_LOGD(TAG, "new group (%d) @%p", group_id, group);
     }
 
@@ -412,11 +430,16 @@ 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;
-        periph_module_disable(timer_group_periph_signals.groups[group_id].module);
     }
     _lock_release(&s_platform.mutex);
 
     if (do_deinitialize) {
+        // disable bus clock for the timer group
+        PERIPH_RCC_RELEASE_ATOMIC(timer_group_periph_signals.groups[group_id].module, ref_count) {
+            if (ref_count == 0) {
+                timer_ll_enable_bus_clock(group_id, false);
+            }
+        }
         free(group);
         ESP_LOGD(TAG, "del group (%d)", group_id);
     }
@@ -476,9 +499,15 @@ static esp_err_t gptimer_select_periph_clock(gptimer_t *timer, gptimer_clock_sou
     }
 #endif // CONFIG_PM_ENABLE
 
-    timer_ll_set_clock_source(timer->hal.dev, timer_id, src_clk);
+    // !!! HARDWARE SHARED RESOURCE !!!
+    // on some ESP chip, different peripheral's clock source setting are mixed in the same register
+    // so we need to make this done in an atomic way
+    GPTIMER_CLOCK_SRC_ATOMIC() {
+        timer_ll_set_clock_source(timer->hal.dev, timer_id, src_clk);
+        timer_ll_enable_clock(timer->hal.dev, timer_id, true);
+    }
     timer->clk_src = src_clk;
-    unsigned int prescale = counter_src_hz / resolution_hz; // potential resolution loss here
+    uint32_t prescale = counter_src_hz / resolution_hz; // potential resolution loss here
     timer_ll_set_clock_prescale(timer->hal.dev, timer_id, prescale);
     timer->resolution_hz = counter_src_hz / prescale; // this is the real resolution
     if (timer->resolution_hz != resolution_hz) {

+ 0 - 8
components/esp_system/fpga_overrides.c

@@ -77,14 +77,6 @@ void esp_clk_init(void)
 
 void esp_perip_clk_init(void)
 {
-    /* 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);
 }
 
 /**

+ 11 - 1
components/esp_system/int_wdt.c

@@ -11,6 +11,7 @@
 #include "soc/soc_caps.h"
 #include "hal/wdt_hal.h"
 #include "hal/mwdt_ll.h"
+#include "hal/timer_ll.h"
 #include "freertos/FreeRTOS.h"
 #include "esp_cpu.h"
 #include "esp_err.h"
@@ -30,6 +31,8 @@
 #define IWDT_TICKS_PER_US       500
 #define IWDT_INSTANCE           WDT_MWDT1
 #define IWDT_INITIAL_TIMEOUT_S  5
+#define IWDT_PERIPH             PERIPH_TIMG1_MODULE
+#define IWDT_TIMER_GROUP        1
 
 #else
 
@@ -38,6 +41,8 @@
 #define IWDT_TICKS_PER_US       500
 #define IWDT_INSTANCE           WDT_MWDT0
 #define IWDT_INITIAL_TIMEOUT_S  5
+#define IWDT_PERIPH             PERIPH_TIMG0_MODULE
+#define IWDT_TIMER_GROUP        0
 
 #endif // SOC_TIMER_GROUPS > 1
 
@@ -99,7 +104,12 @@ static void IRAM_ATTR tick_hook(void)
 
 void esp_int_wdt_init(void)
 {
-    periph_module_enable(PERIPH_TIMG1_MODULE);
+    PERIPH_RCC_ACQUIRE_ATOMIC(IWDT_PERIPH, ref_count) {
+        if (ref_count == 0) {
+            timer_ll_enable_bus_clock(IWDT_TIMER_GROUP, true);
+            timer_ll_reset_register(IWDT_TIMER_GROUP);
+        }
+    }
     /*
      * Initialize the WDT timeout stages. Note that the initial timeout is set to 5 seconds as variable startup times of
      * each CPU can lead to a timeout. The tick hooks will set the WDT timers to the actual timeout.

+ 1 - 10
components/esp_system/port/soc/esp32/clk.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -300,15 +300,6 @@ __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)

+ 1 - 10
components/esp_system/port/soc/esp32c2/clk.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -251,13 +251,4 @@ __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);
 }

+ 1 - 10
components/esp_system/port/soc/esp32c3/clk.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -294,13 +294,4 @@ __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);
 }

+ 0 - 9
components/esp_system/port/soc/esp32c6/clk.c

@@ -294,13 +294,4 @@ __attribute__((weak)) void esp_perip_clk_init(void)
     /* Enable RNG clock. */
     periph_module_enable(PERIPH_RNG_MODULE);
 #endif
-
-    /* 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);
 }

+ 0 - 9
components/esp_system/port/soc/esp32h2/clk.c

@@ -286,13 +286,4 @@ __attribute__((weak)) void esp_perip_clk_init(void)
     /* Enable RNG clock. */
     periph_module_enable(PERIPH_RNG_MODULE);
 #endif
-
-    /* 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);
 }

+ 1 - 10
components/esp_system/port/soc/esp32s2/clk.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -312,13 +312,4 @@ __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);
 }

+ 1 - 10
components/esp_system/port/soc/esp32s3/clk.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -314,13 +314,4 @@ __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);
 }

+ 14 - 2
components/esp_system/task_wdt/task_wdt_impl_timergroup.c

@@ -10,6 +10,7 @@
 #include "sdkconfig.h"
 #include "hal/wdt_hal.h"
 #include "hal/mwdt_ll.h"
+#include "hal/timer_ll.h"
 #include "esp_err.h"
 #include "esp_attr.h"
 #include "esp_intr_alloc.h"
@@ -21,6 +22,7 @@
 #define TWDT_TICKS_PER_US       500
 #define TWDT_PRESCALER          MWDT_LL_DEFAULT_CLK_PRESCALER   // Tick period of 500us if WDT source clock is 80MHz
 #define TWDT_PERIPH_MODULE      PERIPH_TIMG0_MODULE
+#define TWDT_TIMER_GROUP        0
 #define TWDT_INTR_SOURCE        ETS_TG0_WDT_LEVEL_INTR_SOURCE
 
 /**
@@ -55,7 +57,13 @@ esp_err_t esp_task_wdt_impl_timer_allocate(const esp_task_wdt_config_t *config,
     }
 
     if (ret == ESP_OK) {
-        periph_module_enable(TWDT_PERIPH_MODULE);
+        // enable bus clock for the timer group registers
+        PERIPH_RCC_ACQUIRE_ATOMIC(TWDT_PERIPH_MODULE, ref_count) {
+            if (ref_count == 0) {
+                timer_ll_enable_bus_clock(TWDT_TIMER_GROUP, true);
+                timer_ll_reset_register(TWDT_TIMER_GROUP);
+            }
+        }
         wdt_hal_init(&ctx->hal, TWDT_INSTANCE, TWDT_PRESCALER, true);
 
         wdt_hal_write_protect_disable(&ctx->hal);
@@ -106,7 +114,11 @@ 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_disable(TWDT_PERIPH_MODULE);
+        PERIPH_RCC_RELEASE_ATOMIC(TWDT_PERIPH_MODULE, ref_count) {
+            if (ref_count == 0) {
+                timer_ll_enable_bus_clock(TWDT_TIMER_GROUP, false);
+            }
+        }
 
         /* Deregister interrupt */
         ESP_ERROR_CHECK(esp_intr_free(ctx->intr_handle));

+ 12 - 1
components/esp_timer/src/esp_timer_impl_lac.c

@@ -18,6 +18,7 @@
 #include "soc/soc.h"
 #include "soc/timer_group_reg.h"
 #include "soc/rtc.h"
+#include "hal/timer_ll.h"
 #include "freertos/FreeRTOS.h"
 
 /**
@@ -245,7 +246,12 @@ void esp_timer_impl_advance(int64_t time_diff_us)
 
 esp_err_t esp_timer_impl_early_init(void)
 {
-    periph_module_enable(PERIPH_LACT);
+    PERIPH_RCC_ACQUIRE_ATOMIC(PERIPH_LACT, ref_count) {
+        if (ref_count == 0) {
+            timer_ll_enable_bus_clock(LACT_MODULE, true);
+            timer_ll_reset_register(LACT_MODULE);
+        }
+    }
 
     REG_WRITE(CONFIG_REG, 0);
     REG_WRITE(LOAD_LO_REG, 0);
@@ -319,6 +325,11 @@ void esp_timer_impl_deinit(void)
         }
     }
     s_alarm_handler = NULL;
+    PERIPH_RCC_RELEASE_ATOMIC(PERIPH_LACT, ref_count) {
+        if (ref_count == 0) {
+            timer_ll_enable_bus_clock(LACT_MODULE, false);
+        }
+    }
 }
 
 uint64_t esp_timer_impl_get_alarm_reg(void)

+ 51 - 1
components/hal/esp32/include/hal/timer_ll.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -13,6 +13,7 @@
 #include "hal/misc.h"
 #include "hal/timer_types.h"
 #include "soc/timer_group_struct.h"
+#include "soc/dport_reg.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -22,6 +23,55 @@ extern "C" {
 #define TIMER_LL_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1))
 #define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id))
 
+/**
+ * @brief Enable the bus clock for timer group module
+ *
+ * @param group_id Group ID
+ * @param enable true to enable, false to disable
+ */
+static inline void timer_ll_enable_bus_clock(int group_id, bool enable)
+{
+    uint32_t reg_val = DPORT_READ_PERI_REG(DPORT_PERIP_CLK_EN_REG);
+    if (group_id == 0) {
+        reg_val &= ~DPORT_TIMERGROUP_CLK_EN;
+        reg_val |= enable << 13;
+    } else {
+        reg_val &= ~DPORT_TIMERGROUP1_CLK_EN;
+        reg_val |= enable << 15;
+    }
+    DPORT_WRITE_PERI_REG(DPORT_PERIP_CLK_EN_REG, reg_val);
+}
+
+/// 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 timer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; timer_ll_enable_bus_clock(__VA_ARGS__)
+
+/**
+ * @brief Reset the timer group module
+ *
+ * @note  After reset the register, the "flash boot protection" will be enabled again.
+ *        FLash boot protection is not used anymore after system boot up.
+ *        This function will disable it by default in order to prevent the system from being reset unexpectedly.
+ *
+ * @param group_id Group ID
+ */
+static inline void timer_ll_reset_register(int group_id)
+{
+    if (group_id == 0) {
+        DPORT_WRITE_PERI_REG(DPORT_PERIP_RST_EN_REG, DPORT_TIMERGROUP_RST);
+        DPORT_WRITE_PERI_REG(DPORT_PERIP_RST_EN_REG, 0);
+        TIMERG0.wdtconfig0.wdt_flashboot_mod_en = 0;
+    } else {
+        DPORT_WRITE_PERI_REG(DPORT_PERIP_RST_EN_REG, DPORT_TIMERGROUP1_RST);
+        DPORT_WRITE_PERI_REG(DPORT_PERIP_RST_EN_REG, 0);
+        TIMERG1.wdtconfig0.wdt_flashboot_mod_en = 0;
+    }
+}
+
+/// 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 timer_ll_reset_register(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; timer_ll_reset_register(__VA_ARGS__)
+
 /**
  * @brief Set clock source for timer
  *

+ 39 - 1
components/hal/esp32c2/include/hal/timer_ll.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -13,6 +13,7 @@
 #include "hal/misc.h"
 #include "hal/timer_types.h"
 #include "soc/timer_group_struct.h"
+#include "soc/system_struct.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -22,6 +23,43 @@ extern "C" {
 #define TIMER_LL_GET_HW(group_id) (&TIMERG0)
 #define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id))
 
+/**
+ * @brief Enable the bus clock for timer group module
+ *
+ * @param group_id Group ID
+ * @param enable true to enable, false to disable
+ */
+static inline void timer_ll_enable_bus_clock(int group_id, bool enable)
+{
+    (void)group_id;
+    SYSTEM.perip_clk_en0.timergroup_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 timer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; timer_ll_enable_bus_clock(__VA_ARGS__)
+
+/**
+ * @brief Reset the timer group module
+ *
+ * @note  After reset the register, the "flash boot protection" will be enabled again.
+ *        FLash boot protection is not used anymore after system boot up.
+ *        This function will disable it by default in order to prevent the system from being reset unexpectedly.
+ *
+ * @param group_id Group ID
+ */
+static inline void timer_ll_reset_register(int group_id)
+{
+    (void)group_id;
+    SYSTEM.perip_rst_en0.timergroup_rst = 1;
+    SYSTEM.perip_rst_en0.timergroup_rst = 0;
+    TIMERG0.wdtconfig0.wdt_flashboot_mod_en = 0;
+}
+
+/// 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 timer_ll_reset_register(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; timer_ll_reset_register(__VA_ARGS__)
+
 /**
  * @brief Set clock source for timer
  *

+ 47 - 1
components/hal/esp32c3/include/hal/timer_ll.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -13,6 +13,7 @@
 #include "hal/misc.h"
 #include "hal/timer_types.h"
 #include "soc/timer_group_struct.h"
+#include "soc/system_struct.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -22,6 +23,51 @@ extern "C" {
 #define TIMER_LL_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1))
 #define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id))
 
+/**
+ * @brief Enable the bus clock for timer group module
+ *
+ * @param group_id Group ID
+ * @param enable true to enable, false to disable
+ */
+static inline void timer_ll_enable_bus_clock(int group_id, bool enable)
+{
+    if (group_id == 0) {
+        SYSTEM.perip_clk_en0.reg_timergroup_clk_en = enable;
+    } else {
+        SYSTEM.perip_clk_en0.reg_timergroup1_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 timer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; timer_ll_enable_bus_clock(__VA_ARGS__)
+
+/**
+ * @brief Reset the timer group module
+ *
+ * @note  After reset the register, the "flash boot protection" will be enabled again.
+ *        FLash boot protection is not used anymore after system boot up.
+ *        This function will disable it by default in order to prevent the system from being reset unexpectedly.
+ *
+ * @param group_id Group ID
+ */
+static inline void timer_ll_reset_register(int group_id)
+{
+    if (group_id == 0) {
+        SYSTEM.perip_rst_en0.reg_timergroup_rst = 1;
+        SYSTEM.perip_rst_en0.reg_timergroup_rst = 0;
+        TIMERG0.wdtconfig0.wdt_flashboot_mod_en = 0;
+    } else {
+        SYSTEM.perip_rst_en0.reg_timergroup1_rst = 1;
+        SYSTEM.perip_rst_en0.reg_timergroup1_rst = 0;
+        TIMERG1.wdtconfig0.wdt_flashboot_mod_en = 0;
+    }
+}
+
+/// 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 timer_ll_reset_register(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; timer_ll_reset_register(__VA_ARGS__)
+
 /**
  * @brief Set clock source for timer
  *

+ 46 - 1
components/hal/esp32c6/include/hal/timer_ll.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -50,6 +50,51 @@ extern "C" {
                         }},                                                                \
     }[group][timer][event]
 
+/**
+ * @brief Enable the bus clock for timer group module
+ *
+ * @param group_id Group ID
+ * @param enable true to enable, false to disable
+ */
+static inline void timer_ll_enable_bus_clock(int group_id, bool enable)
+{
+    if (group_id == 0) {
+        PCR.timergroup0_conf.tg0_clk_en = enable;
+    } else {
+        PCR.timergroup1_conf.tg1_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 timer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; timer_ll_enable_bus_clock(__VA_ARGS__)
+
+/**
+ * @brief Reset the timer group module
+ *
+ * @note  After reset the register, the "flash boot protection" will be enabled again.
+ *        FLash boot protection is not used anymore after system boot up.
+ *        This function will disable it by default in order to prevent the system from being reset unexpectedly.
+ *
+ * @param group_id Group ID
+ */
+static inline void timer_ll_reset_register(int group_id)
+{
+    if (group_id == 0) {
+        PCR.timergroup0_conf.tg0_rst_en = 1;
+        PCR.timergroup0_conf.tg0_rst_en = 0;
+        TIMERG0.wdtconfig0.wdt_flashboot_mod_en = 0;
+    } else {
+        PCR.timergroup1_conf.tg1_rst_en = 1;
+        PCR.timergroup1_conf.tg1_rst_en = 0;
+        TIMERG1.wdtconfig0.wdt_flashboot_mod_en = 0;
+    }
+}
+
+/// 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 timer_ll_reset_register(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; timer_ll_reset_register(__VA_ARGS__)
+
 /**
  * @brief Set clock source for timer
  *

+ 45 - 0
components/hal/esp32h2/include/hal/timer_ll.h

@@ -50,6 +50,51 @@ extern "C" {
                         }},                                                                \
     }[group][timer][event]
 
+/**
+ * @brief Enable the bus clock for timer group module
+ *
+ * @param group_id Group ID
+ * @param enable true to enable, false to disable
+ */
+static inline void timer_ll_enable_bus_clock(int group_id, bool enable)
+{
+    if (group_id == 0) {
+        PCR.timergroup0_conf.tg0_clk_en = enable;
+    } else {
+        PCR.timergroup1_conf.tg1_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 timer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; timer_ll_enable_bus_clock(__VA_ARGS__)
+
+/**
+ * @brief Reset the timer group module
+ *
+ * @note  After reset the register, the "flash boot protection" will be enabled again.
+ *        FLash boot protection is not used anymore after system boot up.
+ *        This function will disable it by default in order to prevent the system from being reset unexpectedly.
+ *
+ * @param group_id Group ID
+ */
+static inline void timer_ll_reset_register(int group_id)
+{
+    if (group_id == 0) {
+        PCR.timergroup0_conf.tg0_rst_en = 1;
+        PCR.timergroup0_conf.tg0_rst_en = 0;
+        TIMERG0.wdtconfig0.wdt_flashboot_mod_en = 0;
+    } else {
+        PCR.timergroup1_conf.tg1_rst_en = 1;
+        PCR.timergroup1_conf.tg1_rst_en = 0;
+        TIMERG1.wdtconfig0.wdt_flashboot_mod_en = 0;
+    }
+}
+
+/// 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 timer_ll_reset_register(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; timer_ll_reset_register(__VA_ARGS__)
+
 /**
  * @brief Set clock source for timer
  *

+ 0 - 13
components/hal/esp32p4/include/hal/clk_gate_ll.h

@@ -80,10 +80,6 @@ static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph)
         return HP_SYS_CLKRST_REG_MCPWM0_APB_CLK_EN;
     case PERIPH_MCPWM1_MODULE:
         return HP_SYS_CLKRST_REG_MCPWM1_APB_CLK_EN;
-    case PERIPH_TIMG0_MODULE:
-        return HP_SYS_CLKRST_REG_TIMERGRP0_T0_CLK_EN | HP_SYS_CLKRST_REG_TIMERGRP0_T1_CLK_EN | HP_SYS_CLKRST_REG_TIMERGRP0_WDT_CLK_EN;
-    case PERIPH_TIMG1_MODULE:
-        return HP_SYS_CLKRST_REG_TIMERGRP1_T0_CLK_EN | HP_SYS_CLKRST_REG_TIMERGRP1_T1_CLK_EN | HP_SYS_CLKRST_REG_TIMERGRP1_WDT_CLK_EN;
     case PERIPH_SYSTIMER_MODULE:
         return HP_SYS_CLKRST_REG_SYSTIMER_CLK_EN;
     case PERIPH_LEDC_MODULE:
@@ -148,10 +144,6 @@ static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool en
         return HP_SYS_CLKRST_REG_RST_EN_AXI_PDMA;
     case PERIPH_SYSTIMER_MODULE:
         return HP_SYS_CLKRST_REG_RST_EN_STIMER;
-    case PERIPH_TIMG0_MODULE:
-        return HP_SYS_CLKRST_REG_RST_EN_TIMERGRP0;
-    case PERIPH_TIMG1_MODULE:
-        return HP_SYS_CLKRST_REG_RST_EN_TIMERGRP1;
     case PERIPH_UART0_MODULE:
         return HP_SYS_CLKRST_REG_RST_EN_UART0_CORE;
     case PERIPH_UART1_MODULE:
@@ -268,9 +260,6 @@ static inline uint32_t periph_ll_get_clk_en_reg(periph_module_t periph)
     case PERIPH_MCPWM1_MODULE:
     case PERIPH_PCNT_MODULE:
         return HP_SYS_CLKRST_SOC_CLK_CTRL2_REG;
-    case PERIPH_TIMG0_MODULE:
-        return HP_SYS_CLKRST_PERI_CLK_CTRL20_REG;
-    case PERIPH_TIMG1_MODULE:
     case PERIPH_SYSTIMER_MODULE:
     case PERIPH_LEDC_MODULE:
     case PERIPH_RMT_MODULE:
@@ -312,8 +301,6 @@ static inline uint32_t periph_ll_get_rst_en_reg(periph_module_t periph)
     case PERIPH_AHB_PDMA_MODULE:
     case PERIPH_AXI_PDMA_MODULE:
     case PERIPH_SYSTIMER_MODULE:
-    case PERIPH_TIMG0_MODULE:
-    case PERIPH_TIMG1_MODULE:
     case PERIPH_UART0_MODULE:
     case PERIPH_UART1_MODULE:
     case PERIPH_UART2_MODULE:

+ 53 - 0
components/hal/esp32p4/include/hal/timer_ll.h

@@ -24,6 +24,51 @@ extern "C" {
 #define TIMER_LL_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1))
 #define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id))
 
+/**
+ * @brief Enable the bus clock for timer group module
+ *
+ * @param group_id Group ID
+ * @param enable true to enable, false to disable
+ */
+static inline void timer_ll_enable_bus_clock(int group_id, bool enable)
+{
+    if (group_id == 0) {
+        HP_SYS_CLKRST.soc_clk_ctrl2.reg_timergrp0_apb_clk_en = enable;
+    } else {
+        HP_SYS_CLKRST.soc_clk_ctrl2.reg_timergrp1_apb_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 timer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; timer_ll_enable_bus_clock(__VA_ARGS__)
+
+/**
+ * @brief Reset the timer group module
+ *
+ * @note  After reset the register, the "flash boot protection" will be enabled again.
+ *        FLash boot protection is not used anymore after system boot up.
+ *        This function will disable it by default in order to prevent the system from being reset unexpectedly.
+ *
+ * @param group_id Group ID
+ */
+static inline void timer_ll_reset_register(int group_id)
+{
+    if (group_id == 0) {
+        HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_timergrp0 = 1;
+        HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_timergrp0 = 0;
+        TIMERG0.wdtconfig0.wdt_flashboot_mod_en = 0;
+    } else {
+        HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_timergrp1 = 1;
+        HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_timergrp1 = 0;
+        TIMERG1.wdtconfig0.wdt_flashboot_mod_en = 0;
+    }
+}
+
+/// 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 timer_ll_reset_register(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; timer_ll_reset_register(__VA_ARGS__)
+
 /**
  * @brief Set clock source for timer
  *
@@ -63,6 +108,10 @@ static inline void timer_ll_set_clock_source(timg_dev_t *hw, uint32_t timer_num,
     }
 }
 
+/// 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_ATOMIC_ENV variable in advance
+#define timer_ll_set_clock_source(...) (void)__DECLARE_RCC_ATOMIC_ENV; timer_ll_set_clock_source(__VA_ARGS__)
+
 /**
  * @brief Enable Timer Group (GPTimer) module clock
  *
@@ -87,6 +136,10 @@ static inline void timer_ll_enable_clock(timg_dev_t *hw, uint32_t timer_num, boo
     }
 }
 
+/// 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_ATOMIC_ENV variable in advance
+#define timer_ll_enable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; timer_ll_enable_clock(__VA_ARGS__)
+
 /**
  * @brief Enable alarm event
  *

+ 51 - 1
components/hal/esp32s2/include/hal/timer_ll.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -13,6 +13,7 @@
 #include "hal/misc.h"
 #include "hal/timer_types.h"
 #include "soc/timer_group_struct.h"
+#include "soc/system_reg.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -22,6 +23,55 @@ extern "C" {
 #define TIMER_LL_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1))
 #define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id))
 
+/**
+ * @brief Enable the bus clock for timer group module
+ *
+ * @param group_id Group ID
+ * @param enable true to enable, false to disable
+ */
+static inline void timer_ll_enable_bus_clock(int group_id, bool enable)
+{
+    uint32_t reg_val = READ_PERI_REG(DPORT_PERIP_CLK_EN0_REG);
+    if (group_id == 0) {
+        reg_val &= ~DPORT_TIMERGROUP_CLK_EN_M;
+        reg_val |= enable << DPORT_TIMERGROUP_CLK_EN_S;
+    } else {
+        reg_val &= ~DPORT_TIMERGROUP1_CLK_EN_M;
+        reg_val |= enable << DPORT_TIMERGROUP1_CLK_EN_S;
+    }
+    WRITE_PERI_REG(DPORT_PERIP_CLK_EN0_REG, reg_val);
+}
+
+/// 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 timer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; timer_ll_enable_bus_clock(__VA_ARGS__)
+
+/**
+ * @brief Reset the timer group module
+ *
+ * @note  After reset the register, the "flash boot protection" will be enabled again.
+ *        FLash boot protection is not used anymore after system boot up.
+ *        This function will disable it by default in order to prevent the system from being reset unexpectedly.
+ *
+ * @param group_id Group ID
+ */
+static inline void timer_ll_reset_register(int group_id)
+{
+    if (group_id == 0) {
+        WRITE_PERI_REG(DPORT_PERIP_RST_EN0_REG, DPORT_TIMERGROUP_RST_M);
+        WRITE_PERI_REG(DPORT_PERIP_RST_EN0_REG, 0);
+        TIMERG0.wdtconfig0.wdt_flashboot_mod_en = 0;
+    } else {
+        WRITE_PERI_REG(DPORT_PERIP_RST_EN0_REG, DPORT_TIMERGROUP1_RST_M);
+        WRITE_PERI_REG(DPORT_PERIP_RST_EN0_REG, 0);
+        TIMERG1.wdtconfig0.wdt_flashboot_mod_en = 0;
+    }
+}
+
+/// 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 timer_ll_reset_register(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; timer_ll_reset_register(__VA_ARGS__)
+
 /**
  * @brief Set clock source for timer
  *

+ 47 - 1
components/hal/esp32s3/include/hal/timer_ll.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -13,6 +13,7 @@
 #include "hal/misc.h"
 #include "hal/timer_types.h"
 #include "soc/timer_group_struct.h"
+#include "soc/system_struct.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -22,6 +23,51 @@ extern "C" {
 #define TIMER_LL_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1))
 #define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id))
 
+/**
+ * @brief Enable the bus clock for timer group module
+ *
+ * @param group_id Group ID
+ * @param enable true to enable, false to disable
+ */
+static inline void timer_ll_enable_bus_clock(int group_id, bool enable)
+{
+    if (group_id == 0) {
+        SYSTEM.perip_clk_en0.timergroup_clk_en = enable;
+    } else {
+        SYSTEM.perip_clk_en0.timergroup1_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 timer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; timer_ll_enable_bus_clock(__VA_ARGS__)
+
+/**
+ * @brief Reset the timer group module
+ *
+ * @note  After reset the register, the "flash boot protection" will be enabled again.
+ *        FLash boot protection is not used anymore after system boot up.
+ *        This function will disable it by default in order to prevent the system from being reset unexpectedly.
+ *
+ * @param group_id Group ID
+ */
+static inline void timer_ll_reset_register(int group_id)
+{
+    if (group_id == 0) {
+        SYSTEM.perip_rst_en0.timergroup_rst = 1;
+        SYSTEM.perip_rst_en0.timergroup_rst = 0;
+        TIMERG0.wdtconfig0.wdt_flashboot_mod_en = 0;
+    } else {
+        SYSTEM.perip_rst_en0.timergroup1_rst = 1;
+        SYSTEM.perip_rst_en0.timergroup1_rst = 0;
+        TIMERG1.wdtconfig0.wdt_flashboot_mod_en = 0;
+    }
+}
+
+/// 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 timer_ll_reset_register(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; timer_ll_reset_register(__VA_ARGS__)
+
 /**
  * @brief Set clock source for timer
  *

+ 0 - 4
components/hal/timer_hal.c

@@ -13,8 +13,6 @@ void timer_hal_init(timer_hal_context_t *hal, uint32_t group_num, uint32_t timer
 {
     hal->dev = TIMER_LL_GET_HW(group_num);
     hal->timer_id = timer_num;
-    // enable peripheral clock
-    timer_ll_enable_clock(hal->dev, timer_num, true);
     // stop counter, alarm, auto-reload at first place
     timer_ll_enable_counter(hal->dev, timer_num, false);
     timer_ll_enable_auto_reload(hal->dev, timer_num, false);
@@ -27,8 +25,6 @@ void timer_hal_init(timer_hal_context_t *hal, uint32_t group_num, uint32_t timer
 
 void timer_hal_deinit(timer_hal_context_t *hal)
 {
-    // disable peripheral clock
-    timer_ll_enable_clock(hal->dev, hal->timer_id, false);
     // ensure counter, alarm, auto-reload are disabled
     timer_ll_enable_counter(hal->dev, hal->timer_id, false);
     timer_ll_enable_auto_reload(hal->dev, hal->timer_id, false);

+ 1 - 0
components/soc/esp32c2/include/soc/system_struct.h

@@ -905,6 +905,7 @@ typedef struct {
     volatile system_reg_date_reg_t reg_date;
 } system_dev_t;
 
+extern system_dev_t SYSTEM;
 
 #ifndef __cplusplus
 _Static_assert(sizeof(system_dev_t) == 0x1000, "Invalid size of system_dev_t structure");

+ 1 - 0
components/soc/esp32c2/ld/esp32c2.peripherals.ld

@@ -20,3 +20,4 @@ PROVIDE ( GPSPI3  = 0x60025000 );
 PROVIDE ( SYSCON = 0x60026000 );
 PROVIDE ( APB_SARADC = 0x60040000 );
 PROVIDE ( GDMA    = 0x6003F000 );
+PROVIDE ( SYSTEM = 0x600c0000 );

+ 1 - 0
components/soc/esp32c3/ld/esp32c3.peripherals.ld

@@ -33,3 +33,4 @@ PROVIDE ( GPSPI4 = 0x60037000 );
 PROVIDE ( APB_SARADC = 0x60040000 );
 PROVIDE ( USB_SERIAL_JTAG = 0x60043000 );
 PROVIDE ( GDMA    = 0x6003F000 );
+PROVIDE ( SYSTEM = 0x600c0000 );

+ 1 - 0
components/soc/esp32s3/ld/esp32s3.peripherals.ld

@@ -49,3 +49,4 @@ PROVIDE ( USB0     = 0x60080000 );
 PROVIDE ( USB_DWC  = 0x60080000 );
 PROVIDE ( USB_WRAP = 0x60039000 );
 PROVIDE ( WORLD_CONTROLLER = 0x600D0000 );
+PROVIDE ( SYSTEM = 0x600C0000 );