diff --git a/components/esp_hw_support/port/esp32/rtc_clk.c b/components/esp_hw_support/port/esp32/rtc_clk.c index dc20cd378c..a9c246ba84 100644 --- a/components/esp_hw_support/port/esp32/rtc_clk.c +++ b/components/esp_hw_support/port/esp32/rtc_clk.c @@ -786,6 +786,11 @@ void rtc_dig_clk8m_disable(void) esp_rom_delay_us(DELAY_RTC_CLK_SWITCH); } +bool rtc_dig_8m_enabled(void) +{ + return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M); +} + /* Name used in libphy.a:phy_chip_v7.o * TODO: update the library to use rtc_clk_xtal_freq_get */ diff --git a/components/esp_hw_support/port/esp32/rtc_sleep.c b/components/esp_hw_support/port/esp32/rtc_sleep.c index 56d338bb7e..b0ee8cedc3 100644 --- a/components/esp_hw_support/port/esp32/rtc_sleep.c +++ b/components/esp_hw_support/port/esp32/rtc_sleep.c @@ -188,14 +188,7 @@ void rtc_sleep_init(rtc_sleep_config_t cfg) REG_SET_FIELD(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_XTL_FORCE_PU, cfg.xtal_fpu); - if (REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL) == RTC_SLOW_FREQ_8MD256) { - REG_SET_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU); - } else { - REG_CLR_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU); - } - //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)) { - REG_CLR_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PD); + if (!cfg.int_8m_pd_en) { REG_SET_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU); } else { REG_CLR_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU); diff --git a/components/esp_hw_support/port/esp32c3/rtc_clk.c b/components/esp_hw_support/port/esp32c3/rtc_clk.c index b34f9c642a..fa931f5e1d 100644 --- a/components/esp_hw_support/port/esp32c3/rtc_clk.c +++ b/components/esp_hw_support/port/esp32c3/rtc_clk.c @@ -516,6 +516,11 @@ void rtc_dig_clk8m_disable(void) esp_rom_delay_us(DELAY_RTC_CLK_SWITCH); } +bool rtc_dig_8m_enabled(void) +{ + return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M); +} + static bool rtc_clk_set_bbpll_always_on(void) { /* We just keep the rtc bbpll clock on just under the case that diff --git a/components/esp_hw_support/port/esp32c3/rtc_sleep.c b/components/esp_hw_support/port/esp32c3/rtc_sleep.c index cbaa4b689e..f1150910a1 100644 --- a/components/esp_hw_support/port/esp32c3/rtc_sleep.c +++ b/components/esp_hw_support/port/esp32c3/rtc_sleep.c @@ -121,9 +121,7 @@ void rtc_sleep_init(rtc_sleep_config_t cfg) 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); + if (!cfg.int_8m_pd_en) { 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 { diff --git a/components/esp_hw_support/port/esp32s2/rtc_clk.c b/components/esp_hw_support/port/esp32s2/rtc_clk.c index 159f815298..e0e0146a59 100644 --- a/components/esp_hw_support/port/esp32s2/rtc_clk.c +++ b/components/esp_hw_support/port/esp32s2/rtc_clk.c @@ -527,6 +527,11 @@ void rtc_dig_clk8m_disable(void) esp_rom_delay_us(DELAY_RTC_CLK_SWITCH); } +bool rtc_dig_8m_enabled(void) +{ + return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M); +} + /* Name used in libphy.a:phy_chip_v7.o * TODO: update the library to use rtc_clk_xtal_freq_get */ diff --git a/components/esp_hw_support/port/esp32s2/rtc_sleep.c b/components/esp_hw_support/port/esp32s2/rtc_sleep.c index 9c7ded3249..2f7959d6d9 100644 --- a/components/esp_hw_support/port/esp32s2/rtc_sleep.c +++ b/components/esp_hw_support/port/esp32s2/rtc_sleep.c @@ -119,9 +119,7 @@ void rtc_sleep_init(rtc_sleep_config_t cfg) 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)) { - REG_CLR_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PD); + if (!cfg.int_8m_pd_en) { REG_SET_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU); } else { REG_CLR_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU); diff --git a/components/esp_hw_support/port/esp32s3/rtc_clk.c b/components/esp_hw_support/port/esp32s3/rtc_clk.c index 56b13a6e15..4645393b91 100644 --- a/components/esp_hw_support/port/esp32s3/rtc_clk.c +++ b/components/esp_hw_support/port/esp32s3/rtc_clk.c @@ -544,6 +544,11 @@ void rtc_dig_clk8m_disable(void) esp_rom_delay_us(DELAY_RTC_CLK_SWITCH); } +bool rtc_dig_8m_enabled(void) +{ + return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN_M); +} + /* Name used in libphy.a:phy_chip_v7.o * TODO: update the library to use rtc_clk_xtal_freq_get */ diff --git a/components/esp_system/sleep_modes.c b/components/esp_system/sleep_modes.c index f1e59e9e6b..5e935bf314 100644 --- a/components/esp_system/sleep_modes.c +++ b/components/esp_system/sleep_modes.c @@ -504,6 +504,20 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) suspend_uarts(); } +#if SOC_RTC_SLOW_CLOCK_SUPPORT_8MD256 + //Keep the RTC8M_CLK on if RTC clock is 8MD256. + bool rtc_using_8md256 = (rtc_clk_slow_freq_get() == RTC_SLOW_FREQ_8MD256); +#else + bool rtc_using_8md256 = false; +#endif + //Keep the RTC8M_CLK on if the ledc low-speed channel is clocked by RTC8M_CLK in lightsleep mode + bool dig_8m_enabled = !deep_sleep && rtc_dig_8m_enabled(); + + //Override user-configured power modes. + if (rtc_using_8md256 || dig_8m_enabled) { + pd_flags &= ~RTC_SLEEP_PD_INT_8M; + } + // Save current frequency and switch to XTAL rtc_cpu_freq_config_t cpu_freq_config; rtc_clk_cpu_freq_get_config(&cpu_freq_config); @@ -562,6 +576,7 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) } } #endif + uint32_t reject_triggers = 0; if ((pd_flags & RTC_SLEEP_PD_DIG) == 0 && (s_config.wakeup_triggers & RTC_GPIO_TRIG_EN)) { /* Light sleep, enable sleep reject for faster return from this function, @@ -666,7 +681,7 @@ void IRAM_ATTR esp_deep_sleep_start(void) // Correct the sleep time s_config.sleep_time_adjustment = DEEP_SLEEP_TIME_OVERHEAD_US; - uint32_t force_pd_flags = RTC_SLEEP_PD_DIG | RTC_SLEEP_PD_VDDSDIO; + uint32_t force_pd_flags = RTC_SLEEP_PD_DIG | RTC_SLEEP_PD_VDDSDIO | RTC_SLEEP_PD_INT_8M | RTC_SLEEP_PD_XTAL; #if SOC_PM_SUPPORT_WIFI_PD force_pd_flags |= RTC_SLEEP_PD_WIFI; diff --git a/components/soc/esp32/include/soc/rtc.h b/components/soc/esp32/include/soc/rtc.h index 86ca1cd881..ebdc0b6185 100644 --- a/components/soc/esp32/include/soc/rtc.h +++ b/components/soc/esp32/include/soc/rtc.h @@ -479,6 +479,11 @@ void rtc_dig_clk8m_enable(void); */ void rtc_dig_clk8m_disable(void); +/** + * @brief Get whether the rtc digital 8M clock is enabled + */ +bool rtc_dig_8m_enabled(void); + /** * @brief Calculate the real clock value after the clock calibration * @@ -528,7 +533,7 @@ typedef struct rtc_sleep_config_s { .rtc_slowmem_pd_en = ((sleep_flags) & RTC_SLEEP_PD_RTC_SLOW_MEM) ? 1 : 0, \ .rtc_peri_pd_en = ((sleep_flags) & RTC_SLEEP_PD_RTC_PERIPH) ? 1 : 0, \ .wifi_pd_en = 0, \ - .int_8m_pd_en = is_dslp(sleep_flags) ? 1 : ((sleep_flags) & RTC_SLEEP_PD_INT_8M) ? 1 : 0, \ + .int_8m_pd_en = ((sleep_flags) & RTC_SLEEP_PD_INT_8M) ? 1 : 0, \ .rom_mem_pd_en = 0, \ .deep_slp = ((sleep_flags) & RTC_SLEEP_PD_DIG) ? 1 : 0, \ .wdt_flashboot_mod_en = 0, \ diff --git a/components/soc/esp32/include/soc/soc_caps.h b/components/soc/esp32/include/soc/soc_caps.h index 0ea690ed9a..b5ecd9dca2 100644 --- a/components/soc/esp32/include/soc/soc_caps.h +++ b/components/soc/esp32/include/soc/soc_caps.h @@ -90,6 +90,7 @@ */ #define SOC_ADC_SUPPORT_DMA_MODE(PERIPH_NUM) ((PERIPH_NUM==0)? 1: 0) #define SOC_ADC_SUPPORT_RTC_CTRL 1 +#define SOC_RTC_SLOW_CLOCK_SUPPORT_8MD256 (1) /*-------------------------- BROWNOUT CAPS -----------------------------------*/ #if SOC_CAPS_ECO_VER >= 1 diff --git a/components/soc/esp32c3/include/soc/rtc.h b/components/soc/esp32c3/include/soc/rtc.h index 7ac9f8b64c..9a0c95a210 100644 --- a/components/soc/esp32c3/include/soc/rtc.h +++ b/components/soc/esp32c3/include/soc/rtc.h @@ -590,6 +590,11 @@ void rtc_dig_clk8m_enable(void); */ void rtc_dig_clk8m_disable(void); +/** + * @brief Get whether the rtc digital 8M clock is enabled + */ +bool rtc_dig_8m_enabled(void); + /** * @brief Calculate the real clock value after the clock calibration * @@ -674,7 +679,7 @@ typedef struct { .wifi_pd_en = ((sleep_flags) & RTC_SLEEP_PD_WIFI) ? 1 : 0, \ .bt_pd_en = ((sleep_flags) & RTC_SLEEP_PD_BT) ? 1 : 0, \ .cpu_pd_en = ((sleep_flags) & RTC_SLEEP_PD_CPU) ? 1 : 0, \ - .int_8m_pd_en = is_dslp(sleep_flags) ? 1 : ((sleep_flags) & RTC_SLEEP_PD_INT_8M) ? 1 : 0, \ + .int_8m_pd_en = ((sleep_flags) & RTC_SLEEP_PD_INT_8M) ? 1 : 0, \ .dig_peri_pd_en = ((sleep_flags) & RTC_SLEEP_PD_DIG_PERIPH) ? 1 : 0, \ .deep_slp = ((sleep_flags) & RTC_SLEEP_PD_DIG) ? 1 : 0, \ .wdt_flashboot_mod_en = 0, \ @@ -687,7 +692,7 @@ typedef struct { : !((sleep_flags) & RTC_SLEEP_PD_INT_8M) ? RTC_CNTL_DBIAS_1V10 \ : RTC_CNTL_DBIAS_SLP, \ .vddsdio_pd_en = ((sleep_flags) & RTC_SLEEP_PD_VDDSDIO) ? 1 : 0, \ - .xtal_fpu = is_dslp(sleep_flags) ? 0 : ((sleep_flags) & RTC_SLEEP_PD_XTAL) ? 0 : 1, \ + .xtal_fpu = ((sleep_flags) & RTC_SLEEP_PD_XTAL) ? 0 : 1, \ .deep_slp_reject = 1, \ .light_slp_reject = 1 \ }; diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index 68e9f8306a..002c506765 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -140,6 +140,8 @@ #define SOC_RTC_CNTL_CPU_PD_RETENTION_MEM_SIZE (SOC_RTC_CNTL_CPU_PD_REG_FILE_NUM * (SOC_RTC_CNTL_CPU_PD_DMA_BUS_WIDTH >> 3)) +#define SOC_RTC_SLOW_CLOCK_SUPPORT_8MD256 (1) + /*-------------------------- RTCIO CAPS --------------------------------------*/ /* No dedicated RTCIO subsystem on ESP32-C3. RTC functions are still supported * for hold, wake & 32kHz crystal functions - via rtc_cntl_reg */ diff --git a/components/soc/esp32s2/include/soc/rtc.h b/components/soc/esp32s2/include/soc/rtc.h index 62fafb2806..053ddeac2f 100644 --- a/components/soc/esp32s2/include/soc/rtc.h +++ b/components/soc/esp32s2/include/soc/rtc.h @@ -620,6 +620,11 @@ void rtc_dig_clk8m_enable(void); */ void rtc_dig_clk8m_disable(void); +/** + * @brief Get whether the rtc digital 8M clock is enabled + */ +bool rtc_dig_8m_enabled(void); + /** * @brief Calculate the real clock value after the clock calibration * @@ -695,7 +700,7 @@ typedef struct { .rtc_slowmem_pd_en = ((sleep_flags) & RTC_SLEEP_PD_RTC_SLOW_MEM) ? 1 : 0, \ .rtc_peri_pd_en = ((sleep_flags) & RTC_SLEEP_PD_RTC_PERIPH) ? 1 : 0, \ .wifi_pd_en = ((sleep_flags) & RTC_SLEEP_PD_WIFI) ? 1 : 0, \ - .int_8m_pd_en = is_dslp(sleep_flags) ? 1 : ((sleep_flags) & RTC_SLEEP_PD_INT_8M) ? 1 : 0, \ + .int_8m_pd_en = ((sleep_flags) & RTC_SLEEP_PD_INT_8M) ? 1 : 0, \ .deep_slp = ((sleep_flags) & RTC_SLEEP_PD_DIG) ? 1 : 0, \ .wdt_flashboot_mod_en = 0, \ .dig_dbias_wak = RTC_CNTL_DIG_DBIAS_1V10, \ @@ -709,7 +714,7 @@ typedef struct { : !((sleep_flags) & RTC_SLEEP_PD_XTAL) ? RTC_CNTL_DBIAS_1V10 \ : RTC_CNTL_DBIAS_1V00, \ .vddsdio_pd_en = ((sleep_flags) & RTC_SLEEP_PD_VDDSDIO) ? 1 : 0, \ - .xtal_fpu = is_dslp(sleep_flags) ? 0 : ((sleep_flags) & RTC_SLEEP_PD_XTAL) ? 0 : 1, \ + .xtal_fpu = ((sleep_flags) & RTC_SLEEP_PD_XTAL) ? 0 : 1, \ .deep_slp_reject = 1, \ .light_slp_reject = 1 \ }; diff --git a/components/soc/esp32s2/include/soc/soc_caps.h b/components/soc/esp32s2/include/soc/soc_caps.h index fcb71e0113..0967f42e75 100644 --- a/components/soc/esp32s2/include/soc/soc_caps.h +++ b/components/soc/esp32s2/include/soc/soc_caps.h @@ -63,6 +63,7 @@ #define SOC_ADC_MAX_CHANNEL_NUM (10) #define SOC_ADC_MAX_BITWIDTH (13) #define SOC_ADC_HW_CALIBRATION_V1 (1) /*!< support HW offset calibration */ +#define SOC_RTC_SLOW_CLOCK_SUPPORT_8MD256 (1) /** diff --git a/components/soc/esp32s3/include/soc/rtc.h b/components/soc/esp32s3/include/soc/rtc.h index 929510a758..593a58613f 100644 --- a/components/soc/esp32s3/include/soc/rtc.h +++ b/components/soc/esp32s3/include/soc/rtc.h @@ -584,6 +584,11 @@ void rtc_dig_clk8m_enable(void); */ void rtc_dig_clk8m_disable(void); +/** + * @brief Get whether the rtc digital 8M clock is enabled + */ +bool rtc_dig_8m_enabled(void); + /** * @brief Calculate the real clock value after the clock calibration *