rtc_clk_init.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. // Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include <stdbool.h>
  15. #include <stdint.h>
  16. #include <stddef.h>
  17. #include <stdlib.h>
  18. #include "esp32/rom/ets_sys.h"
  19. #include "esp32/rom/rtc.h"
  20. #include "esp32/rom/uart.h"
  21. #include "esp32/rom/gpio.h"
  22. #include "soc/rtc.h"
  23. #include "soc/rtc_periph.h"
  24. #include "soc/sens_periph.h"
  25. #include "soc/efuse_periph.h"
  26. #include "soc/apb_ctrl_reg.h"
  27. #include "i2c_rtc_clk.h"
  28. #include "soc_log.h"
  29. #include "sdkconfig.h"
  30. #include "xtensa/core-macros.h"
  31. #include "rtc_clk_common.h"
  32. /* Number of 8M/256 clock cycles to use for XTAL frequency estimation.
  33. * 10 cycles will take approximately 300 microseconds.
  34. */
  35. #define XTAL_FREQ_EST_CYCLES 10
  36. static rtc_xtal_freq_t rtc_clk_xtal_freq_estimate(void);
  37. static const char* TAG = "rtc_clk_init";
  38. void rtc_clk_init(rtc_clk_config_t cfg)
  39. {
  40. rtc_cpu_freq_config_t old_config, new_config;
  41. /* If we get a TG WDT system reset while running at 240MHz,
  42. * DPORT_CPUPERIOD_SEL register will be reset to 0 resulting in 120MHz
  43. * APB and CPU frequencies after reset. This will cause issues with XTAL
  44. * frequency estimation, so we switch to XTAL frequency first.
  45. *
  46. * Ideally we would only do this if RTC_CNTL_SOC_CLK_SEL == PLL and
  47. * PLL is configured for 480M, but it takes less time to switch to 40M and
  48. * run the following code than querying the PLL does.
  49. */
  50. if (REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_SOC_CLK_SEL) == RTC_CNTL_SOC_CLK_SEL_PLL) {
  51. /* We don't know actual XTAL frequency yet, assume 40MHz.
  52. * REF_TICK divider will be corrected below, once XTAL frequency is
  53. * determined.
  54. */
  55. rtc_clk_cpu_freq_to_xtal(40, 1);
  56. }
  57. /* Set tuning parameters for 8M and 150k clocks.
  58. * Note: this doesn't attempt to set the clocks to precise frequencies.
  59. * Instead, we calibrate these clocks against XTAL frequency later, when necessary.
  60. * - SCK_DCAP value controls tuning of 150k clock.
  61. * The higher the value of DCAP is, the lower is the frequency.
  62. * - CK8M_DFREQ value controls tuning of 8M clock.
  63. * CLK_8M_DFREQ constant gives the best temperature characteristics.
  64. */
  65. REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_SCK_DCAP, cfg.slow_clk_dcap);
  66. REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DFREQ, cfg.clk_8m_dfreq);
  67. /* Configure 8M clock division */
  68. REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DIV_SEL, cfg.clk_8m_div);
  69. /* Enable the internal bus used to configure PLLs */
  70. SET_PERI_REG_BITS(ANA_CONFIG_REG, ANA_CONFIG_M, ANA_CONFIG_M, ANA_CONFIG_S);
  71. CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, I2C_APLL_M | I2C_BBPLL_M);
  72. /* Estimate XTAL frequency */
  73. rtc_xtal_freq_t xtal_freq = cfg.xtal_freq;
  74. if (xtal_freq == RTC_XTAL_FREQ_AUTO) {
  75. if (clk_val_is_valid(READ_PERI_REG(RTC_XTAL_FREQ_REG))) {
  76. /* XTAL frequency has already been set, use existing value */
  77. xtal_freq = rtc_clk_xtal_freq_get();
  78. } else {
  79. /* Not set yet, estimate XTAL frequency based on RTC_FAST_CLK */
  80. xtal_freq = rtc_clk_xtal_freq_estimate();
  81. if (xtal_freq == RTC_XTAL_FREQ_AUTO) {
  82. SOC_LOGW(TAG, "Can't estimate XTAL frequency, assuming 26MHz");
  83. xtal_freq = RTC_XTAL_FREQ_26M;
  84. }
  85. }
  86. } else if (!clk_val_is_valid(READ_PERI_REG(RTC_XTAL_FREQ_REG))) {
  87. /* Exact frequency was set in sdkconfig, but still warn if autodetected
  88. * frequency is different. If autodetection failed, worst case we get a
  89. * bit of garbage output.
  90. */
  91. rtc_xtal_freq_t est_xtal_freq = rtc_clk_xtal_freq_estimate();
  92. if (est_xtal_freq != xtal_freq) {
  93. SOC_LOGW(TAG, "Possibly invalid CONFIG_ESP32_XTAL_FREQ setting (%dMHz). Detected %d MHz.",
  94. xtal_freq, est_xtal_freq);
  95. }
  96. }
  97. uart_tx_wait_idle(0);
  98. rtc_clk_xtal_freq_update(xtal_freq);
  99. rtc_clk_apb_freq_update(xtal_freq * MHZ);
  100. /* Set CPU frequency */
  101. rtc_clk_cpu_freq_get_config(&old_config);
  102. uint32_t freq_before = old_config.freq_mhz;
  103. bool res = rtc_clk_cpu_freq_mhz_to_config(cfg.cpu_freq_mhz, &new_config);
  104. if (!res) {
  105. SOC_LOGE(TAG, "invalid CPU frequency value");
  106. abort();
  107. }
  108. rtc_clk_cpu_freq_set_config(&new_config);
  109. /* Configure REF_TICK */
  110. REG_WRITE(APB_CTRL_XTAL_TICK_CONF_REG, xtal_freq - 1);
  111. REG_WRITE(APB_CTRL_PLL_TICK_CONF_REG, APB_CLK_FREQ / MHZ - 1); /* Under PLL, APB frequency is always 80MHz */
  112. /* Re-calculate the ccount to make time calculation correct. */
  113. XTHAL_SET_CCOUNT( (uint64_t)XTHAL_GET_CCOUNT() * cfg.cpu_freq_mhz / freq_before );
  114. /* Slow & fast clocks setup */
  115. if (cfg.slow_freq == RTC_SLOW_FREQ_32K_XTAL) {
  116. rtc_clk_32k_enable(true);
  117. }
  118. if (cfg.fast_freq == RTC_FAST_FREQ_8M) {
  119. bool need_8md256 = cfg.slow_freq == RTC_SLOW_FREQ_8MD256;
  120. rtc_clk_8m_enable(true, need_8md256);
  121. }
  122. rtc_clk_fast_freq_set(cfg.fast_freq);
  123. rtc_clk_slow_freq_set(cfg.slow_freq);
  124. }
  125. static rtc_xtal_freq_t rtc_clk_xtal_freq_estimate(void)
  126. {
  127. /* Enable 8M/256 clock if needed */
  128. const bool clk_8m_enabled = rtc_clk_8m_enabled();
  129. const bool clk_8md256_enabled = rtc_clk_8md256_enabled();
  130. if (!clk_8md256_enabled) {
  131. rtc_clk_8m_enable(true, true);
  132. }
  133. uint64_t cal_val = rtc_clk_cal_ratio(RTC_CAL_8MD256, XTAL_FREQ_EST_CYCLES);
  134. /* cal_val contains period of 8M/256 clock in XTAL clock cycles
  135. * (shifted by RTC_CLK_CAL_FRACT bits).
  136. * Xtal frequency will be (cal_val * 8M / 256) / 2^19
  137. */
  138. uint32_t freq_mhz = (cal_val * RTC_FAST_CLK_FREQ_APPROX / MHZ / 256 ) >> RTC_CLK_CAL_FRACT;
  139. /* Guess the XTAL type. For now, only 40 and 26MHz are supported.
  140. */
  141. switch (freq_mhz) {
  142. case 21 ... 31:
  143. return RTC_XTAL_FREQ_26M;
  144. case 32 ... 33:
  145. SOC_LOGW(TAG, "Potentially bogus XTAL frequency: %d MHz, guessing 26 MHz", freq_mhz);
  146. return RTC_XTAL_FREQ_26M;
  147. case 34 ... 35:
  148. SOC_LOGW(TAG, "Potentially bogus XTAL frequency: %d MHz, guessing 40 MHz", freq_mhz);
  149. return RTC_XTAL_FREQ_40M;
  150. case 36 ... 45:
  151. return RTC_XTAL_FREQ_40M;
  152. default:
  153. SOC_LOGW(TAG, "Bogus XTAL frequency: %d MHz", freq_mhz);
  154. return RTC_XTAL_FREQ_AUTO;
  155. }
  156. /* Restore 8M and 8md256 clocks to original state */
  157. rtc_clk_8m_enable(clk_8m_enabled, clk_8md256_enabled);
  158. }