feat(gptimer): support gptimer on esp32h4

This commit is contained in:
Chen Jichang
2025-04-01 15:32:16 +08:00
parent 1e30aa74b5
commit faacaaaf8f
21 changed files with 307 additions and 177 deletions

View File

@@ -1,2 +1,2 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | 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-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- |

View File

@@ -27,23 +27,22 @@ uint32_t *freq_value)
uint32_t clk_src_freq = 0;
switch (clk_src) {
case SOC_MOD_CLK_XTAL:
clk_src_freq = 32 * MHZ;
clk_src_freq = SOC_XTAL_FREQ_32M * MHZ;
break;
case SOC_MOD_CLK_PLL_F80M:
clk_src_freq = CLK_LL_PLL_80M_FREQ_MHZ * MHZ;
case SOC_MOD_CLK_PLL_F48M:
clk_src_freq = CLK_LL_PLL_48M_FREQ_MHZ * MHZ;
break;
case SOC_MOD_CLK_PLL_F160M:
clk_src_freq = CLK_LL_PLL_160M_FREQ_MHZ * MHZ;
case SOC_MOD_CLK_PLL_F64M:
clk_src_freq = CLK_LL_PLL_64M_FREQ_MHZ * MHZ;
break;
case SOC_MOD_CLK_PLL_F240M:
clk_src_freq = CLK_LL_PLL_240M_FREQ_MHZ * MHZ;
case SOC_MOD_CLK_PLL_F96M:
clk_src_freq = CLK_LL_PLL_96M_FREQ_MHZ * MHZ;
break;
default:
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

@@ -23,7 +23,7 @@
static const char *TAG = "rtc_clk";
// Current PLL frequency, in 480MHz. Zero if PLL is not enabled.
// Current PLL frequency, in 96MHz. Zero if PLL is not enabled.
static int s_cur_pll_freq;
static uint32_t s_bbpll_digi_consumers_ref_count = 0; // Currently, it only tracks whether the 48MHz PHY clock is in-use by USB Serial/JTAG
@@ -57,7 +57,7 @@ void rtc_clk_32k_enable_external(void)
void rtc_clk_32k_bootstrap(uint32_t cycle)
{
/* No special bootstrapping needed for ESP32-C6, 'cycle' argument is to keep the signature
/* No special bootstrapping needed for ESP32-H4, 'cycle' argument is to keep the signature
* same as for the ESP32. Just enable the XTAL here.
*/
(void)cycle;
@@ -183,7 +183,7 @@ static void rtc_clk_cpu_freq_to_8m(void)
*/
static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
{
clk_ll_cpu_set_hs_divider(CLK_LL_PLL_480M_FREQ_MHZ / cpu_freq_mhz);
clk_ll_cpu_set_hs_divider(CLK_LL_PLL_96M_FREQ_MHZ / cpu_freq_mhz);
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL);
esp_rom_set_cpu_ticks_per_us(cpu_freq_mhz);
}
@@ -206,20 +206,20 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *ou
source_freq_mhz = xtal_freq;
source = SOC_CPU_CLK_SRC_XTAL;
} else if (freq_mhz == 80) {
} else if (freq_mhz == 16) {
real_freq_mhz = freq_mhz;
source = SOC_CPU_CLK_SRC_PLL;
source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ;
source_freq_mhz = CLK_LL_PLL_96M_FREQ_MHZ;
divider = 6;
} else if (freq_mhz == 120) {
} else if (freq_mhz == 24) {
real_freq_mhz = freq_mhz;
source = SOC_CPU_CLK_SRC_PLL;
source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ;
source_freq_mhz = CLK_LL_PLL_96M_FREQ_MHZ;
divider = 4;
} else if (freq_mhz == 160) {
} else if (freq_mhz == 32) {
real_freq_mhz = freq_mhz;
source = SOC_CPU_CLK_SRC_PLL;
source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ;
source_freq_mhz = CLK_LL_PLL_96M_FREQ_MHZ;
divider = 3;
} else {
// unsupported frequency

View File

@@ -1,6 +1,6 @@
choice ESP_DEFAULT_CPU_FREQ_MHZ
prompt "CPU frequency"
default ESP_DEFAULT_CPU_FREQ_MHZ_64 if IDF_ENV_FPGA
default ESP_DEFAULT_CPU_FREQ_MHZ_32 if IDF_ENV_FPGA
help
CPU frequency to be set on application startup.

View File

@@ -27,12 +27,10 @@ extern "C" {
#define MHZ (1000000)
#define CLK_LL_PLL_80M_FREQ_MHZ (80)
#define CLK_LL_PLL_120M_FREQ_MHZ (120)
#define CLK_LL_PLL_160M_FREQ_MHZ (160)
#define CLK_LL_PLL_240M_FREQ_MHZ (240)
#define CLK_LL_PLL_480M_FREQ_MHZ (480)
#define CLK_LL_PLL_8M_FREQ_MHZ (8)
#define CLK_LL_PLL_48M_FREQ_MHZ (48)
#define CLK_LL_PLL_64M_FREQ_MHZ (64)
#define CLK_LL_PLL_96M_FREQ_MHZ (96)
#define CLK_LL_XTAL32K_CONFIG_DEFAULT() { \
.dac = 3, \
@@ -273,8 +271,8 @@ static inline __attribute__((always_inline)) bool clk_ll_rc32k_digi_is_enabled(v
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_bbpll_get_freq_mhz(void)
{
// The target has a fixed 480MHz SPLL
return CLK_LL_PLL_480M_FREQ_MHZ;
// The target has a fixed 96MHz SPLL
return CLK_LL_PLL_96M_FREQ_MHZ;
}
/**
@@ -284,9 +282,9 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_bbpll_get_freq_mhz(
*/
static inline __attribute__((always_inline)) void clk_ll_bbpll_set_freq_mhz(uint32_t pll_freq_mhz)
{
// The target SPLL is fixed to 480MHz
// The target SPLL is fixed to 96MHz
// Do nothing
HAL_ASSERT(pll_freq_mhz == CLK_LL_PLL_480M_FREQ_MHZ);
HAL_ASSERT(pll_freq_mhz == CLK_LL_PLL_96M_FREQ_MHZ);
}
/**
@@ -297,7 +295,7 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_set_freq_mhz(uint
*/
static inline __attribute__((always_inline)) void clk_ll_bbpll_set_config(uint32_t pll_freq_mhz, uint32_t xtal_freq_mhz)
{
HAL_ASSERT(pll_freq_mhz == CLK_LL_PLL_480M_FREQ_MHZ);
HAL_ASSERT(pll_freq_mhz == CLK_LL_PLL_96M_FREQ_MHZ);
uint8_t div_ref;
uint8_t div7_0;
uint8_t dr1;

View File

@@ -515,7 +515,7 @@ static inline void gpio_ll_iomux_set_clk_src(soc_module_clk_t src)
case SOC_MOD_CLK_XTAL:
PCR.iomux_clk_conf.iomux_func_clk_sel = 3;
break;
case SOC_MOD_CLK_PLL_F80M:
case SOC_MOD_CLK_PLL_F48M:
PCR.iomux_clk_conf.iomux_func_clk_sel = 1;
break;
default:

View File

@@ -286,7 +286,7 @@ FORCE_INLINE_ATTR void mwdt_ll_set_clock_source(timg_dev_t *hw, mwdt_clock_sourc
case MWDT_CLK_SRC_XTAL:
clk_id = 0;
break;
case MWDT_CLK_SRC_PLL_F80M:
case MWDT_CLK_SRC_PLL_F48M:
clk_id = 1;
break;
case MWDT_CLK_SRC_RC_FAST:

View File

@@ -4,7 +4,8 @@
* SPDX-License-Identifier: Apache-2.0
*/
// Note that most of the register operations in this layer are non-atomic operations.
// Attention: Timer Group has 3 independent functions: General Purpose Timer, Watchdog Timer and Clock calibration.
// This Low Level driver only serve the General Purpose Timer function.
#pragma once
@@ -16,8 +17,6 @@
#include "soc/pcr_struct.h"
#include "soc/soc_etm_source.h"
//TODO: [ESP32H4] IDF-12373 inherited from verification branch, need check
#ifdef __cplusplus
extern "C" {
#endif
@@ -26,30 +25,30 @@ extern "C" {
#define TIMER_LL_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1))
#define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id))
#define TIMER_LL_ETM_TASK_TABLE(group, timer, task) \
(uint32_t [2][1][GPTIMER_ETM_TASK_MAX]){{{ \
[GPTIMER_ETM_TASK_START_COUNT] = TIMER0_TASK_CNT_START_TIMER0, \
[GPTIMER_ETM_TASK_STOP_COUNT] = TIMER0_TASK_CNT_STOP_TIMER0, \
[GPTIMER_ETM_TASK_EN_ALARM] = TIMER0_TASK_ALARM_START_TIMER0, \
[GPTIMER_ETM_TASK_RELOAD] = TIMER0_TASK_CNT_RELOAD_TIMER0, \
[GPTIMER_ETM_TASK_CAPTURE] = TIMER0_TASK_CNT_CAP_TIMER0, \
}}, \
{{ \
[GPTIMER_ETM_TASK_START_COUNT] = TIMER1_TASK_CNT_START_TIMER0, \
[GPTIMER_ETM_TASK_STOP_COUNT] = TIMER1_TASK_CNT_STOP_TIMER0, \
[GPTIMER_ETM_TASK_EN_ALARM] = TIMER1_TASK_ALARM_START_TIMER0, \
[GPTIMER_ETM_TASK_RELOAD] = TIMER1_TASK_CNT_RELOAD_TIMER0, \
[GPTIMER_ETM_TASK_CAPTURE] = TIMER1_TASK_CNT_CAP_TIMER0, \
}}, \
#define TIMER_LL_ETM_TASK_TABLE(group, timer, task) \
(uint32_t [2][1][GPTIMER_ETM_TASK_MAX]){{{ \
[GPTIMER_ETM_TASK_START_COUNT] = TG0_TASK_CNT_START_TIMER0, \
[GPTIMER_ETM_TASK_STOP_COUNT] = TG0_TASK_CNT_STOP_TIMER0, \
[GPTIMER_ETM_TASK_EN_ALARM] = TG0_TASK_ALARM_START_TIMER0, \
[GPTIMER_ETM_TASK_RELOAD] = TG0_TASK_CNT_RELOAD_TIMER0, \
[GPTIMER_ETM_TASK_CAPTURE] = TG0_TASK_CNT_CAP_TIMER0, \
}}, \
{{ \
[GPTIMER_ETM_TASK_START_COUNT] = TG1_TASK_CNT_START_TIMER0, \
[GPTIMER_ETM_TASK_STOP_COUNT] = TG1_TASK_CNT_STOP_TIMER0, \
[GPTIMER_ETM_TASK_EN_ALARM] = TG1_TASK_ALARM_START_TIMER0, \
[GPTIMER_ETM_TASK_RELOAD] = TG1_TASK_CNT_RELOAD_TIMER0, \
[GPTIMER_ETM_TASK_CAPTURE] = TG1_TASK_CNT_CAP_TIMER0, \
}}, \
}[group][timer][task]
#define TIMER_LL_ETM_EVENT_TABLE(group, timer, event) \
(uint32_t [2][1][GPTIMER_ETM_EVENT_MAX]){{{ \
[GPTIMER_ETM_EVENT_ALARM_MATCH] = TIMER0_EVT_CNT_CMP_TIMER0, \
}}, \
{{ \
[GPTIMER_ETM_EVENT_ALARM_MATCH] = TIMER1_EVT_CNT_CMP_TIMER0, \
}}, \
#define TIMER_LL_ETM_EVENT_TABLE(group, timer, event) \
(uint32_t [2][1][GPTIMER_ETM_EVENT_MAX]){{{ \
[GPTIMER_ETM_EVENT_ALARM_MATCH] = TG0_EVT_CNT_CMP_TIMER0, \
}}, \
{{ \
[GPTIMER_ETM_EVENT_ALARM_MATCH] = TG1_EVT_CNT_CMP_TIMER0, \
}}, \
}[group][timer][event]
/**
@@ -58,7 +57,7 @@ extern "C" {
* @param group_id Group ID
* @param enable true to enable, false to disable
*/
static inline void timer_ll_enable_bus_clock(int group_id, bool enable)
static inline void _timer_ll_enable_bus_clock(int group_id, bool enable)
{
if (group_id == 0) {
PCR.timergroup0_conf.tg0_clk_en = enable;
@@ -69,7 +68,7 @@ static inline void timer_ll_enable_bus_clock(int group_id, bool enable)
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance
#define timer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; timer_ll_enable_bus_clock(__VA_ARGS__)
#define timer_ll_enable_bus_clock(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; _timer_ll_enable_bus_clock(__VA_ARGS__)
/**
* @brief Reset the timer group module
@@ -80,7 +79,7 @@ static inline void timer_ll_enable_bus_clock(int group_id, bool enable)
*
* @param group_id Group ID
*/
static inline void timer_ll_reset_register(int group_id)
static inline void _timer_ll_reset_register(int group_id)
{
if (group_id == 0) {
PCR.timergroup0_conf.tg0_rst_en = 1;
@@ -95,7 +94,7 @@ static inline void timer_ll_reset_register(int group_id)
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance
#define timer_ll_reset_register(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; timer_ll_reset_register(__VA_ARGS__)
#define timer_ll_reset_register(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; _timer_ll_reset_register(__VA_ARGS__)
/**
* @brief Set clock source for timer
@@ -106,28 +105,27 @@ 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;
// switch (clk_src) {
// case GPTIMER_CLK_SRC_XTAL:
// clk_id = 0;
// break;
// case GPTIMER_CLK_SRC_PLL_F80M:
// clk_id = 1;
// break;
// case GPTIMER_CLK_SRC_RC_FAST:
// clk_id = 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;
// }
abort();
(void)timer_num; // only one timer in each group
uint8_t clk_id = 0;
switch (clk_src) {
case GPTIMER_CLK_SRC_XTAL:
clk_id = 0;
break;
case GPTIMER_CLK_SRC_RC_FAST:
clk_id = 1;
break;
case GPTIMER_CLK_SRC_PLL_F48M:
clk_id = 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;
}
}
/**
@@ -139,13 +137,12 @@ 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;
// }
abort();
(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;
}
}
/**
@@ -159,8 +156,7 @@ static inline void timer_ll_enable_clock(timg_dev_t *hw, uint32_t timer_num, boo
__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;
abort();
hw->hw_timer[timer_num].config.tx_alarm_en = en;
}
/**
@@ -172,13 +168,12 @@ static inline void timer_ll_enable_alarm(timg_dev_t *hw, uint32_t timer_num, boo
*/
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;
abort();
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;
}
/**
@@ -192,8 +187,7 @@ static inline void timer_ll_set_clock_prescale(timg_dev_t *hw, uint32_t timer_nu
__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;
abort();
hw->hw_timer[timer_num].config.tx_autoreload = en;
}
/**
@@ -205,8 +199,7 @@ static inline void timer_ll_enable_auto_reload(timg_dev_t *hw, uint32_t timer_nu
*/
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);
abort();
hw->hw_timer[timer_num].config.tx_increase = (direction == GPTIMER_COUNT_UP);
}
/**
@@ -220,8 +213,7 @@ static inline void timer_ll_set_count_direction(timg_dev_t *hw, uint32_t timer_n
__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;
abort();
hw->hw_timer[timer_num].config.tx_en = en;
}
/**
@@ -233,12 +225,11 @@ static inline void timer_ll_enable_counter(timg_dev_t *hw, uint32_t timer_num, b
__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) {
// }
abort();
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) {
}
}
/**
@@ -252,8 +243,7 @@ static inline void timer_ll_trigger_soft_capture(timg_dev_t *hw, uint32_t timer_
__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);
abort();
return ((uint64_t)hw->hw_timer[timer_num].hi.tx_hi << 32) | (hw->hw_timer[timer_num].lo.tx_lo);
}
/**
@@ -266,9 +256,8 @@ static inline uint64_t timer_ll_get_counter_value(timg_dev_t *hw, uint32_t timer
__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;
abort();
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;
}
/**
@@ -281,9 +270,8 @@ static inline void timer_ll_set_alarm_value(timg_dev_t *hw, uint32_t timer_num,
__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;
abort();
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;
}
/**
@@ -296,8 +284,7 @@ static inline void timer_ll_set_reload_value(timg_dev_t *hw, uint32_t timer_num,
__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);
abort();
return ((uint64_t)hw->hw_timer[timer_num].loadhi.tx_load_hi << 32) | (hw->hw_timer[timer_num].loadlo.tx_load_lo);
}
/**
@@ -309,8 +296,7 @@ static inline uint64_t timer_ll_get_reload_value(timg_dev_t *hw, uint32_t timer_
__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;
abort();
hw->hw_timer[timer_num].load.tx_load = 1;
}
/**
@@ -321,8 +307,7 @@ static inline void timer_ll_trigger_soft_reload(timg_dev_t *hw, uint32_t timer_n
*/
static inline void timer_ll_enable_etm(timg_dev_t *hw, bool en)
{
// hw->regclk.etm_en = en;
abort();
hw->regclk.etm_en = en;
}
/**

View File

@@ -212,7 +212,7 @@ FORCE_INLINE_ATTR void uart_ll_set_sclk(uart_dev_t *hw, soc_module_clk_t source_
{
uint32_t sel_value = 0;
switch (source_clk) {
case UART_SCLK_PLL_F80M:
case UART_SCLK_PLL_F48M:
sel_value = 2;
break;
case UART_SCLK_RTC:
@@ -241,7 +241,7 @@ FORCE_INLINE_ATTR void uart_ll_get_sclk(uart_dev_t *hw, soc_module_clk_t *source
switch (UART_LL_PCR_REG_GET(hw, sclk_conf, sclk_sel)) {
default:
case 2:
*source_clk = (soc_module_clk_t)UART_SCLK_PLL_F80M;
*source_clk = (soc_module_clk_t)UART_SCLK_PLL_F48M;
break;
case 1:
*source_clk = (soc_module_clk_t)UART_SCLK_RTC;

View File

@@ -123,7 +123,7 @@ typedef enum {
// For RTC domain
SOC_MOD_CLK_RTC_FAST, /*!< RTC_FAST_CLK can be sourced from XTAL_D2, RC_FAST, or LP_PLL by configuring soc_rtc_fast_clk_src_t */
SOC_MOD_CLK_RTC_SLOW, /*!< RTC_SLOW_CLK can be sourced from RC_SLOW, XTAL32K, OSC_SLOW, or RC32K by configuring soc_rtc_slow_clk_src_t */
// For digital domain: peripherals, WIFI, BLE
// For digital domain: peripherals, BLE
SOC_MOD_CLK_PLL_F48M, /*!< PLL_F48M_CLK is derived from PLL (clock gating + fixed divider of 2), it has a fixed frequency of 48MHz */
SOC_MOD_CLK_PLL_F64M, /*!< PLL_F64M_CLK is derived from FLASH_PLL (clock gating), it has a fixed frequency of 64MHz */
SOC_MOD_CLK_PLL_F96M, /*!< PLL_F96M_CLK is derived from PLL (clock gating), it has a fixed frequency of 96MHz */

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
@@ -291,6 +295,10 @@ config SOC_TIMER_GROUP_TOTAL_TIMERS
int
default 2
config SOC_TIMER_SUPPORT_SLEEP_RETENTION
bool
default y
config SOC_MWDT_SUPPORT_XTAL
bool
default y

View File

@@ -19,7 +19,7 @@ extern "C" {
*
* The exact frequency of RC_FAST_CLK can be computed in runtime through calibration.
*
* 2) External 40MHz Crystal Clock: XTAL
* 2) External 32MHz Crystal Clock: XTAL
*
* 3) Internal 136kHz RC Oscillator: RC_SLOW (may also referred as SOSC in TRM or reg. description)
*
@@ -62,7 +62,7 @@ extern "C" {
typedef enum {
SOC_ROOT_CLK_INT_RC_FAST, /*!< Internal 17.5MHz RC oscillator */
SOC_ROOT_CLK_INT_RC_SLOW, /*!< Internal 136kHz RC oscillator */
SOC_ROOT_CLK_EXT_XTAL, /*!< External 40MHz crystal */
SOC_ROOT_CLK_EXT_XTAL, /*!< External 32MHz crystal */
SOC_ROOT_CLK_EXT_XTAL32K, /*!< External 32kHz crystal */
SOC_ROOT_CLK_INT_RC32K, /*!< Internal 32kHz RC oscillator */
SOC_ROOT_CLK_EXT_OSC_SLOW, /*!< External slow clock signal at pin0 */
@@ -74,7 +74,7 @@ typedef enum {
*/
typedef enum {
SOC_CPU_CLK_SRC_XTAL = 0, /*!< Select XTAL_CLK as CPU_CLK source */
SOC_CPU_CLK_SRC_PLL = 1, /*!< Select PLL_CLK as CPU_CLK source (PLL_CLK is the output of 40MHz crystal oscillator frequency multiplier, 480MHz) */
SOC_CPU_CLK_SRC_PLL = 1, /*!< Select PLL_CLK as CPU_CLK source (PLL_CLK is the output of 32MHz crystal oscillator frequency multiplier, 96MHz) */
SOC_CPU_CLK_SRC_RC_FAST = 2, /*!< Select RC_FAST_CLK as CPU_CLK source */
SOC_CPU_CLK_SRC_INVALID, /*!< Invalid CPU_CLK source */
} soc_cpu_clk_src_t;
@@ -128,15 +128,15 @@ typedef enum {
// For RTC domain
SOC_MOD_CLK_RTC_FAST, /*!< RTC_FAST_CLK can be sourced from XTAL_D2 or RC_FAST by configuring soc_rtc_fast_clk_src_t */
SOC_MOD_CLK_RTC_SLOW, /*!< RTC_SLOW_CLK can be sourced from RC_SLOW, XTAL32K, RC32K, or OSC_SLOW by configuring soc_rtc_slow_clk_src_t */
// For digital domain: peripherals, WIFI, BLE
SOC_MOD_CLK_PLL_F80M, /*!< PLL_F80M_CLK is derived from PLL (clock gating + fixed divider of 6), it has a fixed frequency of 80MHz */
SOC_MOD_CLK_PLL_F160M, /*!< PLL_F160M_CLK is derived from PLL (clock gating + fixed divider of 3), it has a fixed frequency of 160MHz */
SOC_MOD_CLK_PLL_F240M, /*!< PLL_F240M_CLK is derived from PLL (clock gating + fixed divider of 2), it has a fixed frequency of 240MHz */
// For digital domain: peripherals, BLE
SOC_MOD_CLK_PLL_F48M, /*!< PLL_F48M_CLK is derived from PLL (clock gating + fixed divider of 2), it has a fixed frequency of 48MHz */
SOC_MOD_CLK_PLL_F64M, /*!< PLL_F64M_CLK is derived from FLASH_PLL (clock gating), it has a fixed frequency of 64MHz */
SOC_MOD_CLK_PLL_F96M, /*!< PLL_F96M_CLK is derived from PLL (clock gating), it has a fixed frequency of 96MHz */
SOC_MOD_CLK_XTAL32K, /*!< XTAL32K_CLK comes from the external 32kHz crystal, passing a clock gating to the peripherals */
SOC_MOD_CLK_RC_FAST, /*!< RC_FAST_CLK comes from the internal 20MHz rc oscillator, passing a clock gating to the peripherals */
SOC_MOD_CLK_XTAL, /*!< XTAL_CLK comes from the external 40MHz crystal */
SOC_MOD_CLK_XTAL, /*!< XTAL_CLK comes from the external 32MHz crystal */
// For LP peripherals
SOC_MOD_CLK_XTAL_D2, /*!< XTAL_D2_CLK comes from the external 40MHz crystal, passing a div of 2 to the LP peripherals */
SOC_MOD_CLK_XTAL_D2, /*!< XTAL_D2_CLK comes from the external 32MHz crystal, passing a div of 2 to the LP peripherals */
SOC_MOD_CLK_INVALID, /*!< Indication of the end of the available module clock sources */
} soc_module_clk_t;
@@ -166,25 +166,33 @@ typedef enum {
* }
* @endcode
*/
#define SOC_GPTIMER_CLKS {SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_XTAL}
#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
*/
typedef enum {
GPTIMER_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the source clock */
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 */
GPTIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the default choice */
#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;
/**
* @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_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_F80M, /*!< Timer group clock source default choice is PLL_F80M */
TIMER_SRC_CLK_DEFAULT = SOC_MOD_CLK_PLL_F48M, /*!< Timer group clock source default choice is PLL_F48M */
} soc_periph_tg_clk_src_legacy_t;
///////////////////////////////////////////////////UART/////////////////////////////////////////////////////////////////
@@ -193,10 +201,10 @@ typedef enum {
* @brief Type of UART clock source, reserved for the legacy UART driver
*/
typedef enum {
UART_SCLK_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< UART source clock is PLL_F80M */
UART_SCLK_PLL_F48M = SOC_MOD_CLK_PLL_F48M, /*!< UART source clock is PLL_F48M */
UART_SCLK_RTC = SOC_MOD_CLK_RC_FAST, /*!< UART source clock is RC_FAST */
UART_SCLK_XTAL = SOC_MOD_CLK_XTAL, /*!< UART source clock is XTAL */
UART_SCLK_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< UART source clock default choice is PLL_F80M */
UART_SCLK_DEFAULT = SOC_MOD_CLK_PLL_F48M, /*!< UART source clock default choice is PLL_F48M */
} soc_periph_uart_clk_src_legacy_t;
/**
@@ -213,14 +221,14 @@ typedef enum {
/**
* @brief Array initializer for all supported clock sources of SPI
*/
#define SOC_SPI_CLKS {SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_XTAL, SOC_MOD_CLK_RC_FAST}
#define SOC_SPI_CLKS {SOC_MOD_CLK_PLL_F48M, SOC_MOD_CLK_XTAL, SOC_MOD_CLK_RC_FAST}
/**
* @brief Type of SPI clock source.
*/
typedef enum {
SPI_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_80M as SPI source clock */
SPI_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_80M as SPI source clock */
SPI_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F48M, /*!< Select PLL_48M as SPI source clock */
SPI_CLK_SRC_PLL_F48M = SOC_MOD_CLK_PLL_F48M, /*!< Select PLL_48M as SPI source clock */
SPI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as SPI source clock */
SPI_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as SPI source clock */
} soc_periph_spi_clk_src_t;
@@ -230,16 +238,16 @@ typedef enum {
/**
* @brief Array initializer for all supported clock sources of MWDT
*/
#define SOC_MWDT_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_RC_FAST}
#define SOC_MWDT_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_PLL_F48M, SOC_MOD_CLK_RC_FAST}
/**
* @brief MWDT clock source
*/
typedef enum {
MWDT_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
MWDT_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL fixed 80 MHz as the source clock */
MWDT_CLK_SRC_PLL_F48M = SOC_MOD_CLK_PLL_F48M, /*!< Select PLL fixed 48MHz as the source clock */
MWDT_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RTC fast as the source clock */
MWDT_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select PLL fixed 80 MHz as the default clock choice */
MWDT_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select PLL fixed 48MHz as the default clock choice */
} soc_periph_mwdt_clk_src_t;
//////////////////////////////////////////////////FLASH///////////////////////////////////////////////////////////////////

View File

@@ -31,7 +31,7 @@
#define SOC_UART_SUPPORTED 1 // TODO: [ESP32H4] IDF-12398
// #define SOC_GDMA_SUPPORTED 1 // TODO: [ESP32H4] IDF-12382
// #define SOC_AHB_GDMA_SUPPORTED 1 // TODO: [ESP32H4] IDF-12382
// #define SOC_GPTIMER_SUPPORTED 1 // TODO: [ESP32H4] IDF-12373
#define SOC_GPTIMER_SUPPORTED 1
// #define SOC_PCNT_SUPPORTED 1 // TODO: [ESP32H4] IDF-12338
// #define SOC_MCPWM_SUPPORTED 1 // TODO: [ESP32H4] IDF-12380
// #define SOC_TWAI_SUPPORTED 1 // TODO: [ESP32H4] IDF-12352
@@ -435,7 +435,8 @@
#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_ETM (1) // TODO: [ESP32H4] IDF-12355
#define SOC_TIMER_SUPPORT_SLEEP_RETENTION (1)
/*--------------------------- WATCHDOG CAPS ---------------------------------------*/
#define SOC_MWDT_SUPPORT_XTAL (1)
@@ -528,7 +529,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 (1) // TODO: [ESP32H4] IDF-12285
#define SOC_MODEM_CLOCK_IS_INDEPENDENT (1)
#define SOC_CLK_XTAL32K_SUPPORTED (1) /*!< Support to connect an external low frequency crystal */

View File

@@ -54,7 +54,7 @@ typedef union {
* Configures the clock source of UART0.
* 0 (default): XTAL_CLK
* 1: RC_FAST_CLK
* 2: PLL_F80M_CLK
* 2: PLL_F48M_CLK
*/
uint32_t uart0_sclk_sel:2;
/** uart0_sclk_en : R/W; bitpos: [22]; default: 1;
@@ -135,7 +135,7 @@ typedef union {
* Configures the clock source of UART1.
* 0 (default): XTAL_CLK
* 1: RC_FAST_CLK
* 2: PLL_F80M_CLK
* 2: PLL_F48M_CLK
*/
uint32_t uart1_sclk_sel:2;
/** uart1_sclk_en : R/W; bitpos: [22]; default: 1;
@@ -214,7 +214,7 @@ typedef union {
* Configures the clock source for MSPI.
* 0(default): XTAL_CLK
* 1 RC_FAST_CLK
* 2: PLL_F480M_CLK
* 2: PLL_F96M_CLK
*/
uint32_t mspi_func_clk_sel:2;
/** mspi_func_clk_en : R/W; bitpos: [10]; default: 1;
@@ -412,7 +412,7 @@ typedef union {
* Configures the clock source of RMT.
* 0: XTAL_CLK
* 1 (default): RC_FAST_CLK
* 2: PLL_F80M_CLK
* 2: PLL_F48M_CLK
*/
uint32_t rmt_sclk_sel:1;
/** rmt_sclk_en : R/W; bitpos: [21]; default: 0;
@@ -482,7 +482,7 @@ typedef union {
* Configures the clock source of LEDC.
* 0 (default): XTAL_CLK
* 1: RC_FAST_CLK
* 2: PLL_F80M_CLK
* 2: PLL_F48M_CLK
*/
uint32_t ledc_sclk_sel:2;
/** ledc_sclk_en : R/W; bitpos: [22]; default: 0;
@@ -534,7 +534,7 @@ typedef union {
* Configures the clock source of general-purpose timers in Timer Group 0.
* 0 (default): XTAL_CLK
* 1: RC_FAST_CLK
* 2: PLL_F80M_CLK
* 2: PLL_F48M_CLK
*/
uint32_t tg0_timer_clk_sel:2;
/** tg0_timer_clk_en : R/W; bitpos: [22]; default: 1;
@@ -556,7 +556,7 @@ typedef union {
* Configures the clock source of WDT in Timer Group 0.
* 0 (default): XTAL_CLK
* 1: RC_FAST_CLK
* 2: PLL_F80M_CLK
* 2: PLL_F48M_CLK
*/
uint32_t tg0_wdt_clk_sel:2;
/** tg0_wdt_clk_en : R/W; bitpos: [22]; default: 1;
@@ -608,7 +608,7 @@ typedef union {
* Configures the clock source of general-purpose timers in Timer Group 1.
* 0 (default): XTAL_CLK
* 1: RC_FAST_CLK
* 2: PLL_F80M_CLK
* 2: PLL_F48M_CLK
*/
uint32_t tg1_timer_clk_sel:2;
/** tg1_timer_clk_en : R/W; bitpos: [22]; default: 1;
@@ -630,7 +630,7 @@ typedef union {
* Configures the clock source of WDT in Timer Group 1.
* 0 (default): XTAL_CLK
* 1: RC_FAST_CLK
* 2: PLL_F80M_CLK
* 2: PLL_F48M_CLK
*/
uint32_t tg1_wdt_clk_sel:2;
/** tg1_wdt_clk_en : R/W; bitpos: [22]; default: 1;
@@ -1482,7 +1482,7 @@ typedef union {
* Configures the clock source of IO MUX.
* 0 (default): XTAL_CLK
* 1: RC_FAST_CLK
* 2: PLL_F80M_CLK
* 2: PLL_F48M_CLK
*/
uint32_t iomux_func_clk_sel:2;
/** iomux_func_clk_en : R/W; bitpos: [22]; default: 1;
@@ -2549,7 +2549,7 @@ typedef union {
* Configures the clock source of ZERO DETECT.
* 0 (default): XTAL_CLK
* 1: RC_FAST_CLK
* 2: PLL_F80M_CLK
* 2: PLL_F48M_CLK
*/
uint32_t zero_det_func_clk_sel:2;
/** zero_det_func_clk_en : R/W; bitpos: [22]; default: 0;

View File

@@ -603,7 +603,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

@@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | 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-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | 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-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | 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-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- |
# SystemView Heap and Log Tracing Example