From 6336f8191ecc10340033fb2bac30ccc446129fdf Mon Sep 17 00:00:00 2001 From: zlq Date: Mon, 20 Dec 2021 15:09:07 +0800 Subject: [PATCH] C2 rtc code --- components/esp_hw_support/include/esp_sleep.h | 6 ++ .../esp_hw_support/port/esp32c2/rtc_clk.c | 21 +---- .../esp_hw_support/port/esp32c2/rtc_init.c | 11 +-- .../esp_hw_support/port/esp32c2/rtc_pm.c | 1 - .../esp_hw_support/port/esp32c2/rtc_sleep.c | 33 ++++--- .../esp_hw_support/port/esp32c2/rtc_time.c | 14 +-- components/esp_hw_support/sleep_modes.c | 30 ++++++- components/esp_hw_support/sleep_retention.c | 2 +- components/esp_hw_support/test/test_rtc_clk.c | 24 ++++- components/esp_system/port/soc/esp32c2/clk.c | 27 +++--- .../soc/esp32/include/soc/Kconfig.soc_caps.in | 4 + components/soc/esp32/include/soc/soc_caps.h | 1 + .../esp32c2/include/soc/Kconfig.soc_caps.in | 20 ----- .../soc/esp32c2/include/soc/regi2c_defs.h | 6 +- components/soc/esp32c2/include/soc/rtc.h | 88 ++----------------- components/soc/esp32c2/include/soc/soc_caps.h | 8 -- .../esp32c3/include/soc/Kconfig.soc_caps.in | 4 - components/soc/esp32c3/include/soc/soc_caps.h | 1 - .../esp32h2/include/soc/Kconfig.soc_caps.in | 4 - components/soc/esp32h2/include/soc/soc_caps.h | 1 - .../esp32s2/include/soc/Kconfig.soc_caps.in | 4 + components/soc/esp32s2/include/soc/soc_caps.h | 2 + .../esp32s3/include/soc/Kconfig.soc_caps.in | 4 + components/soc/esp32s3/include/soc/soc_caps.h | 2 + 24 files changed, 136 insertions(+), 182 deletions(-) diff --git a/components/esp_hw_support/include/esp_sleep.h b/components/esp_hw_support/include/esp_sleep.h index 54bff37e6c..679c360baa 100644 --- a/components/esp_hw_support/include/esp_sleep.h +++ b/components/esp_hw_support/include/esp_sleep.h @@ -37,9 +37,15 @@ typedef enum { * @brief Power domains which can be powered down in sleep mode */ typedef enum { +#if SOC_PM_SUPPORT_RTC_PERIPH_PD ESP_PD_DOMAIN_RTC_PERIPH, //!< RTC IO, sensors and ULP co-processor +#endif +#if SOC_RTC_SLOW_MEM_SUPPORTED ESP_PD_DOMAIN_RTC_SLOW_MEM, //!< RTC slow memory +#endif +#if SOC_RTC_FAST_MEM_SUPPORTED ESP_PD_DOMAIN_RTC_FAST_MEM, //!< RTC fast memory +#endif ESP_PD_DOMAIN_XTAL, //!< XTAL oscillator #if SOC_PM_SUPPORT_CPU_PD ESP_PD_DOMAIN_CPU, //!< CPU core diff --git a/components/esp_hw_support/port/esp32c2/rtc_clk.c b/components/esp_hw_support/port/esp32c2/rtc_clk.c index 931d2ae3a7..2bc8633c22 100644 --- a/components/esp_hw_support/port/esp32c2/rtc_clk.c +++ b/components/esp_hw_support/port/esp32c2/rtc_clk.c @@ -35,19 +35,6 @@ static int s_cur_pll_freq; static void rtc_clk_cpu_freq_to_8m(void); - -void rtc_clk_32k_bootstrap(uint32_t cycle) -{ - /* No special bootstrapping needed for ESP32-C2, 'cycle' argument is to keep the signature - * same as for the ESP32. Just enable the XTAL here. - */ -} - -bool rtc_clk_32k_enabled(void) -{ - return 0; -} - void rtc_clk_8m_enable(bool clk_8m_en, bool d256_en) { if (clk_8m_en) { @@ -87,7 +74,7 @@ void rtc_clk_slow_freq_set(rtc_slow_freq_t slow_freq) * Or maybe this clock should be connected to digital when xtal 32k clock is enabled instead? */ REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN, - (slow_freq == RTC_SLOW_FREQ_32K_XTAL) ? 1 : 0); + (slow_freq == RTC_SLOW_FREQ_EXT_CLK) ? 1 : 0); /* The clk_8m_d256 will be closed when rtc_state in SLEEP, so if the slow_clk is 8md256, clk_8m must be force power on @@ -105,7 +92,7 @@ uint32_t rtc_clk_slow_freq_get_hz(void) { switch (rtc_clk_slow_freq_get()) { case RTC_SLOW_FREQ_RTC: return RTC_SLOW_CLK_FREQ_150K; - case RTC_SLOW_FREQ_32K_XTAL: return RTC_SLOW_CLK_FREQ_32K; + case RTC_SLOW_FREQ_EXT_CLK: return RTC_SLOW_CLK_FREQ_EXT; case RTC_SLOW_FREQ_8MD256: return RTC_SLOW_CLK_FREQ_8MD256; } return 0; @@ -154,15 +141,13 @@ void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq) REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x6B); uint8_t i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref); uint8_t i2c_bbpll_div_7_0 = div7_0; - uint8_t i2c_bbpll_dcur = (2 << I2C_BBPLL_OC_DLREF_SEL_LSB ) | (1 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur; + uint8_t i2c_bbpll_dcur = (1 << I2C_BBPLL_OC_DLREF_SEL_LSB ) | (3 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur; REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref); REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0); REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1); REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR3, dr3); REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DCUR, i2c_bbpll_dcur); REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_VCO_DBIAS, dbias); - REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DHREF_SEL, 2); - REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DLREF_SEL, 1); s_cur_pll_freq = pll_freq; } diff --git a/components/esp_hw_support/port/esp32c2/rtc_init.c b/components/esp_hw_support/port/esp32c2/rtc_init.c index b0fc68303e..4535f0fe3b 100644 --- a/components/esp_hw_support/port/esp32c2/rtc_init.c +++ b/components/esp_hw_support/port/esp32c2/rtc_init.c @@ -112,6 +112,7 @@ void rtc_init(rtc_config_t cfg) } REG_WRITE(RTC_CNTL_INT_ENA_REG, 0); REG_WRITE(RTC_CNTL_INT_CLR_REG, UINT32_MAX); + REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_FORCE_XPD_CK, 1); } rtc_vddsdio_config_t rtc_vddsdio_get_config(void) @@ -142,11 +143,11 @@ static void calibrate_ocode(void) 5. set cpu to old-config. */ rtc_slow_freq_t slow_clk_freq = rtc_clk_slow_freq_get(); - rtc_slow_freq_t rtc_slow_freq_x32k = RTC_SLOW_FREQ_32K_XTAL; + rtc_slow_freq_t rtc_slow_freq_ext_clk = RTC_SLOW_FREQ_EXT_CLK; rtc_slow_freq_t rtc_slow_freq_8MD256 = RTC_SLOW_FREQ_8MD256; rtc_cal_sel_t cal_clk = RTC_CAL_RTC_MUX; - if (slow_clk_freq == (rtc_slow_freq_x32k)) { - cal_clk = RTC_CAL_32K_XTAL; + if (slow_clk_freq == (rtc_slow_freq_ext_clk)) { + cal_clk = RTC_CAL_EXT_CLK; } else if (slow_clk_freq == rtc_slow_freq_8MD256) { cal_clk = RTC_CAL_8MD256; } @@ -240,7 +241,7 @@ uint32_t get_rtc_dbias_by_efuse(uint8_t chip_version, uint32_t dig_dbias) static void set_rtc_dig_dbias() { /* - 1. a reasonable dig_dbias which by scaning pvt to make 160 CPU run successful stored in efuse; + 1. a reasonable dig_dbias which by scaning pvt to make 120 CPU run successful stored in efuse; 2. also we store some value in efuse, include: k_rtc_ldo (slope of rtc voltage & rtc_dbias); k_dig_ldo (slope of digital voltage & digital_dbias); @@ -248,7 +249,7 @@ static void set_rtc_dig_dbias() v_dig_bias20 (digital voltage when digital dbais is 20). 3. a reasonable rtc_dbias can be calculated by a certion formula. */ - uint32_t rtc_dbias = 28, dig_dbias = 28; + uint32_t rtc_dbias = 31, dig_dbias = 26; uint8_t chip_version = esp_efuse_get_chip_ver(); if (chip_version >= 3) { dig_dbias = get_dig_dbias_by_efuse(chip_version); diff --git a/components/esp_hw_support/port/esp32c2/rtc_pm.c b/components/esp_hw_support/port/esp32c2/rtc_pm.c index aef3e08e49..cba8213e1d 100644 --- a/components/esp_hw_support/port/esp32c2/rtc_pm.c +++ b/components/esp_hw_support/port/esp32c2/rtc_pm.c @@ -43,7 +43,6 @@ pm_sw_reject_t pm_set_sleep_mode(pm_sleep_mode_t sleep_mode, void(*pmac_save_par switch (sleep_mode) { case PM_LIGHT_SLEEP: - cfg.wifi_pd_en = 1; cfg.dig_dbias_wak = 4; cfg.dig_dbias_slp = 0; cfg.rtc_dbias_wak = 0; diff --git a/components/esp_hw_support/port/esp32c2/rtc_sleep.c b/components/esp_hw_support/port/esp32c2/rtc_sleep.c index 183651ffa8..836988adb0 100644 --- a/components/esp_hw_support/port/esp32c2/rtc_sleep.c +++ b/components/esp_hw_support/port/esp32c2/rtc_sleep.c @@ -62,17 +62,15 @@ void rtc_sleep_init(rtc_sleep_config_t cfg) REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN_MONITOR, RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT); REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_BIAS_SLEEP_MONITOR, RTC_CNTL_BIASSLP_MONITOR_DEFAULT); - REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_BIAS_SLEEP_DEEP_SLP, RTC_CNTL_BIASSLP_SLEEP_DEFAULT); + REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_BIAS_SLEEP_DEEP_SLP, + (!cfg.deep_slp && cfg.xtal_fpu) ? RTC_CNTL_BIASSLP_SLEEP_ON : RTC_CNTL_BIASSLP_SLEEP_DEFAULT); REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_PD_CUR_MONITOR, RTC_CNTL_PD_CUR_MONITOR_DEFAULT); - REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_PD_CUR_DEEP_SLP, RTC_CNTL_PD_CUR_SLEEP_DEFAULT); + REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_PD_CUR_DEEP_SLP, + (!cfg.deep_slp && cfg.xtal_fpu) ? RTC_CNTL_PD_CUR_SLEEP_ON : RTC_CNTL_PD_CUR_SLEEP_DEFAULT); if (cfg.deep_slp) { REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_FORCE_XPD_CK, 0); CLEAR_PERI_REG_MASK(RTC_CNTL_REG, RTC_CNTL_REGULATOR_FORCE_PU); - unsigned atten_deep_sleep = RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT; - if (esp_efuse_get_chip_ver() < 3) { - atten_deep_sleep = 0; /* workaround for deep sleep issue in high temp on ECO2 and below */ - } - REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN_DEEP_SLP, atten_deep_sleep); + REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN_DEEP_SLP, RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT); SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_PD_EN); CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_CKGEN_I2C_PU | RTC_CNTL_PLL_I2C_PU | @@ -83,17 +81,32 @@ void rtc_sleep_init(rtc_sleep_config_t cfg) REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DG_VDD_DRV_B_SLP, RTC_CNTL_DG_VDD_DRV_B_SLP_DEFAULT); SET_PERI_REG_MASK(RTC_CNTL_REG, RTC_CNTL_REGULATOR_FORCE_PU); CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_PD_EN); - REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN_DEEP_SLP, RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT); + REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN_DEEP_SLP, + cfg.int_8m_pd_en ? RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT : RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_NODROP); } + //Keep the RTC8M_CLK on in light_sleep mode if the ledc low-speed channel is clocked by RTC8M_CLK. + if (!cfg.int_8m_pd_en && GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M)) { + CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PD); + SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU); + SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_NOGATING); + } else { + CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU); + CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_NOGATING); + } + + /* enable VDDSDIO control by state machine */ + REG_CLR_BIT(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_VDD_SPI_PWR_FORCE); + REG_SET_FIELD(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_VDD_SPI_PD_EN, cfg.vddsdio_pd_en); + REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG_SLEEP, cfg.rtc_dbias_slp); REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG_SLEEP, cfg.dig_dbias_slp); REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_DEEP_SLP_REJECT_EN, cfg.deep_slp_reject); REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_LIGHT_SLP_REJECT_EN, cfg.light_slp_reject); - /* gating XTAL clock */ - REG_CLR_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_XTAL_GLOBAL_FORCE_NOGATING); + REG_SET_FIELD(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_XTL_FORCE_PU, cfg.xtal_fpu); + REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_XTAL_GLOBAL_FORCE_NOGATING, cfg.xtal_fpu); } void rtc_sleep_low_init(uint32_t slowclk_period) diff --git a/components/esp_hw_support/port/esp32c2/rtc_time.c b/components/esp_hw_support/port/esp32c2/rtc_time.c index 2ec6f52f0f..247cb617f9 100644 --- a/components/esp_hw_support/port/esp32c2/rtc_time.c +++ b/components/esp_hw_support/port/esp32c2/rtc_time.c @@ -38,15 +38,15 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) */ if (cal_clk == RTC_CAL_RTC_MUX) { rtc_slow_freq_t slow_freq = rtc_clk_slow_freq_get(); - if (slow_freq == RTC_SLOW_FREQ_32K_XTAL) { - cal_clk = RTC_CAL_32K_XTAL; + if (slow_freq == RTC_SLOW_FREQ_EXT_CLK) { + cal_clk = RTC_CAL_EXT_CLK; } else if (slow_freq == RTC_SLOW_FREQ_8MD256) { cal_clk = RTC_CAL_8MD256; } } /* Enable requested clock (150k clock is always on) */ - int dig_32k_xtal_state = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN); - if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_state) { + int dig_ext_clk_state = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN); + if (cal_clk == RTC_CAL_EXT_CLK && !dig_ext_clk_state) { REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN, 1); } @@ -69,9 +69,9 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) /* Set timeout reg and expect time delay*/ uint32_t expected_freq; - if (cal_clk == RTC_CAL_32K_XTAL) { + if (cal_clk == RTC_CAL_EXT_CLK) { REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_X32K_CAL_TIMEOUT_THRES(slowclk_cycles)); - expected_freq = RTC_SLOW_CLK_FREQ_32K; + expected_freq = RTC_SLOW_CLK_FREQ_EXT; } else if (cal_clk == RTC_CAL_8MD256) { REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_8MD256_CAL_TIMEOUT_THRES(slowclk_cycles)); expected_freq = RTC_SLOW_CLK_FREQ_8MD256; @@ -99,7 +99,7 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) } CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START); - REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN, dig_32k_xtal_state); + REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN, dig_ext_clk_state); if (cal_clk == RTC_CAL_8MD256) { CLEAR_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN); diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 0f3f659f38..ad27186c7c 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -155,7 +155,16 @@ _Static_assert(22 >= SOC_RTCIO_PIN_COUNT, "Chip has more RTCIOs than 22, should static sleep_config_t s_config = { .pd_options = { - ESP_PD_OPTION_AUTO, ESP_PD_OPTION_AUTO, ESP_PD_OPTION_AUTO, ESP_PD_OPTION_AUTO, +#if SOC_PM_SUPPORT_RTC_PERIPH_PD + ESP_PD_OPTION_AUTO, +#endif +#if SOC_RTC_SLOW_MEM_SUPPORTED + ESP_PD_OPTION_AUTO, +#endif +#if SOC_RTC_FAST_MEM_SUPPORTED + ESP_PD_OPTION_AUTO, +#endif + ESP_PD_OPTION_AUTO, #if SOC_PM_SUPPORT_CPU_PD ESP_PD_OPTION_AUTO, #endif @@ -962,6 +971,7 @@ static void ext1_wakeup_prepare(void) rtcio_hal_input_enable(rtc_pin); #endif +#if SOC_PM_SUPPORT_RTC_PERIPH_PD // Pad configuration depends on RTC_PERIPH state in sleep mode if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] != ESP_PD_OPTION_ON) { #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED @@ -973,6 +983,7 @@ static void ext1_wakeup_prepare(void) #endif rtcio_hal_hold_enable(rtc_pin); } +#endif // Keep track of pins which are processed to bail out early rtc_gpio_mask &= ~BIT(rtc_pin); } @@ -1196,6 +1207,7 @@ static uint32_t get_power_down_flags(void) } #endif +#if SOC_RTC_FAST_MEM_SUPPORTED #if !CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP /* RTC_FAST_MEM is needed for deep sleep stub. If RTC_FAST_MEM is Auto, keep it powered on, so that deep sleep stub can run. @@ -1207,7 +1219,9 @@ static uint32_t get_power_down_flags(void) /* If RTC_FAST_MEM is used for heap, force RTC_FAST_MEM to be powered on. */ s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] = ESP_PD_OPTION_ON; #endif +#endif +#if SOC_PM_SUPPORT_RTC_PERIPH_PD // RTC_PERIPH is needed for EXT0 wakeup and GPIO wakeup. // If RTC_PERIPH is auto, and EXT0/GPIO aren't enabled, power down RTC_PERIPH. if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] == ESP_PD_OPTION_AUTO) { @@ -1224,6 +1238,7 @@ static uint32_t get_power_down_flags(void) s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] = ESP_PD_OPTION_OFF; } #else + if (s_config.wakeup_triggers & RTC_GPIO_TRIG_EN) { s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] = ESP_PD_OPTION_ON; } else { @@ -1231,6 +1246,7 @@ static uint32_t get_power_down_flags(void) } #endif // SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP } +#endif // SOC_PM_SUPPORT_RTC_PERIPH_PD #if SOC_PM_SUPPORT_CPU_PD if (!cpu_domain_pd_allowed()) { @@ -1242,27 +1258,35 @@ static uint32_t get_power_down_flags(void) s_config.pd_options[ESP_PD_DOMAIN_XTAL] = ESP_PD_OPTION_OFF; #endif - const char *option_str[] = {"OFF", "ON", "AUTO(OFF)" /* Auto works as OFF */}; + const __attribute__((unused)) char *option_str[] = {"OFF", "ON", "AUTO(OFF)" /* Auto works as OFF */}; /* This function is called from a critical section, log with ESP_EARLY_LOGD. */ +#if SOC_PM_SUPPORT_RTC_PERIPH_PD ESP_EARLY_LOGD(TAG, "RTC_PERIPH: %s", option_str[s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH]]); +#endif #if SOC_RTC_SLOW_MEM_SUPPORTED ESP_EARLY_LOGD(TAG, "RTC_SLOW_MEM: %s", option_str[s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM]]); #endif +#if SOC_RTC_FAST_MEM_SUPPORTED ESP_EARLY_LOGD(TAG, "RTC_FAST_MEM: %s", option_str[s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM]]); +#endif // Prepare flags based on the selected options uint32_t pd_flags = 0; +#if SOC_RTC_FAST_MEM_SUPPORTED if (s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] != ESP_PD_OPTION_ON) { pd_flags |= RTC_SLEEP_PD_RTC_FAST_MEM; } +#endif #if SOC_RTC_SLOW_MEM_SUPPORTED if (s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] != ESP_PD_OPTION_ON) { pd_flags |= RTC_SLEEP_PD_RTC_SLOW_MEM; } #endif +#if SOC_PM_SUPPORT_RTC_PERIPH_PD if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] != ESP_PD_OPTION_ON) { pd_flags |= RTC_SLEEP_PD_RTC_PERIPH; } +#endif #if SOC_PM_SUPPORT_CPU_PD if (s_config.pd_options[ESP_PD_DOMAIN_CPU] != ESP_PD_OPTION_ON) { @@ -1297,7 +1321,7 @@ static uint32_t get_power_down_flags(void) pd_flags |= RTC_SLEEP_PD_VDDSDIO; } -#if ((defined CONFIG_RTC_CLK_SRC_EXT_CRYS) && (defined CONFIG_RTC_EXT_CRYST_ADDIT_CURRENT)) +#if ((defined CONFIG_RTC_CLK_SRC_EXT_CRYS) && (defined CONFIG_RTC_EXT_CRYST_ADDIT_CURRENT) && (SOC_PM_SUPPORT_RTC_PERIPH_PD)) if ((s_config.wakeup_triggers & (RTC_TOUCH_TRIG_EN | RTC_ULP_TRIG_EN)) == 0) { // If enabled EXT1 only and enable the additional current by touch, should be keep RTC_PERIPH power on. pd_flags &= ~RTC_SLEEP_PD_RTC_PERIPH; diff --git a/components/esp_hw_support/sleep_retention.c b/components/esp_hw_support/sleep_retention.c index 89e9f1de57..5a708f47f6 100644 --- a/components/esp_hw_support/sleep_retention.c +++ b/components/esp_hw_support/sleep_retention.c @@ -33,7 +33,7 @@ typedef struct { rtc_cntl_sleep_retent_t retent; } sleep_retention_t; -static DRAM_ATTR sleep_retention_t s_retention; +static DRAM_ATTR __attribute__((unused)) sleep_retention_t s_retention; #if SOC_PM_SUPPORT_TAGMEM_PD diff --git a/components/esp_hw_support/test/test_rtc_clk.c b/components/esp_hw_support/test/test_rtc_clk.c index 9d30f909ef..d293f1f997 100644 --- a/components/esp_hw_support/test/test_rtc_clk.c +++ b/components/esp_hw_support/test/test_rtc_clk.c @@ -70,24 +70,40 @@ static uint32_t calibrate_one(rtc_cal_sel_t cal_clk, const char* name) TEST_CASE("RTC_SLOW_CLK sources calibration", "[rtc_clk]") { +#if !CONFIG_IDF_TARGET_ESP32C2 rtc_clk_32k_enable(true); +#endif rtc_clk_8m_enable(true, true); CALIBRATE_ONE(RTC_CAL_RTC_MUX); CALIBRATE_ONE(RTC_CAL_8MD256); - uint32_t cal_32k = CALIBRATE_ONE(RTC_CAL_32K_XTAL); +#if CONFIG_IDF_TARGET_ESP32C2 + uint32_t cal_ext_slow_clk = CALIBRATE_ONE(RTC_CAL_EXT_CLK); + if (cal_ext_slow_clk == 0) { + printf("EXT CLOCK by PIN has not started up"); + } else { + printf("switching to RTC_SLOW_FREQ_EXT_CLK: "); + rtc_clk_slow_freq_set(RTC_SLOW_FREQ_EXT_CLK); + printf("done\n"); + + CALIBRATE_ONE(RTC_CAL_RTC_MUX); + CALIBRATE_ONE(RTC_CAL_8MD256); + CALIBRATE_ONE(RTC_CAL_EXT_CLK); + } +#else + uint32_t cal_32k = CALIBRATE_ONE(RTC_CAL_32K_XTAL); if (cal_32k == 0) { printf("32K XTAL OSC has not started up"); } else { printf("switching to RTC_SLOW_FREQ_32K_XTAL: "); rtc_clk_slow_freq_set(RTC_SLOW_FREQ_32K_XTAL); printf("done\n"); - CALIBRATE_ONE(RTC_CAL_RTC_MUX); CALIBRATE_ONE(RTC_CAL_8MD256); CALIBRATE_ONE(RTC_CAL_32K_XTAL); } +#endif printf("switching to RTC_SLOW_FREQ_8MD256: "); rtc_clk_slow_freq_set(RTC_SLOW_FREQ_8MD256); @@ -95,7 +111,11 @@ TEST_CASE("RTC_SLOW_CLK sources calibration", "[rtc_clk]") CALIBRATE_ONE(RTC_CAL_RTC_MUX); CALIBRATE_ONE(RTC_CAL_8MD256); +#if CONFIG_IDF_TARGET_ESP32C2 + CALIBRATE_ONE(RTC_CAL_EXT_CLK); +#else CALIBRATE_ONE(RTC_CAL_32K_XTAL); +#endif } /* The following two are not unit tests, but are added here to make it easy to diff --git a/components/esp_system/port/soc/esp32c2/clk.c b/components/esp_system/port/soc/esp32c2/clk.c index c2b719e511..112b3347f5 100644 --- a/components/esp_system/port/soc/esp32c2/clk.c +++ b/components/esp_system/port/soc/esp32c2/clk.c @@ -52,9 +52,8 @@ */ typedef enum { SLOW_CLK_RTC = RTC_SLOW_FREQ_RTC, //!< Internal 150 kHz RC oscillator - SLOW_CLK_32K_XTAL = RTC_SLOW_FREQ_32K_XTAL, //!< External 32 kHz XTAL SLOW_CLK_8MD256 = RTC_SLOW_FREQ_8MD256, //!< Internal 8 MHz RC oscillator, divided by 256 - SLOW_CLK_32K_EXT_OSC = RTC_SLOW_FREQ_32K_XTAL | EXT_OSC_FLAG //!< External 32k oscillator connected to 32K_XP pin + SLOW_CLK_32K_EXT_OSC = RTC_SLOW_FREQ_EXT_CLK | EXT_OSC_FLAG //!< External 32k oscillator connected to 32K_XP pin } slow_clk_sel_t; static void select_rtc_slow_clk(slow_clk_sel_t slow_clk); @@ -137,27 +136,25 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk) /* number of times to repeat 32k XTAL calibration * before giving up and switching to the internal RC */ - int retry_32k_xtal = 3; + int retry_ext_clk = 3; do { - if (rtc_slow_freq == RTC_SLOW_FREQ_32K_XTAL) { - /* 32k XTAL oscillator needs to be enabled and running before it can - * be used. Hardware doesn't have a direct way of checking if the - * oscillator is running. Here we use rtc_clk_cal function to count - * the number of main XTAL cycles in the given number of 32k XTAL - * oscillator cycles. If the 32k XTAL has not started up, calibration + if (rtc_slow_freq == RTC_SLOW_FREQ_EXT_CLK) { + /* external clock needs to be connected to PIN0 before it can + * be used. Here we use rtc_clk_cal function to count + * the number of ext clk cycles in the given number of ext clk + * cycles. If the ext clk has not started up, calibration * will time out, returning 0. */ - ESP_EARLY_LOGD(TAG, "waiting for 32k oscillator to start up"); - + ESP_EARLY_LOGD(TAG, "waiting for external clock by pin0 to start up"); // When SLOW_CLK_CAL_CYCLES is set to 0, clock calibration will not be performed at startup. if (SLOW_CLK_CAL_CYCLES > 0) { - cal_val = rtc_clk_cal(RTC_CAL_32K_XTAL, SLOW_CLK_CAL_CYCLES); + cal_val = rtc_clk_cal(RTC_CAL_EXT_CLK, SLOW_CLK_CAL_CYCLES); if (cal_val == 0 || cal_val < MIN_32K_XTAL_CAL_VAL) { - if (retry_32k_xtal-- > 0) { + if (retry_ext_clk-- > 0) { continue; } - ESP_EARLY_LOGW(TAG, "32 kHz XTAL not found, switching to internal 150 kHz oscillator"); + ESP_EARLY_LOGW(TAG, "external clock connected to pin0 not found, switching to internal 150 kHz oscillator"); rtc_slow_freq = RTC_SLOW_FREQ_RTC; } } @@ -182,7 +179,7 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk) void rtc_clk_select_rtc_slow_clk(void) { - select_rtc_slow_clk(RTC_SLOW_FREQ_32K_XTAL); + select_rtc_slow_clk(RTC_SLOW_FREQ_EXT_CLK); } /* This function is not exposed as an API at this point. diff --git a/components/soc/esp32/include/soc/Kconfig.soc_caps.in b/components/soc/esp32/include/soc/Kconfig.soc_caps.in index 2460284b91..d81a6b7e73 100644 --- a/components/soc/esp32/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32/include/soc/Kconfig.soc_caps.in @@ -635,6 +635,10 @@ config SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP bool default y +config SOC_PM_SUPPORT_RTC_PERIPH_PD + bool + default y + config SOC_SDMMC_USE_IOMUX bool default y diff --git a/components/soc/esp32/include/soc/soc_caps.h b/components/soc/esp32/include/soc/soc_caps.h index c057f16658..f8d110b021 100644 --- a/components/soc/esp32/include/soc/soc_caps.h +++ b/components/soc/esp32/include/soc/soc_caps.h @@ -348,6 +348,7 @@ /*-------------------------- Power Management CAPS ---------------------------*/ #define SOC_PM_SUPPORT_EXT_WAKEUP (1) #define SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP (1) /*!