diff --git a/components/esp_system/fpga_overrides.c b/components/esp_system/fpga_overrides.c index 9ef5cea90d..2439c16000 100644 --- a/components/esp_system/fpga_overrides.c +++ b/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); } /** diff --git a/components/hal/esp32p4/include/hal/timer_ll.h b/components/hal/esp32p4/include/hal/timer_ll.h new file mode 100644 index 0000000000..2b127b19c8 --- /dev/null +++ b/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 +#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 diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index 9deb48926b..7dd7b0b22f 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/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 diff --git a/components/soc/esp32p4/include/soc/clk_tree_defs.h b/components/soc/esp32p4/include/soc/clk_tree_defs.h index 5450aaa3bf..c78bc31e47 100644 --- a/components/soc/esp32p4/include/soc/clk_tree_defs.h +++ b/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; + +/** + * @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 diff --git a/components/soc/esp32p4/include/soc/interrupts.h b/components/soc/esp32p4/include/soc/interrupts.h index bb3fd7c4b5..8bf26b96b1 100644 --- a/components/soc/esp32p4/include/soc/interrupts.h +++ b/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, diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index 7ac71c2d7d..9cec44c48d 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/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 */ diff --git a/components/soc/esp32p4/include/soc/timer_group_struct.h b/components/soc/esp32p4/include/soc/timer_group_struct.h index f3ef60a5d3..c49119c6a2 100644 --- a/components/soc/esp32p4/include/soc/timer_group_struct.h +++ b/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 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; - - 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; +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; diff --git a/components/soc/esp32p4/timer_periph.c b/components/soc/esp32p4/timer_periph.c index 96eb286c20..f799a91f7e 100644 --- a/components/soc/esp32p4/timer_periph.c +++ b/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, + } + } + } };