mirror of
https://github.com/espressif/esp-idf.git
synced 2024-09-20 00:36:01 -04:00
Merge branch 'bugfix/range_CONFIG_ESP32_RTC_CLK_CAL_CYCLES' into 'master'
soc/clk: Fix range CONFIG_ESP32_RTC_CLK_CAL_CYCLES See merge request idf/esp-idf!2719
This commit is contained in:
commit
5376a06d7b
@ -694,7 +694,8 @@ config ESP32_RTC_CLK_CAL_CYCLES
|
|||||||
int "Number of cycles for RTC_SLOW_CLK calibration"
|
int "Number of cycles for RTC_SLOW_CLK calibration"
|
||||||
default 3000 if ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL
|
default 3000 if ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL
|
||||||
default 1024 if ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC
|
default 1024 if ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC
|
||||||
range 0 125000
|
range 0 27000 if ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL
|
||||||
|
range 0 32766 if ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC
|
||||||
help
|
help
|
||||||
When the startup code initializes RTC_SLOW_CLK, it can perform
|
When the startup code initializes RTC_SLOW_CLK, it can perform
|
||||||
calibration by comparing the RTC_SLOW_CLK frequency with main XTAL
|
calibration by comparing the RTC_SLOW_CLK frequency with main XTAL
|
||||||
|
@ -128,7 +128,9 @@ static void select_rtc_slow_clk(rtc_slow_freq_t slow_clk)
|
|||||||
{
|
{
|
||||||
uint32_t cal_val = 0;
|
uint32_t cal_val = 0;
|
||||||
uint32_t wait = 0;
|
uint32_t wait = 0;
|
||||||
const uint32_t warning_timeout = 3 /* sec */ * 32768 /* Hz */ / (2 * SLOW_CLK_CAL_CYCLES);
|
uint32_t freq_hz = ((slow_clk == RTC_SLOW_FREQ_32K_XTAL) ? 32768 : 150000);
|
||||||
|
uint32_t warning_timeout = 3 /* sec */ * freq_hz /* Hz */ / (SLOW_CLK_CAL_CYCLES + 1);
|
||||||
|
warning_timeout = ((warning_timeout == 0) ? 3 /* sec */ : warning_timeout);
|
||||||
bool changing_clock_to_150k = false;
|
bool changing_clock_to_150k = false;
|
||||||
do {
|
do {
|
||||||
if (slow_clk == RTC_SLOW_FREQ_32K_XTAL) {
|
if (slow_clk == RTC_SLOW_FREQ_32K_XTAL) {
|
||||||
@ -141,13 +143,16 @@ static void select_rtc_slow_clk(rtc_slow_freq_t slow_clk)
|
|||||||
*/
|
*/
|
||||||
ESP_EARLY_LOGD(TAG, "waiting for 32k oscillator to start up");
|
ESP_EARLY_LOGD(TAG, "waiting for 32k oscillator to start up");
|
||||||
rtc_clk_32k_enable(true);
|
rtc_clk_32k_enable(true);
|
||||||
|
// When SLOW_CLK_CAL_CYCLES is set to 0, clock calibration will not be performed at startup.
|
||||||
|
if (SLOW_CLK_CAL_CYCLES > 0) {
|
||||||
cal_val = rtc_clk_cal(RTC_CAL_32K_XTAL, SLOW_CLK_CAL_CYCLES);
|
cal_val = rtc_clk_cal(RTC_CAL_32K_XTAL, SLOW_CLK_CAL_CYCLES);
|
||||||
if(cal_val == 0 || cal_val < 15000000L){
|
if (cal_val == 0 || cal_val < 15000000L) {
|
||||||
ESP_EARLY_LOGE(TAG, "RTC: Not found External 32 kHz XTAL. Switching to Internal 150 kHz RC chain");
|
ESP_EARLY_LOGE(TAG, "RTC: Not found External 32 kHz XTAL. Switching to Internal 150 kHz RC chain");
|
||||||
slow_clk = RTC_SLOW_FREQ_RTC;
|
slow_clk = RTC_SLOW_FREQ_RTC;
|
||||||
changing_clock_to_150k = true;
|
changing_clock_to_150k = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
rtc_clk_slow_freq_set(slow_clk);
|
rtc_clk_slow_freq_set(slow_clk);
|
||||||
if (changing_clock_to_150k == true && wait > 1){
|
if (changing_clock_to_150k == true && wait > 1){
|
||||||
// This helps when there are errors when switching the clock from External 32 kHz XTAL to Internal 150 kHz RC chain.
|
// This helps when there are errors when switching the clock from External 32 kHz XTAL to Internal 150 kHz RC chain.
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "soc/rtc.h"
|
#include "soc/rtc.h"
|
||||||
#include "soc/rtc_cntl_reg.h"
|
#include "soc/rtc_cntl_reg.h"
|
||||||
#include "soc/timer_group_reg.h"
|
#include "soc/timer_group_reg.h"
|
||||||
|
#include "assert.h"
|
||||||
|
|
||||||
#define MHZ (1000000)
|
#define MHZ (1000000)
|
||||||
|
|
||||||
@ -35,11 +36,12 @@
|
|||||||
/**
|
/**
|
||||||
* @brief Clock calibration function used by rtc_clk_cal and rtc_clk_cal_ratio
|
* @brief Clock calibration function used by rtc_clk_cal and rtc_clk_cal_ratio
|
||||||
* @param cal_clk which clock to calibrate
|
* @param cal_clk which clock to calibrate
|
||||||
* @param slowclk_cycles number of slow clock cycles to count
|
* @param slowclk_cycles number of slow clock cycles to count. Max value is 32766.
|
||||||
* @return number of XTAL clock cycles within the given number of slow clock cycles
|
* @return number of XTAL clock cycles within the given number of slow clock cycles
|
||||||
*/
|
*/
|
||||||
static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
||||||
{
|
{
|
||||||
|
assert(slowclk_cycles < 32767);
|
||||||
/* Enable requested clock (150k clock is always on) */
|
/* Enable requested clock (150k clock is always on) */
|
||||||
int dig_32k_xtal_state = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN);
|
int dig_32k_xtal_state = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN);
|
||||||
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_state) {
|
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_state) {
|
||||||
@ -56,16 +58,21 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
|
|||||||
/* Figure out how long to wait for calibration to finish */
|
/* Figure out how long to wait for calibration to finish */
|
||||||
uint32_t expected_freq;
|
uint32_t expected_freq;
|
||||||
rtc_slow_freq_t slow_freq = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL);
|
rtc_slow_freq_t slow_freq = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL);
|
||||||
|
uint32_t us_timer_max = 0xFFFFFFFF;
|
||||||
if (cal_clk == RTC_CAL_32K_XTAL ||
|
if (cal_clk == RTC_CAL_32K_XTAL ||
|
||||||
(cal_clk == RTC_CAL_RTC_MUX && slow_freq == RTC_SLOW_FREQ_32K_XTAL)) {
|
(cal_clk == RTC_CAL_RTC_MUX && slow_freq == RTC_SLOW_FREQ_32K_XTAL)) {
|
||||||
expected_freq = 32768; /* standard 32k XTAL */
|
expected_freq = 32768; /* standard 32k XTAL */
|
||||||
|
us_timer_max = (uint32_t) (TIMG_RTC_CALI_VALUE / rtc_clk_xtal_freq_get());
|
||||||
} else if (cal_clk == RTC_CAL_8MD256 ||
|
} else if (cal_clk == RTC_CAL_8MD256 ||
|
||||||
(cal_clk == RTC_CAL_RTC_MUX && slow_freq == RTC_SLOW_FREQ_8MD256)) {
|
(cal_clk == RTC_CAL_RTC_MUX && slow_freq == RTC_SLOW_FREQ_8MD256)) {
|
||||||
expected_freq = RTC_FAST_CLK_FREQ_APPROX / 256;
|
expected_freq = RTC_FAST_CLK_FREQ_APPROX / 256;
|
||||||
} else {
|
} else {
|
||||||
expected_freq = 150000; /* 150k internal oscillator */
|
expected_freq = 150000; /* 150k internal oscillator */
|
||||||
|
us_timer_max = (uint32_t) (TIMG_RTC_CALI_VALUE / rtc_clk_xtal_freq_get());
|
||||||
}
|
}
|
||||||
uint32_t us_time_estimate = (uint32_t) (((uint64_t) slowclk_cycles) * MHZ / expected_freq);
|
uint32_t us_time_estimate = (uint32_t) (((uint64_t) slowclk_cycles) * MHZ / expected_freq);
|
||||||
|
// The required amount of slowclk_cycles can produce in a counter TIMG a overflow error. Decrease the slowclk_cycles for fix it.
|
||||||
|
assert(us_time_estimate < us_timer_max);
|
||||||
/* Start calibration */
|
/* Start calibration */
|
||||||
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
|
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
|
||||||
SET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
|
SET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
|
||||||
|
Loading…
Reference in New Issue
Block a user