Merge branch 'feature/s3_wdt_bringup' into 'master'

TIMG and WDT bringup for S3

Closes IDF-1881, IDF-3229, IDF-3301, and IDF-3274

See merge request espressif/esp-idf!13957
This commit is contained in:
Angus Gratton
2021-07-09 04:43:41 +00:00
12 changed files with 1296 additions and 782 deletions

View File

@@ -276,7 +276,9 @@ static void bootloader_check_wdt_reset(void)
if (wdt_rst) { if (wdt_rst) {
// if reset by WDT dump info from trace port // if reset by WDT dump info from trace port
wdt_reset_info_dump(0); wdt_reset_info_dump(0);
#if !CONFIG_FREERTOS_UNICORE
wdt_reset_info_dump(1); wdt_reset_info_dump(1);
#endif
} }
wdt_reset_cpu0_info_enable(); wdt_reset_cpu0_info_enable();
} }

View File

@@ -27,20 +27,39 @@ extern "C" {
#include "hal/wdt_types.h" #include "hal/wdt_types.h"
#include "esp_attr.h" #include "esp_attr.h"
/* The value that needs to be written to MWDT_LL_WKEY to write-enable the wdt registers */
#define MWDT_LL_WKEY_VALUE 0x50D83AA1
/* Possible values for MWDT_LL_STGx */
#define MWDT_LL_STG_SEL_OFF 0
#define MWDT_LL_STG_SEL_INT 1
#define MWDT_LL_STG_SEL_RESET_CPU 2
#define MWDT_LL_STG_SEL_RESET_SYSTEM 3
/* Possible values for MWDT_LL_CPU_RESET_LENGTH and MWDT_LL_SYS_RESET_LENGTH */
#define MWDT_LL_RESET_LENGTH_100_NS 0
#define MWDT_LL_RESET_LENGTH_200_NS 1
#define MWDT_LL_RESET_LENGTH_300_NS 2
#define MWDT_LL_RESET_LENGTH_400_NS 3
#define MWDT_LL_RESET_LENGTH_500_NS 4
#define MWDT_LL_RESET_LENGTH_800_NS 5
#define MWDT_LL_RESET_LENGTH_1600_NS 6
#define MWDT_LL_RESET_LENGTH_3200_NS 7
//Type check wdt_stage_action_t //Type check wdt_stage_action_t
_Static_assert(WDT_STAGE_ACTION_OFF == TIMG_WDT_STG_SEL_OFF, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); _Static_assert(WDT_STAGE_ACTION_OFF == MWDT_LL_STG_SEL_OFF, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
_Static_assert(WDT_STAGE_ACTION_INT == TIMG_WDT_STG_SEL_INT, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); _Static_assert(WDT_STAGE_ACTION_INT == MWDT_LL_STG_SEL_INT, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
_Static_assert(WDT_STAGE_ACTION_RESET_CPU == TIMG_WDT_STG_SEL_RESET_CPU, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); _Static_assert(WDT_STAGE_ACTION_RESET_CPU == MWDT_LL_STG_SEL_RESET_CPU, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
_Static_assert(WDT_STAGE_ACTION_RESET_SYSTEM == TIMG_WDT_STG_SEL_RESET_SYSTEM, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); _Static_assert(WDT_STAGE_ACTION_RESET_SYSTEM == MWDT_LL_STG_SEL_RESET_SYSTEM, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
//Type check wdt_reset_sig_length_t //Type check wdt_reset_sig_length_t
_Static_assert(WDT_RESET_SIG_LENGTH_100ns == TIMG_WDT_RESET_LENGTH_100_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); _Static_assert(WDT_RESET_SIG_LENGTH_100ns == MWDT_LL_RESET_LENGTH_100_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
_Static_assert(WDT_RESET_SIG_LENGTH_200ns == TIMG_WDT_RESET_LENGTH_200_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); _Static_assert(WDT_RESET_SIG_LENGTH_200ns == MWDT_LL_RESET_LENGTH_200_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
_Static_assert(WDT_RESET_SIG_LENGTH_300ns == TIMG_WDT_RESET_LENGTH_300_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); _Static_assert(WDT_RESET_SIG_LENGTH_300ns == MWDT_LL_RESET_LENGTH_300_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
_Static_assert(WDT_RESET_SIG_LENGTH_400ns == TIMG_WDT_RESET_LENGTH_400_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); _Static_assert(WDT_RESET_SIG_LENGTH_400ns == MWDT_LL_RESET_LENGTH_400_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
_Static_assert(WDT_RESET_SIG_LENGTH_500ns == TIMG_WDT_RESET_LENGTH_500_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); _Static_assert(WDT_RESET_SIG_LENGTH_500ns == MWDT_LL_RESET_LENGTH_500_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
_Static_assert(WDT_RESET_SIG_LENGTH_800ns == TIMG_WDT_RESET_LENGTH_800_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); _Static_assert(WDT_RESET_SIG_LENGTH_800ns == MWDT_LL_RESET_LENGTH_800_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
_Static_assert(WDT_RESET_SIG_LENGTH_1_6us == TIMG_WDT_RESET_LENGTH_1600_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); _Static_assert(WDT_RESET_SIG_LENGTH_1_6us == MWDT_LL_RESET_LENGTH_1600_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
_Static_assert(WDT_RESET_SIG_LENGTH_3_2us == TIMG_WDT_RESET_LENGTH_3200_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); _Static_assert(WDT_RESET_SIG_LENGTH_3_2us == MWDT_LL_RESET_LENGTH_3200_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
/** /**
* @brief Enable the MWDT * @brief Enable the MWDT
@@ -49,7 +68,7 @@ _Static_assert(WDT_RESET_SIG_LENGTH_3_2us == TIMG_WDT_RESET_LENGTH_3200_NS, "Add
*/ */
FORCE_INLINE_ATTR void mwdt_ll_enable(timg_dev_t *hw) FORCE_INLINE_ATTR void mwdt_ll_enable(timg_dev_t *hw)
{ {
hw->wdt_config0.en = 1; hw->wdtconfig0.wdt_en = 1;
} }
/** /**
@@ -62,7 +81,7 @@ FORCE_INLINE_ATTR void mwdt_ll_enable(timg_dev_t *hw)
*/ */
FORCE_INLINE_ATTR void mwdt_ll_disable(timg_dev_t *hw) FORCE_INLINE_ATTR void mwdt_ll_disable(timg_dev_t *hw)
{ {
hw->wdt_config0.en = 0; hw->wdtconfig0.wdt_en = 0;
} }
/** /**
@@ -73,7 +92,7 @@ FORCE_INLINE_ATTR void mwdt_ll_disable(timg_dev_t *hw)
*/ */
FORCE_INLINE_ATTR bool mwdt_ll_check_if_enabled(timg_dev_t *hw) FORCE_INLINE_ATTR bool mwdt_ll_check_if_enabled(timg_dev_t *hw)
{ {
return (hw->wdt_config0.en) ? true : false; return (hw->wdtconfig0.wdt_en) ? true : false;
} }
/** /**
@@ -88,20 +107,20 @@ FORCE_INLINE_ATTR void mwdt_ll_config_stage(timg_dev_t *hw, wdt_stage_t stage, u
{ {
switch (stage) { switch (stage) {
case WDT_STAGE0: case WDT_STAGE0:
hw->wdt_config0.stg0 = behavior; hw->wdtconfig0.wdt_stg0 = behavior;
hw->wdt_config2 = timeout; hw->wdtconfig2.wdt_stg0_hold = timeout;
break; break;
case WDT_STAGE1: case WDT_STAGE1:
hw->wdt_config0.stg1 = behavior; hw->wdtconfig0.wdt_stg1 = behavior;
hw->wdt_config3 = timeout; hw->wdtconfig3.wdt_stg1_hold = timeout;
break; break;
case WDT_STAGE2: case WDT_STAGE2:
hw->wdt_config0.stg2 = behavior; hw->wdtconfig0.wdt_stg2 = behavior;
hw->wdt_config4 = timeout; hw->wdtconfig4.wdt_stg2_hold = timeout;
break; break;
case WDT_STAGE3: case WDT_STAGE3:
hw->wdt_config0.stg3 = behavior; hw->wdtconfig0.wdt_stg3 = behavior;
hw->wdt_config5 = timeout; hw->wdtconfig5.wdt_stg3_hold = timeout;
break; break;
default: default:
break; break;
@@ -118,16 +137,16 @@ FORCE_INLINE_ATTR void mwdt_ll_disable_stage(timg_dev_t *hw, uint32_t stage)
{ {
switch (stage) { switch (stage) {
case WDT_STAGE0: case WDT_STAGE0:
hw->wdt_config0.stg0 = WDT_STAGE_ACTION_OFF; hw->wdtconfig0.wdt_stg0 = WDT_STAGE_ACTION_OFF;
break; break;
case WDT_STAGE1: case WDT_STAGE1:
hw->wdt_config0.stg1 = WDT_STAGE_ACTION_OFF; hw->wdtconfig0.wdt_stg1 = WDT_STAGE_ACTION_OFF;
break; break;
case WDT_STAGE2: case WDT_STAGE2:
hw->wdt_config0.stg2 = WDT_STAGE_ACTION_OFF; hw->wdtconfig0.wdt_stg2 = WDT_STAGE_ACTION_OFF;
break; break;
case WDT_STAGE3: case WDT_STAGE3:
hw->wdt_config0.stg3 = WDT_STAGE_ACTION_OFF; hw->wdtconfig0.wdt_stg3 = WDT_STAGE_ACTION_OFF;
break; break;
default: default:
break; break;
@@ -152,7 +171,7 @@ FORCE_INLINE_ATTR void mwdt_ll_set_edge_intr(timg_dev_t *hw, bool enable)
*/ */
FORCE_INLINE_ATTR void mwdt_ll_set_level_intr(timg_dev_t *hw, bool enable) FORCE_INLINE_ATTR void mwdt_ll_set_level_intr(timg_dev_t *hw, bool enable)
{ {
hw->int_ena.wdt = enable; hw->int_ena_timers.wdt_int_ena = enable;
} }
/** /**
@@ -163,7 +182,7 @@ FORCE_INLINE_ATTR void mwdt_ll_set_level_intr(timg_dev_t *hw, bool enable)
*/ */
FORCE_INLINE_ATTR void mwdt_ll_set_cpu_reset_length(timg_dev_t *hw, wdt_reset_sig_length_t length) FORCE_INLINE_ATTR void mwdt_ll_set_cpu_reset_length(timg_dev_t *hw, wdt_reset_sig_length_t length)
{ {
hw->wdt_config0.cpu_reset_length = length; hw->wdtconfig0.wdt_cpu_reset_length = length;
} }
/** /**
@@ -174,7 +193,7 @@ FORCE_INLINE_ATTR void mwdt_ll_set_cpu_reset_length(timg_dev_t *hw, wdt_reset_si
*/ */
FORCE_INLINE_ATTR void mwdt_ll_set_sys_reset_length(timg_dev_t *hw, wdt_reset_sig_length_t length) FORCE_INLINE_ATTR void mwdt_ll_set_sys_reset_length(timg_dev_t *hw, wdt_reset_sig_length_t length)
{ {
hw->wdt_config0.sys_reset_length = length; hw->wdtconfig0.wdt_sys_reset_length = length;
} }
/** /**
@@ -189,7 +208,7 @@ FORCE_INLINE_ATTR void mwdt_ll_set_sys_reset_length(timg_dev_t *hw, wdt_reset_si
*/ */
FORCE_INLINE_ATTR void mwdt_ll_set_flashboot_en(timg_dev_t *hw, bool enable) FORCE_INLINE_ATTR void mwdt_ll_set_flashboot_en(timg_dev_t *hw, bool enable)
{ {
hw->wdt_config0.flashboot_mod_en = (enable) ? 1 : 0; hw->wdtconfig0.wdt_flashboot_mod_en = (enable) ? 1 : 0;
} }
/** /**
@@ -200,7 +219,7 @@ FORCE_INLINE_ATTR void mwdt_ll_set_flashboot_en(timg_dev_t *hw, bool enable)
*/ */
FORCE_INLINE_ATTR void mwdt_ll_set_prescaler(timg_dev_t *hw, uint32_t prescaler) FORCE_INLINE_ATTR void mwdt_ll_set_prescaler(timg_dev_t *hw, uint32_t prescaler)
{ {
hw->wdt_config1.clk_prescale = prescaler; hw->wdtconfig1.wdt_clk_prescale = prescaler;
} }
/** /**
@@ -212,7 +231,7 @@ FORCE_INLINE_ATTR void mwdt_ll_set_prescaler(timg_dev_t *hw, uint32_t prescaler)
*/ */
FORCE_INLINE_ATTR void mwdt_ll_feed(timg_dev_t *hw) FORCE_INLINE_ATTR void mwdt_ll_feed(timg_dev_t *hw)
{ {
hw->wdt_feed = 1; hw->wdtfeed.wdt_feed = 1;
} }
/** /**
@@ -224,7 +243,7 @@ FORCE_INLINE_ATTR void mwdt_ll_feed(timg_dev_t *hw)
*/ */
FORCE_INLINE_ATTR void mwdt_ll_write_protect_enable(timg_dev_t *hw) FORCE_INLINE_ATTR void mwdt_ll_write_protect_enable(timg_dev_t *hw)
{ {
hw->wdt_wprotect = 0; hw->wdtwprotect.wdt_wkey = 0;
} }
/** /**
@@ -234,7 +253,7 @@ FORCE_INLINE_ATTR void mwdt_ll_write_protect_enable(timg_dev_t *hw)
*/ */
FORCE_INLINE_ATTR void mwdt_ll_write_protect_disable(timg_dev_t *hw) FORCE_INLINE_ATTR void mwdt_ll_write_protect_disable(timg_dev_t *hw)
{ {
hw->wdt_wprotect = TIMG_WDT_WKEY_VALUE; hw->wdtwprotect.wdt_wkey = MWDT_LL_WKEY_VALUE;
} }
/** /**
@@ -244,7 +263,7 @@ FORCE_INLINE_ATTR void mwdt_ll_write_protect_disable(timg_dev_t *hw)
*/ */
FORCE_INLINE_ATTR void mwdt_ll_clear_intr_status(timg_dev_t *hw) FORCE_INLINE_ATTR void mwdt_ll_clear_intr_status(timg_dev_t *hw)
{ {
hw->int_clr.wdt = 1; hw->int_clr_timers.wdt_int_clr = 1;
} }
/** /**
@@ -255,7 +274,7 @@ FORCE_INLINE_ATTR void mwdt_ll_clear_intr_status(timg_dev_t *hw)
*/ */
FORCE_INLINE_ATTR void mwdt_ll_set_intr_enable(timg_dev_t *hw, bool enable) FORCE_INLINE_ATTR void mwdt_ll_set_intr_enable(timg_dev_t *hw, bool enable)
{ {
hw->int_ena.wdt = (enable) ? 1 : 0; hw->int_ena_timers.wdt_int_ena = (enable) ? 1 : 0;
} }
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -28,21 +28,42 @@ extern "C" {
#include "soc/efuse_reg.h" #include "soc/efuse_reg.h"
#include "esp_attr.h" #include "esp_attr.h"
/* The value that needs to be written to RTC_CNTL_WDT_WKEY to write-enable the wdt registers */
#define RWDT_LL_WDT_WKEY_VALUE 0x50D83AA1
/* stage action selection values */
#define RWDT_LL_STG_SEL_OFF 0
#define RWDT_LL_STG_SEL_INT 1
#define RWDT_LL_STG_SEL_RESET_CPU 2
#define RWDT_LL_STG_SEL_RESET_SYSTEM 3
#define RWDT_LL_STG_SEL_RESET_RTC 4
/* Possible values for RTC_CNTL_WDT_CPU_RESET_LENGTH and RTC_CNTL_WDT_SYS_RESET_LENGTH */
#define RWDT_LL_RESET_LENGTH_100_NS 0
#define RWDT_LL_RESET_LENGTH_200_NS 1
#define RWDT_LL_RESET_LENGTH_300_NS 2
#define RWDT_LL_RESET_LENGTH_400_NS 3
#define RWDT_LL_RESET_LENGTH_500_NS 4
#define RWDT_LL_RESET_LENGTH_800_NS 5
#define RWDT_LL_RESET_LENGTH_1600_NS 6
#define RWDT_LL_RESET_LENGTH_3200_NS 7
//Type check wdt_stage_action_t //Type check wdt_stage_action_t
_Static_assert(WDT_STAGE_ACTION_OFF == RTC_WDT_STG_SEL_OFF, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); _Static_assert(WDT_STAGE_ACTION_OFF == RWDT_LL_STG_SEL_OFF, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
_Static_assert(WDT_STAGE_ACTION_INT == RTC_WDT_STG_SEL_INT, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); _Static_assert(WDT_STAGE_ACTION_INT == RWDT_LL_STG_SEL_INT, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
_Static_assert(WDT_STAGE_ACTION_RESET_CPU == RTC_WDT_STG_SEL_RESET_CPU, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); _Static_assert(WDT_STAGE_ACTION_RESET_CPU == RWDT_LL_STG_SEL_RESET_CPU, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
_Static_assert(WDT_STAGE_ACTION_RESET_SYSTEM == RTC_WDT_STG_SEL_RESET_SYSTEM, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); _Static_assert(WDT_STAGE_ACTION_RESET_SYSTEM == RWDT_LL_STG_SEL_RESET_SYSTEM, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
_Static_assert(WDT_STAGE_ACTION_RESET_RTC == RTC_WDT_STG_SEL_RESET_RTC, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); _Static_assert(WDT_STAGE_ACTION_RESET_RTC == RWDT_LL_STG_SEL_RESET_RTC, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t");
//Type check wdt_reset_sig_length_t //Type check wdt_reset_sig_length_t
_Static_assert(WDT_RESET_SIG_LENGTH_100ns == RTC_WDT_RESET_LENGTH_100_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); _Static_assert(WDT_RESET_SIG_LENGTH_100ns == RWDT_LL_RESET_LENGTH_100_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
_Static_assert(WDT_RESET_SIG_LENGTH_200ns == RTC_WDT_RESET_LENGTH_200_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); _Static_assert(WDT_RESET_SIG_LENGTH_200ns == RWDT_LL_RESET_LENGTH_200_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
_Static_assert(WDT_RESET_SIG_LENGTH_300ns == RTC_WDT_RESET_LENGTH_300_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); _Static_assert(WDT_RESET_SIG_LENGTH_300ns == RWDT_LL_RESET_LENGTH_300_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
_Static_assert(WDT_RESET_SIG_LENGTH_400ns == RTC_WDT_RESET_LENGTH_400_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); _Static_assert(WDT_RESET_SIG_LENGTH_400ns == RWDT_LL_RESET_LENGTH_400_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
_Static_assert(WDT_RESET_SIG_LENGTH_500ns == RTC_WDT_RESET_LENGTH_500_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); _Static_assert(WDT_RESET_SIG_LENGTH_500ns == RWDT_LL_RESET_LENGTH_500_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
_Static_assert(WDT_RESET_SIG_LENGTH_800ns == RTC_WDT_RESET_LENGTH_800_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); _Static_assert(WDT_RESET_SIG_LENGTH_800ns == RWDT_LL_RESET_LENGTH_800_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
_Static_assert(WDT_RESET_SIG_LENGTH_1_6us == RTC_WDT_RESET_LENGTH_1600_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); _Static_assert(WDT_RESET_SIG_LENGTH_1_6us == RWDT_LL_RESET_LENGTH_1600_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
_Static_assert(WDT_RESET_SIG_LENGTH_3_2us == RTC_WDT_RESET_LENGTH_3200_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); _Static_assert(WDT_RESET_SIG_LENGTH_3_2us == RWDT_LL_RESET_LENGTH_3200_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t");
/** /**
* @brief Enable the RWDT * @brief Enable the RWDT
@@ -270,7 +291,7 @@ FORCE_INLINE_ATTR void rwdt_ll_write_protect_enable(rtc_cntl_dev_t *hw)
*/ */
FORCE_INLINE_ATTR void rwdt_ll_write_protect_disable(rtc_cntl_dev_t *hw) FORCE_INLINE_ATTR void rwdt_ll_write_protect_disable(rtc_cntl_dev_t *hw)
{ {
hw->wdt_wprotect = RTC_CNTL_WDT_WKEY_VALUE; hw->wdt_wprotect = RWDT_LL_WDT_WKEY_VALUE;
} }
/** /**

View File

@@ -53,10 +53,10 @@ static inline void timer_ll_set_divider(timg_dev_t *hw, timer_idx_t timer_num, u
if (divider >= 65536) { if (divider >= 65536) {
divider = 0; divider = 0;
} }
int timer_en = hw->hw_timer[timer_num].config.enable; int timer_en = hw->hw_timer[timer_num].config.tn_en;
hw->hw_timer[timer_num].config.enable = 0; hw->hw_timer[timer_num].config.tn_en = 0;
hw->hw_timer[timer_num].config.divider = divider; hw->hw_timer[timer_num].config.tn_divider = divider;
hw->hw_timer[timer_num].config.enable = timer_en; hw->hw_timer[timer_num].config.tn_en = timer_en;
} }
/** /**
@@ -70,7 +70,7 @@ static inline void timer_ll_set_divider(timg_dev_t *hw, timer_idx_t timer_num, u
*/ */
static inline void timer_ll_get_divider(timg_dev_t *hw, timer_idx_t timer_num, uint32_t *divider) static inline void timer_ll_get_divider(timg_dev_t *hw, timer_idx_t timer_num, uint32_t *divider)
{ {
uint32_t d = hw->hw_timer[timer_num].config.divider; uint32_t d = hw->hw_timer[timer_num].config.tn_divider;
if (d == 0) { if (d == 0) {
d = 65536; d = 65536;
} else if (d == 1) { } else if (d == 1) {
@@ -90,9 +90,9 @@ static inline void timer_ll_get_divider(timg_dev_t *hw, timer_idx_t timer_num, u
*/ */
static inline void timer_ll_set_counter_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t load_val) static inline void timer_ll_set_counter_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t load_val)
{ {
hw->hw_timer[timer_num].load_high.load_hi = (uint32_t) (load_val >> 32); hw->hw_timer[timer_num].loadhi.tn_load_hi = (uint32_t) (load_val >> 32);
hw->hw_timer[timer_num].load_low = (uint32_t) load_val; hw->hw_timer[timer_num].loadlo.tn_load_lo = (uint32_t) load_val;
hw->hw_timer[timer_num].reload = 1; hw->hw_timer[timer_num].load.tn_load = 1;
} }
/** /**
@@ -106,9 +106,9 @@ static inline void timer_ll_set_counter_value(timg_dev_t *hw, timer_idx_t timer_
*/ */
FORCE_INLINE_ATTR void timer_ll_get_counter_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t *timer_val) FORCE_INLINE_ATTR void timer_ll_get_counter_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t *timer_val)
{ {
hw->hw_timer[timer_num].update.update = 1; hw->hw_timer[timer_num].update.tn_update = 1;
while (hw->hw_timer[timer_num].update.update) {} while (hw->hw_timer[timer_num].update.tn_update) {}
*timer_val = ((uint64_t) hw->hw_timer[timer_num].cnt_high.hi << 32) | (hw->hw_timer[timer_num].cnt_low); *timer_val = ((uint64_t) hw->hw_timer[timer_num].hi.tn_hi << 32) | (hw->hw_timer[timer_num].lo.tn_lo);
} }
/** /**
@@ -122,7 +122,7 @@ FORCE_INLINE_ATTR void timer_ll_get_counter_value(timg_dev_t *hw, timer_idx_t ti
*/ */
static inline void timer_ll_set_counter_increase(timg_dev_t *hw, timer_idx_t timer_num, bool increase_en) static inline void timer_ll_set_counter_increase(timg_dev_t *hw, timer_idx_t timer_num, bool increase_en)
{ {
hw->hw_timer[timer_num].config.increase = increase_en; hw->hw_timer[timer_num].config.tn_increase = increase_en;
} }
/** /**
@@ -137,7 +137,7 @@ static inline void timer_ll_set_counter_increase(timg_dev_t *hw, timer_idx_t tim
*/ */
static inline bool timer_ll_get_counter_increase(timg_dev_t *hw, timer_idx_t timer_num) static inline bool timer_ll_get_counter_increase(timg_dev_t *hw, timer_idx_t timer_num)
{ {
return hw->hw_timer[timer_num].config.increase; return hw->hw_timer[timer_num].config.tn_increase;
} }
/** /**
@@ -151,7 +151,7 @@ static inline bool timer_ll_get_counter_increase(timg_dev_t *hw, timer_idx_t tim
*/ */
FORCE_INLINE_ATTR void timer_ll_set_counter_enable(timg_dev_t *hw, timer_idx_t timer_num, bool counter_en) FORCE_INLINE_ATTR void timer_ll_set_counter_enable(timg_dev_t *hw, timer_idx_t timer_num, bool counter_en)
{ {
hw->hw_timer[timer_num].config.enable = counter_en; hw->hw_timer[timer_num].config.tn_en = counter_en;
} }
/** /**
@@ -166,7 +166,7 @@ FORCE_INLINE_ATTR void timer_ll_set_counter_enable(timg_dev_t *hw, timer_idx_t t
*/ */
static inline bool timer_ll_get_counter_enable(timg_dev_t *hw, timer_idx_t timer_num) static inline bool timer_ll_get_counter_enable(timg_dev_t *hw, timer_idx_t timer_num)
{ {
return hw->hw_timer[timer_num].config.enable; return hw->hw_timer[timer_num].config.tn_en;
} }
/** /**
@@ -180,7 +180,7 @@ static inline bool timer_ll_get_counter_enable(timg_dev_t *hw, timer_idx_t timer
*/ */
static inline void timer_ll_set_auto_reload(timg_dev_t *hw, timer_idx_t timer_num, bool auto_reload_en) static inline void timer_ll_set_auto_reload(timg_dev_t *hw, timer_idx_t timer_num, bool auto_reload_en)
{ {
hw->hw_timer[timer_num].config.autoreload = auto_reload_en; hw->hw_timer[timer_num].config.tn_autoreload = auto_reload_en;
} }
/** /**
@@ -195,7 +195,7 @@ static inline void timer_ll_set_auto_reload(timg_dev_t *hw, timer_idx_t timer_nu
*/ */
FORCE_INLINE_ATTR bool timer_ll_get_auto_reload(timg_dev_t *hw, timer_idx_t timer_num) FORCE_INLINE_ATTR bool timer_ll_get_auto_reload(timg_dev_t *hw, timer_idx_t timer_num)
{ {
return hw->hw_timer[timer_num].config.autoreload; return hw->hw_timer[timer_num].config.tn_autoreload;
} }
/** /**
@@ -209,8 +209,8 @@ FORCE_INLINE_ATTR bool timer_ll_get_auto_reload(timg_dev_t *hw, timer_idx_t time
*/ */
FORCE_INLINE_ATTR void timer_ll_set_alarm_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t alarm_value) FORCE_INLINE_ATTR void timer_ll_set_alarm_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t alarm_value)
{ {
hw->hw_timer[timer_num].alarm_high.alarm_hi = (uint32_t) (alarm_value >> 32); hw->hw_timer[timer_num].alarmhi.tn_alarm_hi = (uint32_t) (alarm_value >> 32);
hw->hw_timer[timer_num].alarm_low = (uint32_t) alarm_value; hw->hw_timer[timer_num].alarmlo.tn_alarm_lo = (uint32_t) alarm_value;
} }
/** /**
@@ -224,7 +224,7 @@ FORCE_INLINE_ATTR void timer_ll_set_alarm_value(timg_dev_t *hw, timer_idx_t time
*/ */
static inline void timer_ll_get_alarm_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t *alarm_value) static inline void timer_ll_get_alarm_value(timg_dev_t *hw, timer_idx_t timer_num, uint64_t *alarm_value)
{ {
*alarm_value = ((uint64_t) hw->hw_timer[timer_num].alarm_high.alarm_hi << 32) | (hw->hw_timer[timer_num].alarm_low); *alarm_value = ((uint64_t) hw->hw_timer[timer_num].alarmhi.tn_alarm_hi << 32) | (hw->hw_timer[timer_num].alarmlo.tn_alarm_lo);
} }
/** /**
@@ -238,7 +238,7 @@ static inline void timer_ll_get_alarm_value(timg_dev_t *hw, timer_idx_t timer_nu
*/ */
FORCE_INLINE_ATTR void timer_ll_set_alarm_enable(timg_dev_t *hw, timer_idx_t timer_num, bool alarm_en) FORCE_INLINE_ATTR void timer_ll_set_alarm_enable(timg_dev_t *hw, timer_idx_t timer_num, bool alarm_en)
{ {
hw->hw_timer[timer_num].config.alarm_en = alarm_en; hw->hw_timer[timer_num].config.tn_alarm_en = alarm_en;
} }
/** /**
@@ -253,7 +253,7 @@ FORCE_INLINE_ATTR void timer_ll_set_alarm_enable(timg_dev_t *hw, timer_idx_t tim
*/ */
static inline bool timer_ll_get_alarm_enable(timg_dev_t *hw, timer_idx_t timer_num) static inline bool timer_ll_get_alarm_enable(timg_dev_t *hw, timer_idx_t timer_num)
{ {
return hw->hw_timer[timer_num].config.alarm_en; return hw->hw_timer[timer_num].config.tn_alarm_en;
} }
/** /**
@@ -266,7 +266,7 @@ static inline bool timer_ll_get_alarm_enable(timg_dev_t *hw, timer_idx_t timer_n
*/ */
FORCE_INLINE_ATTR void timer_ll_intr_enable(timg_dev_t *hw, timer_idx_t timer_num) FORCE_INLINE_ATTR void timer_ll_intr_enable(timg_dev_t *hw, timer_idx_t timer_num)
{ {
hw->int_ena.val |= BIT(timer_num); hw->int_ena_timers.val |= BIT(timer_num);
} }
/** /**
@@ -279,7 +279,7 @@ FORCE_INLINE_ATTR void timer_ll_intr_enable(timg_dev_t *hw, timer_idx_t timer_nu
*/ */
FORCE_INLINE_ATTR void timer_ll_intr_disable(timg_dev_t *hw, timer_idx_t timer_num) FORCE_INLINE_ATTR void timer_ll_intr_disable(timg_dev_t *hw, timer_idx_t timer_num)
{ {
hw->int_ena.val &= (~BIT(timer_num)); hw->int_ena_timers.val &= (~BIT(timer_num));
} }
/** /**
@@ -292,7 +292,7 @@ FORCE_INLINE_ATTR void timer_ll_intr_disable(timg_dev_t *hw, timer_idx_t timer_n
*/ */
FORCE_INLINE_ATTR void timer_ll_clear_intr_status(timg_dev_t *hw, timer_idx_t timer_num) FORCE_INLINE_ATTR void timer_ll_clear_intr_status(timg_dev_t *hw, timer_idx_t timer_num)
{ {
hw->int_clr.val |= BIT(timer_num); hw->int_clr_timers.val |= BIT(timer_num);
} }
/** /**
@@ -305,7 +305,7 @@ FORCE_INLINE_ATTR void timer_ll_clear_intr_status(timg_dev_t *hw, timer_idx_t ti
*/ */
FORCE_INLINE_ATTR void timer_ll_get_intr_status(timg_dev_t *hw, uint32_t *intr_status) FORCE_INLINE_ATTR void timer_ll_get_intr_status(timg_dev_t *hw, uint32_t *intr_status)
{ {
*intr_status = hw->int_st.val & 0x03; *intr_status = hw->int_st_timers.val & 0x03;
} }
/** /**
@@ -319,7 +319,7 @@ FORCE_INLINE_ATTR void timer_ll_get_intr_status(timg_dev_t *hw, uint32_t *intr_s
FORCE_INLINE_ATTR void timer_ll_get_intr_raw_status(timer_group_t group_num, uint32_t *intr_raw_status) FORCE_INLINE_ATTR void timer_ll_get_intr_raw_status(timer_group_t group_num, uint32_t *intr_raw_status)
{ {
timg_dev_t *hw = TIMER_LL_GET_HW(group_num); timg_dev_t *hw = TIMER_LL_GET_HW(group_num);
*intr_raw_status = hw->int_raw.val & 0x03; *intr_raw_status = hw->int_raw_timers.val & 0x03;
} }
/** /**
@@ -388,7 +388,7 @@ static inline bool timer_ll_get_edge_int_enable(timg_dev_t *hw, timer_idx_t time
*/ */
static inline uint32_t timer_ll_get_intr_status_reg(timg_dev_t *hw) static inline uint32_t timer_ll_get_intr_status_reg(timg_dev_t *hw)
{ {
return (uint32_t) & (hw->int_st.val); return (uint32_t) & (hw->int_st_timers.val);
} }
static inline uint32_t timer_ll_get_intr_mask_bit(timg_dev_t *hw, timer_idx_t timer_num) static inline uint32_t timer_ll_get_intr_mask_bit(timg_dev_t *hw, timer_idx_t timer_num)
@@ -406,7 +406,7 @@ static inline uint32_t timer_ll_get_intr_mask_bit(timg_dev_t *hw, timer_idx_t ti
*/ */
static inline void timer_ll_set_use_xtal(timg_dev_t *hw, timer_idx_t timer_num, bool use_xtal_en) static inline void timer_ll_set_use_xtal(timg_dev_t *hw, timer_idx_t timer_num, bool use_xtal_en)
{ {
hw->hw_timer[timer_num].config.use_xtal = use_xtal_en; hw->hw_timer[timer_num].config.tn_use_xtal = use_xtal_en;
} }
/** /**
@@ -420,7 +420,7 @@ static inline void timer_ll_set_use_xtal(timg_dev_t *hw, timer_idx_t timer_num,
*/ */
static inline bool timer_ll_get_use_xtal(timg_dev_t *hw, timer_idx_t timer_num) static inline bool timer_ll_get_use_xtal(timg_dev_t *hw, timer_idx_t timer_num)
{ {
return hw->hw_timer[timer_num].config.use_xtal; return hw->hw_timer[timer_num].config.tn_use_xtal;
} }
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -20,20 +20,9 @@
extern "C" { extern "C" {
#endif #endif
/* The value that needs to be written to RTC_CNTL_WDT_WKEY to write-enable the wdt registers */
#define RTC_CNTL_WDT_WKEY_VALUE 0x50D83AA1
/* The value that needs to be written to RTC_CNTL_SWD_WPROTECT_REG to write-enable the wdt registers */ /* The value that needs to be written to RTC_CNTL_SWD_WPROTECT_REG to write-enable the wdt registers */
#define RTC_CNTL_SWD_WKEY_VALUE 0x8F1D312A #define RTC_CNTL_SWD_WKEY_VALUE 0x8F1D312A
/* Possible values for RTC_CNTL_WDT_CPU_RESET_LENGTH and RTC_CNTL_WDT_SYS_RESET_LENGTH */
#define RTC_WDT_RESET_LENGTH_100_NS 0
#define RTC_WDT_RESET_LENGTH_200_NS 1
#define RTC_WDT_RESET_LENGTH_300_NS 2
#define RTC_WDT_RESET_LENGTH_400_NS 3
#define RTC_WDT_RESET_LENGTH_500_NS 4
#define RTC_WDT_RESET_LENGTH_800_NS 5
#define RTC_WDT_RESET_LENGTH_1600_NS 6
#define RTC_WDT_RESET_LENGTH_3200_NS 7
#define RTC_CNTL_TIME0_REG RTC_CNTL_TIME_LOW0_REG #define RTC_CNTL_TIME0_REG RTC_CNTL_TIME_LOW0_REG
#define RTC_CNTL_TIME1_REG RTC_CNTL_TIME_HIGH0_REG #define RTC_CNTL_TIME1_REG RTC_CNTL_TIME_HIGH0_REG
@@ -2041,13 +2030,6 @@ ork.*/
#define RTC_CNTL_WDT_STG3_M ((RTC_CNTL_WDT_STG3_V)<<(RTC_CNTL_WDT_STG3_S)) #define RTC_CNTL_WDT_STG3_M ((RTC_CNTL_WDT_STG3_V)<<(RTC_CNTL_WDT_STG3_S))
#define RTC_CNTL_WDT_STG3_V 0x7 #define RTC_CNTL_WDT_STG3_V 0x7
#define RTC_CNTL_WDT_STG3_S 19 #define RTC_CNTL_WDT_STG3_S 19
/* RTC_CNTL_WDT_STGX : */
/*description: stage action selection values */
#define RTC_WDT_STG_SEL_OFF 0
#define RTC_WDT_STG_SEL_INT 1
#define RTC_WDT_STG_SEL_RESET_CPU 2
#define RTC_WDT_STG_SEL_RESET_SYSTEM 3
#define RTC_WDT_STG_SEL_RESET_RTC 4
/* RTC_CNTL_WDT_CPU_RESET_LENGTH : R/W ;bitpos:[18:16] ;default: 3'h1 ; */ /* RTC_CNTL_WDT_CPU_RESET_LENGTH : R/W ;bitpos:[18:16] ;default: 3'h1 ; */
/*description: CPU reset counter length.*/ /*description: CPU reset counter length.*/

File diff suppressed because it is too large Load Diff

View File

@@ -1,219 +1,559 @@
// Copyright 2017-2021 Espressif Systems (Shanghai) PTE LTD /** Copyright 2021 Espressif Systems (Shanghai) PTE LTD
// *
// Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
// You may obtain a copy of the License at * You may obtain a copy of the License at
// *
// http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
// *
// Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
// limitations under the License. * limitations under the License.
#ifndef _SOC_TIMER_GROUP_STRUCT_H_ */
#define _SOC_TIMER_GROUP_STRUCT_H_ #pragma once
#include <stdint.h> #include <stdint.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
typedef volatile struct { /** Group: Configuration and control registers */
/** Type of tnconfig register
* Timer n configuration register
*/
typedef union {
struct { struct {
union { uint32_t reserved_0:9;
struct { /** tn_use_xtal : R/W; bitpos: [9]; default: 0;
uint32_t reserved0 : 9; * 1: Use XTAL_CLK as the source clock of timer group. 0: Use APB_CLK as the source
uint32_t use_xtal : 1; * clock of timer group.
uint32_t alarm_en : 1; */
uint32_t reserved11 : 1; uint32_t tn_use_xtal:1;
uint32_t reserved12 : 1; /** tn_alarm_en : R/W/SC; bitpos: [10]; default: 0;
uint32_t divider : 16; * When set, the alarm is enabled. This bit is automatically cleared once an
uint32_t autoreload : 1; * alarm occurs.
uint32_t increase : 1; */
uint32_t enable : 1; uint32_t tn_alarm_en:1;
uint32_t reserved_11:2;
/** tn_divider : R/W; bitpos: [28:13]; default: 1;
* Timer n clock (Tn_clk) prescaler value.
*/
uint32_t tn_divider:16;
/** tn_autoreload : R/W; bitpos: [29]; default: 1;
* When set, timer n auto-reload at alarm is enabled.
*/
uint32_t tn_autoreload:1;
/** tn_increase : R/W; bitpos: [30]; default: 1;
* When set, the timer n time-base counter will increment every clock tick. When
* cleared, the timer n time-base counter will decrement.
*/
uint32_t tn_increase:1;
/** tn_en : R/W; bitpos: [31]; default: 0;
* When set, the timer n time-base counter is enabled.
*/
uint32_t tn_en:1;
}; };
uint32_t val; uint32_t val;
} config; } timg_tnconfig_reg_t;
uint32_t cnt_low;
union { /** Type of tnlo register
* Timer n current value, low 32 bits
*/
typedef union {
struct { struct {
uint32_t hi : 22; /** tn_lo : RO; bitpos: [31:0]; default: 0;
uint32_t reserved22 : 10; * After writing to TIMG_TnUPDATE_REG, the low 32 bits of the time-base counter
* of timer n can be read here.
*/
uint32_t tn_lo:32;
}; };
uint32_t val; uint32_t val;
} cnt_high; } timg_tnlo_reg_t;
union {
/** Type of tnhi register
* Timer n current value, high 22 bits
*/
typedef union {
struct { struct {
uint32_t reserved0 : 31; /** tn_hi : RO; bitpos: [21:0]; default: 0;
uint32_t update : 1; * After writing to TIMG_TnUPDATE_REG, the high 22 bits of the time-base counter
* of timer n can be read here.
*/
uint32_t tn_hi:22;
uint32_t reserved_22:10;
}; };
uint32_t val; uint32_t val;
} update; } timg_tnhi_reg_t;
uint32_t alarm_low;
union { /** Type of tnupdate register
* Write to copy current timer value to TIMGn_Tn_(LO/HI)_REG
*/
typedef union {
struct { struct {
uint32_t alarm_hi : 22; uint32_t reserved_0:31;
uint32_t reserved22 : 10; /** tn_update : R/W/SC; bitpos: [31]; default: 0;
* After writing 0 or 1 to TIMG_TnUPDATE_REG, the counter value is latched.
*/
uint32_t tn_update:1;
}; };
uint32_t val; uint32_t val;
} alarm_high; } timg_tnupdate_reg_t;
uint32_t load_low;
union { /** Type of tnalarmlo register
* Timer n alarm value, low 32 bits
*/
typedef union {
struct { struct {
uint32_t load_hi : 22; /** tn_alarm_lo : R/W; bitpos: [31:0]; default: 0;
uint32_t reserved22 : 10; * Timer n alarm trigger time-base counter value, low 32 bits.
*/
uint32_t tn_alarm_lo:32;
}; };
uint32_t val; uint32_t val;
} load_high; } timg_tnalarmlo_reg_t;
uint32_t reload;
} hw_timer[2]; /** Type of tnalarmhi register
union { * Timer n alarm value, high bits
*/
typedef union {
struct { struct {
uint32_t reserved0 : 12; /** tn_alarm_hi : R/W; bitpos: [21:0]; default: 0;
uint32_t appcpu_reset_en : 1; * Timer n alarm trigger time-base counter value, high 22 bits.
uint32_t procpu_reset_en : 1; */
uint32_t flashboot_mod_en : 1; uint32_t tn_alarm_hi:22;
uint32_t sys_reset_length : 3; uint32_t reserved_22:10;
uint32_t cpu_reset_length : 3;
uint32_t reserved21 : 1;
uint32_t reserved22 : 1;
uint32_t stg3 : 2;
uint32_t stg2 : 2;
uint32_t stg1 : 2;
uint32_t stg0 : 2;
uint32_t en : 1;
}; };
uint32_t val; uint32_t val;
} wdt_config0; } timg_tnalarmhi_reg_t;
union {
/** Type of tnloadlo register
* Timer n reload value, low 32 bits
*/
typedef union {
struct { struct {
uint32_t reserved0 : 16; /** tn_load_lo : R/W; bitpos: [31:0]; default: 0;
uint32_t clk_prescale : 16; * Low 32 bits of the value that a reload will load onto timer n time-base
* Counter.
*/
uint32_t tn_load_lo:32;
}; };
uint32_t val; uint32_t val;
} wdt_config1; } timg_tnloadlo_reg_t;
uint32_t wdt_config2;
uint32_t wdt_config3; /** Type of tnloadhi register
uint32_t wdt_config4; * Timer n reload value, high 22 bits
uint32_t wdt_config5; */
uint32_t wdt_feed; typedef union {
uint32_t wdt_wprotect;
union {
struct { struct {
uint32_t reserved0 : 12; /** tn_load_hi : R/W; bitpos: [21:0]; default: 0;
uint32_t start_cycling : 1; * High 22 bits of the value that a reload will load onto timer n time-base
uint32_t clk_sel : 2; * counter.
uint32_t rdy : 1; */
uint32_t max : 15; uint32_t tn_load_hi:22;
uint32_t start : 1; uint32_t reserved_22:10;
}; };
uint32_t val; uint32_t val;
} rtc_cali_cfg; } timg_tnloadhi_reg_t;
union {
/** Type of tnload register
* Write to reload timer from TIMG_Tn_(LOADLOLOADHI)_REG
*/
typedef union {
struct { struct {
uint32_t cycling_data_vld : 1; /** tn_load : WT; bitpos: [31:0]; default: 0;
uint32_t reserved1 : 6; *
uint32_t value : 25; * Write any value to trigger a timer n time-base counter reload.
*/
uint32_t tn_load:32;
}; };
uint32_t val; uint32_t val;
} rtc_cali_cfg1; } timg_tnload_reg_t;
union {
/** Group: Configuration and control registers for WDT */
/** Type of wdtconfig0 register
* Watchdog timer configuration register
*/
typedef union {
struct { struct {
uint32_t t0 : 1; uint32_t reserved_0:12;
uint32_t t1 : 1; /** wdt_appcpu_reset_en : R/W; bitpos: [12]; default: 0;
uint32_t wdt : 1; * Reserved
uint32_t reserved3 : 29; */
uint32_t wdt_appcpu_reset_en:1;
/** wdt_procpu_reset_en : R/W; bitpos: [13]; default: 0;
* WDT reset CPU enable.
*/
uint32_t wdt_procpu_reset_en:1;
/** wdt_flashboot_mod_en : R/W; bitpos: [14]; default: 1;
* When set, Flash boot protection is enabled.
*/
uint32_t wdt_flashboot_mod_en:1;
/** wdt_sys_reset_length : R/W; bitpos: [17:15]; default: 1;
* System reset signal length selection. 0: 100 ns, 1: 200 ns,
* 2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us.
*/
uint32_t wdt_sys_reset_length:3;
/** wdt_cpu_reset_length : R/W; bitpos: [20:18]; default: 1;
* CPU reset signal length selection. 0: 100 ns, 1: 200 ns,
* 2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us.
*/
uint32_t wdt_cpu_reset_length:3;
uint32_t reserved_21:2;
/** wdt_stg3 : R/W; bitpos: [24:23]; default: 0;
* Stage 3 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*/
uint32_t wdt_stg3:2;
/** wdt_stg2 : R/W; bitpos: [26:25]; default: 0;
* Stage 2 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*/
uint32_t wdt_stg2:2;
/** wdt_stg1 : R/W; bitpos: [28:27]; default: 0;
* Stage 1 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*/
uint32_t wdt_stg1:2;
/** wdt_stg0 : R/W; bitpos: [30:29]; default: 0;
* Stage 0 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset system.
*/
uint32_t wdt_stg0:2;
/** wdt_en : R/W; bitpos: [31]; default: 0;
* When set, MWDT is enabled.
*/
uint32_t wdt_en:1;
}; };
uint32_t val; uint32_t val;
} int_ena; } timg_wdtconfig0_reg_t;
union {
/** Type of wdtconfig1 register
* Watchdog timer prescaler register
*/
typedef union {
struct { struct {
uint32_t t0 : 1; uint32_t reserved_0:16;
uint32_t t1 : 1; /** wdt_clk_prescale : R/W; bitpos: [31:16]; default: 1;
uint32_t wdt : 1; * MWDT clock prescaler value. MWDT clock period = 12.5 ns *
uint32_t reserved3 : 29; * TIMG_WDT_CLK_PRESCALE.
*/
uint32_t wdt_clk_prescale:16;
}; };
uint32_t val; uint32_t val;
} int_raw; } timg_wdtconfig1_reg_t;
union {
/** Type of wdtconfig2 register
* Watchdog timer stage 0 timeout value
*/
typedef union {
struct { struct {
uint32_t t0 : 1; /** wdt_stg0_hold : R/W; bitpos: [31:0]; default: 26000000;
uint32_t t1 : 1; * Stage 0 timeout value, in MWDT clock cycles.
uint32_t wdt : 1; */
uint32_t reserved3 : 29; uint32_t wdt_stg0_hold:32;
}; };
uint32_t val; uint32_t val;
} int_st; } timg_wdtconfig2_reg_t;
union {
/** Type of wdtconfig3 register
* Watchdog timer stage 1 timeout value
*/
typedef union {
struct { struct {
uint32_t t0 : 1; /** wdt_stg1_hold : R/W; bitpos: [31:0]; default: 134217727;
uint32_t t1 : 1; * Stage 1 timeout value, in MWDT clock cycles.
uint32_t wdt : 1; */
uint32_t reserved3 : 29; uint32_t wdt_stg1_hold:32;
}; };
uint32_t val; uint32_t val;
} int_clr; } timg_wdtconfig3_reg_t;
union {
/** Type of wdtconfig4 register
* Watchdog timer stage 2 timeout value
*/
typedef union {
struct { struct {
uint32_t timeout : 1; /*timeout indicator*/ /** wdt_stg2_hold : R/W; bitpos: [31:0]; default: 1048575;
uint32_t reserved1 : 2; * Stage 2 timeout value, in MWDT clock cycles.
uint32_t timeout_rst_cnt : 4; /*Cycles that release calibration timeout reset*/ */
uint32_t timeout_thres : 25; /*timeout if cali value counts over threshold*/ uint32_t wdt_stg2_hold:32;
}; };
uint32_t val; uint32_t val;
} rtc_cali_cfg2; } timg_wdtconfig4_reg_t;
uint32_t reserved_84;
uint32_t reserved_88; /** Type of wdtconfig5 register
uint32_t reserved_8c; * Watchdog timer stage 3 timeout value
uint32_t reserved_90; */
uint32_t reserved_94; typedef union {
uint32_t reserved_98;
uint32_t reserved_9c;
uint32_t reserved_a0;
uint32_t reserved_a4;
uint32_t reserved_a8;
uint32_t reserved_ac;
uint32_t reserved_b0;
uint32_t reserved_b4;
uint32_t reserved_b8;
uint32_t reserved_bc;
uint32_t reserved_c0;
uint32_t reserved_c4;
uint32_t reserved_c8;
uint32_t reserved_cc;
uint32_t reserved_d0;
uint32_t reserved_d4;
uint32_t reserved_d8;
uint32_t reserved_dc;
uint32_t reserved_e0;
uint32_t reserved_e4;
uint32_t reserved_e8;
uint32_t reserved_ec;
uint32_t reserved_f0;
uint32_t reserved_f4;
union {
struct { struct {
uint32_t date : 28; /** wdt_stg3_hold : R/W; bitpos: [31:0]; default: 1048575;
uint32_t reserved28 : 4; * Stage 3 timeout value, in MWDT clock cycles.
*/
uint32_t wdt_stg3_hold:32;
}; };
uint32_t val; uint32_t val;
} timg_date; } timg_wdtconfig5_reg_t;
union {
/** Type of wdtfeed register
* Write to feed the watchdog timer
*/
typedef union {
struct { struct {
uint32_t reserved0 : 31; /** wdt_feed : WT; bitpos: [31:0]; default: 0;
* Write any value to feed the MWDT. (WO)
*/
uint32_t wdt_feed:32;
};
uint32_t val;
} timg_wdtfeed_reg_t;
/** Type of wdtwprotect register
* Watchdog write protect register
*/
typedef union {
struct {
/** wdt_wkey : R/W; bitpos: [31:0]; default: 1356348065;
* If the register contains a different value than its reset value, write
* protection is enabled.
*/
uint32_t wdt_wkey:32;
};
uint32_t val;
} timg_wdtwprotect_reg_t;
/** Group: Configuration and control registers for RTC CALI */
/** Type of rtccalicfg register
* RTC calibration configure register
*/
typedef union {
struct {
uint32_t reserved_0:12;
/** rtc_cali_start_cycling : R/W; bitpos: [12]; default: 1;
* Reserved
*/
uint32_t rtc_cali_start_cycling:1;
/** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 1;
* 0:rtc slow clock. 1:clk_80m. 2:xtal_32k.
*/
uint32_t rtc_cali_clk_sel:2;
/** rtc_cali_rdy : RO; bitpos: [15]; default: 0;
* Reserved
*/
uint32_t rtc_cali_rdy:1;
/** rtc_cali_max : R/W; bitpos: [30:16]; default: 1;
* Reserved
*/
uint32_t rtc_cali_max:15;
/** rtc_cali_start : R/W; bitpos: [31]; default: 0;
* Reserved
*/
uint32_t rtc_cali_start:1;
};
uint32_t val;
} timg_rtccalicfg_reg_t;
/** Type of rtccalicfg1 register
* RTC calibration configure1 register
*/
typedef union {
struct {
/** rtc_cali_cycling_data_vld : RO; bitpos: [0]; default: 0;
* Reserved
*/
uint32_t rtc_cali_cycling_data_vld:1;
uint32_t reserved_1:6;
/** rtc_cali_value : RO; bitpos: [31:7]; default: 0;
* Reserved
*/
uint32_t rtc_cali_value:25;
};
uint32_t val;
} timg_rtccalicfg1_reg_t;
/** Type of rtccalicfg2 register
* Timer group calibration register
*/
typedef union {
struct {
/** rtc_cali_timeout : RO; bitpos: [0]; default: 0;
* RTC calibration timeout indicator
*/
uint32_t rtc_cali_timeout:1;
uint32_t reserved_1:2;
/** rtc_cali_timeout_rst_cnt : R/W; bitpos: [6:3]; default: 3;
* Cycles that release calibration timeout reset
*/
uint32_t rtc_cali_timeout_rst_cnt:4;
/** rtc_cali_timeout_thres : R/W; bitpos: [31:7]; default: 33554431;
* Threshold value for the RTC calibration timer. If the calibration timer's value
* exceeds this threshold, a timeout is triggered.
*/
uint32_t rtc_cali_timeout_thres:25;
};
uint32_t val;
} timg_rtccalicfg2_reg_t;
/** Group: Interrupt registers */
/** Type of int_ena_timers register
* Interrupt enable bits
*/
typedef union {
struct {
/** t0_int_ena : R/W; bitpos: [0]; default: 0;
* The interrupt enable bit for the TIMG_T0_INT interrupt.
*/
uint32_t t0_int_ena:1;
/** t1_int_ena : R/W; bitpos: [1]; default: 0;
* The interrupt enable bit for the TIMG_T1_INT interrupt.
*/
uint32_t t1_int_ena:1;
/** wdt_int_ena : R/W; bitpos: [2]; default: 0;
* The interrupt enable bit for the TIMG_WDT_INT interrupt.
*/
uint32_t wdt_int_ena:1;
uint32_t reserved_3:29;
};
uint32_t val;
} timg_int_ena_timers_reg_t;
/** Type of int_raw_timers register
* Raw interrupt status
*/
typedef union {
struct {
/** t0_int_raw : R/WTC/SS; bitpos: [0]; default: 0;
* The raw interrupt status bit for the TIMG_T0_INT interrupt.
*/
uint32_t t0_int_raw:1;
/** t1_int_raw : R/WTC/SS; bitpos: [1]; default: 0;
* The raw interrupt status bit for the TIMG_T1_INT interrupt.
*/
uint32_t t1_int_raw:1;
/** wdt_int_raw : R/WTC/SS; bitpos: [2]; default: 0;
* The raw interrupt status bit for the TIMG_WDT_INT interrupt.
*/
uint32_t wdt_int_raw:1;
uint32_t reserved_3:29;
};
uint32_t val;
} timg_int_raw_timers_reg_t;
/** Type of int_st_timers register
* Masked interrupt status
*/
typedef union {
struct {
/** t0_int_st : RO; bitpos: [0]; default: 0;
* The masked interrupt status bit for the TIMG_T0_INT interrupt.
*/
uint32_t t0_int_st:1;
/** t1_int_st : RO; bitpos: [1]; default: 0;
* The masked interrupt status bit for the TIMG_T1_INT interrupt.
*/
uint32_t t1_int_st:1;
/** wdt_int_st : RO; bitpos: [2]; default: 0;
* The masked interrupt status bit for the TIMG_WDT_INT interrupt.
*/
uint32_t wdt_int_st:1;
uint32_t reserved_3:29;
};
uint32_t val;
} timg_int_st_timers_reg_t;
/** Type of int_clr_timers register
* Interrupt clear bits
*/
typedef union {
struct {
/** t0_int_clr : WT; bitpos: [0]; default: 0;
* Set this bit to clear the TIMG_T0_INT interrupt.
*/
uint32_t t0_int_clr:1;
/** t1_int_clr : WT; bitpos: [1]; default: 0;
* Set this bit to clear the TIMG_T1_INT interrupt.
*/
uint32_t t1_int_clr:1;
/** wdt_int_clr : WT; bitpos: [2]; default: 0;
* Set this bit to clear the TIMG_WDT_INT interrupt.
*/
uint32_t wdt_int_clr:1;
uint32_t reserved_3:29;
};
uint32_t val;
} timg_int_clr_timers_reg_t;
/** Group: Configuration registers */
/** Type of ntimers_date register
* Timer version control register
*/
typedef union {
struct {
/** ntimers_date : R/W; bitpos: [27:0]; default: 33566833;
* Timer version control register
*/
uint32_t ntimers_date:28;
uint32_t reserved_28:4;
};
uint32_t val;
} timg_ntimers_date_reg_t;
/** Type of regclk register
* Timer group clock gate register
*/
typedef union {
struct {
uint32_t reserved_0:31;
/** clk_en : R/W; bitpos: [31]; default: 0;
* Register clock gate signal. 1: The clock for software to read and write registers
* is always on. 0: The clock for software to read and write registers only exits when
* the operation happens.
*/
uint32_t clk_en:1; uint32_t clk_en:1;
}; };
uint32_t val; uint32_t val;
} clk; } timg_regclk_reg_t;
typedef struct {
volatile timg_tnconfig_reg_t config;
volatile timg_tnlo_reg_t lo;
volatile timg_tnhi_reg_t hi;
volatile timg_tnupdate_reg_t update;
volatile timg_tnalarmlo_reg_t alarmlo;
volatile timg_tnalarmhi_reg_t alarmhi;
volatile timg_tnloadlo_reg_t loadlo;
volatile timg_tnloadhi_reg_t loadhi;
volatile timg_tnload_reg_t load;
} timg_hwtimer_reg_t;
typedef struct {
volatile timg_hwtimer_reg_t hw_timer[2];
volatile timg_wdtconfig0_reg_t wdtconfig0;
volatile timg_wdtconfig1_reg_t wdtconfig1;
volatile timg_wdtconfig2_reg_t wdtconfig2;
volatile timg_wdtconfig3_reg_t wdtconfig3;
volatile timg_wdtconfig4_reg_t wdtconfig4;
volatile timg_wdtconfig5_reg_t wdtconfig5;
volatile timg_wdtfeed_reg_t wdtfeed;
volatile timg_wdtwprotect_reg_t wdtwprotect;
volatile timg_rtccalicfg_reg_t rtccalicfg;
volatile timg_rtccalicfg1_reg_t rtccalicfg1;
volatile timg_int_ena_timers_reg_t int_ena_timers;
volatile timg_int_raw_timers_reg_t int_raw_timers;
volatile timg_int_st_timers_reg_t int_st_timers;
volatile timg_int_clr_timers_reg_t int_clr_timers;
volatile timg_rtccalicfg2_reg_t rtccalicfg2;
uint32_t reserved_084[29];
volatile timg_ntimers_date_reg_t ntimers_date;
volatile timg_regclk_reg_t regclk;
} timg_dev_t; } timg_dev_t;
extern timg_dev_t TIMERG0; extern timg_dev_t TIMERG0;
extern timg_dev_t TIMERG1; extern timg_dev_t TIMERG1;
_Static_assert(sizeof(timg_dev_t) == 0x100, "Invalid size of timg_dev_t structure");
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /*_SOC_TIMG_STRUCT_H_ */

View File

@@ -3,21 +3,14 @@ General Purpose Timer
:link_to_translation:`zh_CN:[中文]` :link_to_translation:`zh_CN:[中文]`
{IDF_TARGET_TIMER_COUNTER_BIT_WIDTH:default="54", esp32="64", esp32s2="64", esp32c3="54"} {IDF_TARGET_TIMER_COUNTER_BIT_WIDTH:default="54", esp32="64", esp32s2="64"}
{IDF_TARGET_TIMERS_PER_GROUP:default="two", esp32c3="one"}
{IDF_TARGET_TIMERS_TOTAL:default="four", esp32c3="two"}
Introduction Introduction
------------ ------------
.. only:: not esp32c3 The {IDF_TARGET_NAME} chip contains two hardware timer groups. Each group has {IDF_TARGET_TIMERS_PER_GROUP} general-purpose hardware timer(s). They are all {IDF_TARGET_TIMER_COUNTER_BIT_WIDTH}-bit generic timers based on 16-bit pre-scalers and {IDF_TARGET_TIMER_COUNTER_BIT_WIDTH}-bit up / down counters which are capable of being auto-reloaded.
The {IDF_TARGET_NAME} chip contains two hardware timer groups. Each group has two general-purpose hardware timers.
.. only:: esp32c3
The {IDF_TARGET_NAME} chip contains two hardware timer groups. Each group has one general-purpose hardware timer and one main system watchdog timer.
All general purpose timers are based on 16-bit pre-scalers and {IDF_TARGET_TIMER_COUNTER_BIT_WIDTH}-bit auto-reload-capable up-down counters.
Functional Overview Functional Overview
@@ -36,7 +29,7 @@ The following sections of this document cover the typical steps to configure and
Timer Initialization Timer Initialization
^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^
The two {IDF_TARGET_NAME} timer groups, with two timers in each, provide the total of four individual timers for use. An {IDF_TARGET_NAME} timer group should be identified using :cpp:type:`timer_group_t`. An individual timer in a group should be identified with :cpp:type:`timer_idx_t`. The two {IDF_TARGET_NAME} timer groups, with {IDF_TARGET_TIMERS_PER_GROUP} timer(s) in each, provide the total of {IDF_TARGET_TIMERS_TOTAL} individual timers for use. An {IDF_TARGET_NAME} timer group should be identified using :cpp:type:`timer_group_t`. An individual timer in a group should be identified with :cpp:type:`timer_idx_t`.
First of all, the timer should be initialized by calling the function :cpp:func:`timer_init` and passing a structure :cpp:type:`timer_config_t` to it to define how the timer should operate. In particular, the following timer parameters can be set: First of all, the timer should be initialized by calling the function :cpp:func:`timer_init` and passing a structure :cpp:type:`timer_config_t` to it to define how the timer should operate. In particular, the following timer parameters can be set:

View File

@@ -28,17 +28,12 @@ In addition to these examples, `commmon_components` directory contains code shar
# Using Examples # Using Examples
Before building an example, be sure to follow the Getting Started guide to ensure you have the required development environment. Before building an example, be sure to follow the [ESP-IDF Getting Started Guide](https://idf.espressif.com/) to ensure you have the required development environment.
* [ESP-IDF Getting Started Guide on ESP32](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/index.html)
* [ESP-IDF Getting Started Guide on ESP32-S2](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/get-started/index.html)
* [ESP-IDF Getting Started Guide on ESP32-C3](https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/get-started/index.html)
Building an example is the same as building any other project: Building an example is the same as building any other project:
* Change into the directory of the new example you'd like to build. * Change into the directory of the new example you'd like to build.
* Run `idf.py set-target TARGET` to select the correct chip target to build before opening the project configuration menu. By default the target is `esp32` and the options are `esp32`, `esp32s2` and `esp32c3`. * Run `idf.py set-target TARGET` to select the correct chip target to build before opening the project configuration menu. By default the target is `esp32`. For all options see `idf.py set-target --help`
* Run `idf.py menuconfig` to open the project configuration menu. Most examples have a project-specific "Example Configuration" section here (for example, to set the WiFi SSID & password to use). * Run `idf.py menuconfig` to open the project configuration menu. Most examples have a project-specific "Example Configuration" section here (for example, to set the WiFi SSID & password to use).
* `idf.py build` to build the example. * `idf.py build` to build the example.
* Follow the printed instructions to flash, or run `idf.py -p PORT flash`. * Follow the printed instructions to flash, or run `idf.py -p PORT flash`.

View File

@@ -15,12 +15,7 @@ Run `idf.py -p PORT flash monitor` to build, flash and monitor the project.
(To exit the serial monitor, type ``Ctrl-]``.) (To exit the serial monitor, type ``Ctrl-]``.)
See the Getting Started Guide for all the steps to configure and use the ESP-IDF to build projects. See the [ESP-IDF Getting Started Guide](https://idf.espressif.com/) for all the steps to configure and use the ESP-IDF to build projects.
* [ESP-IDF Getting Started Guide on ESP32](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/index.html)
* [ESP-IDF Getting Started Guide on ESP32-S2](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/get-started/index.html)
* [ESP-IDF Getting Started Guide on ESP32-C3](https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/get-started/index.html)
## Example Output ## Example Output
``` ```

View File

@@ -6,7 +6,7 @@ from typing import Any
import ttfw_idf import ttfw_idf
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC') @ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32c3'])
def test_examples_timergroup(env, extra_data): # type: (Any, Any) -> None def test_examples_timergroup(env, extra_data): # type: (Any, Any) -> None
dut = env.get_dut('timer_group', 'examples/peripherals/timer_group') dut = env.get_dut('timer_group', 'examples/peripherals/timer_group')
dut.start_app() dut.start_app()

View File

@@ -10,7 +10,7 @@ Before project configuration and build, be sure to set the correct chip target u
### Hardware Required ### Hardware Required
* A development board with ESP32/ESP32-S2/ESP32-C3 SoC (e.g., ESP32-DevKitC, ESP-WROVER-KIT, etc.) * A development board with ESP32-S or ESP32-C series chip
* A USB cable for Power supply and programming * A USB cable for Power supply and programming
### Configure the project ### Configure the project
@@ -25,11 +25,7 @@ Run `idf.py -p PORT flash monitor` to build, flash and monitor the project.
(To exit the serial monitor, type ``Ctrl-]``.) (To exit the serial monitor, type ``Ctrl-]``.)
See the Getting Started Guide for all the steps to configure and use the ESP-IDF to build projects. See the [ESP-IDF Getting Started Guide](https://idf.espressif.com/) for all the steps to configure and use the ESP-IDF to build projects.
* [ESP-IDF Getting Started Guide on ESP32](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/index.html)
* [ESP-IDF Getting Started Guide on ESP32-S2](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/get-started/index.html)
* [ESP-IDF Getting Started Guide on ESP32-C3](https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/get-started/index.html)
## Example Output ## Example Output