mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-05 21:54:33 +02:00
fix(clk): ESP32H21 uses RC_SLOW_D4 as RTC slow clock
This commit is contained in:
@@ -1,11 +1,11 @@
|
|||||||
choice RTC_CLK_SRC
|
choice RTC_CLK_SRC
|
||||||
prompt "RTC clock source"
|
prompt "RTC clock source"
|
||||||
default RTC_CLK_SRC_INT_RC
|
default RTC_CLK_SRC_INT_RC_D4
|
||||||
help
|
help
|
||||||
Choose which clock is used as RTC clock source.
|
Choose which clock is used as RTC clock source.
|
||||||
|
|
||||||
config RTC_CLK_SRC_INT_RC
|
config RTC_CLK_SRC_INT_RC_D4
|
||||||
bool "Internal 600 kHz RC oscillator"
|
bool "Internal 600 kHz RC oscillator, divide by 4"
|
||||||
config RTC_CLK_SRC_EXT_CRYS
|
config RTC_CLK_SRC_EXT_CRYS
|
||||||
bool "External 32 kHz crystal"
|
bool "External 32 kHz crystal"
|
||||||
select ESP_SYSTEM_RTC_EXT_XTAL
|
select ESP_SYSTEM_RTC_EXT_XTAL
|
||||||
@@ -17,9 +17,9 @@ endchoice
|
|||||||
config RTC_CLK_CAL_CYCLES
|
config 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 RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC
|
default 3000 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC
|
||||||
default 1024 if RTC_CLK_SRC_INT_RC
|
default 1024 if RTC_CLK_SRC_INT_RC_D4
|
||||||
range 0 8190 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC
|
range 0 8190 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC
|
||||||
range 0 32766 if RTC_CLK_SRC_INT_RC
|
range 0 32766 if RTC_CLK_SRC_INT_RC_D4
|
||||||
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
|
||||||
@@ -31,7 +31,7 @@ config RTC_CLK_CAL_CYCLES
|
|||||||
When this option is set to 0, clock calibration will not be performed at
|
When this option is set to 0, clock calibration will not be performed at
|
||||||
startup, and approximate clock frequencies will be assumed:
|
startup, and approximate clock frequencies will be assumed:
|
||||||
|
|
||||||
- 600000 Hz if internal RC oscillator is used as clock source. For this use value 1024.
|
- 150000 Hz if internal RC oscillator is used as clock source. For this use value 1024.
|
||||||
- 32768 Hz if the 32k crystal oscillator is used. For this use value 3000 or more.
|
- 32768 Hz if the 32k crystal oscillator is used. For this use value 3000 or more.
|
||||||
In case more value will help improve the definition of the launch of the crystal.
|
In case more value will help improve the definition of the launch of the crystal.
|
||||||
If the crystal could not start, it will be switched to internal RC.
|
If the crystal could not start, it will be switched to internal RC.
|
||||||
|
@@ -109,15 +109,14 @@ typedef struct rtc_cpu_freq_config_s {
|
|||||||
* @brief Clock source to be calibrated using rtc_clk_cal function
|
* @brief Clock source to be calibrated using rtc_clk_cal function
|
||||||
*
|
*
|
||||||
* @note On previous targets, the enum values somehow reflects the register field values of TIMG_RTC_CALI_CLK_SEL
|
* @note On previous targets, the enum values somehow reflects the register field values of TIMG_RTC_CALI_CLK_SEL
|
||||||
* However, this is not true on ESP32H21. The conversion to register field values is explicitly done in
|
* However, this is not true on ESP32H21. The conversion to register field values is explicitly done internally
|
||||||
* rtc_clk_cal_internal
|
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
RTC_CAL_RTC_MUX = -1, //!< Currently selected RTC_SLOW_CLK
|
RTC_CAL_RTC_MUX = -1, //!< Currently selected RTC_SLOW_CLK
|
||||||
RTC_CAL_RC_SLOW = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, //!< Internal 600kHz RC oscillator
|
RTC_CAL_RC_SLOW = CLK_CAL_RC_SLOW, //!< Internal 600kHz RC oscillator
|
||||||
RTC_CAL_32K_XTAL = SOC_RTC_SLOW_CLK_SRC_XTAL32K, //!< External 32kHz XTAL, as one type of 32k clock
|
RTC_CAL_32K_XTAL = CLK_CAL_32K_XTAL, //!< External 32kHz XTAL, as one type of 32k clock
|
||||||
RTC_CAL_32K_OSC_SLOW = SOC_RTC_SLOW_CLK_SRC_OSC_SLOW, //!< External slow clock signal input by lp_pad_gpiox, as one type of 32k clock
|
RTC_CAL_32K_OSC_SLOW = CLK_CAL_32K_OSC_SLOW, //!< External slow clock signal input by gpio11, as one type of 32k clock
|
||||||
RTC_CAL_RC_FAST //!< Internal 20MHz RC oscillator
|
RTC_CAL_RC_FAST = CLK_CAL_RC_FAST, //!< Internal 20MHz RC oscillator
|
||||||
} rtc_cal_sel_t;
|
} rtc_cal_sel_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -141,8 +140,8 @@ typedef struct {
|
|||||||
.xtal_freq = CONFIG_XTAL_FREQ, \
|
.xtal_freq = CONFIG_XTAL_FREQ, \
|
||||||
.cpu_freq_mhz = CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ, \
|
.cpu_freq_mhz = CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ, \
|
||||||
.fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \
|
.fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \
|
||||||
.slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \
|
.slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4, \
|
||||||
.clk_rtc_clk_div = 0, \
|
.clk_rtc_clk_div = 3, \
|
||||||
.clk_8m_clk_div = 0, \
|
.clk_8m_clk_div = 0, \
|
||||||
.slow_clk_dcap = RTC_CNTL_SCK_DCAP_DEFAULT, \
|
.slow_clk_dcap = RTC_CNTL_SCK_DCAP_DEFAULT, \
|
||||||
.clk_8m_dfreq = RTC_CNTL_CK8M_DFREQ_DEFAULT, \
|
.clk_8m_dfreq = RTC_CNTL_CK8M_DFREQ_DEFAULT, \
|
||||||
|
@@ -249,6 +249,10 @@ void pmu_init()
|
|||||||
|
|
||||||
pmu_power_domain_force_default(PMU_instance());
|
pmu_power_domain_force_default(PMU_instance());
|
||||||
|
|
||||||
|
// default ccm mode
|
||||||
|
REG_SET_FIELD(PMU_DCM_CTRL_REG, PMU_DCDC_CCM_SW_EN, 1);
|
||||||
|
REG_SET_FIELD(PMU_HP_ACTIVE_BIAS_REG, PMU_HP_ACTIVE_DCDC_CCM_ENB, 0);
|
||||||
|
|
||||||
#if !CONFIG_IDF_ENV_FPGA
|
#if !CONFIG_IDF_ENV_FPGA
|
||||||
// TODO: IDF-11548
|
// TODO: IDF-11548
|
||||||
// if (esp_rom_get_reset_reason(0) == RESET_REASON_CHIP_POWER_ON) {
|
// if (esp_rom_get_reset_reason(0) == RESET_REASON_CHIP_POWER_ON) {
|
||||||
|
@@ -106,7 +106,7 @@ soc_rtc_slow_clk_src_t rtc_clk_slow_src_get(void)
|
|||||||
uint32_t rtc_clk_slow_freq_get_hz(void)
|
uint32_t rtc_clk_slow_freq_get_hz(void)
|
||||||
{
|
{
|
||||||
switch (rtc_clk_slow_src_get()) {
|
switch (rtc_clk_slow_src_get()) {
|
||||||
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW: return SOC_CLK_RC_SLOW_FREQ_APPROX;
|
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4: return SOC_CLK_RC_SLOW_FREQ_APPROX / 4;
|
||||||
case SOC_RTC_SLOW_CLK_SRC_XTAL32K: return SOC_CLK_XTAL32K_FREQ_APPROX;
|
case SOC_RTC_SLOW_CLK_SRC_XTAL32K: return SOC_CLK_XTAL32K_FREQ_APPROX;
|
||||||
case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW: return SOC_CLK_OSC_SLOW_FREQ_APPROX;
|
case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW: return SOC_CLK_OSC_SLOW_FREQ_APPROX;
|
||||||
default: return 0;
|
default: return 0;
|
||||||
|
@@ -27,34 +27,28 @@ __attribute__((unused)) static const char *TAG = "rtc_time";
|
|||||||
#define RTC_SLOW_CLK_32K_CAL_TIMEOUT_THRES(cycles) (cycles << 12)
|
#define RTC_SLOW_CLK_32K_CAL_TIMEOUT_THRES(cycles) (cycles << 12)
|
||||||
#define RTC_FAST_CLK_20M_CAL_TIMEOUT_THRES(cycles) (TIMG_RTC_CALI_TIMEOUT_THRES_V) // Just use the max timeout thres value
|
#define RTC_FAST_CLK_20M_CAL_TIMEOUT_THRES(cycles) (TIMG_RTC_CALI_TIMEOUT_THRES_V) // Just use the max timeout thres value
|
||||||
|
|
||||||
/* On ESP32H21, TIMG_RTC_CALI_CLK_SEL can config to 0, 1, 2, 3
|
|
||||||
* 0 or 3: calibrate RC_SLOW clock
|
|
||||||
* 1: calibrate RC_FAST clock
|
|
||||||
* 2: calibrate 32K clock, which 32k depends on reg_32k_sel: 1: External 32 kHz XTAL, 2: External 32kHz clock input by gpio11
|
|
||||||
*/
|
|
||||||
#define TIMG_RTC_CALI_CLK_SEL_RC_SLOW 0
|
|
||||||
#define TIMG_RTC_CALI_CLK_SEL_RC_FAST 1
|
|
||||||
#define TIMG_RTC_CALI_CLK_SEL_32K 2
|
|
||||||
|
|
||||||
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 < TIMG_RTC_CALI_MAX_V);
|
assert(slowclk_cycles < TIMG_RTC_CALI_MAX_V);
|
||||||
|
|
||||||
uint32_t cali_clk_sel = 0;
|
|
||||||
soc_rtc_slow_clk_src_t slow_clk_src = rtc_clk_slow_src_get();
|
soc_rtc_slow_clk_src_t slow_clk_src = rtc_clk_slow_src_get();
|
||||||
soc_rtc_slow_clk_src_t old_32k_cal_clk_sel = clk_ll_32k_calibration_get_target();
|
soc_clk_calibration_clk_src_t cali_clk_sel = (soc_clk_calibration_clk_src_t)cal_clk;
|
||||||
if (cal_clk == RTC_CAL_RTC_MUX) {
|
if (cal_clk == RTC_CAL_RTC_MUX) {
|
||||||
cal_clk = (rtc_cal_sel_t)slow_clk_src;
|
switch (slow_clk_src) {
|
||||||
|
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4:
|
||||||
|
cali_clk_sel = CLK_CAL_RC_SLOW;
|
||||||
|
break;
|
||||||
|
case SOC_RTC_SLOW_CLK_SRC_XTAL32K:
|
||||||
|
cali_clk_sel = CLK_CAL_32K_XTAL;
|
||||||
|
break;
|
||||||
|
case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW:
|
||||||
|
cali_clk_sel = CLK_CAL_32K_OSC_SLOW;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ESP_EARLY_LOGE(TAG, "clock not supported to be calibrated");
|
||||||
|
return 0; // Invalid RTC_SLOW_CLK source
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (cal_clk == RTC_CAL_RC_FAST) {
|
|
||||||
cali_clk_sel = TIMG_RTC_CALI_CLK_SEL_RC_FAST;
|
|
||||||
} else if (cal_clk == RTC_CAL_RC_SLOW) {
|
|
||||||
cali_clk_sel = TIMG_RTC_CALI_CLK_SEL_RC_SLOW;
|
|
||||||
} else {
|
|
||||||
cali_clk_sel = TIMG_RTC_CALI_CLK_SEL_32K;
|
|
||||||
clk_ll_32k_calibration_set_target((soc_rtc_slow_clk_src_t)cal_clk);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Enable requested clock (rc_slow clock is always on) */
|
/* Enable requested clock (rc_slow clock is always on) */
|
||||||
// All clocks on/off takes time to be stable, so we shouldn't frequently enable/disable the clock
|
// All clocks on/off takes time to be stable, so we shouldn't frequently enable/disable the clock
|
||||||
@@ -90,8 +84,8 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Prepare calibration */
|
/* Prepare calibration */
|
||||||
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cali_clk_sel);
|
clk_ll_calibration_set_target(cali_clk_sel);
|
||||||
if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_RC_FAST) {
|
if (cali_clk_sel == CLK_CAL_RC_FAST) {
|
||||||
clk_ll_rc_fast_tick_conf();
|
clk_ll_rc_fast_tick_conf();
|
||||||
}
|
}
|
||||||
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING);
|
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING);
|
||||||
@@ -100,10 +94,10 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
|
|||||||
|
|
||||||
/* Set timeout reg and expect time delay*/
|
/* Set timeout reg and expect time delay*/
|
||||||
uint32_t expected_freq;
|
uint32_t expected_freq;
|
||||||
if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_32K) {
|
if (cali_clk_sel == CLK_CAL_32K_XTAL || cali_clk_sel == CLK_CAL_32K_OSC_SLOW) {
|
||||||
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_32K_CAL_TIMEOUT_THRES(slowclk_cycles));
|
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_32K_CAL_TIMEOUT_THRES(slowclk_cycles));
|
||||||
expected_freq = SOC_CLK_XTAL32K_FREQ_APPROX;
|
expected_freq = SOC_CLK_XTAL32K_FREQ_APPROX;
|
||||||
} else if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_RC_FAST) {
|
} else if (cali_clk_sel == CLK_CAL_RC_FAST) {
|
||||||
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_FAST_CLK_20M_CAL_TIMEOUT_THRES(slowclk_cycles));
|
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_FAST_CLK_20M_CAL_TIMEOUT_THRES(slowclk_cycles));
|
||||||
expected_freq = SOC_CLK_RC_FAST_FREQ_APPROX >> CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS;
|
expected_freq = SOC_CLK_RC_FAST_FREQ_APPROX >> CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS;
|
||||||
} else {
|
} else {
|
||||||
@@ -150,9 +144,9 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always set back the calibration 32kHz clock selection
|
if (cal_clk == RTC_CAL_RTC_MUX && slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4) {
|
||||||
if (old_32k_cal_clk_sel != SOC_RTC_SLOW_CLK_SRC_INVALID) {
|
// calibration was done on RC_SLOW clock, but rtc_slow_clk src is RC_SLOW_D4, so we need to multiply the cal_val by 4
|
||||||
clk_ll_32k_calibration_set_target(old_32k_cal_clk_sel);
|
cal_val *= 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cal_val;
|
return cal_val;
|
||||||
|
@@ -115,7 +115,7 @@ typedef enum {
|
|||||||
RTC_CAL_RTC_MUX = -1, //!< Currently selected RTC_SLOW_CLK
|
RTC_CAL_RTC_MUX = -1, //!< Currently selected RTC_SLOW_CLK
|
||||||
RTC_CAL_RC_SLOW = CLK_CAL_RC_SLOW, //!< Internal 600kHz RC oscillator
|
RTC_CAL_RC_SLOW = CLK_CAL_RC_SLOW, //!< Internal 600kHz RC oscillator
|
||||||
RTC_CAL_32K_XTAL = CLK_CAL_32K_XTAL, //!< External 32kHz XTAL, as one type of 32k clock
|
RTC_CAL_32K_XTAL = CLK_CAL_32K_XTAL, //!< External 32kHz XTAL, as one type of 32k clock
|
||||||
RTC_CAL_32K_OSC_SLOW = CLK_CAL_32K_OSC_SLOW, //!< External slow clock signal input by lp_pad_gpio0, as one type of 32k clock
|
RTC_CAL_32K_OSC_SLOW = CLK_CAL_32K_OSC_SLOW, //!< External slow clock signal input by gpio5, as one type of 32k clock
|
||||||
RTC_CAL_RC_FAST = CLK_CAL_RC_FAST, //!< Internal 20MHz RC oscillator
|
RTC_CAL_RC_FAST = CLK_CAL_RC_FAST, //!< Internal 20MHz RC oscillator
|
||||||
} rtc_cal_sel_t;
|
} rtc_cal_sel_t;
|
||||||
|
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
#include "esp_private/esp_pmu.h"
|
#include "esp_private/esp_pmu.h"
|
||||||
#include "soc/regi2c_dcdc.h"
|
#include "soc/regi2c_dcdc.h"
|
||||||
#include "regi2c_ctrl.h"
|
#include "regi2c_ctrl.h"
|
||||||
|
#include "esp_rom_sys.h"
|
||||||
|
|
||||||
static __attribute__((unused)) const char *TAG = "pmu_init";
|
static __attribute__((unused)) const char *TAG = "pmu_init";
|
||||||
|
|
||||||
@@ -249,4 +250,11 @@ void pmu_init(void)
|
|||||||
// close rfpll to decrease mslp_cur
|
// close rfpll to decrease mslp_cur
|
||||||
REG_SET_FIELD(PMU_RF_PWC_REG, PMU_XPD_FORCE_RFPLL, 1);
|
REG_SET_FIELD(PMU_RF_PWC_REG, PMU_XPD_FORCE_RFPLL, 1);
|
||||||
REG_SET_FIELD(PMU_RF_PWC_REG, PMU_XPD_RFPLL, 0);
|
REG_SET_FIELD(PMU_RF_PWC_REG, PMU_XPD_RFPLL, 0);
|
||||||
|
|
||||||
|
#if !CONFIG_IDF_ENV_FPGA
|
||||||
|
// TODO: IDF-12313
|
||||||
|
// if (esp_rom_get_reset_reason(0) == RESET_REASON_CHIP_POWER_ON) {
|
||||||
|
// esp_ocode_calib_init();
|
||||||
|
// }
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
@@ -57,10 +57,10 @@ __attribute__((weak)) void esp_clk_init(void)
|
|||||||
|
|
||||||
#ifdef CONFIG_BOOTLOADER_WDT_ENABLE
|
#ifdef CONFIG_BOOTLOADER_WDT_ENABLE
|
||||||
// WDT uses a SLOW_CLK clock source. After a function select_rtc_slow_clk a frequency of this source can changed.
|
// WDT uses a SLOW_CLK clock source. After a function select_rtc_slow_clk a frequency of this source can changed.
|
||||||
// If the frequency changes from 600kHz to 32kHz, then the timeout set for the WDT will increase 18.75 times.
|
// If the frequency changes from 150kHz to 32kHz, then the timeout set for the WDT will increase 4.6 times.
|
||||||
// Therefore, for the time of frequency change, set a new lower timeout value (2 sec).
|
// Therefore, for the time of frequency change, set a new lower timeout value (2 sec).
|
||||||
// This prevents excessive delay before resetting in case the supply voltage is drawdown.
|
// This prevents excessive delay before resetting in case the supply voltage is drawdown.
|
||||||
// (If frequency is changed from 600kHz to 32kHz then WDT timeout will increased to 2 sec * 600/32 = 37.5 sec).
|
// (If frequency is changed from 150kHz to 32kHz then WDT timeout will increased to 2 sec * 150/32 = 9.375 sec).
|
||||||
|
|
||||||
wdt_hal_context_t rtc_wdt_ctx = RWDT_HAL_CONTEXT_DEFAULT();
|
wdt_hal_context_t rtc_wdt_ctx = RWDT_HAL_CONTEXT_DEFAULT();
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ __attribute__((weak)) void esp_clk_init(void)
|
|||||||
#elif defined(CONFIG_RTC_CLK_SRC_EXT_OSC)
|
#elif defined(CONFIG_RTC_CLK_SRC_EXT_OSC)
|
||||||
select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_OSC_SLOW);
|
select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_OSC_SLOW);
|
||||||
#else
|
#else
|
||||||
select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_RC_SLOW);
|
select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_BOOTLOADER_WDT_ENABLE
|
#ifdef CONFIG_BOOTLOADER_WDT_ENABLE
|
||||||
@@ -145,8 +145,8 @@ static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src)
|
|||||||
if (retry_32k_xtal-- > 0) {
|
if (retry_32k_xtal-- > 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ESP_EARLY_LOGW(TAG, "32 kHz clock not found, switching to internal 600 kHz oscillator");
|
ESP_EARLY_LOGW(TAG, "32 kHz clock not found, switching to internal 150 kHz oscillator");
|
||||||
rtc_slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW;
|
rtc_slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -57,9 +57,9 @@ __attribute__((weak)) void esp_clk_init(void)
|
|||||||
#ifdef CONFIG_BOOTLOADER_WDT_ENABLE
|
#ifdef CONFIG_BOOTLOADER_WDT_ENABLE
|
||||||
// WDT uses a SLOW_CLK clock source. After a function select_rtc_slow_clk a frequency of this source can changed.
|
// WDT uses a SLOW_CLK clock source. After a function select_rtc_slow_clk a frequency of this source can changed.
|
||||||
// If the frequency changes from 150kHz to 32kHz, then the timeout set for the WDT will increase 4.6 times.
|
// If the frequency changes from 150kHz to 32kHz, then the timeout set for the WDT will increase 4.6 times.
|
||||||
// Therefore, for the time of frequency change, set a new lower timeout value (1.6 sec).
|
// Therefore, for the time of frequency change, set a new lower timeout value (2 sec).
|
||||||
// This prevents excessive delay before resetting in case the supply voltage is drawdown.
|
// This prevents excessive delay before resetting in case the supply voltage is drawdown.
|
||||||
// (If frequency is changed from 150kHz to 32kHz then WDT timeout will increased to 1.6sec * 150/32 = 7.5 sec).
|
// (If frequency is changed from 150kHz to 32kHz then WDT timeout will increased to 2 sec * 150/32 = 9.375 sec).
|
||||||
wdt_hal_context_t rtc_wdt_ctx = RWDT_HAL_CONTEXT_DEFAULT();
|
wdt_hal_context_t rtc_wdt_ctx = RWDT_HAL_CONTEXT_DEFAULT();
|
||||||
uint32_t stage_timeout_ticks = (uint32_t)(2000ULL * rtc_clk_slow_freq_get_hz() / 1000ULL);
|
uint32_t stage_timeout_ticks = (uint32_t)(2000ULL * rtc_clk_slow_freq_get_hz() / 1000ULL);
|
||||||
wdt_hal_write_protect_disable(&rtc_wdt_ctx);
|
wdt_hal_write_protect_disable(&rtc_wdt_ctx);
|
||||||
|
@@ -46,8 +46,8 @@ uint32_t clk_hal_apb_get_freq_hz(void)
|
|||||||
uint32_t clk_hal_lp_slow_get_freq_hz(void)
|
uint32_t clk_hal_lp_slow_get_freq_hz(void)
|
||||||
{
|
{
|
||||||
switch (clk_ll_rtc_slow_get_src()) {
|
switch (clk_ll_rtc_slow_get_src()) {
|
||||||
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW:
|
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4:
|
||||||
return SOC_CLK_RC_SLOW_FREQ_APPROX;
|
return SOC_CLK_RC_SLOW_FREQ_APPROX / 4;
|
||||||
case SOC_RTC_SLOW_CLK_SRC_XTAL32K:
|
case SOC_RTC_SLOW_CLK_SRC_XTAL32K:
|
||||||
return SOC_CLK_XTAL32K_FREQ_APPROX;
|
return SOC_CLK_XTAL32K_FREQ_APPROX;
|
||||||
case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW:
|
case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW:
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
#include "hal/log.h"
|
#include "hal/log.h"
|
||||||
#include "esp32h21/rom/rtc.h"
|
#include "esp32h21/rom/rtc.h"
|
||||||
#include "hal/misc.h"
|
#include "hal/misc.h"
|
||||||
|
#include "soc/timer_group_struct.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -410,40 +411,40 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_apb_get_divider(voi
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Select the calibration 32kHz clock source for timergroup0
|
* @brief Select the calibration clock source for timergroup0
|
||||||
*
|
*
|
||||||
* @param in_sel One of the 32kHz clock sources (XTAL32K_CLK, OSC_SLOW_CLK)
|
* @param clk_sel One of the clock sources in soc_clk_calibration_clk_src_t
|
||||||
*/
|
*/
|
||||||
static inline __attribute__((always_inline)) void clk_ll_32k_calibration_set_target(soc_rtc_slow_clk_src_t in_sel)
|
static inline __attribute__((always_inline)) void clk_ll_calibration_set_target(soc_clk_calibration_clk_src_t clk_sel)
|
||||||
{
|
{
|
||||||
switch (in_sel) {
|
int timg_cali_clk_sel = -1;
|
||||||
case SOC_RTC_SLOW_CLK_SRC_XTAL32K:
|
int clk_32k_sel = -1;
|
||||||
PCR.ctrl_32k_conf.clk_32k_sel = 1;
|
|
||||||
|
switch (clk_sel) {
|
||||||
|
case CLK_CAL_32K_XTAL:
|
||||||
|
timg_cali_clk_sel = 2;
|
||||||
|
clk_32k_sel = 1;
|
||||||
break;
|
break;
|
||||||
case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW:
|
case CLK_CAL_32K_OSC_SLOW:
|
||||||
PCR.ctrl_32k_conf.clk_32k_sel = 2;
|
timg_cali_clk_sel = 2;
|
||||||
|
clk_32k_sel = 2;
|
||||||
|
break;
|
||||||
|
case CLK_CAL_RC_SLOW:
|
||||||
|
timg_cali_clk_sel = 0;
|
||||||
|
break;
|
||||||
|
case CLK_CAL_RC_FAST:
|
||||||
|
timg_cali_clk_sel = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Unsupported 32K_SEL mux input
|
// Unsupported CLK_CAL mux input
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
if (timg_cali_clk_sel >= 0) {
|
||||||
* @brief Get the calibration 32kHz clock source for timergroup0
|
TIMERG0.rtccalicfg.rtc_cali_clk_sel = timg_cali_clk_sel;
|
||||||
*
|
}
|
||||||
* @return soc_rtc_slow_clk_src_t Currently selected calibration 32kHz clock (one of the 32kHz clocks)
|
if (clk_32k_sel >= 0) {
|
||||||
*/
|
PCR.ctrl_32k_conf.clk_32k_sel = clk_32k_sel;
|
||||||
static inline __attribute__((always_inline)) soc_rtc_slow_clk_src_t clk_ll_32k_calibration_get_target(void)
|
|
||||||
{
|
|
||||||
uint32_t clk_sel = PCR.ctrl_32k_conf.clk_32k_sel;
|
|
||||||
switch (clk_sel) {
|
|
||||||
case 1:
|
|
||||||
return SOC_RTC_SLOW_CLK_SRC_XTAL32K;
|
|
||||||
case 2:
|
|
||||||
return SOC_RTC_SLOW_CLK_SRC_OSC_SLOW;
|
|
||||||
default:
|
|
||||||
return SOC_RTC_SLOW_CLK_SRC_INVALID;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -455,7 +456,7 @@ static inline __attribute__((always_inline)) soc_rtc_slow_clk_src_t clk_ll_32k_c
|
|||||||
static inline __attribute__((always_inline)) void clk_ll_rtc_slow_set_src(soc_rtc_slow_clk_src_t in_sel)
|
static inline __attribute__((always_inline)) void clk_ll_rtc_slow_set_src(soc_rtc_slow_clk_src_t in_sel)
|
||||||
{
|
{
|
||||||
switch (in_sel) {
|
switch (in_sel) {
|
||||||
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW:
|
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4:
|
||||||
LP_CLKRST.lp_clk_conf.clkrst_slow_clk_sel = 0;
|
LP_CLKRST.lp_clk_conf.clkrst_slow_clk_sel = 0;
|
||||||
break;
|
break;
|
||||||
case SOC_RTC_SLOW_CLK_SRC_XTAL32K:
|
case SOC_RTC_SLOW_CLK_SRC_XTAL32K:
|
||||||
@@ -480,7 +481,7 @@ static inline __attribute__((always_inline)) soc_rtc_slow_clk_src_t clk_ll_rtc_s
|
|||||||
uint32_t clk_sel = LP_CLKRST.lp_clk_conf.clkrst_slow_clk_sel;
|
uint32_t clk_sel = LP_CLKRST.lp_clk_conf.clkrst_slow_clk_sel;
|
||||||
switch (clk_sel) {
|
switch (clk_sel) {
|
||||||
case 0:
|
case 0:
|
||||||
return SOC_RTC_SLOW_CLK_SRC_RC_SLOW;
|
return SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4;
|
||||||
case 1:
|
case 1:
|
||||||
return SOC_RTC_SLOW_CLK_SRC_XTAL32K;
|
return SOC_RTC_SLOW_CLK_SRC_XTAL32K;
|
||||||
case 3:
|
case 3:
|
||||||
@@ -559,14 +560,14 @@ static inline void clk_ll_rc_fast_tick_conf(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set RC_SLOW_CLK divider
|
* @brief Set RC_SLOW_CLK divider. The output from the divider is passed into rtc_slow_clk MUX.
|
||||||
*
|
*
|
||||||
* @param divider Divider of RC_SLOW_CLK. Usually this divider is set to 1 (reg. value is 0) in bootloader stage.
|
* @param divider Divider of RC_SLOW_CLK. Fixed the divider to 4 on the target.
|
||||||
*/
|
*/
|
||||||
static inline __attribute__((always_inline)) void clk_ll_rc_slow_set_divider(uint32_t divider)
|
static inline __attribute__((always_inline)) void clk_ll_rc_slow_set_divider(uint32_t divider)
|
||||||
{
|
{
|
||||||
// No divider on the target
|
// Register not exposed
|
||||||
HAL_ASSERT(divider == 1);
|
HAL_ASSERT(divider == 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************** LP STORAGE REGISTER STORE/LOAD **************************/
|
/************************** LP STORAGE REGISTER STORE/LOAD **************************/
|
||||||
|
@@ -615,7 +615,7 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_rc_fast_get_divider
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set RC_SLOW_CLK divider
|
* @brief Set RC_SLOW_CLK divider. The output from the divider is passed into rtc_slow_clk MUX.
|
||||||
*
|
*
|
||||||
* @param divider Divider of RC_SLOW_CLK. Fixed the divider to 4 on the target.
|
* @param divider Divider of RC_SLOW_CLK. Fixed the divider to 4 on the target.
|
||||||
*/
|
*/
|
||||||
|
@@ -88,12 +88,12 @@ typedef enum {
|
|||||||
* @note Enum values are matched with the register field values on purpose
|
* @note Enum values are matched with the register field values on purpose
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SOC_RTC_SLOW_CLK_SRC_RC_SLOW = 0, /*!< Select RC_SLOW_CLK as RTC_SLOW_CLK source */
|
SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4 = 0, /*!< Select RC_SLOW_D4_CLK as RTC_SLOW_CLK source */
|
||||||
SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */
|
SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */
|
||||||
SOC_RTC_SLOW_CLK_SRC_OSC_SLOW = 3, /*!< Select OSC_SLOW_CLK (external slow clock) as RTC_SLOW_CLK source */
|
SOC_RTC_SLOW_CLK_SRC_OSC_SLOW = 3, /*!< Select OSC_SLOW_CLK (external slow clock) as RTC_SLOW_CLK source */
|
||||||
SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */
|
SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */
|
||||||
|
|
||||||
SOC_RTC_SLOW_CLK_SRC_DEFAULT = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, /*!< RC_SLOW_CLK is the default clock source for RTC_SLOW_CLK */
|
SOC_RTC_SLOW_CLK_SRC_DEFAULT = SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4, /*!< RC_SLOW_CLK is the default clock source for RTC_SLOW_CLK */
|
||||||
} soc_rtc_slow_clk_src_t;
|
} soc_rtc_slow_clk_src_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -314,6 +314,17 @@ typedef enum {
|
|||||||
FLASH_CLK_SRC_ROM_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as ROM default clock source */
|
FLASH_CLK_SRC_ROM_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as ROM default clock source */
|
||||||
} soc_periph_flash_clk_src_t;
|
} soc_periph_flash_clk_src_t;
|
||||||
|
|
||||||
|
////////////////////////////////////////////RTC CALIBRATION///////////////////////////////////////////////////////////
|
||||||
|
/**
|
||||||
|
* @brief Clock frequency calibration source selection
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
CLK_CAL_RC_SLOW = 0, /*!< Select to calibrate RC_SLOW_CLK */
|
||||||
|
CLK_CAL_32K_XTAL, /*!< Select to calibrate XTAL32K_CLK */
|
||||||
|
CLK_CAL_32K_OSC_SLOW, /*!< Select to calibrate OSC_SLOW_CLK (external slow clock) */
|
||||||
|
CLK_CAL_RC_FAST, /*!< Select to calibrate RC_FAST_CLK */
|
||||||
|
} soc_clk_calibration_clk_src_t;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user