mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
feat(gptimer): add gptimer support on esp32s31
This commit is contained in:
committed by
Chen Ji Chang
parent
29b865dc07
commit
94eeb84814
@@ -1,2 +1,2 @@
|
||||
| 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 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- |
|
||||
| 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 | ESP32-S31 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | --------- |
|
||||
|
||||
@@ -5,7 +5,7 @@ if(CONFIG_GPTIMER_ISR_CACHE_SAFE)
|
||||
list(APPEND srcs "test_gptimer_iram.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_TIMER_SUPPORT_ETM)
|
||||
if(CONFIG_SOC_TIMER_SUPPORT_ETM AND CONFIG_SOC_ETM_SUPPORTED)
|
||||
list(APPEND srcs "test_gptimer_etm.c")
|
||||
endif()
|
||||
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
#include "soc/pcr_struct.h"
|
||||
#include "soc/soc_etm_source.h"
|
||||
|
||||
// Get timer group register base address with giving group number
|
||||
// Total number of general purpose timers
|
||||
#define TIMER_LL_GPTIMERS_TOTAL (TIMG_LL_INST_NUM * TIMG_LL_GPTIMERS_PER_INST)
|
||||
|
||||
// Get timer group register base address with giving group number
|
||||
#define TIMER_LL_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1))
|
||||
|
||||
// Bit width of GPTIMER counter
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -12,9 +12,13 @@
|
||||
#include "hal/timer_types.h"
|
||||
#include "hal/timg_ll.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "soc/soc_etm_source.h"
|
||||
#include "soc/hp_sys_clkrst_struct.h"
|
||||
|
||||
// Total number of general purpose timers
|
||||
#define TIMER_LL_GPTIMERS_TOTAL (TIMG_LL_INST_NUM * TIMG_LL_GPTIMERS_PER_INST)
|
||||
|
||||
// Get timer group register base address with giving group number
|
||||
#define TIMER_LL_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1))
|
||||
|
||||
// Bit width of GPTIMER counter
|
||||
@@ -25,3 +29,376 @@
|
||||
|
||||
// Support RC_FAST as function clock
|
||||
#define TIMER_LL_FUNC_CLOCK_SUPPORT_RC_FAST 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define TIMER_LL_ETM_TASK_TABLE(group, timer, task) \
|
||||
(uint32_t[2][2][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] = TG0_TASK_CNT_START_TIMER1, \
|
||||
[GPTIMER_ETM_TASK_STOP_COUNT] = TG0_TASK_CNT_STOP_TIMER1, \
|
||||
[GPTIMER_ETM_TASK_EN_ALARM] = TG0_TASK_ALARM_START_TIMER1, \
|
||||
[GPTIMER_ETM_TASK_RELOAD] = TG0_TASK_CNT_RELOAD_TIMER1, \
|
||||
[GPTIMER_ETM_TASK_CAPTURE] = TG0_TASK_CNT_CAP_TIMER1, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
{ \
|
||||
[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, \
|
||||
}, \
|
||||
{ \
|
||||
[GPTIMER_ETM_TASK_START_COUNT] = TG1_TASK_CNT_START_TIMER1, \
|
||||
[GPTIMER_ETM_TASK_STOP_COUNT] = TG1_TASK_CNT_STOP_TIMER1, \
|
||||
[GPTIMER_ETM_TASK_EN_ALARM] = TG1_TASK_ALARM_START_TIMER1, \
|
||||
[GPTIMER_ETM_TASK_RELOAD] = TG1_TASK_CNT_RELOAD_TIMER1, \
|
||||
[GPTIMER_ETM_TASK_CAPTURE] = TG1_TASK_CNT_CAP_TIMER1, \
|
||||
}, \
|
||||
}, \
|
||||
}[group][timer][task]
|
||||
|
||||
#define TIMER_LL_ETM_EVENT_TABLE(group, timer, event) \
|
||||
(uint32_t[2][2][GPTIMER_ETM_EVENT_MAX]){ \
|
||||
{ \
|
||||
{ \
|
||||
[GPTIMER_ETM_EVENT_ALARM_MATCH] = TG0_EVT_CNT_CMP_TIMER0, \
|
||||
}, \
|
||||
{ \
|
||||
[GPTIMER_ETM_EVENT_ALARM_MATCH] = TG0_EVT_CNT_CMP_TIMER1, \
|
||||
}, \
|
||||
}, \
|
||||
{ \
|
||||
{ \
|
||||
[GPTIMER_ETM_EVENT_ALARM_MATCH] = TG1_EVT_CNT_CMP_TIMER0, \
|
||||
}, \
|
||||
{ \
|
||||
[GPTIMER_ETM_EVENT_ALARM_MATCH] = TG1_EVT_CNT_CMP_TIMER1, \
|
||||
}, \
|
||||
}, \
|
||||
}[group][timer][event]
|
||||
|
||||
/**
|
||||
* @brief Set clock source for timer
|
||||
*
|
||||
* @param group_id Group ID
|
||||
* @param timer_num Timer number in the group
|
||||
* @param clk_src Clock source
|
||||
*/
|
||||
static inline void _timer_ll_set_clock_source(int group_id, 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 (group_id == 0) {
|
||||
if (timer_num == 0) {
|
||||
HP_SYS_CLKRST.timergrp0_ctrl0.reg_timergrp0_t0_src_sel = clk_id;
|
||||
} else {
|
||||
HP_SYS_CLKRST.timergrp0_ctrl0.reg_timergrp0_t1_src_sel = clk_id;
|
||||
}
|
||||
} else {
|
||||
if (timer_num == 0) {
|
||||
HP_SYS_CLKRST.timergrp1_ctrl0.reg_timergrp1_t0_src_sel = clk_id;
|
||||
} else {
|
||||
HP_SYS_CLKRST.timergrp1_ctrl0.reg_timergrp1_t1_src_sel = clk_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_ATOMIC_ENV variable in advance
|
||||
#define timer_ll_set_clock_source(...) do { \
|
||||
(void)__DECLARE_RCC_ATOMIC_ENV; \
|
||||
_timer_ll_set_clock_source(__VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* @brief Enable Timer Group (GPTimer) module clock
|
||||
*
|
||||
* @param group_id Group ID
|
||||
* @param timer_num Timer index in the group
|
||||
* @param en true to enable, false to disable
|
||||
*/
|
||||
static inline void _timer_ll_enable_clock(int group_id, uint32_t timer_num, bool en)
|
||||
{
|
||||
if (group_id == 0) {
|
||||
if (timer_num == 0) {
|
||||
HP_SYS_CLKRST.timergrp0_ctrl0.reg_timergrp0_t0_clk_en = en;
|
||||
} else {
|
||||
HP_SYS_CLKRST.timergrp0_ctrl0.reg_timergrp0_t1_clk_en = en;
|
||||
}
|
||||
} else {
|
||||
if (timer_num == 0) {
|
||||
HP_SYS_CLKRST.timergrp1_ctrl0.reg_timergrp1_t0_clk_en = en;
|
||||
} else {
|
||||
HP_SYS_CLKRST.timergrp1_ctrl0.reg_timergrp1_t1_clk_en = en;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||
#define timer_ll_enable_clock(...) do { \
|
||||
(void)__DECLARE_RCC_ATOMIC_ENV; \
|
||||
_timer_ll_enable_clock(__VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* @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 counting
|
||||
*
|
||||
* @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
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "hal/assert.h"
|
||||
#include "hal/misc.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "soc/hp_sys_clkrst_struct.h"
|
||||
|
||||
#define TIMG_LL_GET(_attr) TIMG_LL_ ## _attr
|
||||
|
||||
@@ -19,14 +20,12 @@
|
||||
#define TIMG_LL_INST_NUM 2
|
||||
|
||||
// Number of general purpose timers in each Timer Group
|
||||
#define TIMG_LL_GPTIMERS_PER_INST 1
|
||||
#define TIMG_LL_GPTIMERS_PER_INST 2
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// TODO: ["ESP32S31"] IDF-14745
|
||||
|
||||
/**
|
||||
* @brief Enable the bus clock for timer group module
|
||||
*
|
||||
@@ -35,7 +34,11 @@ extern "C" {
|
||||
*/
|
||||
static inline void _timg_ll_enable_bus_clock(int group_id, bool enable)
|
||||
{
|
||||
// TODO: ["ESP32S31"] IDF-14745
|
||||
if (group_id == 0) {
|
||||
HP_SYS_CLKRST.timergrp0_ctrl0.reg_timergrp0_apb_clk_en = enable;
|
||||
} else {
|
||||
HP_SYS_CLKRST.timergrp1_ctrl0.reg_timergrp1_apb_clk_en = enable;
|
||||
}
|
||||
}
|
||||
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
@@ -56,7 +59,15 @@ static inline void _timg_ll_enable_bus_clock(int group_id, bool enable)
|
||||
*/
|
||||
static inline void _timg_ll_reset_register(int group_id)
|
||||
{
|
||||
// TODO: ["ESP32S31"] IDF-14745
|
||||
if (group_id == 0) {
|
||||
HP_SYS_CLKRST.timergrp0_ctrl0.reg_timergrp0_rst_en = 1;
|
||||
HP_SYS_CLKRST.timergrp0_ctrl0.reg_timergrp0_rst_en = 0;
|
||||
TIMERG0.wdtconfig0.wdt_flashboot_mod_en = 0;
|
||||
} else {
|
||||
HP_SYS_CLKRST.timergrp1_ctrl0.reg_timergrp1_rst_en = 1;
|
||||
HP_SYS_CLKRST.timergrp1_ctrl0.reg_timergrp1_rst_en = 0;
|
||||
TIMERG1.wdtconfig0.wdt_flashboot_mod_en = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
|
||||
@@ -1,36 +1,243 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "soc/timer_periph.h"
|
||||
|
||||
// TODO: ["ESP32S31"] IDF-14693
|
||||
#include "hal/timer_periph.h"
|
||||
|
||||
const soc_timg_gptimer_signal_desc_t soc_timg_gptimer_signals[2][2] = {
|
||||
[0] = {
|
||||
[0] = {
|
||||
.module_name = "TIMG0T0",
|
||||
.parent_module = PERIPH_TIMG0_MODULE,
|
||||
.irq_id = ETS_TG0_T0_LEVEL_INTR_SOURCE,
|
||||
.irq_id = ETS_TIMERGRP0_T0_INTR_SOURCE,
|
||||
},
|
||||
[1] = {
|
||||
.module_name = "TIMG0T1",
|
||||
.parent_module = PERIPH_TIMG0_MODULE,
|
||||
.irq_id = ETS_TG0_T1_LEVEL_INTR_SOURCE,
|
||||
.irq_id = ETS_TIMERGRP0_T1_INTR_SOURCE,
|
||||
},
|
||||
},
|
||||
[1] = {
|
||||
[0] = {
|
||||
.module_name = "TIMG1T0",
|
||||
.parent_module = PERIPH_TIMG1_MODULE,
|
||||
.irq_id = ETS_TG1_T0_LEVEL_INTR_SOURCE,
|
||||
.irq_id = ETS_TIMERGRP1_T0_INTR_SOURCE,
|
||||
},
|
||||
[1] = {
|
||||
.module_name = "TIMG1T1",
|
||||
.parent_module = PERIPH_TIMG1_MODULE,
|
||||
.irq_id = ETS_TG1_T1_LEVEL_INTR_SOURCE,
|
||||
.irq_id = ETS_TIMERGRP1_T1_INTR_SOURCE,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
#if SOC_PAU_SUPPORTED
|
||||
/* 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 TG0_TIMER0_RETENTION_REGS_BASE (REG_TIMG_BASE(0))
|
||||
#define TG1_TIMER0_RETENTION_REGS_BASE (REG_TIMG_BASE(1))
|
||||
#define TG_TIMER0_RETENTION_REGS_CNT 7
|
||||
static const uint32_t tg_timer0_regs_map[4] = {0x100000f1, 0x80000000, 0x0, 0x0};
|
||||
|
||||
/* Registers in retention context:
|
||||
* TIMG_T1CONFIG_REG
|
||||
* TIMG_T1ALARMLO_REG
|
||||
* TIMG_T1ALARMHI_REG
|
||||
* TIMG_T1LOADLO_REG
|
||||
* TIMG_T1LOADHI_REG
|
||||
* TIMG_INT_ENA_TIMERS_REG
|
||||
* TIMG_REGCLK_REG
|
||||
*/
|
||||
#define TG0_TIMER1_RETENTION_REGS_BASE (REG_TIMG_BASE(0) + 0x24)
|
||||
#define TG1_TIMER1_RETENTION_REGS_BASE (REG_TIMG_BASE(1) + 0x24)
|
||||
#define TG_TIMER1_RETENTION_REGS_CNT 7
|
||||
static const uint32_t tg_timer1_regs_map[4] = {0x800f1, 0x400000, 0x0, 0x0};
|
||||
|
||||
const regdma_entries_config_t tg0_timer0_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)
|
||||
},
|
||||
// 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)
|
||||
},
|
||||
// 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)
|
||||
},
|
||||
// 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)
|
||||
},
|
||||
// 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),
|
||||
TG0_TIMER0_RETENTION_REGS_BASE, TG0_TIMER0_RETENTION_REGS_BASE,
|
||||
TG_TIMER0_RETENTION_REGS_CNT, 0, 0,
|
||||
tg_timer0_regs_map[0], tg_timer0_regs_map[1],
|
||||
tg_timer0_regs_map[2], tg_timer0_regs_map[3]),
|
||||
.owner = ENTRY(0)
|
||||
},
|
||||
};
|
||||
|
||||
const regdma_entries_config_t tg0_timer1_regdma_entries[] = {
|
||||
// backup stage: trigger a soft capture
|
||||
[0] = {
|
||||
.config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x05),
|
||||
TIMG_T1UPDATE_REG(0), TIMG_T1_UPDATE, TIMG_T1_UPDATE_M, 0, 1),
|
||||
.owner = ENTRY(0)
|
||||
},
|
||||
// backup stage: wait for the capture done
|
||||
[1] = {
|
||||
.config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x06),
|
||||
TIMG_T1UPDATE_REG(0), 0x0, TIMG_T1_UPDATE_M, 0, 1),
|
||||
.owner = ENTRY(0)
|
||||
},
|
||||
// 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(0x07),
|
||||
TIMG_T1LO_REG(0), TIMG_T1LOADLO_REG(0), 2, 0, 0),
|
||||
.owner = ENTRY(0)
|
||||
},
|
||||
// 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(0x08),
|
||||
TIMG_T1LOAD_REG(0), 0x1, TIMG_T1_LOAD_M, 1, 0),
|
||||
.owner = ENTRY(0)
|
||||
},
|
||||
// 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(0x09),
|
||||
TG0_TIMER1_RETENTION_REGS_BASE, TG0_TIMER1_RETENTION_REGS_BASE,
|
||||
TG_TIMER1_RETENTION_REGS_CNT, 0, 0,
|
||||
tg_timer1_regs_map[0], tg_timer1_regs_map[1],
|
||||
tg_timer1_regs_map[2], tg_timer1_regs_map[3]),
|
||||
.owner = ENTRY(0)
|
||||
},
|
||||
};
|
||||
|
||||
const regdma_entries_config_t tg1_timer0_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)
|
||||
},
|
||||
// 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)
|
||||
},
|
||||
// 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)
|
||||
},
|
||||
// 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)
|
||||
},
|
||||
// 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),
|
||||
TG1_TIMER0_RETENTION_REGS_BASE, TG1_TIMER0_RETENTION_REGS_BASE,
|
||||
TG_TIMER0_RETENTION_REGS_CNT, 0, 0,
|
||||
tg_timer0_regs_map[0], tg_timer0_regs_map[1],
|
||||
tg_timer0_regs_map[2], tg_timer0_regs_map[3]),
|
||||
.owner = ENTRY(0)
|
||||
},
|
||||
};
|
||||
|
||||
const regdma_entries_config_t tg1_timer1_regdma_entries[] = {
|
||||
// backup stage: trigger a soft capture
|
||||
[0] = {
|
||||
.config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x05),
|
||||
TIMG_T1UPDATE_REG(1), TIMG_T1_UPDATE, TIMG_T1_UPDATE_M, 0, 1),
|
||||
.owner = ENTRY(0)
|
||||
},
|
||||
// backup stage: wait for the capture done
|
||||
[1] = {
|
||||
.config = REGDMA_LINK_WAIT_INIT(REGDMA_TG1_TIMER_LINK(0x06),
|
||||
TIMG_T1UPDATE_REG(1), 0x0, TIMG_T1_UPDATE_M, 0, 1),
|
||||
.owner = ENTRY(0)
|
||||
},
|
||||
// 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(0x07),
|
||||
TIMG_T1LO_REG(1), TIMG_T1LOADLO_REG(1), 2, 0, 0),
|
||||
.owner = ENTRY(0)
|
||||
},
|
||||
// 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(0x08),
|
||||
TIMG_T1LOAD_REG(1), 0x1, TIMG_T1_LOAD_M, 1, 0),
|
||||
.owner = ENTRY(0)
|
||||
},
|
||||
// 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(0x09),
|
||||
TG1_TIMER1_RETENTION_REGS_BASE, TG1_TIMER1_RETENTION_REGS_BASE,
|
||||
TG_TIMER1_RETENTION_REGS_CNT, 0, 0,
|
||||
tg_timer1_regs_map[0], tg_timer1_regs_map[1],
|
||||
tg_timer1_regs_map[2], tg_timer1_regs_map[3]),
|
||||
.owner = ENTRY(0)
|
||||
},
|
||||
};
|
||||
|
||||
const soc_timg_gptimer_retention_desc_t soc_timg_gptimer_retention_infos[2][2] = {
|
||||
[0] = {
|
||||
[0] = {
|
||||
.module = SLEEP_RETENTION_MODULE_TG0_TIMER0,
|
||||
.regdma_entry_array = tg0_timer0_regdma_entries,
|
||||
.array_size = ARRAY_SIZE(tg0_timer0_regdma_entries)
|
||||
},
|
||||
[1] = {
|
||||
.module = SLEEP_RETENTION_MODULE_TG0_TIMER1,
|
||||
.regdma_entry_array = tg0_timer1_regdma_entries,
|
||||
.array_size = ARRAY_SIZE(tg0_timer1_regdma_entries)
|
||||
},
|
||||
},
|
||||
[1] = {
|
||||
[0] = {
|
||||
.module = SLEEP_RETENTION_MODULE_TG1_TIMER0,
|
||||
.regdma_entry_array = tg1_timer0_regdma_entries,
|
||||
.array_size = ARRAY_SIZE(tg1_timer0_regdma_entries)
|
||||
},
|
||||
[1] = {
|
||||
.module = SLEEP_RETENTION_MODULE_TG1_TIMER1,
|
||||
.regdma_entry_array = tg1_timer1_regdma_entries,
|
||||
.array_size = ARRAY_SIZE(tg1_timer1_regdma_entries)
|
||||
},
|
||||
},
|
||||
};
|
||||
#endif // SOC_PAU_SUPPORTED
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "esp_private/esp_clk_tree_common.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
|
||||
static const char *TAG = "esp_clk_tree";
|
||||
ESP_LOG_ATTR_TAG(TAG, "esp_clk_tree");
|
||||
|
||||
/* TODO: [ESP32S31] IDF-14733 */
|
||||
|
||||
@@ -30,15 +30,15 @@ esp_err_t esp_clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, esp_clk_tree_sr
|
||||
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
|
||||
|
||||
uint32_t clk_src_freq = 0;
|
||||
switch (clk_src) {
|
||||
#if SOC_CLK_TREE_SUPPORTED
|
||||
case SOC_MOD_CLK_CPU:
|
||||
clk_src_freq = clk_hal_cpu_get_freq_hz();
|
||||
break;
|
||||
#endif // SOC_CLK_TREE_SUPPORTED
|
||||
case SOC_MOD_CLK_XTAL:
|
||||
clk_src_freq = clk_hal_xtal_get_freq_mhz() * MHZ;
|
||||
clk_src_freq = SOC_XTAL_FREQ_40M * MHZ;
|
||||
break;
|
||||
case SOC_MOD_CLK_PLL_F20M:
|
||||
clk_src_freq = CLK_LL_PLL_480M_FREQ_MHZ / clk_ll_pll_f20m_get_divider() * MHZ;
|
||||
@@ -52,6 +52,7 @@ esp_err_t esp_clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, esp_clk_tree_sr
|
||||
case SOC_MOD_CLK_PLL_F240M:
|
||||
clk_src_freq = CLK_LL_PLL_240M_FREQ_MHZ * MHZ;
|
||||
break;
|
||||
#if SOC_CLK_TREE_SUPPORTED
|
||||
case SOC_MOD_CLK_CPLL:
|
||||
clk_src_freq = clk_ll_cpll_get_freq_mhz(clk_hal_xtal_get_freq_mhz()) * MHZ;
|
||||
break;
|
||||
@@ -84,6 +85,7 @@ esp_err_t esp_clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, esp_clk_tree_sr
|
||||
case SOC_MOD_CLK_LP_PLL:
|
||||
clk_src_freq = clk_ll_lp_pll_get_freq_mhz() * MHZ;
|
||||
break;
|
||||
#endif // SOC_CLK_TREE_SUPPORTED
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -91,7 +93,7 @@ esp_err_t esp_clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, esp_clk_tree_sr
|
||||
ESP_RETURN_ON_FALSE(clk_src_freq, ESP_FAIL, TAG,
|
||||
"freq shouldn't be 0, calibration failed");
|
||||
*freq_value = clk_src_freq;
|
||||
#endif // SOC_CLK_TREE_SUPPORTED
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -271,6 +275,14 @@ config SOC_SYSTIMER_ALARM_MISS_COMPENSATE
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_TIMER_SUPPORT_ETM
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_TIMER_SUPPORT_SLEEP_RETENTION
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_MWDT_SUPPORT_XTAL
|
||||
bool
|
||||
default y
|
||||
@@ -382,3 +394,7 @@ config SOC_CLK_LP_FAST_SUPPORT_XTAL
|
||||
config SOC_CLK_ANA_I2C_MST_HAS_ROOT_GATE
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PERIPH_CLK_CTRL_SHARED
|
||||
bool
|
||||
default y
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
// #define SOC_AXI_GDMA_SUPPORTED 1 // TODO: [ESP32S31] IDF-14758
|
||||
// #define SOC_DW_GDMA_SUPPORTED 1 // TODO: [ESP32S31] IDF-14758
|
||||
// #define SOC_DMA2D_SUPPORTED 1 // TODO: [ESP32S31] IDF-14762
|
||||
// #define SOC_GPTIMER_SUPPORTED 1 // TODO: [ESP32S31] IDF-14745
|
||||
#define SOC_GPTIMER_SUPPORTED 1
|
||||
// #define SOC_PCNT_SUPPORTED 1 // TODO: [ESP32S31] IDF-14699
|
||||
// #define SOC_LCDCAM_SUPPORTED 1 // TODO: [ESP32S31] IDF-14722
|
||||
// #define SOC_LCDCAM_CAM_SUPPORTED 1 // TODO: [ESP32S31] IDF-14722
|
||||
@@ -216,6 +216,10 @@
|
||||
#define SOC_SYSTIMER_INT_LEVEL 1 // Systimer peripheral uses level interrupt
|
||||
#define SOC_SYSTIMER_ALARM_MISS_COMPENSATE 1 // Systimer peripheral can generate interrupt immediately if t(target) > t(current)
|
||||
|
||||
/*--------------------------- TIMER GROUP CAPS ---------------------------------------*/
|
||||
#define SOC_TIMER_SUPPORT_ETM (1)
|
||||
#define SOC_TIMER_SUPPORT_SLEEP_RETENTION (1)
|
||||
|
||||
/*--------------------------- WATCHDOG CAPS ---------------------------------------*/
|
||||
// TODO: [ESP32S31] IDF-14656
|
||||
#define SOC_MWDT_SUPPORT_XTAL (1)
|
||||
@@ -271,3 +275,5 @@
|
||||
#define SOC_CLK_LP_FAST_SUPPORT_XTAL (1) /*!< Support XTAL clock as the LP_FAST clock source */
|
||||
|
||||
#define SOC_CLK_ANA_I2C_MST_HAS_ROOT_GATE (1) /*!< Any regi2c operation needs enable the analog i2c master clock first */
|
||||
|
||||
#define SOC_PERIPH_CLK_CTRL_SHARED (1) /*!< Peripheral clock control (e.g. set clock source) is shared between various peripherals */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| 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 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- |
|
||||
| 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 | ESP32-S31 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | --------- |
|
||||
|
||||
# Example: General Purpose Timer
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | 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 | ESP32-S31 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | --------- |
|
||||
|
||||
# Wiegand Interface Example
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| 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 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- |
|
||||
| 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 | ESP32-S31 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | --------- |
|
||||
# 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/).
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| 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 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- |
|
||||
| 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 | ESP32-S31 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- | --------- |
|
||||
|
||||
# SystemView Heap and Log Tracing Example
|
||||
|
||||
|
||||
Reference in New Issue
Block a user