From d262fe4bc9329b7acdcd788ccda63c29e6558732 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Thu, 26 Oct 2017 18:33:13 +0800 Subject: [PATCH] soc/rtc: add a function to wait for slow clock cycle Some RTC features are synchronized to RTC_SLOW_CLK, so sometimes software needs to wait for the next slow clock cycle. This function implements waiting using Timer Group clock calibration feature. --- components/soc/esp32/include/soc/rtc.h | 9 +++++++++ components/soc/esp32/rtc_time.c | 17 +++++++++++++++++ 2 files changed, 26 insertions(+) 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); + } +} +