Procházet zdrojové kódy

Merge branch 'feature/gptimer_support_p4' into 'master'

Feature/gptimer support p4

Closes IDF-6515

See merge request espressif/esp-idf!24746
morris před 2 roky
rodič
revize
d1055758e4

+ 10 - 2
components/esp_system/fpga_overrides.c

@@ -1,10 +1,11 @@
 /*
- * SPDX-FileCopyrightText: 2010-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2010-2023 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
 #include "sdkconfig.h"
 #include "soc/soc.h"
+#include "esp_private/periph_ctrl.h"
 #ifndef CONFIG_IDF_TARGET_ESP32
 #include "soc/system_reg.h"
 #endif // not CONFIG_IDF_TARGET_ESP32
@@ -76,7 +77,14 @@ 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);
 }
 
 /**

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

@@ -0,0 +1,324 @@
+/*
+ * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+// Note that most of the register operations in this layer are non-atomic operations.
+
+#pragma once
+
+#include <stdbool.h>
+#include "hal/assert.h"
+#include "hal/misc.h"
+#include "hal/timer_types.h"
+#include "soc/timer_group_struct.h"
+#include "soc/soc_etm_source.h"
+#include "soc/hp_sys_clkrst_struct.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Get timer group register base address with giving group number
+#define TIMER_LL_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1))
+#define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id))
+
+/**
+ * @brief Set clock source for timer
+ *
+ * @param hw Timer Group register base address
+ * @param timer_num Timer number in the group
+ * @param clk_src Clock source
+ */
+static inline void timer_ll_set_clock_source(timg_dev_t *hw, uint32_t timer_num, gptimer_clock_source_t clk_src)
+{
+    uint8_t clk_id = 0;
+    switch (clk_src) {
+    case GPTIMER_CLK_SRC_XTAL:
+        clk_id = 0;
+        break;
+    case GPTIMER_CLK_SRC_PLL_F80M:
+        clk_id = 2;
+        break;
+    case GPTIMER_CLK_SRC_RC_FAST:
+        clk_id = 1;
+        break;
+    default:
+        HAL_ASSERT(false);
+        break;
+    }
+    if (hw == &TIMERG0) {
+        if (timer_num == 0) {
+            HP_SYS_CLKRST.peri_clk_ctrl20.reg_timergrp0_t0_src_sel = clk_id;
+        } else {
+            HP_SYS_CLKRST.peri_clk_ctrl20.reg_timergrp0_t1_src_sel = clk_id;
+        }
+    } else {
+        if (timer_num == 0) {
+            HP_SYS_CLKRST.peri_clk_ctrl21.reg_timergrp1_t0_src_sel = clk_id;
+        } else {
+            HP_SYS_CLKRST.peri_clk_ctrl21.reg_timergrp1_t1_src_sel = clk_id;
+        }
+    }
+}
+
+/**
+ * @brief Enable Timer Group (GPTimer) module clock
+ *
+ * @param hw Timer Group register base address
+ * @param timer_num Timer index in the group
+ * @param en true to enable, false to disable
+ */
+static inline void timer_ll_enable_clock(timg_dev_t *hw, uint32_t timer_num, bool en)
+{
+    if (hw == &TIMERG0) {
+        if (timer_num == 0) {
+            HP_SYS_CLKRST.peri_clk_ctrl20.reg_timergrp0_t0_clk_en = en;
+        } else {
+            HP_SYS_CLKRST.peri_clk_ctrl20.reg_timergrp0_t1_clk_en = en;
+        }
+    } else {
+        if (timer_num == 0) {
+            HP_SYS_CLKRST.peri_clk_ctrl21.reg_timergrp1_t0_clk_en = en;
+        } else {
+            HP_SYS_CLKRST.peri_clk_ctrl21.reg_timergrp1_t1_clk_en = en;
+        }
+    }
+}
+
+/**
+ * @brief Enable alarm event
+ *
+ * @param hw Timer Group register base address
+ * @param timer_num Timer number in the group
+ * @param en True: enable alarm
+ *           False: disable alarm
+ */
+__attribute__((always_inline))
+static inline void timer_ll_enable_alarm(timg_dev_t *hw, uint32_t timer_num, bool en)
+{
+    hw->hw_timer[timer_num].config.tx_alarm_en = en;
+}
+
+/**
+ * @brief Set clock prescale for timer
+ *
+ * @param hw Timer Group register base address
+ * @param timer_num Timer number in the group
+ * @param divider Prescale value (0 and 1 are not valid)
+ */
+static inline void timer_ll_set_clock_prescale(timg_dev_t *hw, uint32_t timer_num, uint32_t divider)
+{
+    HAL_ASSERT(divider >= 2 && divider <= 65536);
+    if (divider >= 65536) {
+        divider = 0;
+    }
+    HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hw_timer[timer_num].config, tx_divider, divider);
+    hw->hw_timer[timer_num].config.tx_divcnt_rst = 1;
+}
+
+/**
+ * @brief Enable auto-reload mode
+ *
+ * @param hw Timer Group register base address
+ * @param timer_num Timer number in the group
+ * @param en True: enable auto reload mode
+ *           False: disable auto reload mode
+ */
+__attribute__((always_inline))
+static inline void timer_ll_enable_auto_reload(timg_dev_t *hw, uint32_t timer_num, bool en)
+{
+    hw->hw_timer[timer_num].config.tx_autoreload = en;
+}
+
+/**
+ * @brief Set count direction
+ *
+ * @param hw Timer peripheral register base address
+ * @param timer_num Timer number in the group
+ * @param direction Count direction
+ */
+static inline void timer_ll_set_count_direction(timg_dev_t *hw, uint32_t timer_num, gptimer_count_direction_t direction)
+{
+    hw->hw_timer[timer_num].config.tx_increase = (direction == GPTIMER_COUNT_UP);
+}
+
+/**
+ * @brief Enable timer, start couting
+ *
+ * @param hw Timer Group register base address
+ * @param timer_num Timer number in the group
+ * @param en True: enable the counter
+ *           False: disable the counter
+ */
+__attribute__((always_inline))
+static inline void timer_ll_enable_counter(timg_dev_t *hw, uint32_t timer_num, bool en)
+{
+    hw->hw_timer[timer_num].config.tx_en = en;
+}
+
+/**
+ * @brief Trigger software capture event
+ *
+ * @param hw Timer Group register base address
+ * @param timer_num Timer number in the group
+ */
+__attribute__((always_inline))
+static inline void timer_ll_trigger_soft_capture(timg_dev_t *hw, uint32_t timer_num)
+{
+    hw->hw_timer[timer_num].update.tx_update = 1;
+    // Timer register is in a different clock domain from Timer hardware logic
+    // We need to wait for the update to take effect before fetching the count value
+    while (hw->hw_timer[timer_num].update.tx_update) {
+    }
+}
+
+/**
+ * @brief Get counter value
+ *
+ * @param hw Timer Group register base address
+ * @param timer_num Timer number in the group
+ *
+ * @return counter value
+ */
+__attribute__((always_inline))
+static inline uint64_t timer_ll_get_counter_value(timg_dev_t *hw, uint32_t timer_num)
+{
+    return ((uint64_t)hw->hw_timer[timer_num].hi.tx_hi << 32) | (hw->hw_timer[timer_num].lo.tx_lo);
+}
+
+/**
+ * @brief Set alarm value
+ *
+ * @param hw Timer Group register base address
+ * @param timer_num Timer number in the group
+ * @param alarm_value When counter reaches alarm value, alarm event will be triggered
+ */
+__attribute__((always_inline))
+static inline void timer_ll_set_alarm_value(timg_dev_t *hw, uint32_t timer_num, uint64_t alarm_value)
+{
+    hw->hw_timer[timer_num].alarmhi.tx_alarm_hi = (uint32_t)(alarm_value >> 32);
+    hw->hw_timer[timer_num].alarmlo.tx_alarm_lo = (uint32_t)alarm_value;
+}
+
+/**
+ * @brief Set reload value
+ *
+ * @param hw Timer Group register base address
+ * @param timer_num Timer number in the group
+ * @param reload_val Reload counter value
+ */
+__attribute__((always_inline))
+static inline void timer_ll_set_reload_value(timg_dev_t *hw, uint32_t timer_num, uint64_t reload_val)
+{
+    hw->hw_timer[timer_num].loadhi.tx_load_hi = (uint32_t)(reload_val >> 32);
+    hw->hw_timer[timer_num].loadlo.tx_load_lo = (uint32_t)reload_val;
+}
+
+/**
+ * @brief Get reload value
+ *
+ * @param hw Timer Group register base address
+ * @param timer_num Timer number in the group
+ * @return reload count value
+ */
+__attribute__((always_inline))
+static inline uint64_t timer_ll_get_reload_value(timg_dev_t *hw, uint32_t timer_num)
+{
+    return ((uint64_t)hw->hw_timer[timer_num].loadhi.tx_load_hi << 32) | (hw->hw_timer[timer_num].loadlo.tx_load_lo);
+}
+
+/**
+ * @brief Trigger software reload, value set by `timer_ll_set_reload_value()` will be reflected into counter immediately
+ *
+ * @param hw Timer Group register base address
+ * @param timer_num Timer number in the group
+ */
+__attribute__((always_inline))
+static inline void timer_ll_trigger_soft_reload(timg_dev_t *hw, uint32_t timer_num)
+{
+    hw->hw_timer[timer_num].load.tx_load = 1;
+}
+
+/**
+ * @brief Enable ETM module
+ *
+ * @param hw Timer Group register base address
+ * @param en True: enable ETM module, False: disable ETM module
+ */
+static inline void timer_ll_enable_etm(timg_dev_t *hw, bool en)
+{
+    hw->regclk.etm_en = en;
+}
+
+/**
+ * @brief Enable timer interrupt by mask
+ *
+ * @param hw Timer Group register base address
+ * @param mask Mask of interrupt events
+ * @param en True: enable interrupt
+ *           False: disable interrupt
+ */
+__attribute__((always_inline))
+static inline void timer_ll_enable_intr(timg_dev_t *hw, uint32_t mask, bool en)
+{
+    if (en) {
+        hw->int_ena_timers.val |= mask;
+    } else {
+        hw->int_ena_timers.val &= ~mask;
+    }
+}
+
+/**
+ * @brief Get interrupt status
+ *
+ * @param hw Timer Group register base address
+ *
+ * @return Interrupt status
+ */
+__attribute__((always_inline))
+static inline uint32_t timer_ll_get_intr_status(timg_dev_t *hw)
+{
+    return hw->int_st_timers.val & 0x03;
+}
+
+/**
+ * @brief Clear interrupt status by mask
+ *
+ * @param hw Timer Group register base address
+ * @param mask Interrupt events mask
+ */
+__attribute__((always_inline))
+static inline void timer_ll_clear_intr_status(timg_dev_t *hw, uint32_t mask)
+{
+    hw->int_clr_timers.val = mask;
+}
+
+/**
+ * @brief Enable the register clock forever
+ *
+ * @param hw Timer Group register base address
+ * @param en True: Enable the register clock forever
+ *           False: Register clock is enabled only when register operation happens
+ */
+static inline void timer_ll_enable_register_clock_always_on(timg_dev_t *hw, bool en)
+{
+    hw->regclk.clk_en = en;
+}
+
+/**
+ * @brief Get interrupt status register address
+ *
+ * @param hw Timer Group register base address
+ *
+ * @return Interrupt status register address
+ */
+static inline volatile void *timer_ll_get_intr_status_reg(timg_dev_t *hw)
+{
+    return &hw->int_st_timers;
+}
+
+#ifdef __cplusplus
+}
+#endif

+ 7 - 7
components/soc/esp32p4/include/soc/Kconfig.soc_caps.in

@@ -19,6 +19,10 @@ config SOC_AXI_GDMA_SUPPORTED
     bool
     default y
 
+config SOC_GPTIMER_SUPPORTED
+    bool
+    default y
+
 config SOC_SUPPORTS_SECURE_DL_MODE
     bool
     default y
@@ -745,7 +749,7 @@ config SOC_TIMER_GROUPS
 
 config SOC_TIMER_GROUP_TIMERS_PER_GROUP
     int
-    default 1
+    default 2
 
 config SOC_TIMER_GROUP_COUNTER_BIT_WIDTH
     int
@@ -761,11 +765,7 @@ config SOC_TIMER_GROUP_SUPPORT_RC_FAST
 
 config SOC_TIMER_GROUP_TOTAL_TIMERS
     int
-    default 2
-
-config SOC_TIMER_SUPPORT_ETM
-    bool
-    default n
+    default 4
 
 config SOC_TWAI_CONTROLLER_NUM
     int
@@ -937,7 +937,7 @@ config SOC_PM_PAU_LINK_NUM
 
 config SOC_CLK_RC_FAST_SUPPORT_CALIBRATION
     bool
-    default y
+    default n
 
 config SOC_MODEM_CLOCK_IS_INDEPENDENT
     bool

+ 45 - 16
components/soc/esp32p4/include/soc/clk_tree_defs.h

@@ -5,6 +5,8 @@
  */
 #pragma once
 
+#include "soc/soc_caps.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -162,16 +164,55 @@ typedef enum {
 
 //////////////////////////////////////////////////GPTimer///////////////////////////////////////////////////////////////
 
+/**
+ * @brief Array initializer for all supported clock sources of GPTimer
+ *
+ * The following code can be used to iterate all possible clocks:
+ * @code{c}
+ * soc_periph_gptimer_clk_src_t gptimer_clks[] = (soc_periph_gptimer_clk_src_t)SOC_GPTIMER_CLKS;
+ * for (size_t i = 0; i< sizeof(gptimer_clks) / sizeof(gptimer_clks[0]); i++) {
+ *     soc_periph_gptimer_clk_src_t clk = gptimer_clks[i];
+ *     // Test GPTimer with the clock `clk`
+ * }
+ * @endcode
+ */
+#if SOC_CLK_TREE_SUPPORTED
+#define SOC_GPTIMER_CLKS {SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_XTAL}
+#else
+#define SOC_GPTIMER_CLKS {SOC_MOD_CLK_XTAL}
+#endif
 
+/**
+ * @brief Type of GPTimer clock source
+ */
+typedef enum {
+    GPTIMER_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the source clock */
+    GPTIMER_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST,   /*!< Select RC_FAST as the source clock */
+    GPTIMER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL,         /*!< Select XTAL as the source clock */
+#if SOC_CLK_TREE_SUPPORTED
+    GPTIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M,  /*!< Select PLL_F80M as the default choice */
+#else
+    GPTIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL,      /*!< Select XTAL as the default choice */
+#endif // SOC_CLK_TREE_SUPPORTED
+} soc_periph_gptimer_clk_src_t;
 
-//////////////////////////////////////////////////RMT///////////////////////////////////////////////////////////////////
-
+/**
+ * @brief Type of Timer Group clock source, reserved for the legacy timer group driver
+ */
+typedef enum {
+    TIMER_SRC_CLK_PLL_F80M = SOC_MOD_CLK_PLL_F80M,     /*!< Timer group clock source is PLL_F80M */
+    TIMER_SRC_CLK_XTAL = SOC_MOD_CLK_XTAL,             /*!< Timer group clock source is XTAL */
+#if SOC_CLK_TREE_SUPPORTED
+    TIMER_SRC_CLK_DEFAULT = SOC_MOD_CLK_PLL_F80M,      /*!< Timer group clock source default choice is PLL_F80M */
+#else
+    TIMER_SRC_CLK_DEFAULT = SOC_MOD_CLK_XTAL,          /*!< Timer group clock source default choice is XTAL */
+#endif // SOC_CLK_TREE_SUPPORTED
+} soc_periph_tg_clk_src_legacy_t;
 
+//////////////////////////////////////////////////RMT///////////////////////////////////////////////////////////////////
 
 //////////////////////////////////////////////////Temp Sensor///////////////////////////////////////////////////////////
 
-
-
 ///////////////////////////////////////////////////UART/////////////////////////////////////////////////////////////////
 
 //TODO: IDF-6511
@@ -187,16 +228,10 @@ typedef enum {
 
 //////////////////////////////////////////////////MCPWM/////////////////////////////////////////////////////////////////
 
-
-
 ///////////////////////////////////////////////// I2S //////////////////////////////////////////////////////////////
 
-
-
 /////////////////////////////////////////////////I2C////////////////////////////////////////////////////////////////////
 
-
-
 /////////////////////////////////////////////////SPI////////////////////////////////////////////////////////////////////
 
 //TODO: IDF-7502
@@ -217,16 +252,12 @@ typedef enum {
 
 //////////////////////////////////////////////////SDM//////////////////////////////////////////////////////////////
 
-
 //////////////////////////////////////////////////GPIO Glitch Filter////////////////////////////////////////////////////
 
-
 //////////////////////////////////////////////////TWAI//////////////////////////////////////////////////////////////////
 
-
 //////////////////////////////////////////////////ADC///////////////////////////////////////////////////////////////////
 
-
 //////////////////////////////////////////////////MWDT/////////////////////////////////////////////////////////////////
 
 //TODO: IDF-6516
@@ -247,10 +278,8 @@ typedef enum {
 
 //////////////////////////////////////////////////LEDC/////////////////////////////////////////////////////////////////
 
-
 //////////////////////////////////////////////////PARLIO////////////////////////////////////////////////////////////////
 
-
 #ifdef __cplusplus
 }
 #endif

+ 4 - 4
components/soc/esp32p4/include/soc/interrupts.h

@@ -61,12 +61,12 @@ typedef enum {
     ETS_RMT_INTR_SOURCE,
     ETS_I2C0_INTR_SOURCE,
     ETS_I2C1_INTR_SOURCE,
+    ETS_TG0_T0_INTR_SOURCE,
+    ETS_TG0_T1_INTR_SOURCE,
     ETS_TG0_WDT_LEVEL_INTR_SOURCE,
+    ETS_TG1_T0_INTR_SOURCE,
+    ETS_TG1_T1_INTR_SOURCE,
     ETS_TG1_WDT_LEVEL_INTR_SOURCE,
-    ETS_TG0_WDT_INTR_SOURCE,
-    ETS_TIMERGROUP1_T0_INTR_SOURCE,
-    ETS_TIMERGROUP1_T1_INTR_SOURCE,
-    ETS_TIMERGROUP1_WDT_INTR_SOURCE,
     ETS_LEDC_INTR_SOURCE,
     ETS_SYSTIMER_TARGET0_INTR_SOURCE,
     ETS_SYSTIMER_TARGET1_INTR_SOURCE,

+ 8 - 9
components/soc/esp32p4/include/soc/soc_caps.h

@@ -32,7 +32,7 @@
 #define SOC_GDMA_SUPPORTED              1
 #define SOC_AHB_GDMA_SUPPORTED          1
 #define SOC_AXI_GDMA_SUPPORTED          1
-// #define SOC_GPTIMER_SUPPORTED           1  //TODO: IDF-6515
+#define SOC_GPTIMER_SUPPORTED           1
 // #define SOC_PCNT_SUPPORTED              1  //TODO: IDF-7475
 // #define SOC_MCPWM_SUPPORTED             1  //TODO: IDF-7493
 // #define SOC_TWAI_SUPPORTED              1  //TODO: IDF-7470
@@ -389,13 +389,12 @@
 #define SOC_LP_TIMER_BIT_WIDTH_HI           16 // Bit width of lp_timer high part
 
 /*--------------------------- TIMER GROUP CAPS ---------------------------------------*/
-#define SOC_TIMER_GROUPS                  (2)
-#define SOC_TIMER_GROUP_TIMERS_PER_GROUP  (1U)
-#define SOC_TIMER_GROUP_COUNTER_BIT_WIDTH (54)
-#define SOC_TIMER_GROUP_SUPPORT_XTAL      (1)
-#define SOC_TIMER_GROUP_SUPPORT_RC_FAST   (1)
-#define SOC_TIMER_GROUP_TOTAL_TIMERS      (2)
-#define SOC_TIMER_SUPPORT_ETM             (0)
+#define SOC_TIMER_GROUPS                  2
+#define SOC_TIMER_GROUP_TIMERS_PER_GROUP  2
+#define SOC_TIMER_GROUP_COUNTER_BIT_WIDTH 54
+#define SOC_TIMER_GROUP_SUPPORT_XTAL      1
+#define SOC_TIMER_GROUP_SUPPORT_RC_FAST   1
+#define SOC_TIMER_GROUP_TOTAL_TIMERS      4
 
 /*-------------------------- TWAI CAPS ---------------------------------------*/
 #define SOC_TWAI_CONTROLLER_NUM         2
@@ -470,7 +469,7 @@
 #define SOC_PM_PAU_LINK_NUM             (4)
 
 /*-------------------------- CLOCK SUBSYSTEM CAPS ----------------------------------------*/
-#define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION       (1)
+#define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION       (0)
 #define SOC_MODEM_CLOCK_IS_INDEPENDENT            (0)
 
 #define SOC_CLK_XTAL32K_SUPPORTED                 (1)     /*!< Support to connect an external low frequency crystal */

+ 90 - 103
components/soc/esp32p4/include/soc/timer_group_struct.h

@@ -16,34 +16,34 @@ extern "C" {
  */
 typedef union {
     struct {
-        uint32_t reserved_0:10;
+        uint32_t reserved_0: 10;
         /** tx_alarm_en : R/W/SC; bitpos: [10]; default: 0;
          *  When set, the alarm is enabled. This bit is automatically cleared once an
          *  alarm occurs.
          */
-        uint32_t tx_alarm_en:1;
-        uint32_t reserved_11:1;
+        uint32_t tx_alarm_en: 1;
+        uint32_t reserved_11: 1;
         /** tx_divcnt_rst : WT; bitpos: [12]; default: 0;
          *  When set, Timer x 's clock divider counter will be reset.
          */
-        uint32_t tx_divcnt_rst:1;
+        uint32_t tx_divcnt_rst: 1;
         /** tx_divider : R/W; bitpos: [28:13]; default: 1;
          *  Timer x clock (Tx_clk) prescaler value.
          */
-        uint32_t tx_divider:16;
+        uint32_t tx_divider: 16;
         /** tx_autoreload : R/W; bitpos: [29]; default: 1;
          *  When set, timer x auto-reload at alarm is enabled.
          */
-        uint32_t tx_autoreload:1;
+        uint32_t tx_autoreload: 1;
         /** tx_increase : R/W; bitpos: [30]; default: 1;
          *  When set, the timer x time-base counter will increment every clock tick. When
          *  cleared, the timer x time-base counter will decrement.
          */
-        uint32_t tx_increase:1;
+        uint32_t tx_increase: 1;
         /** tx_en : R/W/SS/SC; bitpos: [31]; default: 0;
          *  When set, the timer x time-base counter is enabled.
          */
-        uint32_t tx_en:1;
+        uint32_t tx_en: 1;
     };
     uint32_t val;
 } timg_txconfig_reg_t;
@@ -57,7 +57,7 @@ typedef union {
          *  After writing to TIMG_TxUPDATE_REG, the low 32 bits of the time-base counter
          *  of timer x can be read here.
          */
-        uint32_t tx_lo:32;
+        uint32_t tx_lo: 32;
     };
     uint32_t val;
 } timg_txlo_reg_t;
@@ -71,8 +71,8 @@ typedef union {
          *  After writing to TIMG_TxUPDATE_REG, the high 22 bits of the time-base counter
          *  of timer x can be read here.
          */
-        uint32_t tx_hi:22;
-        uint32_t reserved_22:10;
+        uint32_t tx_hi: 22;
+        uint32_t reserved_22: 10;
     };
     uint32_t val;
 } timg_txhi_reg_t;
@@ -82,11 +82,11 @@ typedef union {
  */
 typedef union {
     struct {
-        uint32_t reserved_0:31;
+        uint32_t reserved_0: 31;
         /** tx_update : R/W/SC; bitpos: [31]; default: 0;
          *  After writing 0 or 1 to TIMG_TxUPDATE_REG, the counter value is latched.
          */
-        uint32_t tx_update:1;
+        uint32_t tx_update: 1;
     };
     uint32_t val;
 } timg_txupdate_reg_t;
@@ -99,7 +99,7 @@ typedef union {
         /** tx_alarm_lo : R/W; bitpos: [31:0]; default: 0;
          *  Timer x alarm trigger time-base counter value, low 32 bits.
          */
-        uint32_t tx_alarm_lo:32;
+        uint32_t tx_alarm_lo: 32;
     };
     uint32_t val;
 } timg_txalarmlo_reg_t;
@@ -112,8 +112,8 @@ typedef union {
         /** tx_alarm_hi : R/W; bitpos: [21:0]; default: 0;
          *  Timer x alarm trigger time-base counter value, high 22 bits.
          */
-        uint32_t tx_alarm_hi:22;
-        uint32_t reserved_22:10;
+        uint32_t tx_alarm_hi: 22;
+        uint32_t reserved_22: 10;
     };
     uint32_t val;
 } timg_txalarmhi_reg_t;
@@ -127,7 +127,7 @@ typedef union {
          *  Low 32 bits of the value that a reload will load onto timer x time-base
          *  Counter.
          */
-        uint32_t tx_load_lo:32;
+        uint32_t tx_load_lo: 32;
     };
     uint32_t val;
 } timg_txloadlo_reg_t;
@@ -141,8 +141,8 @@ typedef union {
          *  High 22 bits of the value that a reload will load onto timer x time-base
          *  counter.
          */
-        uint32_t tx_load_hi:22;
-        uint32_t reserved_22:10;
+        uint32_t tx_load_hi: 22;
+        uint32_t reserved_22: 10;
     };
     uint32_t val;
 } timg_txloadhi_reg_t;
@@ -156,66 +156,65 @@ typedef union {
          *
          *  Write any value to trigger a timer x time-base counter reload.
          */
-        uint32_t tx_load:32;
+        uint32_t tx_load: 32;
     };
     uint32_t val;
 } timg_txload_reg_t;
 
-
 /** Group: WDT Control and configuration registers */
 /** Type of wdtconfig0 register
  *  Watchdog timer configuration register
  */
 typedef union {
     struct {
-        uint32_t reserved_0:12;
+        uint32_t reserved_0: 12;
         /** wdt_appcpu_reset_en : R/W; bitpos: [12]; default: 0;
          *  WDT reset CPU enable.
          */
-        uint32_t wdt_appcpu_reset_en:1;
+        uint32_t wdt_appcpu_reset_en: 1;
         /** wdt_procpu_reset_en : R/W; bitpos: [13]; default: 0;
          *  WDT reset CPU enable.
          */
-        uint32_t wdt_procpu_reset_en:1;
+        uint32_t wdt_procpu_reset_en: 1;
         /** wdt_flashboot_mod_en : R/W; bitpos: [14]; default: 1;
          *  When set, Flash boot protection is enabled.
          */
-        uint32_t wdt_flashboot_mod_en:1;
+        uint32_t wdt_flashboot_mod_en: 1;
         /** wdt_sys_reset_length : R/W; bitpos: [17:15]; default: 1;
          *  System reset signal length selection. 0: 100 ns, 1: 200 ns,
          *  2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us.
          */
-        uint32_t wdt_sys_reset_length:3;
+        uint32_t wdt_sys_reset_length: 3;
         /** wdt_cpu_reset_length : R/W; bitpos: [20:18]; default: 1;
          *  CPU reset signal length selection. 0: 100 ns, 1: 200 ns,
          *  2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us.
          */
-        uint32_t wdt_cpu_reset_length:3;
-        uint32_t reserved_21:1;
+        uint32_t wdt_cpu_reset_length: 3;
+        uint32_t reserved_21: 1;
         /** wdt_conf_update_en : WT; bitpos: [22]; default: 0;
          *  update the WDT configuration registers
          */
-        uint32_t wdt_conf_update_en:1;
+        uint32_t wdt_conf_update_en: 1;
         /** wdt_stg3 : R/W; bitpos: [24:23]; default: 0;
          *  Stage 3 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
          */
-        uint32_t wdt_stg3:2;
+        uint32_t wdt_stg3: 2;
         /** wdt_stg2 : R/W; bitpos: [26:25]; default: 0;
          *  Stage 2 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
          */
-        uint32_t wdt_stg2:2;
+        uint32_t wdt_stg2: 2;
         /** wdt_stg1 : R/W; bitpos: [28:27]; default: 0;
          *  Stage 1 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
          */
-        uint32_t wdt_stg1:2;
+        uint32_t wdt_stg1: 2;
         /** wdt_stg0 : R/W; bitpos: [30:29]; default: 0;
          *  Stage 0 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
          */
-        uint32_t wdt_stg0:2;
+        uint32_t wdt_stg0: 2;
         /** wdt_en : R/W; bitpos: [31]; default: 0;
          *  When set, MWDT is enabled.
          */
-        uint32_t wdt_en:1;
+        uint32_t wdt_en: 1;
     };
     uint32_t val;
 } timg_wdtconfig0_reg_t;
@@ -228,13 +227,13 @@ typedef union {
         /** wdt_divcnt_rst : WT; bitpos: [0]; default: 0;
          *  When set, WDT 's clock divider counter will be reset.
          */
-        uint32_t wdt_divcnt_rst:1;
-        uint32_t reserved_1:15;
+        uint32_t wdt_divcnt_rst: 1;
+        uint32_t reserved_1: 15;
         /** wdt_clk_prescale : R/W; bitpos: [31:16]; default: 1;
          *  MWDT clock prescaler value. MWDT clock period = 12.5 ns *
          *  TIMG_WDT_CLK_PRESCALE.
          */
-        uint32_t wdt_clk_prescale:16;
+        uint32_t wdt_clk_prescale: 16;
     };
     uint32_t val;
 } timg_wdtconfig1_reg_t;
@@ -247,7 +246,7 @@ typedef union {
         /** wdt_stg0_hold : R/W; bitpos: [31:0]; default: 26000000;
          *  Stage 0 timeout value, in MWDT clock cycles.
          */
-        uint32_t wdt_stg0_hold:32;
+        uint32_t wdt_stg0_hold: 32;
     };
     uint32_t val;
 } timg_wdtconfig2_reg_t;
@@ -260,7 +259,7 @@ typedef union {
         /** wdt_stg1_hold : R/W; bitpos: [31:0]; default: 134217727;
          *  Stage 1 timeout value, in MWDT clock cycles.
          */
-        uint32_t wdt_stg1_hold:32;
+        uint32_t wdt_stg1_hold: 32;
     };
     uint32_t val;
 } timg_wdtconfig3_reg_t;
@@ -273,7 +272,7 @@ typedef union {
         /** wdt_stg2_hold : R/W; bitpos: [31:0]; default: 1048575;
          *  Stage 2 timeout value, in MWDT clock cycles.
          */
-        uint32_t wdt_stg2_hold:32;
+        uint32_t wdt_stg2_hold: 32;
     };
     uint32_t val;
 } timg_wdtconfig4_reg_t;
@@ -286,7 +285,7 @@ typedef union {
         /** wdt_stg3_hold : R/W; bitpos: [31:0]; default: 1048575;
          *  Stage 3 timeout value, in MWDT clock cycles.
          */
-        uint32_t wdt_stg3_hold:32;
+        uint32_t wdt_stg3_hold: 32;
     };
     uint32_t val;
 } timg_wdtconfig5_reg_t;
@@ -299,7 +298,7 @@ typedef union {
         /** wdt_feed : WT; bitpos: [31:0]; default: 0;
          *  Write any value to feed the MWDT. (WO)
          */
-        uint32_t wdt_feed:32;
+        uint32_t wdt_feed: 32;
     };
     uint32_t val;
 } timg_wdtfeed_reg_t;
@@ -313,39 +312,38 @@ typedef union {
          *  If the register contains a different value than its reset value, write
          *  protection is enabled.
          */
-        uint32_t wdt_wkey:32;
+        uint32_t wdt_wkey: 32;
     };
     uint32_t val;
 } timg_wdtwprotect_reg_t;
 
-
 /** Group: RTC CALI Control and configuration registers */
 /** Type of rtccalicfg register
  *  RTC calibration configure register
  */
 typedef union {
     struct {
-        uint32_t reserved_0:12;
+        uint32_t reserved_0: 12;
         /** rtc_cali_start_cycling : R/W; bitpos: [12]; default: 1;
          *  0: one-shot frequency calculation,1: periodic frequency calculation,
          */
-        uint32_t rtc_cali_start_cycling:1;
+        uint32_t rtc_cali_start_cycling: 1;
         /** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 0;
          *  0:rtc slow clock. 1:clk_8m, 2:xtal_32k.
          */
-        uint32_t rtc_cali_clk_sel:2;
+        uint32_t rtc_cali_clk_sel: 2;
         /** rtc_cali_rdy : RO; bitpos: [15]; default: 0;
          *  indicate one-shot frequency calculation is done.
          */
-        uint32_t rtc_cali_rdy:1;
+        uint32_t rtc_cali_rdy: 1;
         /** rtc_cali_max : R/W; bitpos: [30:16]; default: 1;
          *  Configure the time to calculate RTC slow clock's frequency.
          */
-        uint32_t rtc_cali_max:15;
+        uint32_t rtc_cali_max: 15;
         /** rtc_cali_start : R/W; bitpos: [31]; default: 0;
          *  Set this bit to start one-shot frequency calculation.
          */
-        uint32_t rtc_cali_start:1;
+        uint32_t rtc_cali_start: 1;
     };
     uint32_t val;
 } timg_rtccalicfg_reg_t;
@@ -358,13 +356,13 @@ typedef union {
         /** rtc_cali_cycling_data_vld : RO; bitpos: [0]; default: 0;
          *  indicate periodic frequency calculation is done.
          */
-        uint32_t rtc_cali_cycling_data_vld:1;
-        uint32_t reserved_1:6;
+        uint32_t rtc_cali_cycling_data_vld: 1;
+        uint32_t reserved_1: 6;
         /** rtc_cali_value : RO; bitpos: [31:7]; default: 0;
          *  When one-shot or periodic frequency calculation is done, read this value to
          *  calculate RTC slow clock's frequency.
          */
-        uint32_t rtc_cali_value:25;
+        uint32_t rtc_cali_value: 25;
     };
     uint32_t val;
 } timg_rtccalicfg1_reg_t;
@@ -377,22 +375,21 @@ typedef union {
         /** rtc_cali_timeout : RO; bitpos: [0]; default: 0;
          *  RTC calibration timeout indicator
          */
-        uint32_t rtc_cali_timeout:1;
-        uint32_t reserved_1:2;
+        uint32_t rtc_cali_timeout: 1;
+        uint32_t reserved_1: 2;
         /** rtc_cali_timeout_rst_cnt : R/W; bitpos: [6:3]; default: 3;
          *  Cycles that release calibration timeout reset
          */
-        uint32_t rtc_cali_timeout_rst_cnt:4;
+        uint32_t rtc_cali_timeout_rst_cnt: 4;
         /** rtc_cali_timeout_thres : R/W; bitpos: [31:7]; default: 33554431;
          *  Threshold value for the RTC calibration timer. If the calibration timer's value
          *  exceeds this threshold, a timeout is triggered.
          */
-        uint32_t rtc_cali_timeout_thres:25;
+        uint32_t rtc_cali_timeout_thres: 25;
     };
     uint32_t val;
 } timg_rtccalicfg2_reg_t;
 
-
 /** Group: Interrupt registers */
 /** Type of int_ena_timers register
  *  Interrupt enable bits
@@ -402,16 +399,16 @@ typedef union {
         /** t0_int_ena : R/W; bitpos: [0]; default: 0;
          *  The interrupt enable bit for the TIMG_T$x_INT interrupt.
          */
-        uint32_t t0_int_ena:1;
+        uint32_t t0_int_ena: 1;
         /** t1_int_ena : R/W; bitpos: [1]; default: 0;
          *  The interrupt enable bit for the TIMG_T$x_INT interrupt.
          */
-        uint32_t t1_int_ena:1;
+        uint32_t t1_int_ena: 1;
         /** wdt_int_ena : R/W; bitpos: [2]; default: 0;
          *  The interrupt enable bit for the TIMG_WDT_INT interrupt.
          */
-        uint32_t wdt_int_ena:1;
-        uint32_t reserved_3:29;
+        uint32_t wdt_int_ena: 1;
+        uint32_t reserved_3: 29;
     };
     uint32_t val;
 } timg_int_ena_timers_reg_t;
@@ -424,16 +421,16 @@ typedef union {
         /** t0_int_raw : R/SS/WTC; bitpos: [0]; default: 0;
          *  The raw interrupt status bit for the TIMG_T$x_INT interrupt.
          */
-        uint32_t t0_int_raw:1;
+        uint32_t t0_int_raw: 1;
         /** t1_int_raw : R/SS/WTC; bitpos: [1]; default: 0;
          *  The raw interrupt status bit for the TIMG_T$x_INT interrupt.
          */
-        uint32_t t1_int_raw:1;
+        uint32_t t1_int_raw: 1;
         /** wdt_int_raw : R/SS/WTC; bitpos: [2]; default: 0;
          *  The raw interrupt status bit for the TIMG_WDT_INT interrupt.
          */
-        uint32_t wdt_int_raw:1;
-        uint32_t reserved_3:29;
+        uint32_t wdt_int_raw: 1;
+        uint32_t reserved_3: 29;
     };
     uint32_t val;
 } timg_int_raw_timers_reg_t;
@@ -446,16 +443,16 @@ typedef union {
         /** t0_int_st : RO; bitpos: [0]; default: 0;
          *  The masked interrupt status bit for the TIMG_T$x_INT interrupt.
          */
-        uint32_t t0_int_st:1;
+        uint32_t t0_int_st: 1;
         /** t1_int_st : RO; bitpos: [1]; default: 0;
          *  The masked interrupt status bit for the TIMG_T$x_INT interrupt.
          */
-        uint32_t t1_int_st:1;
+        uint32_t t1_int_st: 1;
         /** wdt_int_st : RO; bitpos: [2]; default: 0;
          *  The masked interrupt status bit for the TIMG_WDT_INT interrupt.
          */
-        uint32_t wdt_int_st:1;
-        uint32_t reserved_3:29;
+        uint32_t wdt_int_st: 1;
+        uint32_t reserved_3: 29;
     };
     uint32_t val;
 } timg_int_st_timers_reg_t;
@@ -468,21 +465,20 @@ typedef union {
         /** t0_int_clr : WT; bitpos: [0]; default: 0;
          *  Set this bit to clear the TIMG_T$x_INT interrupt.
          */
-        uint32_t t0_int_clr:1;
+        uint32_t t0_int_clr: 1;
         /** t1_int_clr : WT; bitpos: [1]; default: 0;
          *  Set this bit to clear the TIMG_T$x_INT interrupt.
          */
-        uint32_t t1_int_clr:1;
+        uint32_t t1_int_clr: 1;
         /** wdt_int_clr : WT; bitpos: [2]; default: 0;
          *  Set this bit to clear the TIMG_WDT_INT interrupt.
          */
-        uint32_t wdt_int_clr:1;
-        uint32_t reserved_3:29;
+        uint32_t wdt_int_clr: 1;
+        uint32_t reserved_3: 29;
     };
     uint32_t val;
 } timg_int_clr_timers_reg_t;
 
-
 /** Group: Version register */
 /** Type of ntimers_date register
  *  Timer version control register
@@ -492,56 +488,47 @@ typedef union {
         /** ntimgs_date : R/W; bitpos: [27:0]; default: 35688770;
          *  Timer version control register
          */
-        uint32_t ntimgs_date:28;
-        uint32_t reserved_28:4;
+        uint32_t ntimgs_date: 28;
+        uint32_t reserved_28: 4;
     };
     uint32_t val;
 } timg_ntimers_date_reg_t;
 
-
 /** Group: Clock configuration registers */
 /** Type of regclk register
  *  Timer group clock gate register
  */
 typedef union {
     struct {
-        uint32_t reserved_0:28;
+        uint32_t reserved_0: 28;
         /** etm_en : R/W; bitpos: [28]; default: 1;
          *  enable timer's etm task and event
          */
-        uint32_t etm_en:1;
-        uint32_t reserved_29:2;
+        uint32_t etm_en: 1;
+        uint32_t reserved_29: 2;
         /** clk_en : R/W; bitpos: [31]; default: 0;
          *  Register clock gate signal. 1: Registers can be read and written to by software. 0:
          *  Registers can not be read or written to by software.
          */
-        uint32_t clk_en:1;
+        uint32_t clk_en: 1;
     };
     uint32_t val;
 } timg_regclk_reg_t;
 
-
 typedef struct {
-    volatile timg_txconfig_reg_t t0config;
-    volatile timg_txlo_reg_t t0lo;
-    volatile timg_txhi_reg_t t0hi;
-    volatile timg_txupdate_reg_t t0update;
-    volatile timg_txalarmlo_reg_t t0alarmlo;
-    volatile timg_txalarmhi_reg_t t0alarmhi;
-    volatile timg_txloadlo_reg_t t0loadlo;
-    volatile timg_txloadhi_reg_t t0loadhi;
-    volatile timg_txload_reg_t t0load;
-
-
-    volatile timg_txconfig_reg_t t1config;
-    volatile timg_txlo_reg_t t1lo;
-    volatile timg_txhi_reg_t t1hi;
-    volatile timg_txupdate_reg_t t1update;
-    volatile timg_txalarmlo_reg_t t1alarmlo;
-    volatile timg_txalarmhi_reg_t t1alarmhi;
-    volatile timg_txloadlo_reg_t t1loadlo;
-    volatile timg_txloadhi_reg_t t1loadhi;
-    volatile timg_txload_reg_t t1load;
+    volatile timg_txconfig_reg_t config;
+    volatile timg_txlo_reg_t lo;
+    volatile timg_txhi_reg_t hi;
+    volatile timg_txupdate_reg_t update;
+    volatile timg_txalarmlo_reg_t alarmlo;
+    volatile timg_txalarmhi_reg_t alarmhi;
+    volatile timg_txloadlo_reg_t loadlo;
+    volatile timg_txloadhi_reg_t loadhi;
+    volatile timg_txload_reg_t load;
+} timg_hwtimer_reg_t;
+
+typedef struct timg_dev_t {
+    volatile timg_hwtimer_reg_t hw_timer[2];
     volatile timg_wdtconfig0_reg_t wdtconfig0;
     volatile timg_wdtconfig1_reg_t wdtconfig1;
     volatile timg_wdtconfig2_reg_t wdtconfig2;

+ 16 - 1
components/soc/esp32p4/timer_periph.c

@@ -7,5 +7,20 @@
 #include "soc/timer_periph.h"
 
 const timer_group_signal_conn_t timer_group_periph_signals = {
-
+    .groups = {
+        [0] = {
+            .module = PERIPH_TIMG0_MODULE,
+            .timer_irq_id = {
+                [0] = ETS_TG0_T0_INTR_SOURCE,
+                [1] = ETS_TG0_T1_INTR_SOURCE,
+            }
+        },
+        [1] = {
+            .module = PERIPH_TIMG1_MODULE,
+            .timer_irq_id = {
+                [0] = ETS_TG1_T0_INTR_SOURCE,
+                [1] = ETS_TG1_T1_INTR_SOURCE,
+            }
+        }
+    }
 };