feat(driver_gptimer): esp32h21 add basic gptimer support

This commit is contained in:
wanckl 2025-02-17 19:44:45 +08:00
parent 4f2105d03e
commit cfe4bf339f
24 changed files with 258 additions and 196 deletions

View File

@ -1,2 +1,2 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- |

View File

@ -1,2 +1,2 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- |

View File

@ -15,6 +15,8 @@ endif()
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
# the component can be registered as WHOLE_ARCHIVE
idf_component_register(SRCS ${srcs}
idf_component_register(
SRCS ${srcs}
PRIV_REQUIRES unity esp_driver_gptimer esp_driver_gpio
WHOLE_ARCHIVE)
WHOLE_ARCHIVE
)

View File

@ -103,7 +103,7 @@ TEST_CASE("gptimer_wallclock_with_various_clock_sources", "[gptimer]")
printf("get raw count of gptimer %d: %llu\r\n", i, value);
// convert the raw count to us
value = value * 1000000 / timer_resolution_hz[i];
TEST_ASSERT_UINT_WITHIN(200, 20000, value);
TEST_ASSERT_UINT_WITHIN(400, 20000, value); //200 more threshold for cpu on stop process
}
printf("restart timers\r\n");
for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {
@ -121,7 +121,7 @@ TEST_CASE("gptimer_wallclock_with_various_clock_sources", "[gptimer]")
printf("get raw count of gptimer %d: %llu\r\n", i, value);
// convert the raw count to us
value = value * 1000000 / timer_resolution_hz[i];
TEST_ASSERT_UINT_WITHIN(400, 40000, value);
TEST_ASSERT_UINT_WITHIN(600, 40000, value); //same 200 for cpu time
}
printf("disable timers\r\n");
for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) {

View File

@ -24,8 +24,15 @@ uint32_t *freq_value)
ESP_RETURN_ON_FALSE(precision < ESP_CLK_TREE_SRC_FREQ_PRECISION_INVALID, ESP_ERR_INVALID_ARG, TAG, "unknown precision");
ESP_RETURN_ON_FALSE(freq_value, ESP_ERR_INVALID_ARG, TAG, "null pointer");
#if !SOC_CLK_TREE_SUPPORTED
// Have only XTAL 32M before clock tree supported
assert(clk_src == SOC_MOD_CLK_XTAL);
#endif
uint32_t clk_src_freq = 0;
switch (clk_src) {
case SOC_MOD_CLK_XTAL:
clk_src_freq = SOC_XTAL_FREQ_32M * MHZ;
break;
case SOC_MOD_CLK_PLL_F48M:
clk_src_freq = CLK_LL_PLL_48M_FREQ_MHZ * MHZ;
break;
@ -39,8 +46,7 @@ uint32_t *freq_value)
break;
}
ESP_RETURN_ON_FALSE(clk_src_freq, ESP_FAIL, TAG,
"freq shouldn't be 0, calibration failed");
ESP_RETURN_ON_FALSE(clk_src_freq, ESP_FAIL, TAG, "freq shouldn't be 0, calibration failed");
*freq_value = clk_src_freq;
return ESP_OK;
}

View File

@ -21,7 +21,7 @@ if(CONFIG_SOC_ETM_SUPPORTED)
list(APPEND srcs "test_etm_core.c")
endif()
if(CONFIG_SOC_GPTIMER_SUPPORTED)
if(CONFIG_SOC_GPTIMER_SUPPORTED AND CONFIG_SOC_GPSPI_SUPPORTED)
list(APPEND srcs "test_intr_alloc.c")
endif()

View File

@ -53,7 +53,7 @@
#endif // SOC_TIMER_GROUPS > 1
#if CONFIG_ESP_INT_WDT
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_MWDT_SUPPORT_SLEEP_RETENTION
static const char* TAG = "int_wdt";
static esp_err_t sleep_int_wdt_retention_init(void *arg)
{
@ -160,7 +160,7 @@ void esp_int_wdt_init(void)
wdt_hal_enable(&iwdt_context);
wdt_hal_write_protect_enable(&iwdt_context);
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_MWDT_SUPPORT_SLEEP_RETENTION
esp_int_wdt_retention_enable(IWDT_TIMER_GROUP);
#endif

View File

@ -21,7 +21,7 @@
#include "esp_private/periph_ctrl.h"
#include "esp_private/esp_task_wdt_impl.h"
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_MWDT_SUPPORT_SLEEP_RETENTION
#include "esp_private/sleep_retention.h"
#endif
@ -46,7 +46,7 @@ typedef struct {
* init function. */
static twdt_ctx_hard_t init_context;
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_MWDT_SUPPORT_SLEEP_RETENTION
static const char* TAG = "task_wdt";
static esp_err_t sleep_task_wdt_retention_init(void *arg)
{
@ -124,7 +124,7 @@ esp_err_t esp_task_wdt_impl_timer_allocate(const esp_task_wdt_config_t *config,
/* Return the implementation context to the caller */
*obj = (twdt_ctx_t) ctx;
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_MWDT_SUPPORT_SLEEP_RETENTION
esp_task_wdt_retention_enable(TWDT_TIMER_GROUP);
#endif
}
@ -171,7 +171,7 @@ void esp_task_wdt_impl_timer_free(twdt_ctx_t obj)
/* Deregister interrupt */
ESP_ERROR_CHECK(esp_intr_free(ctx->intr_handle));
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_MWDT_SUPPORT_SLEEP_RETENTION
ESP_ERROR_CHECK(esp_task_wdt_retention_disable(TWDT_TIMER_GROUP));
#endif
}

View File

@ -16,7 +16,7 @@
#include "soc/rtc.h"
#include "soc/soc_caps.h"
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_MWDT_SUPPORT_SLEEP_RETENTION
#include "esp_sleep.h"
#include "esp_private/esp_sleep_internal.h"
#include "esp_private/sleep_cpu.h"
@ -49,7 +49,7 @@ TEST_CASE("Task WDT task timeout", "[task_wdt]")
TEST_ASSERT_EQUAL(ESP_OK, esp_task_wdt_deinit());
}
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_MWDT_SUPPORT_SLEEP_RETENTION
TEST_CASE("Task WDT task timeout after peripheral powerdown lightsleep", "[task_wdt]")
{
timeout_flag = false;

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -276,31 +276,23 @@ FORCE_INLINE_ATTR void mwdt_ll_set_intr_enable(timg_dev_t *hw, bool enable)
* @param hw Beginning address of the peripheral registers.
* @param clk_src Clock source
*/
FORCE_INLINE_ATTR void mwdt_ll_set_clock_source(timg_dev_t *hw, mwdt_clock_source_t clk_src)
{
uint8_t clk_id = 0;
uint8_t group_id = (hw == &TIMERG0) ? 0 : 1;
switch (clk_src) {
case MWDT_CLK_SRC_XTAL:
clk_id = 0;
PCR.timergroup[group_id].timergroup_wdt_clk_conf.tg_wdt_clk_sel = 0;
break;
case MWDT_CLK_SRC_RC_FAST:
clk_id = 1;
PCR.timergroup[group_id].timergroup_wdt_clk_conf.tg_wdt_clk_sel = 1;
break;
case MWDT_CLK_SRC_PLL_F48M:
clk_id = 2;
PCR.timergroup[group_id].timergroup_wdt_clk_conf.tg_wdt_clk_sel = 2;
break;
default:
HAL_ASSERT(false);
break;
}
if (hw == &TIMERG0) {
PCR.timergroup0_wdt_clk_conf.tg0_wdt_clk_sel = clk_id;
} else {
PCR.timergroup1_wdt_clk_conf.tg1_wdt_clk_sel = clk_id;
}
}
/**
@ -312,11 +304,8 @@ FORCE_INLINE_ATTR void mwdt_ll_set_clock_source(timg_dev_t *hw, mwdt_clock_sourc
__attribute__((always_inline))
static inline void mwdt_ll_enable_clock(timg_dev_t *hw, bool en)
{
if (hw == &TIMERG0) {
PCR.timergroup0_wdt_clk_conf.tg0_wdt_clk_en = en;
} else {
PCR.timergroup1_wdt_clk_conf.tg1_wdt_clk_en = en;
}
uint8_t group_id = (hw == &TIMERG0) ? 0 : 1;
PCR.timergroup[group_id].timergroup_wdt_clk_conf.tg_wdt_clk_en = en;
}
#ifdef __cplusplus

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -17,8 +17,6 @@
#include "soc/pcr_struct.h"
#include "soc/soc_etm_source.h"
//TODO: [ESP32H21] IDF-11594, inherit from h2
#ifdef __cplusplus
extern "C" {
#endif
@ -62,11 +60,7 @@ extern "C" {
*/
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;
}
PCR.timergroup[group_id].timergroup_conf.tg_clk_en = enable;
}
/// use a macro to wrap the function, force the caller to use it in a critical section
@ -84,15 +78,11 @@ static inline void _timer_ll_enable_bus_clock(int group_id, bool enable)
*/
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;
}
timg_dev_t *hw = TIMER_LL_GET_HW(group_id);
PCR.timergroup[group_id].timergroup_conf.tg_rst_en = 1;
PCR.timergroup[group_id].timergroup_conf.tg_rst_en = 0;
hw->wdtconfig0.wdt_flashboot_mod_en = 0;
}
/// use a macro to wrap the function, force the caller to use it in a critical section
@ -109,26 +99,21 @@ static inline void _timer_ll_reset_register(int group_id)
static inline void timer_ll_set_clock_source(timg_dev_t *hw, uint32_t timer_num, gptimer_clock_source_t clk_src)
{
(void)timer_num; // only one timer in each group
uint8_t clk_id = 0;
uint8_t group_id = (hw == &TIMERG0) ? 0 : 1;
switch (clk_src) {
case GPTIMER_CLK_SRC_XTAL:
clk_id = 0;
PCR.timergroup[group_id].timergroup_timer_clk_conf.tg_timer_clk_sel = 0;
break;
case GPTIMER_CLK_SRC_RC_FAST:
clk_id = 1;
PCR.timergroup[group_id].timergroup_timer_clk_conf.tg_timer_clk_sel = 1;
break;
case GPTIMER_CLK_SRC_PLL_F48M:
clk_id = 2;
PCR.timergroup[group_id].timergroup_timer_clk_conf.tg_timer_clk_sel = 2;
break;
default:
HAL_ASSERT(false);
break;
}
if (hw == &TIMERG0) {
PCR.timergroup0_timer_clk_conf.tg0_timer_clk_sel = clk_id;
} else {
PCR.timergroup1_timer_clk_conf.tg1_timer_clk_sel = clk_id;
}
}
/**
@ -141,11 +126,9 @@ static inline void timer_ll_set_clock_source(timg_dev_t *hw, uint32_t timer_num,
static inline void timer_ll_enable_clock(timg_dev_t *hw, uint32_t timer_num, bool en)
{
(void)timer_num; // only one timer in each group
if (hw == &TIMERG0) {
PCR.timergroup0_timer_clk_conf.tg0_timer_clk_en = en;
} else {
PCR.timergroup1_timer_clk_conf.tg1_timer_clk_en = en;
}
uint8_t group_id = (hw == &TIMERG0) ? 0 : 1;
PCR.timergroup[group_id].timergroup_timer_clk_conf.tg_timer_clk_en = en;
}
/**

View File

@ -7,6 +7,10 @@ config SOC_UART_SUPPORTED
bool
default y
config SOC_GPTIMER_SUPPORTED
bool
default y
config SOC_EFUSE_KEY_PURPOSE_FIELD
bool
default y
@ -467,6 +471,10 @@ config SOC_TIMER_GROUP_TIMERS_PER_GROUP
int
default 1
config SOC_TIMER_GROUP_TOTAL_TIMERS
int
default 2
config SOC_TIMER_GROUP_COUNTER_BIT_WIDTH
int
default 54
@ -479,9 +487,9 @@ config SOC_TIMER_GROUP_SUPPORT_RC_FAST
bool
default y
config SOC_TIMER_GROUP_TOTAL_TIMERS
int
default 2
config SOC_TIMER_SUPPORT_SLEEP_RETENTION
bool
default y
config SOC_MWDT_SUPPORT_XTAL
bool

View File

@ -158,7 +158,11 @@ typedef enum {
* }
* @endcode
*/
#if SOC_CLK_TREE_SUPPORTED
#define SOC_GPTIMER_CLKS {SOC_MOD_CLK_PLL_F48M, 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
@ -167,7 +171,11 @@ typedef enum {
GPTIMER_CLK_SRC_PLL_F48M = SOC_MOD_CLK_PLL_F48M, /*!< Select PLL_F48M 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_F48M, /*!< Select PLL_F48M as the default choice */
#else
GPTIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default choice if no clk_tree */
#endif
} soc_periph_gptimer_clk_src_t;
/**
@ -176,7 +184,11 @@ typedef enum {
typedef enum {
TIMER_SRC_CLK_PLL_F48M = SOC_MOD_CLK_PLL_F48M, /*!< Timer group clock source is PLL_F48M */
TIMER_SRC_CLK_XTAL = SOC_MOD_CLK_XTAL, /*!< Timer group clock source is XTAL */
TIMER_SRC_CLK_DEFAULT = SOC_MOD_CLK_PLL_F48M, /*!< Timer group clock source default choice is PLL_F48M */
#if SOC_CLK_TREE_SUPPORTED
TIMER_SRC_CLK_DEFAULT = SOC_MOD_CLK_PLL_F48M, /*!< Select PLL_F48M as the default choice */
#else
TIMER_SRC_CLK_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default choice if no clk_tree */
#endif
} soc_periph_tg_clk_src_legacy_t;
///////////////////////////////////////////////////UART/////////////////////////////////////////////////////////////////

View File

@ -23,7 +23,7 @@
#define SOC_UART_SUPPORTED 1 //TODO: [ESP32H21] IDF-11618
// #define SOC_GDMA_SUPPORTED 1 //TODO: [ESP32H21] IDF-11603
// #define SOC_AHB_GDMA_SUPPORTED 1 //TODO: [ESP32H21] IDF-11603
// #define SOC_GPTIMER_SUPPORTED 1 //TODO: [ESP32H21] IDF-11594
#define SOC_GPTIMER_SUPPORTED 1
// #define SOC_BT_SUPPORTED 1
// #define SOC_IEEE802154_SUPPORTED 1
// #define SOC_IEEE802154_BLE_ONLY 1
@ -436,12 +436,12 @@
/*--------------------------- TIMER GROUP CAPS ---------------------------------------*/
#define SOC_TIMER_GROUPS (2)
#define SOC_TIMER_GROUP_TIMERS_PER_GROUP (1U)
#define SOC_TIMER_GROUP_TOTAL_TIMERS (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 (2)
// #define SOC_TIMER_SUPPORT_ETM (1)
// #define SOC_TIMER_SUPPORT_SLEEP_RETENTION (1)
// #define SOC_TIMER_SUPPORT_ETM (1) //TODO: [ESP32H21] IDF-11576
#define SOC_TIMER_SUPPORT_SLEEP_RETENTION (1)
/*--------------------------- WATCHDOG CAPS ---------------------------------------*/
#define SOC_MWDT_SUPPORT_XTAL (1)

View File

@ -424,145 +424,75 @@ typedef union {
uint32_t val;
} pcr_ledc_sclk_conf_reg_t;
/** Type of timergroup0_conf register
* TIMERGROUP0 configuration register
/** Type of timergroup_conf register
* TIMERGROUP configuration register
*/
typedef union {
struct {
/** tg0_clk_en : R/W; bitpos: [0]; default: 1;
/** tg_clk_en : R/W; bitpos: [0]; default: 1;
* Set 1 to enable timer_group0 apb clock
*/
uint32_t tg0_clk_en:1;
/** tg0_rst_en : R/W; bitpos: [1]; default: 0;
uint32_t tg_clk_en:1;
/** tg_rst_en : R/W; bitpos: [1]; default: 0;
* Set 0 to reset timer_group0 module
*/
uint32_t tg0_rst_en:1;
/** tg0_wdt_ready : RO; bitpos: [2]; default: 1;
uint32_t tg_rst_en:1;
/** tg_wdt_ready : RO; bitpos: [2]; default: 1;
* Query this field after reset timer_group0 wdt module
*/
uint32_t tg0_wdt_ready:1;
/** tg0_timer0_ready : RO; bitpos: [3]; default: 1;
uint32_t tg_wdt_ready:1;
/** tg_timer0_ready : RO; bitpos: [3]; default: 1;
* Query this field after reset timer_group0 timer0 module
*/
uint32_t tg0_timer0_ready:1;
/** tg0_timer1_ready : RO; bitpos: [4]; default: 1;
uint32_t tg_timer0_ready:1;
/** tg_timer1_ready : RO; bitpos: [4]; default: 1;
* reserved
*/
uint32_t tg0_timer1_ready:1;
uint32_t tg_timer1_ready:1;
uint32_t reserved_5:27;
};
uint32_t val;
} pcr_timergroup0_conf_reg_t;
} pcr_timergroup_conf_reg_t;
/** Type of timergroup0_timer_clk_conf register
* TIMERGROUP0_TIMER_CLK configuration register
/** Type of timergroup_timer_clk_conf register
* TIMERGROUP_TIMER_CLK configuration register
*/
typedef union {
struct {
uint32_t reserved_0:20;
/** tg0_timer_clk_sel : R/W; bitpos: [21:20]; default: 0;
* set this field to select clock-source. 0(default): XTAL, 1: 80MHz, 2: FOSC, 3:
/** tg_timer_clk_sel : R/W; bitpos: [21:20]; default: 0;
* set this field to select clock-source. 0(default): XTAL, 1: FOSC, 2: 48MHz, 3:
* reserved.
*/
uint32_t tg0_timer_clk_sel:2;
/** tg0_timer_clk_en : R/W; bitpos: [22]; default: 1;
uint32_t tg_timer_clk_sel:2;
/** tg_timer_clk_en : R/W; bitpos: [22]; default: 1;
* Set 1 to enable timer_group0 timer clock
*/
uint32_t tg0_timer_clk_en:1;
uint32_t tg_timer_clk_en:1;
uint32_t reserved_23:9;
};
uint32_t val;
} pcr_timergroup0_timer_clk_conf_reg_t;
} pcr_timergroup_timer_clk_conf_reg_t;
/** Type of timergroup0_wdt_clk_conf register
* TIMERGROUP0_WDT_CLK configuration register
/** Type of timergroup_wdt_clk_conf register
* TIMERGROUP_WDT_CLK configuration register
*/
typedef union {
struct {
uint32_t reserved_0:20;
/** tg0_wdt_clk_sel : R/W; bitpos: [21:20]; default: 0;
* set this field to select clock-source. 0(default): XTAL, 1: 80MHz, 2: FOSC, 3:
/** tg_wdt_clk_sel : R/W; bitpos: [21:20]; default: 0;
* set this field to select clock-source. 0(default): XTAL, 1: FOSC, 2: 48MHz, 3:
* reserved.
*/
uint32_t tg0_wdt_clk_sel:2;
/** tg0_wdt_clk_en : R/W; bitpos: [22]; default: 1;
uint32_t tg_wdt_clk_sel:2;
/** tg_wdt_clk_en : R/W; bitpos: [22]; default: 1;
* Set 1 to enable timer_group0 wdt clock
*/
uint32_t tg0_wdt_clk_en:1;
uint32_t tg_wdt_clk_en:1;
uint32_t reserved_23:9;
};
uint32_t val;
} pcr_timergroup0_wdt_clk_conf_reg_t;
/** Type of timergroup1_conf register
* TIMERGROUP1 configuration register
*/
typedef union {
struct {
/** tg1_clk_en : R/W; bitpos: [0]; default: 1;
* Set 1 to enable timer_group1 apb clock
*/
uint32_t tg1_clk_en:1;
/** tg1_rst_en : R/W; bitpos: [1]; default: 0;
* Set 0 to reset timer_group1 module
*/
uint32_t tg1_rst_en:1;
/** tg1_wdt_ready : RO; bitpos: [2]; default: 1;
* Query this field after reset timer_group1 wdt module
*/
uint32_t tg1_wdt_ready:1;
/** tg1_timer0_ready : RO; bitpos: [3]; default: 1;
* Query this field after reset timer_group1 timer0 module
*/
uint32_t tg1_timer0_ready:1;
/** tg1_timer1_ready : RO; bitpos: [4]; default: 1;
* reserved
*/
uint32_t tg1_timer1_ready:1;
uint32_t reserved_5:27;
};
uint32_t val;
} pcr_timergroup1_conf_reg_t;
/** Type of timergroup1_timer_clk_conf register
* TIMERGROUP1_TIMER_CLK configuration register
*/
typedef union {
struct {
uint32_t reserved_0:20;
/** tg1_timer_clk_sel : R/W; bitpos: [21:20]; default: 0;
* set this field to select clock-source. 0(default): XTAL, 1: 80MHz, 2: FOSC, 3:
* reserved.
*/
uint32_t tg1_timer_clk_sel:2;
/** tg1_timer_clk_en : R/W; bitpos: [22]; default: 1;
* Set 1 to enable timer_group1 timer clock
*/
uint32_t tg1_timer_clk_en:1;
uint32_t reserved_23:9;
};
uint32_t val;
} pcr_timergroup1_timer_clk_conf_reg_t;
/** Type of timergroup1_wdt_clk_conf register
* TIMERGROUP1_WDT_CLK configuration register
*/
typedef union {
struct {
uint32_t reserved_0:20;
/** tg1_wdt_clk_sel : R/W; bitpos: [21:20]; default: 0;
* set this field to select clock-source. 0(default): XTAL, 1: 80MHz, 2: FOSC, 3:
* reserved.
*/
uint32_t tg1_wdt_clk_sel:2;
/** tg1_wdt_clk_en : R/W; bitpos: [22]; default: 1;
* Set 1 to enable timer_group0 wdt clock
*/
uint32_t tg1_wdt_clk_en:1;
uint32_t reserved_23:9;
};
uint32_t val;
} pcr_timergroup1_wdt_clk_conf_reg_t;
} pcr_timergroup_wdt_clk_conf_reg_t;
/** Type of systimer_conf register
* SYSTIMER configuration register
@ -1944,6 +1874,13 @@ typedef union {
uint32_t val;
} pcr_date_reg_t;
/** Type of timergroup PCR config register
*/
typedef struct {
volatile pcr_timergroup_conf_reg_t timergroup_conf;
volatile pcr_timergroup_timer_clk_conf_reg_t timergroup_timer_clk_conf;
volatile pcr_timergroup_wdt_clk_conf_reg_t timergroup_wdt_clk_conf;
} pcr_timergroup_reg_t;
typedef struct {
volatile pcr_uart0_conf_reg_t uart0_conf;
@ -1963,12 +1900,7 @@ typedef struct {
volatile pcr_rmt_sclk_conf_reg_t rmt_sclk_conf;
volatile pcr_ledc_conf_reg_t ledc_conf;
volatile pcr_ledc_sclk_conf_reg_t ledc_sclk_conf;
volatile pcr_timergroup0_conf_reg_t timergroup0_conf;
volatile pcr_timergroup0_timer_clk_conf_reg_t timergroup0_timer_clk_conf;
volatile pcr_timergroup0_wdt_clk_conf_reg_t timergroup0_wdt_clk_conf;
volatile pcr_timergroup1_conf_reg_t timergroup1_conf;
volatile pcr_timergroup1_timer_clk_conf_reg_t timergroup1_timer_clk_conf;
volatile pcr_timergroup1_wdt_clk_conf_reg_t timergroup1_wdt_clk_conf;
volatile pcr_timergroup_reg_t timergroup[2];
volatile pcr_systimer_conf_reg_t systimer_conf;
volatile pcr_systimer_func_clk_conf_reg_t systimer_func_clk_conf;
volatile pcr_twai0_conf_reg_t twai0_conf;

View File

@ -531,7 +531,7 @@ typedef struct {
volatile timg_txload_reg_t load;
} timg_hwtimer_reg_t;
typedef struct {
typedef struct timg_dev_t {
volatile timg_hwtimer_reg_t hw_timer[1];
uint32_t reserved_024[9];
volatile timg_wdtconfig0_reg_t wdtconfig0;

View File

@ -0,0 +1,131 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#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] = {
.module = PERIPH_TIMG1_MODULE,
.timer_irq_id = {
[0] = ETS_TG1_T0_INTR_SOURCE,
}
}
}
};
#if SOC_PAU_SUPPORTED && SOC_TIMER_SUPPORT_SLEEP_RETENTION
/* Registers in retention context:
* TIMG_T0CONFIG_REG
* TIMG_T0ALARMLO_REG
* TIMG_T0ALARMHI_REG
* TIMG_T0LOADLO_REG
* TIMG_T0LOADHI_REG
* TIMG_INT_ENA_TIMERS_REG
* TIMG_REGCLK_REG
*/
#define TG_TIMER_RETENTION_REGS_CNT 7
static const uint32_t tg_timer_regs_map[4] = {0x100000f1, 0x80000000, 0x0, 0x0};
const regdma_entries_config_t tg0_timer_regdma_entries[] = {
// backup stage: trigger a soft capture
[0] = {
.config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x00),
TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1),
.owner = ENTRY(0) | ENTRY(2)
},
// backup stage: wait for the capture done
[1] = {
.config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x01),
TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1),
.owner = ENTRY(0) | ENTRY(2)
},
// backup stage: save the captured counter value
// restore stage: store the captured counter value to the loader register
[2] = {
.config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x02),
TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0),
.owner = ENTRY(0) | ENTRY(2)
},
// restore stage: trigger a soft reload, so the timer can continue from where it was backed up
[3] = {
.config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x03),
TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0),
.owner = ENTRY(0) | ENTRY(2)
},
// backup stage: save other configuration and status registers
// restore stage: restore the configuration and status registers
[4] = {
.config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG0_TIMER_LINK(0x04),
TIMG_T0CONFIG_REG(0), TIMG_T0CONFIG_REG(0),
TG_TIMER_RETENTION_REGS_CNT, 0, 0,
tg_timer_regs_map[0], tg_timer_regs_map[1],
tg_timer_regs_map[2], tg_timer_regs_map[3]),
.owner = ENTRY(0) | ENTRY(2)
},
};
const regdma_entries_config_t tg1_timer_regdma_entries[] = {
// backup stage: trigger a soft capture
[0] = {
.config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x00),
TIMG_T0UPDATE_REG(1), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1),
.owner = ENTRY(0) | ENTRY(2)
},
// backup stage: wait for the capture done
[1] = {
.config = REGDMA_LINK_WAIT_INIT(REGDMA_TG1_TIMER_LINK(0x01),
TIMG_T0UPDATE_REG(1), 0x0, TIMG_T0_UPDATE_M, 0, 1),
.owner = ENTRY(0) | ENTRY(2)
},
// backup stage: save the captured counter value
// restore stage: store the captured counter value to the loader register
[2] = {
.config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x02),
TIMG_T0LO_REG(1), TIMG_T0LOADLO_REG(1), 2, 0, 0),
.owner = ENTRY(0) | ENTRY(2)
},
// restore stage: trigger a soft reload, so the timer can continue from where it was backed up
[3] = {
.config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x03),
TIMG_T0LOAD_REG(1), 0x1, TIMG_T0_LOAD_M, 1, 0),
.owner = ENTRY(0) | ENTRY(2)
},
// backup stage: save other configuration and status registers
// restore stage: restore the configuration and status registers
[4] = {
.config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG1_TIMER_LINK(0x04),
TIMG_T0CONFIG_REG(1), TIMG_T0CONFIG_REG(1),
TG_TIMER_RETENTION_REGS_CNT, 0, 0,
tg_timer_regs_map[0], tg_timer_regs_map[1],
tg_timer_regs_map[2], tg_timer_regs_map[3]),
.owner = ENTRY(0) | ENTRY(2)
},
};
const tg_timer_reg_retention_info_t tg_timer_reg_retention_info[SOC_TIMER_GROUPS][SOC_TIMER_GROUP_TIMERS_PER_GROUP] = {
[0] = {
[0] = {
.module = SLEEP_RETENTION_MODULE_TG0_TIMER0,
.regdma_entry_array = tg0_timer_regdma_entries,
.array_size = ARRAY_SIZE(tg0_timer_regdma_entries)
}
},
[1] = {
[0] = {
.module = SLEEP_RETENTION_MODULE_TG1_TIMER0,
.regdma_entry_array = tg1_timer_regdma_entries,
.array_size = ARRAY_SIZE(tg1_timer_regdma_entries)
}
},
};
#endif //SOC_PAU_SUPPORTED && SOC_TIMER_SUPPORT_SLEEP_RETENTION

View File

@ -13,9 +13,9 @@
#include "soc/periph_defs.h"
#include "soc/regdma.h"
#if SOC_TIMER_SUPPORT_SLEEP_RETENTION
#if SOC_PAU_SUPPORTED
#include "soc/retention_periph_defs.h"
#endif // SOC_TIMER_SUPPORT_SLEEP_RETENTION
#endif // SOC_PAU_SUPPORTED
#ifdef __cplusplus
extern "C" {
@ -30,7 +30,7 @@ typedef struct {
extern const timer_group_signal_conn_t timer_group_periph_signals;
#if SOC_TIMER_SUPPORT_SLEEP_RETENTION
#if SOC_PAU_SUPPORTED && SOC_TIMER_SUPPORT_SLEEP_RETENTION
typedef struct {
const periph_retention_module_t module;
const regdma_entries_config_t *regdma_entry_array;

View File

@ -172,7 +172,6 @@ api-reference/peripherals/cap_touch_sens.rst
api-reference/peripherals/index.rst
api-reference/peripherals/rmt.rst
api-reference/peripherals/ds.rst
api-reference/peripherals/gptimer.rst
api-reference/peripherals/sdio_slave.rst
api-reference/peripherals/bitscrambler.rst
api-reference/peripherals/temp_sensor.rst

View File

@ -439,7 +439,7 @@ examples/peripherals/timer_group/gptimer:
examples/peripherals/timer_group/gptimer_capture_hc_sr04:
disable:
- if: SOC_GPTIMER_SUPPORTED != 1 or SOC_TIMER_SUPPORT_ETM != 1
- if: SOC_ETM_SUPPORTED != 1 or SOC_TIMER_SUPPORT_ETM != 1
depends_components:
- esp_driver_gptimer

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- |
# Example: General Purpose Timer

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- |
# Wiegand Interface Example

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- |
# Example: Application Level Tracing - SystemView Tracing (sysview_tracing)
This test code shows how to perform system-wide behavioral analysis of the program using [SEGGER SystemView tool](https://www.segger.com/products/development-tools/systemview/).

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- |
# SystemView Heap and Log Tracing Example