Add support for 32k XTAL as RTC_SLOW_CLK source

- RTC_CNTL_SLOWCLK_FREQ define is removed; rtc_clk_slow_freq_get_hz
  function can be used instead to get an approximate RTC_SLOW_CLK
  frequency

- Clock calibration is performed at startup. The value is saved and used
  for timekeeping and when entering deep sleep.

- When using the 32k XTAL, startup code will wait for the oscillator to
  start up. This can be possibly optimized by starting a separate task
  to wait for oscillator startup, and performing clock switch in that
  task.

- Fix a bug that 32k XTAL would be disabled in rtc_clk_init.

- Fix a rounding error in rtc_clk_cal, which caused systematic frequency
  error.

- Fix an overflow bug which caused rtc_clk_cal to timeout early if the
  slow_clk_cycles argument would exceed certain value

- Improve 32k XTAL oscillator startup time by introducing bootstrapping
  code, which uses internal pullup/pulldown resistors on 32K_N/32K_P
  pins to set better initial conditions for the oscillator.
This commit is contained in:
Ivan Grokhotkov
2017-04-24 18:36:47 +08:00
parent 8131c77860
commit 6353bc40d7
16 changed files with 330 additions and 136 deletions

View File

@@ -17,6 +17,7 @@
#include "esp_attr.h"
#include "esp_deep_sleep.h"
#include "esp_log.h"
#include "esp_clk.h"
#include "rom/cache.h"
#include "rom/rtc.h"
#include "rom/uart.h"
@@ -183,13 +184,7 @@ esp_err_t esp_deep_sleep_enable_timer_wakeup(uint64_t time_in_us)
static void timer_wakeup_prepare()
{
// Do calibration if not using 32k XTAL
uint32_t period;
if (rtc_clk_slow_freq_get() != RTC_SLOW_FREQ_32K_XTAL) {
period = rtc_clk_cal(RTC_CAL_RTC_MUX, 128);
} else {
period = (uint32_t) ((1000000ULL /* us*Hz */ << RTC_CLK_CAL_FRACT) / 32768 /* Hz */);
}
uint32_t period = esp_clk_slowclk_cal_get();
uint64_t rtc_count_delta = rtc_time_us_to_slowclk(s_config.sleep_duration, period);
uint64_t cur_rtc_count = rtc_time_get();
rtc_sleep_set_wakeup_time(cur_rtc_count + rtc_count_delta);