rtc_time.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. /*
  2. * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <stdint.h>
  7. #include "esp32c6/rom/ets_sys.h"
  8. #include "soc/rtc.h"
  9. #include "soc/lp_timer_reg.h"
  10. #include "hal/lp_timer_hal.h"
  11. #include "hal/clk_tree_ll.h"
  12. #include "hal/timer_ll.h"
  13. #include "soc/timer_group_reg.h"
  14. #include "esp_rom_sys.h"
  15. #include "assert.h"
  16. #include "hal/efuse_hal.h"
  17. #include "soc/chip_revision.h"
  18. #include "esp_private/periph_ctrl.h"
  19. static const char *TAG = "rtc_time";
  20. /* Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0.
  21. * This feature counts the number of XTAL clock cycles within a given number of
  22. * RTC_SLOW_CLK cycles.
  23. *
  24. * Slow clock calibration feature has two modes of operation: one-off and cycling.
  25. * In cycling mode (which is enabled by default on SoC reset), counting of XTAL
  26. * cycles within RTC_SLOW_CLK cycle is done continuously. Cycling mode is enabled
  27. * using TIMG_RTC_CALI_START_CYCLING bit. In one-off mode counting is performed
  28. * once, and TIMG_RTC_CALI_RDY bit is set when counting is done. One-off mode is
  29. * enabled using TIMG_RTC_CALI_START bit.
  30. */
  31. /* On ESP32C6, TIMG_RTC_CALI_CLK_SEL can config to 0, 1, 2, 3
  32. * 0 or 3: calibrate RC_SLOW clock
  33. * 1: calibrate RC_FAST clock
  34. * 2: calibrate 32K clock, which 32k depends on reg_32k_sel: 0: Internal 32 kHz RC oscillator, 1: External 32 kHz XTAL, 2: External 32kHz clock input by lp_pad_gpio0
  35. */
  36. #define TIMG_RTC_CALI_CLK_SEL_RC_SLOW 0
  37. #define TIMG_RTC_CALI_CLK_SEL_RC_FAST 1
  38. #define TIMG_RTC_CALI_CLK_SEL_32K 2
  39. /**
  40. * @brief Clock calibration function used by rtc_clk_cal
  41. *
  42. * Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0.
  43. * This feature counts the number of XTAL clock cycles within a given number of
  44. * RTC_SLOW_CLK cycles.
  45. *
  46. * Slow clock calibration feature has two modes of operation: one-off and cycling.
  47. * In cycling mode (which is enabled by default on SoC reset), counting of XTAL
  48. * cycles within RTC_SLOW_CLK cycle is done continuously. Cycling mode is enabled
  49. * using TIMG_RTC_CALI_START_CYCLING bit. In one-off mode counting is performed
  50. * once, and TIMG_RTC_CALI_RDY bit is set when counting is done. One-off mode is
  51. * enabled using TIMG_RTC_CALI_START bit.
  52. *
  53. * @param cal_clk which clock to calibrate
  54. * @param slowclk_cycles number of slow clock cycles to count
  55. * @return number of XTAL clock cycles within the given number of slow clock cycles
  56. */
  57. static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
  58. {
  59. assert(slowclk_cycles < TIMG_RTC_CALI_MAX_V);
  60. uint32_t cali_clk_sel = 0;
  61. soc_rtc_slow_clk_src_t slow_clk_src = rtc_clk_slow_src_get();
  62. soc_rtc_slow_clk_src_t old_32k_cal_clk_sel = clk_ll_32k_calibration_get_target();
  63. if (cal_clk == RTC_CAL_RTC_MUX) {
  64. cal_clk = (rtc_cal_sel_t)slow_clk_src;
  65. }
  66. if (cal_clk == RTC_CAL_RC_FAST) {
  67. cali_clk_sel = TIMG_RTC_CALI_CLK_SEL_RC_FAST;
  68. } else if (cal_clk == RTC_CAL_RC_SLOW) {
  69. cali_clk_sel = TIMG_RTC_CALI_CLK_SEL_RC_SLOW;
  70. } else {
  71. cali_clk_sel = TIMG_RTC_CALI_CLK_SEL_32K;
  72. clk_ll_32k_calibration_set_target((soc_rtc_slow_clk_src_t)cal_clk);
  73. }
  74. /* Enable requested clock (150k clock is always on) */
  75. // All clocks on/off takes time to be stable, so we shouldn't frequently enable/disable the clock
  76. // Only enable if orignally was disabled, and set back to the disable state after calibration is done
  77. // If the clock is already on, then do nothing
  78. bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled();
  79. if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
  80. clk_ll_xtal32k_digi_enable();
  81. }
  82. bool rc_fast_enabled = clk_ll_rc_fast_is_enabled();
  83. bool dig_rc_fast_enabled = clk_ll_rc_fast_digi_is_enabled();
  84. if (cal_clk == RTC_CAL_RC_FAST) {
  85. if (!rc_fast_enabled) {
  86. rtc_clk_8m_enable(true);
  87. }
  88. if (!dig_rc_fast_enabled) {
  89. rtc_dig_clk8m_enable();
  90. }
  91. }
  92. bool rc32k_enabled = clk_ll_rc32k_is_enabled();
  93. bool dig_rc32k_enabled = clk_ll_rc32k_digi_is_enabled();
  94. if (cal_clk == RTC_CAL_RC32K) {
  95. if (!rc32k_enabled) {
  96. rtc_clk_rc32k_enable(true);
  97. }
  98. if (!dig_rc32k_enabled) {
  99. clk_ll_rc32k_digi_enable();
  100. }
  101. }
  102. /* There may be another calibration process already running during we call this function,
  103. * so we should wait the last process is done.
  104. */
  105. if (GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING)) {
  106. /**
  107. * Set a small timeout threshold to accelerate the generation of timeout.
  108. * The internal circuit will be reset when the timeout occurs and will not affect the next calibration.
  109. */
  110. REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, 1);
  111. while (!GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY)
  112. && !GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT));
  113. }
  114. /* Prepare calibration */
  115. REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cali_clk_sel);
  116. CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING);
  117. REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles);
  118. /* Figure out how long to wait for calibration to finish */
  119. /* Set timeout reg and expect time delay*/
  120. uint32_t expected_freq;
  121. if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_32K) {
  122. REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_32K_CAL_TIMEOUT_THRES(slowclk_cycles));
  123. expected_freq = SOC_CLK_XTAL32K_FREQ_APPROX;
  124. } else if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_RC_FAST) {
  125. REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_FAST_CLK_20M_CAL_TIMEOUT_THRES(slowclk_cycles));
  126. expected_freq = SOC_CLK_RC_FAST_FREQ_APPROX;
  127. } else {
  128. REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_150K_CAL_TIMEOUT_THRES(slowclk_cycles));
  129. expected_freq = SOC_CLK_RC_SLOW_FREQ_APPROX;
  130. }
  131. uint32_t us_time_estimate = (uint32_t) (((uint64_t) slowclk_cycles) * MHZ / expected_freq);
  132. /* Start calibration */
  133. CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
  134. SET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
  135. /* Wait for calibration to finish up to another us_time_estimate */
  136. esp_rom_delay_us(us_time_estimate);
  137. uint32_t cal_val;
  138. while (true) {
  139. if (GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY)) {
  140. cal_val = REG_GET_FIELD(TIMG_RTCCALICFG1_REG(0), TIMG_RTC_CALI_VALUE);
  141. /*The Fosc CLK of calibration circuit is divided by 32 for ECO1.
  142. So we need to multiply the frequency of the Fosc for ECO1 and above chips by 32 times.
  143. And ensure that this modification will not affect ECO0.*/
  144. if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) {
  145. if (cal_clk == RTC_CAL_RC_FAST) {
  146. cal_val = cal_val >> 5;
  147. }
  148. }
  149. break;
  150. }
  151. if (GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT)) {
  152. cal_val = 0;
  153. break;
  154. }
  155. }
  156. CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
  157. /* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */
  158. if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
  159. clk_ll_xtal32k_digi_disable();
  160. }
  161. if (cal_clk == RTC_CAL_RC_FAST) {
  162. if (!dig_rc_fast_enabled) {
  163. rtc_dig_clk8m_disable();
  164. }
  165. if (!rc_fast_enabled) {
  166. rtc_clk_8m_enable(false);
  167. }
  168. }
  169. if (cal_clk == RTC_CAL_RC32K) {
  170. if (!dig_rc32k_enabled) {
  171. clk_ll_rc32k_digi_disable();
  172. }
  173. if (!rc32k_enabled) {
  174. rtc_clk_rc32k_enable(false);
  175. }
  176. }
  177. // Always set back the calibration 32kHz clock selection
  178. if (old_32k_cal_clk_sel != SOC_RTC_SLOW_CLK_SRC_INVALID) {
  179. clk_ll_32k_calibration_set_target(old_32k_cal_clk_sel);
  180. }
  181. return cal_val;
  182. }
  183. static bool rtc_clk_cal_32k_valid(rtc_xtal_freq_t xtal_freq, uint32_t slowclk_cycles, uint64_t actual_xtal_cycles)
  184. {
  185. uint64_t expected_xtal_cycles = (xtal_freq * 1000000ULL * slowclk_cycles) >> 15; // xtal_freq(hz) * slowclk_cycles / 32768
  186. uint64_t delta = expected_xtal_cycles / 2000; // 5/10000 = 0.05% error range
  187. return (actual_xtal_cycles >= (expected_xtal_cycles - delta)) && (actual_xtal_cycles <= (expected_xtal_cycles + delta));
  188. }
  189. uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
  190. {
  191. rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get();
  192. /*The Fosc CLK of calibration circuit is divided by 32 for ECO1.
  193. So we need to divide the calibrate cycles of the FOSC for ECO1 and above chips by 32 to
  194. avoid excessive calibration time.*/
  195. if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) {
  196. if (cal_clk == RTC_CAL_RC_FAST) {
  197. slowclk_cycles = slowclk_cycles >> 5;
  198. }
  199. }
  200. uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles);
  201. if (cal_clk == RTC_CAL_32K_XTAL && !rtc_clk_cal_32k_valid(xtal_freq, slowclk_cycles, xtal_cycles)) {
  202. return 0;
  203. }
  204. uint64_t divider = ((uint64_t)xtal_freq) * slowclk_cycles;
  205. uint64_t period_64 = ((xtal_cycles << RTC_CLK_CAL_FRACT) + divider / 2 - 1) / divider;
  206. uint32_t period = (uint32_t)(period_64 & UINT32_MAX);
  207. return period;
  208. }
  209. uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period)
  210. {
  211. /* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
  212. * TODO: fix overflow.
  213. */
  214. return (time_in_us << RTC_CLK_CAL_FRACT) / period;
  215. }
  216. uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period)
  217. {
  218. return (rtc_cycles * period) >> RTC_CLK_CAL_FRACT;
  219. }
  220. uint64_t rtc_time_get(void)
  221. {
  222. return lp_timer_hal_get_cycle_count();
  223. }
  224. void rtc_clk_wait_for_slow_cycle(void) //This function may not by useful any more
  225. {
  226. // TODO: IDF-5781
  227. ESP_EARLY_LOGW(TAG, "rtc_clk_wait_for_slow_cycle() has not been implemented yet");
  228. }
  229. uint32_t rtc_clk_freq_cal(uint32_t cal_val)
  230. {
  231. if (cal_val == 0) {
  232. return 0; // cal_val will be denominator, return 0 as the symbol of failure.
  233. }
  234. return 1000000ULL * (1 << RTC_CLK_CAL_FRACT) / cal_val;
  235. }
  236. /// @brief if the calibration is used, we need to enable the timer group0 first
  237. __attribute__((constructor))
  238. static void enable_timer_group0_for_calibration(void)
  239. {
  240. PERIPH_RCC_ACQUIRE_ATOMIC(PERIPH_TIMG0_MODULE, ref_count) {
  241. if (ref_count == 0) {
  242. timer_ll_enable_bus_clock(0, true);
  243. timer_ll_reset_register(0);
  244. }
  245. }
  246. }