diff --git a/components/soc/esp32/include/soc/rtc.h b/components/soc/esp32/include/soc/rtc.h index 2a5926994..584196ea7 100644 --- a/components/soc/esp32/include/soc/rtc.h +++ b/components/soc/esp32/include/soc/rtc.h @@ -373,6 +373,15 @@ uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period); */ uint64_t rtc_time_get(); +/** + * @brief Busy loop until next RTC_SLOW_CLK cycle + * + * This function returns not earlier than the next RTC_SLOW_CLK clock cycle. + * In some cases (e.g. when RTC_SLOW_CLK cycle is very close), it may return + * one RTC_SLOW_CLK cycle later. + */ +void rtc_clk_wait_for_slow_cycle(); + /** * @brief sleep configuration for rtc_sleep_init function */ diff --git a/components/soc/esp32/rtc_time.c b/components/soc/esp32/rtc_time.c index 07a9337a3..6f354f884 100644 --- a/components/soc/esp32/rtc_time.c +++ b/components/soc/esp32/rtc_time.c @@ -135,3 +135,20 @@ uint64_t rtc_time_get() t |= ((uint64_t) READ_PERI_REG(RTC_CNTL_TIME1_REG)) << 32; return t; } + +void rtc_clk_wait_for_slow_cycle() +{ + REG_CLR_BIT(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING | TIMG_RTC_CALI_START); + REG_CLR_BIT(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY); + REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, RTC_CAL_RTC_MUX); + /* Request to run calibration for 0 slow clock cycles. + * RDY bit will be set on the nearest slow clock cycle. + */ + REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, 0); + REG_SET_BIT(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START); + ets_delay_us(1); /* RDY needs some time to go low */ + while (!GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY)) { + ets_delay_us(1); + } +} +