diff --git a/components/soc/esp32s2beta/include/soc/rtc.h b/components/soc/esp32s2beta/include/soc/rtc.h index 73d7f4b5d..c8e713696 100644 --- a/components/soc/esp32s2beta/include/soc/rtc.h +++ b/components/soc/esp32s2beta/include/soc/rtc.h @@ -247,6 +247,11 @@ bool rtc_clk_8md256_enabled(void); */ void rtc_clk_apll_enable(bool enable, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2, uint32_t o_div); +/** + * @brief Set XTAL wait cycles by RTC slow clock's period + */ +void rtc_clk_set_xtal_wait(void); + /** * @brief Select source for RTC_SLOW_CLK * @param slow_freq clock source (one of rtc_slow_freq_t values) diff --git a/components/soc/esp32s2beta/rtc_clk.c b/components/soc/esp32s2beta/rtc_clk.c index cdbf7d0fd..d02a18b47 100644 --- a/components/soc/esp32s2beta/rtc_clk.c +++ b/components/soc/esp32s2beta/rtc_clk.c @@ -265,6 +265,29 @@ void rtc_clk_apll_enable(bool enable, uint32_t sdm0, uint32_t sdm1, uint32_t sdm } } +void rtc_clk_set_xtal_wait(void) +{ + /* + the `xtal_wait` time need 1ms, so we need calibrate slow clk period, + and `RTC_CNTL_XTL_BUF_WAIT` depend on it. + */ + 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_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; + } else if (slow_clk_freq == rtc_slow_freq_8MD256) { + cal_clk = RTC_CAL_8MD256; + } + uint32_t slow_clk_period = rtc_clk_cal(cal_clk, 2000); + uint32_t xtal_wait_1ms = 100; + if (slow_clk_period) { + xtal_wait_1ms = (1000 << RTC_CLK_CAL_FRACT) / slow_clk_period; + } + REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, xtal_wait_1ms); +} + void rtc_clk_slow_freq_set(rtc_slow_freq_t slow_freq) { REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, slow_freq); @@ -275,6 +298,11 @@ void rtc_clk_slow_freq_set(rtc_slow_freq_t slow_freq) REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN, (slow_freq == RTC_SLOW_FREQ_32K_XTAL) ? 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 + */ + REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG,RTC_CNTL_CK8M_FORCE_PU, (slow_freq == RTC_SLOW_FREQ_8MD256) ? 1 : 0); + rtc_clk_set_xtal_wait(); ets_delay_us(DELAY_SLOW_CLK_SWITCH); } @@ -458,6 +486,7 @@ static void rtc_clk_cpu_freq_to_xtal(void) rtc_clk_apb_freq_update(xtal_freq * MHZ); s_cur_freq = RTC_CPU_FREQ_XTAL; + s_cur_pll = RTC_PLL_NONE; } /** @@ -570,12 +599,15 @@ void rtc_clk_cpu_freq_set(rtc_cpu_freq_t cpu_freq) } if ((cpu_freq == RTC_CPU_FREQ_80M) || (cpu_freq == RTC_CPU_320M_80M)) { + REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_80M_160M); DPORT_REG_SET_FIELD(DPORT_CPU_PER_CONF_REG, DPORT_CPUPERIOD_SEL, 0); ets_update_cpu_frequency(80); } else if ((cpu_freq == RTC_CPU_FREQ_160M) || (cpu_freq == RTC_CPU_320M_160M)) { + REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_80M_160M); DPORT_REG_SET_FIELD(DPORT_CPU_PER_CONF_REG, DPORT_CPUPERIOD_SEL, 1); ets_update_cpu_frequency(160); } else if (cpu_freq == RTC_CPU_FREQ_240M) { + REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_240M); DPORT_REG_SET_FIELD(DPORT_CPU_PER_CONF_REG, DPORT_CPUPERIOD_SEL, 2); ets_update_cpu_frequency(240); } diff --git a/components/soc/esp32s2beta/rtc_init.c b/components/soc/esp32s2beta/rtc_init.c index 53cbd470e..29d53753a 100644 --- a/components/soc/esp32s2beta/rtc_init.c +++ b/components/soc/esp32s2beta/rtc_init.c @@ -49,9 +49,8 @@ void rtc_init(rtc_config_t cfg) { CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PVTMON_PU); - + rtc_clk_set_xtal_wait(); REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, cfg.pll_wait); - REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, cfg.xtal_wait); REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, cfg.ck8m_wait); /* Moved from rtc sleep to rtc init to save sleep function running time */ diff --git a/components/soc/esp32s2beta/rtc_sleep.c b/components/soc/esp32s2beta/rtc_sleep.c index 892cb45ff..56865ce74 100644 --- a/components/soc/esp32s2beta/rtc_sleep.c +++ b/components/soc/esp32s2beta/rtc_sleep.c @@ -144,7 +144,7 @@ void rtc_sleep_init(rtc_sleep_config_t cfg) RTC_CNTL_RFRX_PBUS_PU | RTC_CNTL_TXRF_I2C_PU); } else { 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, 0); + REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN, 6); } /* enable VDDSDIO control by state machine */ diff --git a/components/soc/esp32s2beta/rtc_time.c b/components/soc/esp32s2beta/rtc_time.c index e6d0e139d..af7829a72 100644 --- a/components/soc/esp32s2beta/rtc_time.c +++ b/components/soc/esp32s2beta/rtc_time.c @@ -51,6 +51,14 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) } /* Prepare calibration */ REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cal_clk); + /* There may be another calibration process already running during we call this function, + * so we should wait the last process is done. + */ + if (!GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT)) { + if (GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING)) { + while(!GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY)); + } + } CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING); REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles); /* Figure out how long to wait for calibration to finish */ @@ -58,14 +66,14 @@ 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) { - REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, (slowclk_cycles << 12)); + REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, (slowclk_cycles << 13)); expected_freq = 32768; } else if (cal_clk == RTC_CAL_8MD256) { - REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, (slowclk_cycles << 12)); + REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, (slowclk_cycles << 13)); expected_freq = RTC_FAST_CLK_FREQ_APPROX / 256; } else { - REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, (slowclk_cycles << 10)); - expected_freq = 150000; + REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, (slowclk_cycles << 11)); + expected_freq = 90000; } uint32_t us_time_estimate = (uint32_t) (((uint64_t) slowclk_cycles) * MHZ / expected_freq); /* Start calibration */ @@ -85,6 +93,7 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) break; } } + 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);