refactor(clk): add soc_clk_calibration_clk_src_t for all targets

Cleaned up RTC calibration clock selection code
This commit is contained in:
Song Ruo Jing
2025-07-21 22:00:00 +08:00
parent 07120c1d38
commit 2b01b7c6f8
54 changed files with 786 additions and 495 deletions

View File

@@ -93,9 +93,9 @@ 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
*/ */
typedef enum { typedef enum {
RTC_CAL_RTC_MUX = 0, //!< Currently selected RTC SLOW_CLK RTC_CAL_RTC_MUX = CLK_CAL_RTC_SLOW, //!< Currently selected RTC SLOW_CLK
RTC_CAL_8MD256 = 1, //!< Internal 8 MHz RC oscillator, divided by 256 RTC_CAL_8MD256 = CLK_CAL_RC_FAST_D256, //!< Internal 8 MHz RC oscillator, divided by 256
RTC_CAL_32K_XTAL = 2 //!< External 32 kHz XTAL RTC_CAL_32K_XTAL = CLK_CAL_32K_XTAL, //!< External 32 kHz XTAL
} rtc_cal_sel_t; } rtc_cal_sel_t;
/** /**

View File

@@ -37,30 +37,32 @@ static const char *TAG = "rtc_time";
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); assert(slowclk_cycles < 32767);
/* Enable requested clock (150k clock is always on) */ soc_timg0_calibration_clk_src_t cali_clk_sel = (soc_timg0_calibration_clk_src_t)cal_clk;
/* Enable requested clock (rtc slow clock is always on) */
bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled(); bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled();
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) { if (cali_clk_sel == CLK_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
clk_ll_xtal32k_digi_enable(); clk_ll_xtal32k_digi_enable();
} }
bool rc_fast_enabled = clk_ll_rc_fast_is_enabled(); bool rc_fast_enabled = clk_ll_rc_fast_is_enabled();
bool rc_fast_d256_enabled = clk_ll_rc_fast_d256_is_enabled(); bool rc_fast_d256_enabled = clk_ll_rc_fast_d256_is_enabled();
if (cal_clk == RTC_CAL_8MD256) { if (cali_clk_sel == CLK_CAL_RC_FAST_D256) {
rtc_clk_8m_enable(true, true); rtc_clk_8m_enable(true, true);
clk_ll_rc_fast_d256_digi_enable(); clk_ll_rc_fast_d256_digi_enable();
} }
/* Prepare calibration */ /* Prepare calibration */
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cal_clk); clk_ll_calibration_set_target(cali_clk_sel);
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);
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles); REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles);
/* 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;
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();
if (cal_clk == RTC_CAL_32K_XTAL || if (cali_clk_sel == CLK_CAL_32K_XTAL ||
(cal_clk == RTC_CAL_RTC_MUX && slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K)) { (cali_clk_sel == CLK_CAL_RTC_SLOW && slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K)) {
expected_freq = SOC_CLK_XTAL32K_FREQ_APPROX; /* standard 32k XTAL */ expected_freq = SOC_CLK_XTAL32K_FREQ_APPROX; /* standard 32k XTAL */
} else if (cal_clk == RTC_CAL_8MD256 || } else if (cali_clk_sel == CLK_CAL_RC_FAST_D256 ||
(cal_clk == RTC_CAL_RTC_MUX && slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256)) { (cali_clk_sel == CLK_CAL_RTC_SLOW && slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256)) {
expected_freq = SOC_CLK_RC_FAST_D256_FREQ_APPROX; expected_freq = SOC_CLK_RC_FAST_D256_FREQ_APPROX;
} else { } else {
expected_freq = SOC_CLK_RC_SLOW_FREQ_APPROX; /* 150k internal oscillator */ expected_freq = SOC_CLK_RC_SLOW_FREQ_APPROX; /* 150k internal oscillator */
@@ -94,11 +96,11 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
} }
/* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */ /* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) { if (cali_clk_sel == CLK_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
clk_ll_xtal32k_digi_disable(); clk_ll_xtal32k_digi_disable();
} }
if (cal_clk == RTC_CAL_8MD256) { if (cali_clk_sel == CLK_CAL_RC_FAST_D256) {
clk_ll_rc_fast_d256_digi_disable(); clk_ll_rc_fast_d256_digi_disable();
rtc_clk_8m_enable(rc_fast_enabled, rc_fast_d256_enabled); rtc_clk_8m_enable(rc_fast_enabled, rc_fast_d256_enabled);
} }

View File

@@ -159,12 +159,10 @@ 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
*/ */
typedef enum { typedef enum {
RTC_CAL_RTC_MUX = 0, //!< Currently selected RTC SLOW_CLK RTC_CAL_RTC_MUX = -1, //!< Currently selected RTC SLOW_CLK
RTC_CAL_8MD256 = 1, //!< Internal 8 MHz RC oscillator, divided by 256 RTC_CAL_8MD256 = CLK_CAL_RC_FAST_D256, //!< Internal 17.5 MHz RC oscillator, divided by 256
RTC_CAL_32K_OSC_SLOW = 2, //!< External 32.768 KHz CLK RTC_CAL_32K_OSC_SLOW = CLK_CAL_32K_OSC_SLOW, //!< External 32 kHz CLK
RTC_CAL_INTERNAL_OSC = CLK_CAL_RC_SLOW, //!< Internal 150 kHz RC oscillator
// deprecated name
RTC_CAL_EXT_32K __attribute__((deprecated)) = RTC_CAL_32K_OSC_SLOW,
} rtc_cal_sel_t; } rtc_cal_sel_t;
/** /**
@@ -409,8 +407,6 @@ void rtc_clk_apb_freq_update(uint32_t apb_freq);
*/ */
uint32_t rtc_clk_apb_freq_get(void); uint32_t rtc_clk_apb_freq_get(void);
uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles);
/** /**
* @brief Measure RTC slow clock's period, based on main XTAL frequency * @brief Measure RTC slow clock's period, based on main XTAL frequency
* *

View File

@@ -33,30 +33,29 @@
* @param slowclk_cycles number of slow clock cycles to count * @param slowclk_cycles number of slow clock cycles to count
* @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
*/ */
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)
{ {
/* On ESP32-C2, choosing RTC_CAL_RTC_MUX results in calibration of
* the 150k RTC clock regardless of the currently selected SLOW_CLK.
* On the ESP32, it used the currently selected SLOW_CLK.
* The following code emulates ESP32 behavior:
*/
if (cal_clk == RTC_CAL_RTC_MUX) { if (cal_clk == RTC_CAL_RTC_MUX) {
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();
if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) { if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) {
cal_clk = RTC_CAL_INTERNAL_OSC;
} else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) {
cal_clk = RTC_CAL_32K_OSC_SLOW; cal_clk = RTC_CAL_32K_OSC_SLOW;
} else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { } else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) {
cal_clk = RTC_CAL_8MD256; cal_clk = RTC_CAL_8MD256;
} }
} }
soc_timg0_calibration_clk_src_t cali_clk_sel = (soc_timg0_calibration_clk_src_t)cal_clk;
/* Enable requested clock (150k clock is always on) */ /* Enable requested clock (150k clock is always on) */
bool dig_ext_clk_enabled = clk_ll_xtal32k_digi_is_enabled(); bool dig_ext_clk_enabled = clk_ll_xtal32k_digi_is_enabled();
if (cal_clk == RTC_CAL_32K_OSC_SLOW && !dig_ext_clk_enabled) { if (cali_clk_sel == CLK_CAL_32K_OSC_SLOW && !dig_ext_clk_enabled) {
clk_ll_xtal32k_digi_enable(); clk_ll_xtal32k_digi_enable();
} }
bool rc_fast_enabled = clk_ll_rc_fast_is_enabled(); bool rc_fast_enabled = clk_ll_rc_fast_is_enabled();
bool rc_fast_d256_enabled = clk_ll_rc_fast_d256_is_enabled(); bool rc_fast_d256_enabled = clk_ll_rc_fast_d256_is_enabled();
if (cal_clk == RTC_CAL_8MD256) { if (cali_clk_sel == CLK_CAL_RC_FAST_D256) {
rtc_clk_8m_enable(true, true); rtc_clk_8m_enable(true, true);
clk_ll_rc_fast_d256_digi_enable(); clk_ll_rc_fast_d256_digi_enable();
} }
@@ -74,17 +73,17 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
} }
/* Prepare calibration */ /* Prepare calibration */
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cal_clk); clk_ll_calibration_set_target(cali_clk_sel);
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);
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles); REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles);
/* Figure out how long to wait for calibration to finish */ /* Figure out how long to wait for calibration to finish */
/* Set timeout reg and expect time delay*/ /* Set timeout reg and expect time delay*/
uint32_t expected_freq; uint32_t expected_freq;
if (cal_clk == RTC_CAL_32K_OSC_SLOW) { if (cali_clk_sel == CLK_CAL_32K_OSC_SLOW) {
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_X32K_CAL_TIMEOUT_THRES(slowclk_cycles)); REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_X32K_CAL_TIMEOUT_THRES(slowclk_cycles));
expected_freq = SOC_CLK_OSC_SLOW_FREQ_APPROX; expected_freq = SOC_CLK_OSC_SLOW_FREQ_APPROX;
} else if (cal_clk == RTC_CAL_8MD256) { } else if (cali_clk_sel == CLK_CAL_RC_FAST_D256) {
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_8MD256_CAL_TIMEOUT_THRES(slowclk_cycles)); REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_8MD256_CAL_TIMEOUT_THRES(slowclk_cycles));
expected_freq = SOC_CLK_RC_FAST_D256_FREQ_APPROX; expected_freq = SOC_CLK_RC_FAST_D256_FREQ_APPROX;
} else { } else {
@@ -112,11 +111,11 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START); CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
/* if dig_ext_clk was originally off and enabled due to calibration, then set back to off state */ /* if dig_ext_clk was originally off and enabled due to calibration, then set back to off state */
if (cal_clk == RTC_CAL_32K_OSC_SLOW && !dig_ext_clk_enabled) { if (cali_clk_sel == CLK_CAL_32K_OSC_SLOW && !dig_ext_clk_enabled) {
clk_ll_xtal32k_digi_disable(); clk_ll_xtal32k_digi_disable();
} }
if (cal_clk == RTC_CAL_8MD256) { if (cali_clk_sel == CLK_CAL_RC_FAST_D256) {
clk_ll_rc_fast_d256_digi_disable(); clk_ll_rc_fast_d256_digi_disable();
rtc_clk_8m_enable(rc_fast_enabled, rc_fast_d256_enabled); rtc_clk_8m_enable(rc_fast_enabled, rc_fast_d256_enabled);
} }

View File

@@ -161,10 +161,10 @@ 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
*/ */
typedef enum { typedef enum {
RTC_CAL_RTC_MUX = 0, //!< Currently selected RTC SLOW_CLK RTC_CAL_RTC_MUX = -1, //!< Currently selected RTC SLOW_CLK
RTC_CAL_8MD256 = 1, //!< Internal 8 MHz RC oscillator, divided by 256 RTC_CAL_8MD256 = CLK_CAL_RC_FAST_D256, //!< Internal 17.5 MHz RC oscillator, divided by 256
RTC_CAL_32K_XTAL = 2, //!< External 32 kHz XTAL RTC_CAL_32K_XTAL = CLK_CAL_32K_XTAL, //!< External 32 kHz XTAL
RTC_CAL_INTERNAL_OSC = 3 //!< Internal 150 kHz oscillator RTC_CAL_INTERNAL_OSC = CLK_CAL_RC_SLOW, //!< Internal 150 kHz oscillator
} rtc_cal_sel_t; } rtc_cal_sel_t;
/** /**
@@ -437,8 +437,6 @@ void rtc_clk_apb_freq_update(uint32_t apb_freq);
*/ */
uint32_t rtc_clk_apb_freq_get(void); uint32_t rtc_clk_apb_freq_get(void);
uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles);
/** /**
* @brief Measure RTC slow clock's period, based on main XTAL frequency * @brief Measure RTC slow clock's period, based on main XTAL frequency
* *

View File

@@ -33,33 +33,29 @@
* @param slowclk_cycles number of slow clock cycles to count * @param slowclk_cycles number of slow clock cycles to count
* @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
*/ */
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)
{ {
/* On ESP32C3, choosing RTC_CAL_RTC_MUX results in calibration of
* the 150k RTC clock regardless of the currently selected SLOW_CLK.
* On the ESP32, it used the currently selected SLOW_CLK.
* The following code emulates ESP32 behavior:
*/
if (cal_clk == RTC_CAL_RTC_MUX) { if (cal_clk == RTC_CAL_RTC_MUX) {
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();
if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) {
cal_clk = RTC_CAL_INTERNAL_OSC;
} else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
cal_clk = RTC_CAL_32K_XTAL; cal_clk = RTC_CAL_32K_XTAL;
} else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { } else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) {
cal_clk = RTC_CAL_8MD256; cal_clk = RTC_CAL_8MD256;
} }
} else if (cal_clk == RTC_CAL_INTERNAL_OSC) {
cal_clk = RTC_CAL_RTC_MUX;
} }
soc_timg0_calibration_clk_src_t cali_clk_sel = (soc_timg0_calibration_clk_src_t)cal_clk;
/* Enable requested clock (150k clock is always on) */ /* Enable requested clock (150k clock is always on) */
bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled(); bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled();
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) { if (cali_clk_sel == CLK_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
clk_ll_xtal32k_digi_enable(); clk_ll_xtal32k_digi_enable();
} }
bool rc_fast_enabled = clk_ll_rc_fast_is_enabled(); bool rc_fast_enabled = clk_ll_rc_fast_is_enabled();
bool rc_fast_d256_enabled = clk_ll_rc_fast_d256_is_enabled(); bool rc_fast_d256_enabled = clk_ll_rc_fast_d256_is_enabled();
if (cal_clk == RTC_CAL_8MD256) { if (cali_clk_sel == CLK_CAL_RC_FAST_D256) {
rtc_clk_8m_enable(true, true); rtc_clk_8m_enable(true, true);
clk_ll_rc_fast_d256_digi_enable(); clk_ll_rc_fast_d256_digi_enable();
} }
@@ -77,17 +73,17 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
} }
/* Prepare calibration */ /* Prepare calibration */
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cal_clk); clk_ll_calibration_set_target(cali_clk_sel);
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);
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles); REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles);
/* Figure out how long to wait for calibration to finish */ /* Figure out how long to wait for calibration to finish */
/* Set timeout reg and expect time delay*/ /* Set timeout reg and expect time delay*/
uint32_t expected_freq; uint32_t expected_freq;
if (cal_clk == RTC_CAL_32K_XTAL) { if (cali_clk_sel == CLK_CAL_32K_XTAL) {
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_X32K_CAL_TIMEOUT_THRES(slowclk_cycles)); REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_X32K_CAL_TIMEOUT_THRES(slowclk_cycles));
expected_freq = SOC_CLK_XTAL32K_FREQ_APPROX; expected_freq = SOC_CLK_XTAL32K_FREQ_APPROX;
} else if (cal_clk == RTC_CAL_8MD256) { } else if (cali_clk_sel == CLK_CAL_RC_FAST_D256) {
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_8MD256_CAL_TIMEOUT_THRES(slowclk_cycles)); REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_8MD256_CAL_TIMEOUT_THRES(slowclk_cycles));
expected_freq = SOC_CLK_RC_FAST_D256_FREQ_APPROX; expected_freq = SOC_CLK_RC_FAST_D256_FREQ_APPROX;
} else { } else {
@@ -115,11 +111,11 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START); CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
/* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */ /* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) { if (cali_clk_sel == CLK_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
clk_ll_xtal32k_digi_disable(); clk_ll_xtal32k_digi_disable();
} }
if (cal_clk == RTC_CAL_8MD256) { if (cali_clk_sel == CLK_CAL_RC_FAST_D256) {
clk_ll_rc_fast_d256_digi_disable(); clk_ll_rc_fast_d256_digi_disable();
rtc_clk_8m_enable(rc_fast_enabled, rc_fast_d256_enabled); rtc_clk_8m_enable(rc_fast_enabled, rc_fast_d256_enabled);
} }

View File

@@ -116,15 +116,13 @@ 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 ESP32C5, the enum values somehow reflects the register field values of PCR_32K_SEL.
*/ */
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_32K_XTAL = 1, //!< 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 = 2, //!< 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 lp_pad_gpio0, as one type of 32k clock
RTC_CAL_RC_SLOW = 3, //!< Internal 150kHz RC oscillator RTC_CAL_RC_SLOW = CLK_CAL_RC_SLOW, //!< Internal 150kHz RC oscillator
RTC_CAL_RC_FAST = 4, //!< Internal 20MHz RC oscillator RTC_CAL_RC_FAST = CLK_CAL_RC_FAST, //!< Internal 20MHz RC oscillator
RTC_CAL_INVALID_CLK, //!< Clock not available to calibrate RTC_CAL_INVALID_CLK, //!< Clock not available to calibrate
} rtc_cal_sel_t; } rtc_cal_sel_t;

View File

@@ -19,13 +19,19 @@
__attribute__((unused)) static const char *TAG = "rtc_time"; __attribute__((unused)) static const char *TAG = "rtc_time";
/* Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0. #define CLK_CAL_TIMEOUT_THRES(cali_clk_sel, cycles) ((cali_clk_sel == CLK_CAL_32K_XTAL || cali_clk_sel == CLK_CAL_32K_OSC_SLOW) ? (cycles << 12) : (cycles << 10))
/**
* @brief Clock calibration function used by rtc_clk_cal
*
* Calibration of clock frequency is performed using a special feature of TIMG0.
* This feature counts the number of XTAL clock cycles within a given number of * This feature counts the number of XTAL clock cycles within a given number of
* RTC_SLOW_CLK cycles. * clock cycles.
*
* @param cal_clk which clock to calibrate
* @param slowclk_cycles number of slow clock cycles to count
* @return number of XTAL clock cycles within the given number of slow clock cycles
*/ */
#define CLK_CAL_TIMEOUT_THRES(cal_clk, cycles) ((cal_clk == RTC_CAL_32K_XTAL || cal_clk == RTC_CAL_32K_OSC_SLOW) ? (cycles << 12) : (cycles << 10))
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);
@@ -44,19 +50,20 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
ESP_EARLY_LOGE(TAG, "clock not supported to be calibrated"); ESP_EARLY_LOGE(TAG, "clock not supported to be calibrated");
return 0; return 0;
} }
soc_timg0_calibration_clk_src_t cali_clk_sel = (soc_timg0_calibration_clk_src_t)cal_clk;
/* Enable requested clock (150k clock is always on) */ /* Enable requested clock (150k 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
// Only enable if originally was disabled, and set back to the disable state after calibration is done // Only enable if originally was disabled, and set back to the disable state after calibration is done
// If the clock is already on, then do nothing // If the clock is already on, then do nothing
bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled(); bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled();
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) { if (cali_clk_sel == CLK_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
clk_ll_xtal32k_digi_enable(); clk_ll_xtal32k_digi_enable();
} }
bool rc_fast_enabled = clk_ll_rc_fast_is_enabled(); bool rc_fast_enabled = clk_ll_rc_fast_is_enabled();
bool dig_rc_fast_enabled = clk_ll_rc_fast_digi_is_enabled(); bool dig_rc_fast_enabled = clk_ll_rc_fast_digi_is_enabled();
if (cal_clk == RTC_CAL_RC_FAST) { if (cali_clk_sel == CLK_CAL_RC_FAST) {
if (!rc_fast_enabled) { if (!rc_fast_enabled) {
rtc_clk_8m_enable(true); rtc_clk_8m_enable(true);
} }
@@ -79,8 +86,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(PCR_CTRL_32K_CONF_REG, PCR_32K_SEL, cal_clk); clk_ll_calibration_set_target(cali_clk_sel);
if (cal_clk == RTC_CAL_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);
@@ -88,11 +95,11 @@ 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 */
/* Set timeout reg and expect time delay*/ /* Set timeout reg and expect time delay*/
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, CLK_CAL_TIMEOUT_THRES(cal_clk, slowclk_cycles)); REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, CLK_CAL_TIMEOUT_THRES(cali_clk_sel, slowclk_cycles));
uint32_t expected_freq; uint32_t expected_freq;
if (cal_clk == RTC_CAL_32K_XTAL || cal_clk == RTC_CAL_32K_OSC_SLOW) { if (cali_clk_sel == CLK_CAL_32K_XTAL || cali_clk_sel == CLK_CAL_32K_OSC_SLOW) {
expected_freq = SOC_CLK_XTAL32K_FREQ_APPROX; expected_freq = SOC_CLK_XTAL32K_FREQ_APPROX;
} else if (cal_clk == RTC_CAL_RC_FAST) { } else if (cali_clk_sel == CLK_CAL_RC_FAST) {
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 {
expected_freq = SOC_CLK_RC_SLOW_FREQ_APPROX; expected_freq = SOC_CLK_RC_SLOW_FREQ_APPROX;
@@ -111,7 +118,7 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
/*The Fosc CLK of calibration circuit is divided by a factor, k. /*The Fosc CLK of calibration circuit is divided by a factor, k.
So we need to multiply the frequency of the FOSC by k times.*/ So we need to multiply the frequency of the FOSC by k times.*/
if (cal_clk == RTC_CAL_RC_FAST) { if (cali_clk_sel == CLK_CAL_RC_FAST) {
cal_val = cal_val >> CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS; cal_val = cal_val >> CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS;
} }
break; break;
@@ -125,11 +132,11 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
clk_ll_enable_timergroup_rtc_calibration_clock(false); clk_ll_enable_timergroup_rtc_calibration_clock(false);
/* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */ /* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) { if (cali_clk_sel == CLK_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
clk_ll_xtal32k_digi_disable(); clk_ll_xtal32k_digi_disable();
} }
if (cal_clk == RTC_CAL_RC_FAST) { if (cali_clk_sel == CLK_CAL_RC_FAST) {
if (!dig_rc_fast_enabled) { if (!dig_rc_fast_enabled) {
rtc_dig_clk8m_disable(); rtc_dig_clk8m_disable();
} }

View File

@@ -123,18 +123,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
* However, this is not true on ESP32C6. The conversion to register field values is explicitly done in
* 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 150kHz RC oscillator RTC_CAL_RC_SLOW = CLK_CAL_RC_SLOW, //!< Internal 150kHz RC oscillator
RTC_CAL_RC32K = SOC_RTC_SLOW_CLK_SRC_RC32K, //!< Internal 32kHz RC oscillator, as one type of 32k clock RTC_CAL_RC32K = CLK_CAL_RC32K, //!< Internal 32kHz 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
RTC_CAL_32K_OSC_SLOW = SOC_RTC_SLOW_CLK_SRC_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 lp_pad_gpio0
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;
/** /**

View File

@@ -20,27 +20,6 @@
__attribute__((unused)) static const char *TAG = "rtc_time"; __attribute__((unused)) static const char *TAG = "rtc_time";
/* Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0.
* This feature counts the number of XTAL clock cycles within a given number of
* RTC_SLOW_CLK cycles.
*
* Slow clock calibration feature has two modes of operation: one-off and cycling.
* In cycling mode (which is enabled by default on SoC reset), counting of XTAL
* cycles within RTC_SLOW_CLK cycle is done continuously. Cycling mode is enabled
* using TIMG_RTC_CALI_START_CYCLING bit. In one-off mode counting is performed
* once, and TIMG_RTC_CALI_RDY bit is set when counting is done. One-off mode is
* enabled using TIMG_RTC_CALI_START bit.
*/
/* On ESP32C6, 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: 0: Internal 32 kHz RC oscillator, 1: External 32 kHz XTAL, 2: External 32kHz clock input by lp_pad_gpio0
*/
#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
/** /**
* @brief Clock calibration function used by rtc_clk_cal * @brief Clock calibration function used by rtc_clk_cal
* *
@@ -63,34 +42,32 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
{ {
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 old_32k_cal_clk_sel = clk_ll_32k_calibration_get_target();
if (cal_clk == RTC_CAL_RTC_MUX) { if (cal_clk == RTC_CAL_RTC_MUX) {
cal_clk = (rtc_cal_sel_t)slow_clk_src; soc_rtc_slow_clk_src_t slow_clk_src = rtc_clk_slow_src_get();
if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) {
cal_clk = RTC_CAL_RC_SLOW;
} else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) {
cal_clk = RTC_CAL_32K_OSC_SLOW;
} else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
cal_clk = RTC_CAL_32K_XTAL;
} else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) {
cal_clk = RTC_CAL_RC32K;
} }
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);
} }
soc_timg0_calibration_clk_src_t cali_clk_sel = (soc_timg0_calibration_clk_src_t)cal_clk;
/* Enable requested clock (150k clock is always on) */ /* Enable requested clock (150k 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
// Only enable if originally was disabled, and set back to the disable state after calibration is done // Only enable if originally was disabled, and set back to the disable state after calibration is done
// If the clock is already on, then do nothing // If the clock is already on, then do nothing
bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled(); bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled();
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) { if (cali_clk_sel == CLK_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
clk_ll_xtal32k_digi_enable(); clk_ll_xtal32k_digi_enable();
} }
bool rc_fast_enabled = clk_ll_rc_fast_is_enabled(); bool rc_fast_enabled = clk_ll_rc_fast_is_enabled();
bool dig_rc_fast_enabled = clk_ll_rc_fast_digi_is_enabled(); bool dig_rc_fast_enabled = clk_ll_rc_fast_digi_is_enabled();
if (cal_clk == RTC_CAL_RC_FAST) { if (cali_clk_sel == CLK_CAL_RC_FAST) {
if (!rc_fast_enabled) { if (!rc_fast_enabled) {
rtc_clk_8m_enable(true); rtc_clk_8m_enable(true);
} }
@@ -101,7 +78,7 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
bool rc32k_enabled = clk_ll_rc32k_is_enabled(); bool rc32k_enabled = clk_ll_rc32k_is_enabled();
bool dig_rc32k_enabled = clk_ll_rc32k_digi_is_enabled(); bool dig_rc32k_enabled = clk_ll_rc32k_digi_is_enabled();
if (cal_clk == RTC_CAL_RC32K) { if (cali_clk_sel == CLK_CAL_RC32K) {
if (!rc32k_enabled) { if (!rc32k_enabled) {
rtc_clk_rc32k_enable(true); rtc_clk_rc32k_enable(true);
} }
@@ -124,8 +101,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);
@@ -134,10 +111,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 || cali_clk_sel == CLK_CAL_RC32K) {
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; expected_freq = SOC_CLK_RC_FAST_FREQ_APPROX;
if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) { if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) {
@@ -165,7 +142,7 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
And the 32-divider belongs to REF_TICK module, so we need to enable its clock during And the 32-divider belongs to REF_TICK module, so we need to enable its clock during
calibration. */ calibration. */
if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) { if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) {
if (cal_clk == RTC_CAL_RC_FAST) { if (cali_clk_sel == CLK_CAL_RC_FAST) {
cal_val = cal_val >> CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS; cal_val = cal_val >> CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS;
CLEAR_PERI_REG_MASK(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE); CLEAR_PERI_REG_MASK(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE);
} }
@@ -180,11 +157,11 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START); CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
/* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */ /* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) { if (cali_clk_sel == CLK_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
clk_ll_xtal32k_digi_disable(); clk_ll_xtal32k_digi_disable();
} }
if (cal_clk == RTC_CAL_RC_FAST) { if (cali_clk_sel == CLK_CAL_RC_FAST) {
if (!dig_rc_fast_enabled) { if (!dig_rc_fast_enabled) {
rtc_dig_clk8m_disable(); rtc_dig_clk8m_disable();
} }
@@ -193,7 +170,7 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
} }
} }
if (cal_clk == RTC_CAL_RC32K) { if (cali_clk_sel == CLK_CAL_RC32K) {
if (!dig_rc32k_enabled) { if (!dig_rc32k_enabled) {
clk_ll_rc32k_digi_disable(); clk_ll_rc32k_digi_disable();
} }
@@ -202,11 +179,6 @@ 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 (old_32k_cal_clk_sel != SOC_RTC_SLOW_CLK_SRC_INVALID) {
clk_ll_32k_calibration_set_target(old_32k_cal_clk_sel);
}
return cal_val; return cal_val;
} }

View File

@@ -116,15 +116,13 @@ 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 ESP32C61, the enum values somehow reflects the register field values of PCR_32K_SEL.
*/ */
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_32K_XTAL = 1, //!< 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 = 2, //!< 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 lp_pad_gpio0, as one type of 32k clock
RTC_CAL_RC_SLOW = 3, //!< Internal 150kHz RC oscillator RTC_CAL_RC_SLOW = CLK_CAL_RC_SLOW, //!< Internal 150kHz RC oscillator
RTC_CAL_RC_FAST = 4, //!< Internal 20MHz RC oscillator RTC_CAL_RC_FAST = CLK_CAL_RC_FAST, //!< Internal 20MHz RC oscillator
RTC_CAL_INVALID_CLK, //!< Clock not available to calibrate RTC_CAL_INVALID_CLK, //!< Clock not available to calibrate
} rtc_cal_sel_t; } rtc_cal_sel_t;

View File

@@ -18,13 +18,19 @@
__attribute__((unused)) static const char *TAG = "rtc_time"; __attribute__((unused)) static const char *TAG = "rtc_time";
/* Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0. #define CLK_CAL_TIMEOUT_THRES(cali_clk_sel, cycles) ((cali_clk_sel == CLK_CAL_32K_XTAL || cali_clk_sel == CLK_CAL_32K_OSC_SLOW) ? (cycles << 12) : (cycles << 10))
/**
* @brief Clock calibration function used by rtc_clk_cal
*
* Calibration of clock frequency is performed using a special feature of TIMG0.
* This feature counts the number of XTAL clock cycles within a given number of * This feature counts the number of XTAL clock cycles within a given number of
* RTC_SLOW_CLK cycles. * clock cycles.
*
* @param cal_clk which clock to calibrate
* @param slowclk_cycles number of slow clock cycles to count
* @return number of XTAL clock cycles within the given number of slow clock cycles
*/ */
#define CLK_CAL_TIMEOUT_THRES(cal_clk, cycles) ((cal_clk == RTC_CAL_32K_XTAL || cal_clk == RTC_CAL_32K_OSC_SLOW) ? (cycles << 12) : (cycles << 10))
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);
@@ -43,19 +49,20 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
ESP_EARLY_LOGE(TAG, "clock not supported to be calibrated"); ESP_EARLY_LOGE(TAG, "clock not supported to be calibrated");
return 0; return 0;
} }
soc_timg0_calibration_clk_src_t cali_clk_sel = (soc_timg0_calibration_clk_src_t)cal_clk;
/* Enable requested clock (150k clock is always on) */ /* Enable requested clock (150k 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
// Only enable if originally was disabled, and set back to the disable state after calibration is done // Only enable if originally was disabled, and set back to the disable state after calibration is done
// If the clock is already on, then do nothing // If the clock is already on, then do nothing
bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled(); bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled();
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) { if (cali_clk_sel == CLK_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
clk_ll_xtal32k_digi_enable(); clk_ll_xtal32k_digi_enable();
} }
bool rc_fast_enabled = clk_ll_rc_fast_is_enabled(); bool rc_fast_enabled = clk_ll_rc_fast_is_enabled();
bool dig_rc_fast_enabled = clk_ll_rc_fast_digi_is_enabled(); bool dig_rc_fast_enabled = clk_ll_rc_fast_digi_is_enabled();
if (cal_clk == RTC_CAL_RC_FAST) { if (cali_clk_sel == CLK_CAL_RC_FAST) {
if (!rc_fast_enabled) { if (!rc_fast_enabled) {
rtc_clk_8m_enable(true); rtc_clk_8m_enable(true);
} }
@@ -78,8 +85,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(PCR_CTRL_32K_CONF_REG, PCR_32K_SEL, cal_clk); clk_ll_calibration_set_target(cali_clk_sel);
if (cal_clk == RTC_CAL_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);
@@ -87,11 +94,11 @@ 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 */
/* Set timeout reg and expect time delay*/ /* Set timeout reg and expect time delay*/
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, CLK_CAL_TIMEOUT_THRES(cal_clk, slowclk_cycles)); REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, CLK_CAL_TIMEOUT_THRES(cali_clk_sel, slowclk_cycles));
uint32_t expected_freq; uint32_t expected_freq;
if (cal_clk == RTC_CAL_32K_XTAL || cal_clk == RTC_CAL_32K_OSC_SLOW) { if (cali_clk_sel == CLK_CAL_32K_XTAL || cali_clk_sel == CLK_CAL_32K_OSC_SLOW) {
expected_freq = SOC_CLK_XTAL32K_FREQ_APPROX; expected_freq = SOC_CLK_XTAL32K_FREQ_APPROX;
} else if (cal_clk == RTC_CAL_RC_FAST) { } else if (cali_clk_sel == CLK_CAL_RC_FAST) {
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 {
expected_freq = SOC_CLK_RC_SLOW_FREQ_APPROX; expected_freq = SOC_CLK_RC_SLOW_FREQ_APPROX;
@@ -110,7 +117,7 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
/*The Fosc CLK of calibration circuit is divided by a factor, k. /*The Fosc CLK of calibration circuit is divided by a factor, k.
So we need to multiply the frequency of the FOSC by k times.*/ So we need to multiply the frequency of the FOSC by k times.*/
if (cal_clk == RTC_CAL_RC_FAST) { if (cali_clk_sel == CLK_CAL_RC_FAST) {
cal_val = cal_val >> CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS; cal_val = cal_val >> CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS;
} }
break; break;
@@ -123,11 +130,11 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START); CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
/* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */ /* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) { if (cali_clk_sel == CLK_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
clk_ll_xtal32k_digi_disable(); clk_ll_xtal32k_digi_disable();
} }
if (cal_clk == RTC_CAL_RC_FAST) { if (cali_clk_sel == CLK_CAL_RC_FAST) {
if (!dig_rc_fast_enabled) { if (!dig_rc_fast_enabled) {
rtc_dig_clk8m_disable(); rtc_dig_clk8m_disable();
} }

View File

@@ -125,18 +125,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
* However, this is not true on ESP32H2. The conversion to register field values is explicitly done in
* 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 150kHz RC oscillator RTC_CAL_RC_SLOW = CLK_CAL_RC_SLOW, //!< Internal 150kHz RC oscillator
RTC_CAL_RC32K = SOC_RTC_SLOW_CLK_SRC_RC32K, //!< Internal 32kHz RC oscillator, as one type of 32k clock RTC_CAL_RC32K = CLK_CAL_RC32K, //!< Internal 32kHz 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
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 lp_pad_gpiox
RTC_CAL_RC_FAST //!< Internal 8MHz RC oscillator RTC_CAL_RC_FAST = CLK_CAL_RC_FAST, //!< Internal 8MHz RC oscillator
} rtc_cal_sel_t; } rtc_cal_sel_t;
/** /**

View File

@@ -20,27 +20,6 @@
__attribute__((unused)) static const char *TAG = "rtc_time"; __attribute__((unused)) static const char *TAG = "rtc_time";
/* Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0.
* This feature counts the number of XTAL clock cycles within a given number of
* RTC_SLOW_CLK cycles.
*
* Slow clock calibration feature has two modes of operation: one-off and cycling.
* In cycling mode (which is enabled by default on SoC reset), counting of XTAL
* cycles within RTC_SLOW_CLK cycle is done continuously. Cycling mode is enabled
* using TIMG_RTC_CALI_START_CYCLING bit. In one-off mode counting is performed
* once, and TIMG_RTC_CALI_RDY bit is set when counting is done. One-off mode is
* enabled using TIMG_RTC_CALI_START bit.
*/
/* On ESP32H2, 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: 0: Internal 32 kHz RC oscillator, 1: External 32 kHz XTAL, 2: External 32kHz clock input by gpio13
*/
#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
/** /**
* @brief Clock calibration function used by rtc_clk_cal * @brief Clock calibration function used by rtc_clk_cal
* *
@@ -63,34 +42,32 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
{ {
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 old_32k_cal_clk_sel = clk_ll_32k_calibration_get_target();
if (cal_clk == RTC_CAL_RTC_MUX) { if (cal_clk == RTC_CAL_RTC_MUX) {
cal_clk = (rtc_cal_sel_t)slow_clk_src; soc_rtc_slow_clk_src_t slow_clk_src = rtc_clk_slow_src_get();
if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) {
cal_clk = RTC_CAL_RC_SLOW;
} else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) {
cal_clk = RTC_CAL_32K_OSC_SLOW;
} else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
cal_clk = RTC_CAL_32K_XTAL;
} else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) {
cal_clk = RTC_CAL_RC32K;
} }
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);
} }
soc_timg0_calibration_clk_src_t cali_clk_sel = (soc_timg0_calibration_clk_src_t)cal_clk;
/* Enable requested clock (150k clock is always on) */ /* Enable requested clock (150k 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
// Only enable if originally was disabled, and set back to the disable state after calibration is done // Only enable if originally was disabled, and set back to the disable state after calibration is done
// If the clock is already on, then do nothing // If the clock is already on, then do nothing
bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled(); bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled();
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) { if (cali_clk_sel == CLK_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
clk_ll_xtal32k_digi_enable(); clk_ll_xtal32k_digi_enable();
} }
bool rc_fast_enabled = clk_ll_rc_fast_is_enabled(); bool rc_fast_enabled = clk_ll_rc_fast_is_enabled();
bool dig_rc_fast_enabled = clk_ll_rc_fast_digi_is_enabled(); bool dig_rc_fast_enabled = clk_ll_rc_fast_digi_is_enabled();
if (cal_clk == RTC_CAL_RC_FAST) { if (cali_clk_sel == CLK_CAL_RC_FAST) {
if (!rc_fast_enabled) { if (!rc_fast_enabled) {
rtc_clk_8m_enable(true); rtc_clk_8m_enable(true);
} }
@@ -101,7 +78,7 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
bool rc32k_enabled = clk_ll_rc32k_is_enabled(); bool rc32k_enabled = clk_ll_rc32k_is_enabled();
bool dig_rc32k_enabled = clk_ll_rc32k_digi_is_enabled(); bool dig_rc32k_enabled = clk_ll_rc32k_digi_is_enabled();
if (cal_clk == RTC_CAL_RC32K) { if (cali_clk_sel == CLK_CAL_RC32K) {
if (!rc32k_enabled) { if (!rc32k_enabled) {
rtc_clk_rc32k_enable(true); rtc_clk_rc32k_enable(true);
} }
@@ -124,8 +101,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);
@@ -134,10 +111,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 || cali_clk_sel == CLK_CAL_RC32K) {
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_8M_CAL_TIMEOUT_THRES(slowclk_cycles)); REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_FAST_CLK_8M_CAL_TIMEOUT_THRES(slowclk_cycles));
expected_freq = SOC_CLK_RC_FAST_FREQ_APPROX; expected_freq = SOC_CLK_RC_FAST_FREQ_APPROX;
if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 2)) { if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 2)) {
@@ -165,7 +142,7 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
And the 32-divider belongs to REF_TICK module, so we need to enable its clock during And the 32-divider belongs to REF_TICK module, so we need to enable its clock during
calibration. */ calibration. */
if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 2)) { if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 2)) {
if (cal_clk == RTC_CAL_RC_FAST) { if (cali_clk_sel == CLK_CAL_RC_FAST) {
cal_val = cal_val >> CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS; cal_val = cal_val >> CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS;
CLEAR_PERI_REG_MASK(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE); CLEAR_PERI_REG_MASK(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE);
} }
@@ -180,11 +157,11 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START); CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
/* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */ /* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) { if (cali_clk_sel == CLK_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
clk_ll_xtal32k_digi_disable(); clk_ll_xtal32k_digi_disable();
} }
if (cal_clk == RTC_CAL_RC_FAST) { if (cali_clk_sel == CLK_CAL_RC_FAST) {
if (!dig_rc_fast_enabled) { if (!dig_rc_fast_enabled) {
rtc_dig_clk8m_disable(); rtc_dig_clk8m_disable();
} }
@@ -193,7 +170,7 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
} }
} }
if (cal_clk == RTC_CAL_RC32K) { if (cali_clk_sel == CLK_CAL_RC32K) {
if (!dig_rc32k_enabled) { if (!dig_rc32k_enabled) {
clk_ll_rc32k_digi_disable(); clk_ll_rc32k_digi_disable();
} }
@@ -202,11 +179,6 @@ 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 (old_32k_cal_clk_sel != SOC_RTC_SLOW_CLK_SRC_INVALID) {
clk_ll_32k_calibration_set_target(old_32k_cal_clk_sel);
}
return cal_val; return cal_val;
} }

View File

@@ -18,21 +18,27 @@
__attribute__((unused)) static const char *TAG = "rtc_time"; __attribute__((unused)) static const char *TAG = "rtc_time";
/* Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0.
* This feature counts the number of XTAL clock cycles within a given number of
* RTC_SLOW_CLK cycles.
*/
#define RTC_SLOW_CLK_600K_CAL_TIMEOUT_THRES(cycles) (cycles << 10) #define RTC_SLOW_CLK_600K_CAL_TIMEOUT_THRES(cycles) (cycles << 10)
#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
/**
* @brief Clock calibration function used by rtc_clk_cal
*
* Calibration of clock frequency is performed using a special feature of TIMG0.
* This feature counts the number of XTAL clock cycles within a given number of
* clock cycles.
*
* @param cal_clk which clock to calibrate
* @param slowclk_cycles number of slow clock cycles to count
* @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 < TIMG_RTC_CALI_MAX_V); assert(slowclk_cycles < TIMG_RTC_CALI_MAX_V);
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_clk_calibration_clk_src_t cali_clk_sel = (soc_clk_calibration_clk_src_t)cal_clk; soc_timg0_calibration_clk_src_t cali_clk_sel = (soc_timg0_calibration_clk_src_t)cal_clk;
if (cal_clk == RTC_CAL_RTC_MUX) { if (cal_clk == RTC_CAL_RTC_MUX) {
switch (slow_clk_src) { switch (slow_clk_src) {
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4: case SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4:
@@ -55,13 +61,13 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
// Only enable if originally was disabled, and set back to the disable state after calibration is done // Only enable if originally was disabled, and set back to the disable state after calibration is done
// If the clock is already on, then do nothing // If the clock is already on, then do nothing
bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled(); bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled();
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) { if (cali_clk_sel == CLK_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
clk_ll_xtal32k_digi_enable(); clk_ll_xtal32k_digi_enable();
} }
bool rc_fast_enabled = clk_ll_rc_fast_is_enabled(); bool rc_fast_enabled = clk_ll_rc_fast_is_enabled();
bool dig_rc_fast_enabled = clk_ll_rc_fast_digi_is_enabled(); bool dig_rc_fast_enabled = clk_ll_rc_fast_digi_is_enabled();
if (cal_clk == RTC_CAL_RC_FAST) { if (cali_clk_sel == CLK_CAL_RC_FAST) {
if (!rc_fast_enabled) { if (!rc_fast_enabled) {
rtc_clk_8m_enable(true); rtc_clk_8m_enable(true);
} }
@@ -118,7 +124,7 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
/* The Fosc CLK of calibration circuit is divided by a factor, k. /* The Fosc CLK of calibration circuit is divided by a factor, k.
So we need to multiply the frequency of the FOSC by k times. */ So we need to multiply the frequency of the FOSC by k times. */
if (cal_clk == RTC_CAL_RC_FAST) { if (cali_clk_sel == CLK_CAL_RC_FAST) {
cal_val = cal_val >> CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS; cal_val = cal_val >> CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS;
} }
break; break;
@@ -131,11 +137,11 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START); CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
/* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */ /* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) { if (cali_clk_sel == CLK_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
clk_ll_xtal32k_digi_disable(); clk_ll_xtal32k_digi_disable();
} }
if (cal_clk == RTC_CAL_RC_FAST) { if (cali_clk_sel == CLK_CAL_RC_FAST) {
if (!dig_rc_fast_enabled) { if (!dig_rc_fast_enabled) {
rtc_dig_clk8m_disable(); rtc_dig_clk8m_disable();
} }

View File

@@ -23,15 +23,26 @@ static const char *TAG = "rtc_time";
// Calibration can only be performed on relatively slow speed clock signal. Therefore, for high-speed clocks, // Calibration can only be performed on relatively slow speed clock signal. Therefore, for high-speed clocks,
// calibration is performed on their DIV_CLKs. The divider is configurable. We set: // calibration is performed on their DIV_CLKs. The divider is configurable. We set:
#define CLK_CAL_DIV_VAL(cal_clk) \ #define CLK_CAL_DIV_VAL(cali_clk_sel) \
((cal_clk == RTC_CAL_RC_FAST) ? 32 : 1) ((cali_clk_sel == CLK_CAL_RC_FAST) ? 32 : 1)
/**
* @brief Clock calibration function used by rtc_clk_cal
*
* Calibration of clock frequency is performed using a special feature of TIMG0.
* This feature counts the number of XTAL clock cycles within a given number of
* clock cycles.
*
* @param cal_clk which clock to calibrate
* @param slowclk_cycles number of slow clock cycles to count
* @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 < TIMG_RTC_CALI_MAX_V); assert(slowclk_cycles < TIMG_RTC_CALI_MAX_V);
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_clk_calibration_clk_src_t cali_clk_sel = (soc_clk_calibration_clk_src_t)cal_clk; soc_timg0_calibration_clk_src_t cali_clk_sel = (soc_timg0_calibration_clk_src_t)cal_clk;
if (cal_clk == RTC_CAL_RTC_MUX) { if (cal_clk == RTC_CAL_RTC_MUX) {
switch (slow_clk_src) { switch (slow_clk_src) {
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4: case SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4:
@@ -54,13 +65,13 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
// Only enable if originally was disabled, and set back to the disable state after calibration is done // Only enable if originally was disabled, and set back to the disable state after calibration is done
// If the clock is already on, then do nothing // If the clock is already on, then do nothing
bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled(); bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled();
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) { if (cali_clk_sel == CLK_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
clk_ll_xtal32k_digi_enable(); clk_ll_xtal32k_digi_enable();
} }
bool rc_fast_enabled = clk_ll_rc_fast_is_enabled(); bool rc_fast_enabled = clk_ll_rc_fast_is_enabled();
bool dig_rc_fast_enabled = clk_ll_rc_fast_digi_is_enabled(); bool dig_rc_fast_enabled = clk_ll_rc_fast_digi_is_enabled();
if (cal_clk == RTC_CAL_RC_FAST) { if (cali_clk_sel == CLK_CAL_RC_FAST) {
if (!rc_fast_enabled) { if (!rc_fast_enabled) {
rtc_clk_8m_enable(true); rtc_clk_8m_enable(true);
} }
@@ -84,7 +95,7 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
/* Prepare calibration */ /* Prepare calibration */
clk_ll_calibration_set_target(cali_clk_sel); clk_ll_calibration_set_target(cali_clk_sel);
uint32_t clk_cal_divider = CLK_CAL_DIV_VAL(cal_clk); uint32_t clk_cal_divider = CLK_CAL_DIV_VAL(cali_clk_sel);
clk_ll_calibration_set_divider(clk_cal_divider); clk_ll_calibration_set_divider(clk_cal_divider);
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);
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles); REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles);
@@ -126,11 +137,11 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
clk_ll_calibration_set_divider(1); clk_ll_calibration_set_divider(1);
/* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */ /* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) { if (cali_clk_sel == CLK_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
clk_ll_xtal32k_digi_disable(); clk_ll_xtal32k_digi_disable();
} }
if (cal_clk == RTC_CAL_RC_FAST) { if (cali_clk_sel == CLK_CAL_RC_FAST) {
if (!dig_rc_fast_enabled) { if (!dig_rc_fast_enabled) {
rtc_dig_clk8m_disable(); rtc_dig_clk8m_disable();
} }
@@ -156,7 +167,7 @@ static bool rtc_clk_cal_32k_valid(soc_xtal_freq_t xtal_freq, uint32_t slowclk_cy
uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
{ {
slowclk_cycles /= (cal_clk == RTC_CAL_RTC_MUX) ? 1 : CLK_CAL_DIV_VAL(cal_clk); slowclk_cycles /= (cal_clk == RTC_CAL_RTC_MUX) ? 1 : CLK_CAL_DIV_VAL((soc_timg0_calibration_clk_src_t)cal_clk);
assert(slowclk_cycles); assert(slowclk_cycles);
soc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get(); soc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get();
uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles); uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles);

View File

@@ -151,23 +151,21 @@ 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 ESP32P4, the enum values somehow reflects the register field values of HP_SYS_CLKRST_REG_TIMERGRP0_TGRT_CLK_SRC_SEL.
*/ */
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_MPLL = 0, //!< 500MHz MSPI_PLL_CLK RTC_CAL_MPLL = CLK_CAL_MPLL, //!< 500MHz MSPI_PLL_CLK
RTC_CAL_SPLL = 1, //!< 480MHz SYS_PLL_CLK RTC_CAL_SPLL = CLK_CAL_SPLL, //!< 480MHz SYS_PLL_CLK
RTC_CAL_CPLL = 2, //!< 400MHz CPU_PLL_CLK RTC_CAL_CPLL = CLK_CAL_CPLL, //!< 400MHz CPU_PLL_CLK
RTC_CAL_APLL = 3, //!< AUDIO_PLL_CLK RTC_CAL_APLL = CLK_CAL_APLL, //!< AUDIO_PLL_CLK
RTC_CAL_SDIO_PLL0 = 4, //!< SDIO_PLL0_CLK RTC_CAL_SDIO_PLL0 = CLK_CAL_SDIO_PLL0, //!< SDIO_PLL0_CLK
RTC_CAL_SDIO_PLL1 = 5, //!< SDIO_PLL1_CLK RTC_CAL_SDIO_PLL1 = CLK_CAL_SDIO_PLL1, //!< SDIO_PLL1_CLK
RTC_CAL_SDIO_PLL2 = 6, //!< SDIO_PLL2_CLK RTC_CAL_SDIO_PLL2 = CLK_CAL_SDIO_PLL2, //!< SDIO_PLL2_CLK
RTC_CAL_RC_FAST = 7, //!< Internal 20MHz RC oscillator RTC_CAL_RC_FAST = CLK_CAL_RC_FAST, //!< Internal 20MHz RC oscillator
RTC_CAL_RC_SLOW = 8, //!< Internal 150kHz RC oscillator RTC_CAL_RC_SLOW = CLK_CAL_RC_SLOW, //!< Internal 150kHz RC oscillator
RTC_CAL_RC32K = 9, //!< Internal 32kHz RC oscillator, as one type of 32k clock RTC_CAL_RC32K = CLK_CAL_RC32K, //!< Internal 32kHz RC oscillator, as one type of 32k clock
RTC_CAL_32K_XTAL = 10, //!< 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_LP_PLL = 11, //!< 8MHz LP_PLL_CLK RTC_CAL_LP_PLL = CLK_CAL_LP_PLL, //!< 8MHz LP_PLL_CLK
RTC_CAL_INVALID_CLK, //!< Clock not available to calibrate RTC_CAL_INVALID_CLK, //!< Clock not available to calibrate
} rtc_cal_sel_t; } rtc_cal_sel_t;
@@ -391,26 +389,6 @@ void rtc_clk_cpu_freq_set_xtal(void);
*/ */
uint32_t rtc_clk_apb_freq_get(void); uint32_t rtc_clk_apb_freq_get(void);
/**
* @brief Clock calibration function used by rtc_clk_cal
*
* Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0.
* This feature counts the number of XTAL clock cycles within a given number of
* RTC_SLOW_CLK cycles.
*
* Slow clock calibration feature has two modes of operation: one-off and cycling.
* In cycling mode (which is enabled by default on SoC reset), counting of XTAL
* cycles within RTC_SLOW_CLK cycle is done continuously. Cycling mode is enabled
* using TIMG_RTC_CALI_START_CYCLING bit. In one-off mode counting is performed
* once, and TIMG_RTC_CALI_RDY bit is set when counting is done. One-off mode is
* enabled using TIMG_RTC_CALI_START bit.
*
* @param cal_clk which clock to calibrate
* @param slowclk_cycles number of slow clock cycles to count
* @return number of XTAL clock cycles within the given number of slow clock cycles
*/
uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles);
/** /**
* @brief Measure RTC slow clock's period, based on main XTAL frequency * @brief Measure RTC slow clock's period, based on main XTAL frequency
* *

View File

@@ -18,37 +18,43 @@
__attribute__((unused)) static const char *TAG = "rtc_time"; __attribute__((unused)) static const char *TAG = "rtc_time";
/* Calibration of clock frequency is performed using a special feature of TIMG0. #define CLK_CAL_TIMEOUT_THRES(cali_clk_sel, cycles) ((cali_clk_sel == CLK_CAL_RC32K || cali_clk_sel == CLK_CAL_32K_XTAL) ? (cycles << 12) : (cycles << 10))
* This feature counts the number of XTAL clock cycles within a given number of
* clock cycles.
*/
#define CLK_CAL_TIMEOUT_THRES(cal_clk, cycles) ((cal_clk == RTC_CAL_RC32K || cal_clk == RTC_CAL_32K_XTAL) ? (cycles << 12) : (cycles << 10))
// Calibration can only be performed on relatively slow speed clock signal. Therefore, for high-speed clocks, // Calibration can only be performed on relatively slow speed clock signal. Therefore, for high-speed clocks,
// calibration is performed on their DIV_CLKs. The divider is configurable. We set: // calibration is performed on their DIV_CLKs. The divider is configurable. We set:
#define CLK_CAL_DIV_VAL(cal_clk) \ #define CLK_CAL_DIV_VAL(cali_clk_sel) \
((cal_clk == RTC_CAL_RC_SLOW || cal_clk == RTC_CAL_RC32K || cal_clk == RTC_CAL_32K_XTAL) ? 1 : \ ((cali_clk_sel == CLK_CAL_RC_SLOW || cali_clk_sel == CLK_CAL_RC32K || cali_clk_sel == CLK_CAL_32K_XTAL) ? 1 : \
(cal_clk == RTC_CAL_LP_PLL) ? 25 : \ (cali_clk_sel == CLK_CAL_LP_PLL) ? 25 : \
(cal_clk == RTC_CAL_RC_FAST) ? 50 : \ (cali_clk_sel == CLK_CAL_RC_FAST) ? 50 : \
(cal_clk == RTC_CAL_APLL) ? 200 : \ (cali_clk_sel == CLK_CAL_APLL) ? 200 : \
4000) 4000)
// CLK_CAL_FREQ_APPROX = CLK_FREQ_APPROX / CLK_CAL_DIV_VAL // CLK_CAL_FREQ_APPROX = CLK_FREQ_APPROX / CLK_CAL_DIV_VAL
#define CLK_CAL_FREQ_APPROX(cal_clk) \ #define CLK_CAL_FREQ_APPROX(cali_clk_sel) \
((cal_clk == RTC_CAL_MPLL) ? (CLK_LL_PLL_500M_FREQ_MHZ * MHZ / 4000) : \ ((cali_clk_sel == CLK_CAL_MPLL) ? (CLK_LL_PLL_500M_FREQ_MHZ * MHZ / 4000) : \
(cal_clk == RTC_CAL_SPLL) ? (CLK_LL_PLL_480M_FREQ_MHZ * MHZ / 4000) : \ (cali_clk_sel == CLK_CAL_SPLL) ? (CLK_LL_PLL_480M_FREQ_MHZ * MHZ / 4000) : \
(cal_clk == RTC_CAL_CPLL) ? (CLK_LL_PLL_400M_FREQ_MHZ * MHZ / 4000) : \ (cali_clk_sel == CLK_CAL_CPLL) ? (CLK_LL_PLL_400M_FREQ_MHZ * MHZ / 4000) : \
(cal_clk == RTC_CAL_APLL) ? (105 * MHZ / 200) : \ (cali_clk_sel == CLK_CAL_APLL) ? (105 * MHZ / 200) : \
(cal_clk == RTC_CAL_SDIO_PLL0 || cal_clk == RTC_CAL_SDIO_PLL1 || cal_clk == RTC_CAL_SDIO_PLL2) ? (200 * MHZ / 4000) : \ (cali_clk_sel == CLK_CAL_SDIO_PLL0 || cali_clk_sel == CLK_CAL_SDIO_PLL1 || cali_clk_sel == CLK_CAL_SDIO_PLL2) ? (200 * MHZ / 4000) : \
(cal_clk == RTC_CAL_RC_FAST) ? (SOC_CLK_RC_FAST_FREQ_APPROX / 50) : \ (cali_clk_sel == CLK_CAL_RC_FAST) ? (SOC_CLK_RC_FAST_FREQ_APPROX / 50) : \
(cal_clk == RTC_CAL_RC_SLOW) ? (SOC_CLK_RC_SLOW_FREQ_APPROX) : \ (cali_clk_sel == CLK_CAL_RC_SLOW) ? (SOC_CLK_RC_SLOW_FREQ_APPROX) : \
(cal_clk == RTC_CAL_RC32K) ? (SOC_CLK_RC32K_FREQ_APPROX) : \ (cali_clk_sel == CLK_CAL_RC32K) ? (SOC_CLK_RC32K_FREQ_APPROX) : \
(cal_clk == RTC_CAL_32K_XTAL) ? (SOC_CLK_XTAL32K_FREQ_APPROX) : \ (cali_clk_sel == CLK_CAL_32K_XTAL) ? (SOC_CLK_XTAL32K_FREQ_APPROX) : \
(cal_clk == RTC_CAL_LP_PLL) ? (CLK_LL_PLL_8M_FREQ_MHZ * MHZ / 25) : \ (cali_clk_sel == CLK_CAL_LP_PLL) ? (CLK_LL_PLL_8M_FREQ_MHZ * MHZ / 25) : \
0) 0)
uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) /**
* @brief Clock calibration function used by rtc_clk_cal
*
* Calibration of clock frequency is performed using a special feature of TIMG0.
* This feature counts the number of XTAL clock cycles within a given number of
* clock cycles.
*
* @param cal_clk which clock to calibrate
* @param slowclk_cycles number of slow clock cycles to count
* @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)
{ {
assert(slowclk_cycles < TIMG_RTC_CALI_MAX_V); assert(slowclk_cycles < TIMG_RTC_CALI_MAX_V);
@@ -66,19 +72,20 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
ESP_EARLY_LOGE(TAG, "clock not supported to be calibrated"); ESP_EARLY_LOGE(TAG, "clock not supported to be calibrated");
return 0; return 0;
} }
soc_timg0_calibration_clk_src_t cali_clk_sel = (soc_timg0_calibration_clk_src_t)cal_clk;
/* Enable requested clock (some clocks are always on) */ /* Enable requested clock (some clocks are 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
// Only enable if originally was disabled, and set back to the disable state after calibration is done // Only enable if originally was disabled, and set back to the disable state after calibration is done
// If the clock is already on, then do nothing // If the clock is already on, then do nothing
bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled(); bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled();
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) { if (cali_clk_sel == CLK_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
clk_ll_xtal32k_digi_enable(); clk_ll_xtal32k_digi_enable();
} }
bool rc_fast_enabled = clk_ll_rc_fast_is_enabled(); bool rc_fast_enabled = clk_ll_rc_fast_is_enabled();
bool dig_rc_fast_enabled = clk_ll_rc_fast_digi_is_enabled(); bool dig_rc_fast_enabled = clk_ll_rc_fast_digi_is_enabled();
if (cal_clk == RTC_CAL_RC_FAST) { if (cali_clk_sel == CLK_CAL_RC_FAST) {
if (!rc_fast_enabled) { if (!rc_fast_enabled) {
rtc_clk_8m_enable(true); rtc_clk_8m_enable(true);
} }
@@ -89,7 +96,7 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
bool rc32k_enabled = clk_ll_rc32k_is_enabled(); bool rc32k_enabled = clk_ll_rc32k_is_enabled();
bool dig_rc32k_enabled = clk_ll_rc32k_digi_is_enabled(); bool dig_rc32k_enabled = clk_ll_rc32k_digi_is_enabled();
if (cal_clk == RTC_CAL_RC32K) { if (cali_clk_sel == CLK_CAL_RC32K) {
if (!rc32k_enabled) { if (!rc32k_enabled) {
rtc_clk_rc32k_enable(true); rtc_clk_rc32k_enable(true);
} }
@@ -112,16 +119,16 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
} }
/* Prepare calibration */ /* Prepare calibration */
REG_SET_FIELD(HP_SYS_CLKRST_PERI_CLK_CTRL21_REG, HP_SYS_CLKRST_REG_TIMERGRP0_TGRT_CLK_SRC_SEL, cal_clk); clk_ll_calibration_set_target(cali_clk_sel);
uint32_t clk_cal_divider = CLK_CAL_DIV_VAL(cal_clk); uint32_t clk_cal_divider = CLK_CAL_DIV_VAL(cali_clk_sel);
REG_SET_FIELD(HP_SYS_CLKRST_PERI_CLK_CTRL21_REG, HP_SYS_CLKRST_REG_TIMERGRP0_TGRT_CLK_DIV_NUM, clk_cal_divider - 1); clk_ll_calibration_set_divider(clk_cal_divider);
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);
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles); REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles);
/* Figure out how long to wait for calibration to finish */ /* Figure out how long to wait for calibration to finish */
/* Set timeout reg and expect time delay*/ /* Set timeout reg and expect time delay*/
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, CLK_CAL_TIMEOUT_THRES(cal_clk, slowclk_cycles)); REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, CLK_CAL_TIMEOUT_THRES(cali_clk_sel, slowclk_cycles));
uint32_t expected_freq = CLK_CAL_FREQ_APPROX(cal_clk); uint32_t expected_freq = CLK_CAL_FREQ_APPROX(cali_clk_sel);
assert(expected_freq); assert(expected_freq);
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);
/* Start calibration */ /* Start calibration */
@@ -143,14 +150,14 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
} }
} }
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START); CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_PERI_CLK_CTRL21_REG, HP_SYS_CLKRST_REG_TIMERGRP0_TGRT_CLK_DIV_NUM_M); clk_ll_calibration_set_divider(1);
/* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */ /* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) { if (cali_clk_sel == CLK_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
clk_ll_xtal32k_digi_disable(); clk_ll_xtal32k_digi_disable();
} }
if (cal_clk == RTC_CAL_RC_FAST) { if (cali_clk_sel == CLK_CAL_RC_FAST) {
if (!dig_rc_fast_enabled) { if (!dig_rc_fast_enabled) {
rtc_dig_clk8m_disable(); rtc_dig_clk8m_disable();
} }
@@ -159,7 +166,7 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
} }
} }
if (cal_clk == RTC_CAL_RC32K) { if (cali_clk_sel == CLK_CAL_RC32K) {
if (!dig_rc32k_enabled) { if (!dig_rc32k_enabled) {
clk_ll_rc32k_digi_disable(); clk_ll_rc32k_digi_disable();
} }
@@ -180,7 +187,7 @@ static bool rtc_clk_cal_32k_valid(uint32_t xtal_freq, uint32_t slowclk_cycles, u
uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
{ {
slowclk_cycles /= (cal_clk == RTC_CAL_RTC_MUX) ? 1 : CLK_CAL_DIV_VAL(cal_clk); slowclk_cycles /= (cal_clk == RTC_CAL_RTC_MUX) ? 1 : CLK_CAL_DIV_VAL((soc_timg0_calibration_clk_src_t)cal_clk);
assert(slowclk_cycles); assert(slowclk_cycles);
soc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get(); soc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get();
uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles); uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles);

View File

@@ -163,10 +163,10 @@ 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
*/ */
typedef enum { typedef enum {
RTC_CAL_RTC_MUX = 0, //!< Currently selected RTC SLOW_CLK RTC_CAL_RTC_MUX = -1, //!< Currently selected RTC SLOW_CLK
RTC_CAL_8MD256 = 1, //!< Internal 8 MHz RC oscillator, divided by 256 RTC_CAL_8MD256 = CLK_CAL_RC_FAST_D256, //!< Internal 8 MHz RC oscillator, divided by 256
RTC_CAL_32K_XTAL = 2, //!< External 32 kHz XTAL RTC_CAL_32K_XTAL = CLK_CAL_32K_XTAL, //!< External 32 kHz XTAL
RTC_CAL_INTERNAL_OSC = 3 //!< Internal 150 kHz oscillator RTC_CAL_INTERNAL_OSC = CLK_CAL_RC_SLOW, //!< Internal 150 kHz oscillator
} rtc_cal_sel_t; } rtc_cal_sel_t;
/** /**
@@ -470,8 +470,6 @@ void rtc_clk_apb_freq_update(uint32_t apb_freq);
*/ */
uint32_t rtc_clk_apb_freq_get(void); uint32_t rtc_clk_apb_freq_get(void);
uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles, uint32_t cal_mode);
/** /**
* @brief Measure RTC slow clock's period, based on main XTAL frequency * @brief Measure RTC slow clock's period, based on main XTAL frequency
* *

View File

@@ -28,11 +28,11 @@
/** /**
* @brief One-off clock calibration function used by rtc_clk_cal_internal * @brief One-off clock calibration function used by rtc_clk_cal_internal
* @param cal_clk which clock to calibrate * @param cali_clk_sel which clock to calibrate
* @param slowclk_cycles number of slow clock cycles to count * @param slowclk_cycles number of slow clock cycles to count
* @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_oneoff(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) static uint32_t rtc_clk_cal_internal_oneoff(soc_timg0_calibration_clk_src_t cali_clk_sel, uint32_t slowclk_cycles)
{ {
/* There may be another calibration process already running during we call this function, /* There may be another calibration process already running during we call this function,
* so we should wait the last process is done. * so we should wait the last process is done.
@@ -48,17 +48,17 @@ static uint32_t rtc_clk_cal_internal_oneoff(rtc_cal_sel_t cal_clk, uint32_t slow
} }
/* Prepare calibration */ /* Prepare calibration */
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cal_clk); clk_ll_calibration_set_target(cali_clk_sel);
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);
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles); REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles);
/* Figure out how long to wait for calibration to finish */ /* Figure out how long to wait for calibration to finish */
/* Set timeout reg and expect time delay*/ /* Set timeout reg and expect time delay*/
uint32_t expected_freq; uint32_t expected_freq;
if (cal_clk == RTC_CAL_32K_XTAL) { if (cali_clk_sel == CLK_CAL_32K_XTAL) {
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_X32K_CAL_TIMEOUT_THRES(slowclk_cycles)); REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_X32K_CAL_TIMEOUT_THRES(slowclk_cycles));
expected_freq = SOC_CLK_XTAL32K_FREQ_APPROX; expected_freq = SOC_CLK_XTAL32K_FREQ_APPROX;
} else if (cal_clk == RTC_CAL_8MD256) { } else if (cali_clk_sel == CLK_CAL_RC_FAST_D256) {
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_8MD256_CAL_TIMEOUT_THRES(slowclk_cycles)); REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_8MD256_CAL_TIMEOUT_THRES(slowclk_cycles));
expected_freq = SOC_CLK_RC_FAST_D256_FREQ_APPROX; expected_freq = SOC_CLK_RC_FAST_D256_FREQ_APPROX;
} else { } else {
@@ -89,20 +89,19 @@ static uint32_t rtc_clk_cal_internal_oneoff(rtc_cal_sel_t cal_clk, uint32_t slow
/** /**
* @brief Cycling clock calibration function used by rtc_clk_cal_internal * @brief Cycling clock calibration function used by rtc_clk_cal_internal
* @param cal_clk which clock to calibrate * @param cali_clk_sel which clock to calibrate
* @param slowclk_cycles number of slow clock cycles to count * @param slowclk_cycles number of slow clock cycles to count
* @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_cycling(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) static uint32_t rtc_clk_cal_internal_cycling(soc_timg0_calibration_clk_src_t cali_clk_sel, uint32_t slowclk_cycles)
{ {
/* Get which slowclk is in calibration and max cali cycles */ /* Get which slowclk is in calibration and max cali cycles */
rtc_cal_sel_t in_calibration_clk; soc_timg0_calibration_clk_src_t in_calibration_clk = REG_GET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL);
in_calibration_clk = REG_GET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL);
uint32_t cali_slowclk_cycles = REG_GET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX); uint32_t cali_slowclk_cycles = REG_GET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX);
/* If no calibration in process or calibration period equal to 0, use slowclk_cycles cycles to calibrate slowclk */ /* If no calibration in process or calibration period equal to 0, use slowclk_cycles cycles to calibrate slowclk */
if (cali_slowclk_cycles == 0 || !GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING) || in_calibration_clk != cal_clk) { if (cali_slowclk_cycles == 0 || !GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING) || in_calibration_clk != cali_clk_sel) {
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);
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cal_clk); clk_ll_calibration_set_target(cali_clk_sel);
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles); REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles);
SET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING); SET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING);
cali_slowclk_cycles = slowclk_cycles; cali_slowclk_cycles = slowclk_cycles;
@@ -137,52 +136,48 @@ static uint32_t rtc_clk_xtal_to_slowclk(uint64_t xtal_cycles, uint32_t slowclk_c
* @param slowclk_cycles number of slow clock cycles to count * @param slowclk_cycles number of slow clock cycles to count
* @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
*/ */
uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles, uint32_t cal_mode) static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles, uint32_t cal_mode)
{ {
/* On ESP32S2, choosing RTC_CAL_RTC_MUX results in calibration of
* the 90k RTC clock regardless of the currently selected SLOW_CLK.
* On the ESP32, it used the currently selected SLOW_CLK.
* The following code emulates ESP32 behavior:
*/
if (cal_clk == RTC_CAL_RTC_MUX) { if (cal_clk == RTC_CAL_RTC_MUX) {
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();
if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) {
cal_clk = RTC_CAL_INTERNAL_OSC;
} else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
cal_clk = RTC_CAL_32K_XTAL; cal_clk = RTC_CAL_32K_XTAL;
} else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { } else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) {
cal_clk = RTC_CAL_8MD256; cal_clk = RTC_CAL_8MD256;
} }
} else if (cal_clk == RTC_CAL_INTERNAL_OSC) {
cal_clk = RTC_CAL_RTC_MUX;
} }
soc_timg0_calibration_clk_src_t cali_clk_sel = (soc_timg0_calibration_clk_src_t)cal_clk;
/* Enable requested clock (90k clock is always on) */ /* Enable requested clock (90k clock is always on) */
bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled(); bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled();
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) { if (cali_clk_sel == CLK_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
clk_ll_xtal32k_digi_enable(); clk_ll_xtal32k_digi_enable();
} }
bool rc_fast_enabled = clk_ll_rc_fast_is_enabled(); bool rc_fast_enabled = clk_ll_rc_fast_is_enabled();
bool rc_fast_d256_enabled = clk_ll_rc_fast_d256_is_enabled(); bool rc_fast_d256_enabled = clk_ll_rc_fast_d256_is_enabled();
if (cal_clk == RTC_CAL_8MD256) { if (cali_clk_sel == CLK_CAL_RC_FAST_D256) {
rtc_clk_8m_enable(true, true); rtc_clk_8m_enable(true, true);
clk_ll_rc_fast_d256_digi_enable(); clk_ll_rc_fast_d256_digi_enable();
} }
uint32_t cal_val; uint32_t cal_val;
if (cal_mode == RTC_TIME_CAL_ONEOFF_MODE) { if (cal_mode == RTC_TIME_CAL_ONEOFF_MODE) {
cal_val = rtc_clk_cal_internal_oneoff(cal_clk, slowclk_cycles); cal_val = rtc_clk_cal_internal_oneoff(cali_clk_sel, slowclk_cycles);
} else { } else {
cal_val = rtc_clk_cal_internal_cycling(cal_clk, slowclk_cycles); cal_val = rtc_clk_cal_internal_cycling(cali_clk_sel, slowclk_cycles);
} }
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START); CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
/* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */ /* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) { if (cali_clk_sel == CLK_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
clk_ll_xtal32k_digi_disable(); clk_ll_xtal32k_digi_disable();
} }
if (cal_clk == RTC_CAL_8MD256) { if (cali_clk_sel == CLK_CAL_RC_FAST_D256) {
clk_ll_rc_fast_d256_digi_disable(); clk_ll_rc_fast_d256_digi_disable();
rtc_clk_8m_enable(rc_fast_enabled, rc_fast_d256_enabled); rtc_clk_8m_enable(rc_fast_enabled, rc_fast_d256_enabled);
} }

View File

@@ -165,10 +165,10 @@ 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
*/ */
typedef enum { typedef enum {
RTC_CAL_RTC_MUX = 0, //!< Currently selected RTC SLOW_CLK RTC_CAL_RTC_MUX = -1, //!< Currently selected RTC SLOW_CLK
RTC_CAL_8MD256 = 1, //!< Internal 8 MHz RC oscillator, divided by 256 RTC_CAL_8MD256 = CLK_CAL_RC_FAST_D256, //!< Internal 17.5 MHz RC oscillator, divided by 256
RTC_CAL_32K_XTAL = 2, //!< External 32 kHz XTAL RTC_CAL_32K_XTAL = CLK_CAL_32K_XTAL, //!< External 32 kHz XTAL
RTC_CAL_INTERNAL_OSC = 3 //!< Internal 150 kHz oscillator RTC_CAL_INTERNAL_OSC = CLK_CAL_RC_SLOW, //!< Internal 150 kHz oscillator
} rtc_cal_sel_t; } rtc_cal_sel_t;
/** /**
@@ -448,8 +448,6 @@ void rtc_clk_apb_freq_update(uint32_t apb_freq);
*/ */
uint32_t rtc_clk_apb_freq_get(void); uint32_t rtc_clk_apb_freq_get(void);
uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles);
/** /**
* @brief Measure RTC slow clock's period, based on main XTAL frequency * @brief Measure RTC slow clock's period, based on main XTAL frequency
* *

View File

@@ -32,33 +32,29 @@
* @param slowclk_cycles number of slow clock cycles to count * @param slowclk_cycles number of slow clock cycles to count
* @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
*/ */
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)
{ {
/* On ESP32S3, choosing RTC_CAL_RTC_MUX results in calibration of
* the 150k RTC clock regardless of the currently selected SLOW_CLK.
* On the ESP32, it used the currently selected SLOW_CLK.
* The following code emulates ESP32 behavior:
*/
if (cal_clk == RTC_CAL_RTC_MUX) { if (cal_clk == RTC_CAL_RTC_MUX) {
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();
if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) {
cal_clk = RTC_CAL_INTERNAL_OSC;
} else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
cal_clk = RTC_CAL_32K_XTAL; cal_clk = RTC_CAL_32K_XTAL;
} else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { } else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) {
cal_clk = RTC_CAL_8MD256; cal_clk = RTC_CAL_8MD256;
} }
} else if (cal_clk == RTC_CAL_INTERNAL_OSC) {
cal_clk = RTC_CAL_RTC_MUX;
} }
soc_timg0_calibration_clk_src_t cali_clk_sel = (soc_timg0_calibration_clk_src_t)cal_clk;
/* Enable requested clock (150k clock is always on) */ /* Enable requested clock (150k clock is always on) */
bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled(); bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled();
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) { if (cali_clk_sel == CLK_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
clk_ll_xtal32k_digi_enable(); clk_ll_xtal32k_digi_enable();
} }
bool rc_fast_enabled = clk_ll_rc_fast_is_enabled(); bool rc_fast_enabled = clk_ll_rc_fast_is_enabled();
bool rc_fast_d256_enabled = clk_ll_rc_fast_d256_is_enabled(); bool rc_fast_d256_enabled = clk_ll_rc_fast_d256_is_enabled();
if (cal_clk == RTC_CAL_8MD256) { if (cali_clk_sel == CLK_CAL_RC_FAST_D256) {
rtc_clk_8m_enable(true, true); rtc_clk_8m_enable(true, true);
clk_ll_rc_fast_d256_digi_enable(); clk_ll_rc_fast_d256_digi_enable();
} }
@@ -76,17 +72,17 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
} }
/* Prepare calibration */ /* Prepare calibration */
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cal_clk); clk_ll_calibration_set_target(cali_clk_sel);
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);
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles); REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles);
/* Figure out how long to wait for calibration to finish */ /* Figure out how long to wait for calibration to finish */
/* Set timeout reg and expect time delay*/ /* Set timeout reg and expect time delay*/
uint32_t expected_freq; uint32_t expected_freq;
if (cal_clk == RTC_CAL_32K_XTAL) { if (cali_clk_sel == CLK_CAL_32K_XTAL) {
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_X32K_CAL_TIMEOUT_THRES(slowclk_cycles)); REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_X32K_CAL_TIMEOUT_THRES(slowclk_cycles));
expected_freq = SOC_CLK_XTAL32K_FREQ_APPROX; expected_freq = SOC_CLK_XTAL32K_FREQ_APPROX;
} else if (cal_clk == RTC_CAL_8MD256) { } else if (cali_clk_sel == CLK_CAL_RC_FAST_D256) {
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_8MD256_CAL_TIMEOUT_THRES(slowclk_cycles)); REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_8MD256_CAL_TIMEOUT_THRES(slowclk_cycles));
expected_freq = SOC_CLK_RC_FAST_D256_FREQ_APPROX; expected_freq = SOC_CLK_RC_FAST_D256_FREQ_APPROX;
} else { } else {
@@ -114,11 +110,11 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START); CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
/* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */ /* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) { if (cali_clk_sel == CLK_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
clk_ll_xtal32k_digi_disable(); clk_ll_xtal32k_digi_disable();
} }
if (cal_clk == RTC_CAL_8MD256) { if (cali_clk_sel == CLK_CAL_RC_FAST_D256) {
clk_ll_rc_fast_d256_digi_disable(); clk_ll_rc_fast_d256_digi_disable();
rtc_clk_8m_enable(rc_fast_enabled, rc_fast_d256_enabled); rtc_clk_8m_enable(rc_fast_enabled, rc_fast_d256_enabled);
} }

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -13,6 +13,7 @@
#include "soc/rtc_io_reg.h" #include "soc/rtc_io_reg.h"
#include "soc/dport_reg.h" #include "soc/dport_reg.h"
#include "soc/syscon_reg.h" #include "soc/syscon_reg.h"
#include "soc/timer_group_struct.h"
#include "hal/regi2c_ctrl.h" #include "hal/regi2c_ctrl.h"
#include "soc/regi2c_bbpll.h" #include "soc/regi2c_bbpll.h"
#include "soc/regi2c_apll.h" #include "soc/regi2c_apll.h"
@@ -702,6 +703,29 @@ static inline __attribute__((always_inline)) void clk_ll_ref_tick_set_divider(so
} }
} }
/**
* @brief Select the calibration clock source for timergroup0
*
* @param clk_sel One of the clock sources in soc_timg0_calibration_clk_src_t
*/
static inline __attribute__((always_inline)) void clk_ll_calibration_set_target(soc_timg0_calibration_clk_src_t clk_sel)
{
switch (clk_sel) {
case CLK_CAL_RTC_SLOW:
TIMERG0.rtccalicfg.rtc_cali_clk_sel = 0;
break;
case CLK_CAL_RC_FAST_D256:
TIMERG0.rtccalicfg.rtc_cali_clk_sel = 1;
break;
case CLK_CAL_32K_XTAL:
TIMERG0.rtccalicfg.rtc_cali_clk_sel = 2;
break;
default:
// Unsupported CLK_CAL mux input
abort();
}
}
/** /**
* @brief Select the clock source for RTC_SLOW_CLK * @brief Select the clock source for RTC_SLOW_CLK
* *

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -13,6 +13,7 @@
#include "soc/rtc_cntl_reg.h" #include "soc/rtc_cntl_reg.h"
#include "hal/regi2c_ctrl.h" #include "hal/regi2c_ctrl.h"
#include "soc/regi2c_bbpll.h" #include "soc/regi2c_bbpll.h"
#include "soc/timer_group_struct.h"
#include "hal/assert.h" #include "hal/assert.h"
#include "hal/log.h" #include "hal/log.h"
#include "esp32c2/rom/rtc.h" #include "esp32c2/rom/rtc.h"
@@ -386,6 +387,29 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_divider(voi
return REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT) + 1; return REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT) + 1;
} }
/**
* @brief Select the calibration clock source for timergroup0
*
* @param clk_sel One of the clock sources in soc_timg0_calibration_clk_src_t
*/
static inline __attribute__((always_inline)) void clk_ll_calibration_set_target(soc_timg0_calibration_clk_src_t clk_sel)
{
switch (clk_sel) {
case CLK_CAL_RC_SLOW:
TIMERG0.rtccalicfg.rtc_cali_clk_sel = 0;
break;
case CLK_CAL_RC_FAST_D256:
TIMERG0.rtccalicfg.rtc_cali_clk_sel = 1;
break;
case CLK_CAL_32K_OSC_SLOW:
TIMERG0.rtccalicfg.rtc_cali_clk_sel = 2;
break;
default:
// Unsupported CLK_CAL mux input
abort();
}
}
/** /**
* @brief Select the clock source for RTC_SLOW_CLK * @brief Select the clock source for RTC_SLOW_CLK
* *

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -13,6 +13,7 @@
#include "soc/rtc_cntl_reg.h" #include "soc/rtc_cntl_reg.h"
#include "hal/regi2c_ctrl.h" #include "hal/regi2c_ctrl.h"
#include "soc/regi2c_bbpll.h" #include "soc/regi2c_bbpll.h"
#include "soc/timer_group_struct.h"
#include "hal/assert.h" #include "hal/assert.h"
#include "hal/log.h" #include "hal/log.h"
#include "esp32c3/rom/rtc.h" #include "esp32c3/rom/rtc.h"
@@ -494,6 +495,29 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_divider(voi
return REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT) + 1; return REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT) + 1;
} }
/**
* @brief Select the calibration clock source for timergroup0
*
* @param clk_sel One of the clock sources in soc_timg0_calibration_clk_src_t
*/
static inline __attribute__((always_inline)) void clk_ll_calibration_set_target(soc_timg0_calibration_clk_src_t clk_sel)
{
switch (clk_sel) {
case CLK_CAL_RC_SLOW:
TIMERG0.rtccalicfg.rtc_cali_clk_sel = 0;
break;
case CLK_CAL_RC_FAST_D256:
TIMERG0.rtccalicfg.rtc_cali_clk_sel = 1;
break;
case CLK_CAL_32K_XTAL:
TIMERG0.rtccalicfg.rtc_cali_clk_sel = 2;
break;
default:
// Unsupported CLK_CAL mux input
abort();
}
}
/** /**
* @brief Select the clock source for RTC_SLOW_CLK * @brief Select the clock source for RTC_SLOW_CLK
* *

View File

@@ -441,6 +441,55 @@ static inline __attribute__((always_inline)) void clk_ll_soc_root_clk_auto_gatin
} }
} }
/**
* @brief Enable the RTC clock calibration reference XTAL source on timer group0.
* @param enable Enable or disable the XTAL source.
*/
static inline __attribute__((always_inline)) void clk_ll_enable_timergroup_rtc_calibration_clock(bool enable)
{
PCR.timergroup_xtal_conf.tg0_xtal_clk_en = enable;
}
/**
* @brief Select the calibration clock source for timergroup0
*
* @param clk_sel One of the clock sources in soc_timg0_calibration_clk_src_t
*/
static inline __attribute__((always_inline)) void clk_ll_calibration_set_target(soc_timg0_calibration_clk_src_t clk_sel)
{
int timg_cali_clk_sel = -1;
switch (clk_sel) {
case CLK_CAL_32K_XTAL:
timg_cali_clk_sel = 1;
break;
case CLK_CAL_32K_OSC_SLOW:
timg_cali_clk_sel = 2;
break;
case CLK_CAL_RC_SLOW:
timg_cali_clk_sel = 3;
break;
case CLK_CAL_RC_FAST:
timg_cali_clk_sel = 4;
break;
default:
// Unsupported CLK_CAL mux input
abort();
}
if (timg_cali_clk_sel >= 0) {
PCR.ctrl_32k_conf.clk_32k_sel = timg_cali_clk_sel;
}
}
/**
* @brief Set the frequency division factor of RC_FAST clock
*/
static inline __attribute__((always_inline)) void clk_ll_rc_fast_tick_conf(void)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ctrl_32k_conf, fosc_tick_num, (1 << CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS) - 1); // divider = 1 << CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS
}
/** /**
* @brief Select the clock source for RTC_SLOW_CLK * @brief Select the clock source for RTC_SLOW_CLK
* *
@@ -549,14 +598,6 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_rc_fast_get_divider
return 1; return 1;
} }
/**
* @brief Set the frequency division factor of RC_FAST clock
*/
static inline void clk_ll_rc_fast_tick_conf(void)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ctrl_32k_conf, fosc_tick_num, (1 << CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS) - 1); // divider = 1 << CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS
}
/** /**
* @brief Set RC_SLOW_CLK divider * @brief Set RC_SLOW_CLK divider
* *
@@ -568,15 +609,6 @@ static inline __attribute__((always_inline)) void clk_ll_rc_slow_set_divider(uin
HAL_ASSERT(divider == 1); HAL_ASSERT(divider == 1);
} }
/**
* @brief Enable the RTC clock calibration reference XTAL source on timer group0.
* @param enable enable or disable the XTAL source.
*/
static inline __attribute__((always_inline)) void clk_ll_enable_timergroup_rtc_calibration_clock(bool enable)
{
PCR.timergroup_xtal_conf.tg0_xtal_clk_en = enable;
}
/************************** LP STORAGE REGISTER STORE/LOAD **************************/ /************************** LP STORAGE REGISTER STORE/LOAD **************************/
/** /**
* @brief Store RTC_SLOW_CLK calibration value in RTC storage register * @brief Store RTC_SLOW_CLK calibration value in RTC storage register

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -14,6 +14,7 @@
#include "soc/pmu_reg.h" #include "soc/pmu_reg.h"
#include "hal/regi2c_ctrl.h" #include "hal/regi2c_ctrl.h"
#include "soc/regi2c_bbpll.h" #include "soc/regi2c_bbpll.h"
#include "soc/timer_group_struct.h"
#include "hal/assert.h" #include "hal/assert.h"
#include "hal/log.h" #include "hal/log.h"
#include "esp32c6/rom/rtc.h" #include "esp32c6/rom/rtc.h"
@@ -577,46 +578,53 @@ static inline __attribute__((always_inline)) void clk_ll_mspi_fast_set_ls_divide
} }
/** /**
* @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 (RC32K_CLK, XTAL32K_CLK, OSC_SLOW_CLK) * @param clk_sel One of the clock sources in soc_timg0_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_timg0_calibration_clk_src_t clk_sel)
{ {
switch (in_sel) { int timg_cali_clk_sel = -1;
case SOC_RTC_SLOW_CLK_SRC_RC32K: int clk_32k_sel = -1;
PCR.ctrl_32k_conf.clk_32k_sel = 0;
switch (clk_sel) {
case CLK_CAL_RC32K:
timg_cali_clk_sel = 2;
clk_32k_sel = 0;
break; break;
case SOC_RTC_SLOW_CLK_SRC_XTAL32K: case CLK_CAL_32K_XTAL:
PCR.ctrl_32k_conf.clk_32k_sel = 1; 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) {
TIMERG0.rtccalicfg.rtc_cali_clk_sel = timg_cali_clk_sel;
}
if (clk_32k_sel >= 0) {
PCR.ctrl_32k_conf.clk_32k_sel = clk_32k_sel;
}
} }
/** /**
* @brief Get the calibration 32kHz clock source for timergroup0 * @brief Set the frequency division factor of RC_FAST clock
*
* @return soc_rtc_slow_clk_src_t Currently selected calibration 32kHz clock (one of the 32kHz clocks)
*/ */
static inline __attribute__((always_inline)) soc_rtc_slow_clk_src_t clk_ll_32k_calibration_get_target(void) static inline __attribute__((always_inline)) void clk_ll_rc_fast_tick_conf(void)
{ {
uint32_t clk_sel = PCR.ctrl_32k_conf.clk_32k_sel; HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ctrl_tick_conf, fosc_tick_num, REG_FOSC_TICK_NUM); // enable a division of 32 to the fosc clock
switch (clk_sel) {
case 0:
return SOC_RTC_SLOW_CLK_SRC_RC32K;
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;
}
} }
/** /**
@@ -806,15 +814,6 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_rtc_slow_load_cal(v
} }
/*
Set the frequency division factor of ref_tick
*/
static inline void clk_ll_rc_fast_tick_conf(void)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ctrl_tick_conf, fosc_tick_num, REG_FOSC_TICK_NUM); // enable a division of 32 to the fosc clock
}
/* /*
* Enable/Disable the clock gate for clock output signal source * Enable/Disable the clock gate for clock output signal source
*/ */

View File

@@ -396,6 +396,46 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_apb_get_divider(voi
return HAL_FORCE_READ_U32_REG_FIELD(PCR.apb_freq_conf, apb_div_num) + 1; return HAL_FORCE_READ_U32_REG_FIELD(PCR.apb_freq_conf, apb_div_num) + 1;
} }
/**
* @brief Select the calibration clock source for timergroup0
*
* @param clk_sel One of the clock sources in soc_timg0_calibration_clk_src_t
*/
static inline __attribute__((always_inline)) void clk_ll_calibration_set_target(soc_timg0_calibration_clk_src_t clk_sel)
{
int timg_cali_clk_sel = -1;
switch (clk_sel) {
case CLK_CAL_32K_XTAL:
timg_cali_clk_sel = 1;
break;
case CLK_CAL_32K_OSC_SLOW:
timg_cali_clk_sel = 2;
break;
case CLK_CAL_RC_SLOW:
timg_cali_clk_sel = 3;
break;
case CLK_CAL_RC_FAST:
timg_cali_clk_sel = 4;
break;
default:
// Unsupported CLK_CAL mux input
abort();
}
if (timg_cali_clk_sel >= 0) {
PCR.ctrl_32k_conf.clk_32k_sel = timg_cali_clk_sel;
}
}
/**
* @brief Set the frequency division factor of RC_FAST clock
*/
static inline __attribute__((always_inline)) void clk_ll_rc_fast_tick_conf(void)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ctrl_32k_conf, fosc_tick_num, (1 << CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS) - 1); // divider = 1 << CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS
}
/** /**
* @brief Select the clock source for RTC_SLOW_CLK * @brief Select the clock source for RTC_SLOW_CLK
* *
@@ -504,14 +544,6 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_rc_fast_get_divider
return 1; return 1;
} }
/**
* @brief Set the frequency division factor of RC_FAST clock
*/
static inline void clk_ll_rc_fast_tick_conf(void)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ctrl_32k_conf, fosc_tick_num, (1 << CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS) - 1); // divider = 1 << CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS
}
/** /**
* @brief Set RC_SLOW_CLK divider * @brief Set RC_SLOW_CLK divider
* *

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -15,6 +15,7 @@
#include "hal/regi2c_ctrl.h" #include "hal/regi2c_ctrl.h"
#include "soc/regi2c_bbpll.h" #include "soc/regi2c_bbpll.h"
#include "soc/regi2c_pmu.h" #include "soc/regi2c_pmu.h"
#include "soc/timer_group_struct.h"
#include "hal/assert.h" #include "hal/assert.h"
#include "hal/log.h" #include "hal/log.h"
#include "esp32h2/rom/rtc.h" #include "esp32h2/rom/rtc.h"
@@ -458,46 +459,53 @@ 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 (RC32K_CLK, XTAL32K_CLK, OSC_SLOW_CLK) * @param clk_sel One of the clock sources in soc_timg0_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_timg0_calibration_clk_src_t clk_sel)
{ {
switch (in_sel) { int timg_cali_clk_sel = -1;
case SOC_RTC_SLOW_CLK_SRC_RC32K: int clk_32k_sel = -1;
PCR.ctrl_32k_conf.clk_32k_sel = 0;
switch (clk_sel) {
case CLK_CAL_RC32K:
timg_cali_clk_sel = 2;
clk_32k_sel = 0;
break; break;
case SOC_RTC_SLOW_CLK_SRC_XTAL32K: case CLK_CAL_32K_XTAL:
PCR.ctrl_32k_conf.clk_32k_sel = 1; 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) {
TIMERG0.rtccalicfg.rtc_cali_clk_sel = timg_cali_clk_sel;
}
if (clk_32k_sel >= 0) {
PCR.ctrl_32k_conf.clk_32k_sel = clk_32k_sel;
}
} }
/** /**
* @brief Get the calibration 32kHz clock source for timergroup0 * @brief Set the frequency division factor of RC_FAST clock
*
* @return soc_rtc_slow_clk_src_t Currently selected calibration 32kHz clock (one of the 32kHz clocks)
*/ */
static inline __attribute__((always_inline)) soc_rtc_slow_clk_src_t clk_ll_32k_calibration_get_target(void) static inline __attribute__((always_inline)) void clk_ll_rc_fast_tick_conf(void)
{ {
uint32_t clk_sel = PCR.ctrl_32k_conf.clk_32k_sel; HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ctrl_tick_conf, fosc_tick_num, REG_FOSC_TICK_NUM); // enable a division of 32 to the fosc clock
switch (clk_sel) {
case 0:
return SOC_RTC_SLOW_CLK_SRC_RC32K;
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;
}
} }
/** /**
@@ -742,14 +750,6 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_rtc_slow_load_cal(v
return REG_READ(RTC_SLOW_CLK_CAL_REG); return REG_READ(RTC_SLOW_CLK_CAL_REG);
} }
/*
Set the frequency division factor of ref_tick
*/
static inline void clk_ll_rc_fast_tick_conf(void)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ctrl_tick_conf, fosc_tick_num, REG_FOSC_TICK_NUM); // enable a division of 32 to the fosc clock
}
/* /*
* Enable/Disable the clock gate for clock output signal source * Enable/Disable the clock gate for clock output signal source
*/ */

View File

@@ -413,9 +413,9 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_apb_get_divider(voi
/** /**
* @brief Select the calibration clock source for timergroup0 * @brief Select the calibration clock source for timergroup0
* *
* @param clk_sel One of the clock sources in soc_clk_calibration_clk_src_t * @param clk_sel One of the clock sources in soc_timg0_calibration_clk_src_t
*/ */
static inline __attribute__((always_inline)) void clk_ll_calibration_set_target(soc_clk_calibration_clk_src_t clk_sel) static inline __attribute__((always_inline)) void clk_ll_calibration_set_target(soc_timg0_calibration_clk_src_t clk_sel)
{ {
int timg_cali_clk_sel = -1; int timg_cali_clk_sel = -1;
int clk_32k_sel = -1; int clk_32k_sel = -1;
@@ -448,6 +448,14 @@ static inline __attribute__((always_inline)) void clk_ll_calibration_set_target(
} }
} }
/**
* @brief Set the frequency division factor of RC_FAST clock
*/
static inline __attribute__((always_inline)) void clk_ll_rc_fast_tick_conf(void)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ctrl_tick_conf, fosc_tick_num, (1 << CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS) - 1); // divider = 1 << CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS
}
/** /**
* @brief Select the clock source for RTC_SLOW_CLK * @brief Select the clock source for RTC_SLOW_CLK
* *
@@ -551,14 +559,6 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_rc_fast_get_divider
return 1; return 1;
} }
/**
* @brief Set the frequency division factor of RC_FAST clock
*/
static inline void clk_ll_rc_fast_tick_conf(void)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ctrl_tick_conf, fosc_tick_num, (1 << CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS) - 1); // divider = 1 << CLK_LL_RC_FAST_CALIB_TICK_DIV_BITS
}
/** /**
* @brief Set RC_SLOW_CLK divider. The output from the divider is passed into rtc_slow_clk MUX. * @brief Set RC_SLOW_CLK divider. The output from the divider is passed into rtc_slow_clk MUX.
* *

View File

@@ -422,9 +422,9 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_apb_get_divider(voi
/** /**
* @brief Select the calibration clock source for timergroup0 * @brief Select the calibration clock source for timergroup0
* *
* @param clk_sel One of the clock sources in soc_clk_calibration_clk_src_t * @param clk_sel One of the clock sources in soc_timg0_calibration_clk_src_t
*/ */
static inline __attribute__((always_inline)) void clk_ll_calibration_set_target(soc_clk_calibration_clk_src_t clk_sel) static inline __attribute__((always_inline)) void clk_ll_calibration_set_target(soc_timg0_calibration_clk_src_t clk_sel)
{ {
int timg_cali_clk_sel = -1; int timg_cali_clk_sel = -1;
int timg_secure_clk_sel = -1; int timg_secure_clk_sel = -1;

View File

@@ -725,6 +725,73 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_pll_f20m_get_divide
return HAL_FORCE_READ_U32_REG_FIELD(HP_SYS_CLKRST.ref_clk_ctrl1, reg_ref_20m_clk_div_num) + 1; return HAL_FORCE_READ_U32_REG_FIELD(HP_SYS_CLKRST.ref_clk_ctrl1, reg_ref_20m_clk_div_num) + 1;
} }
/**
* @brief Select the calibration clock source for timergroup0
*
* @param clk_sel One of the clock sources in soc_timg0_calibration_clk_src_t
*/
static inline __attribute__((always_inline)) void clk_ll_calibration_set_target(soc_timg0_calibration_clk_src_t clk_sel)
{
int timg_cali_clk_sel = -1;
switch (clk_sel) {
case CLK_CAL_MPLL:
timg_cali_clk_sel = 0;
break;
case CLK_CAL_SPLL:
timg_cali_clk_sel = 1;
break;
case CLK_CAL_CPLL:
timg_cali_clk_sel = 2;
break;
case CLK_CAL_APLL:
timg_cali_clk_sel = 3;
break;
case CLK_CAL_SDIO_PLL0:
timg_cali_clk_sel = 4;
break;
case CLK_CAL_SDIO_PLL1:
timg_cali_clk_sel = 5;
break;
case CLK_CAL_SDIO_PLL2:
timg_cali_clk_sel = 6;
break;
case CLK_CAL_RC_FAST:
timg_cali_clk_sel = 7;
break;
case CLK_CAL_RC_SLOW:
timg_cali_clk_sel = 8;
break;
case CLK_CAL_RC32K:
timg_cali_clk_sel = 9;
break;
case CLK_CAL_32K_XTAL:
timg_cali_clk_sel = 10;
break;
case CLK_CAL_LP_PLL:
timg_cali_clk_sel = 11;
break;
default:
// Unsupported CLK_CAL mux input
abort();
}
if (timg_cali_clk_sel >= 0) {
HP_SYS_CLKRST.peri_clk_ctrl21.reg_timergrp0_tgrt_clk_src_sel = timg_cali_clk_sel;
}
}
/**
* @brief Set a divider for the clock to be calibrated by timergroup0
*
* @param divider Divider. PRE_DIV_CNT = divider - 1.
*/
static inline __attribute__((always_inline)) void clk_ll_calibration_set_divider(uint32_t divider)
{
HAL_ASSERT(divider >= 1);
HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl21, reg_timergrp0_tgrt_clk_div_num, divider - 1);
}
/** /**
* @brief Select the clock source for RTC_SLOW_CLK * @brief Select the clock source for RTC_SLOW_CLK
* *

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -15,6 +15,7 @@
#include "hal/regi2c_ctrl.h" #include "hal/regi2c_ctrl.h"
#include "soc/regi2c_bbpll.h" #include "soc/regi2c_bbpll.h"
#include "soc/regi2c_apll.h" #include "soc/regi2c_apll.h"
#include "soc/timer_group_struct.h"
#include "hal/assert.h" #include "hal/assert.h"
#include "esp32s2/rom/rtc.h" #include "esp32s2/rom/rtc.h"
@@ -618,6 +619,29 @@ static inline __attribute__((always_inline)) void clk_ll_ref_tick_set_divider(so
} }
} }
/**
* @brief Select the calibration clock source for timergroup0
*
* @param clk_sel One of the clock sources in soc_timg0_calibration_clk_src_t
*/
static inline __attribute__((always_inline)) void clk_ll_calibration_set_target(soc_timg0_calibration_clk_src_t clk_sel)
{
switch (clk_sel) {
case CLK_CAL_RC_SLOW:
TIMERG0.rtccalicfg.rtc_cali_clk_sel = 0;
break;
case CLK_CAL_RC_FAST_D256:
TIMERG0.rtccalicfg.rtc_cali_clk_sel = 1;
break;
case CLK_CAL_32K_XTAL:
TIMERG0.rtccalicfg.rtc_cali_clk_sel = 2;
break;
default:
// Unsupported CLK_CAL mux input
abort();
}
}
/** /**
* @brief Select the clock source for RTC_SLOW_CLK * @brief Select the clock source for RTC_SLOW_CLK
* *

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -13,6 +13,7 @@
#include "soc/rtc_cntl_reg.h" #include "soc/rtc_cntl_reg.h"
#include "hal/regi2c_ctrl.h" #include "hal/regi2c_ctrl.h"
#include "soc/regi2c_bbpll.h" #include "soc/regi2c_bbpll.h"
#include "soc/timer_group_struct.h"
#include "hal/assert.h" #include "hal/assert.h"
#include "hal/log.h" #include "hal/log.h"
#include "esp32s3/rom/rtc.h" #include "esp32s3/rom/rtc.h"
@@ -494,6 +495,29 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_divider(voi
return REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT) + 1; return REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT) + 1;
} }
/**
* @brief Select the calibration clock source for timergroup0
*
* @param clk_sel One of the clock sources in soc_timg0_calibration_clk_src_t
*/
static inline __attribute__((always_inline)) void clk_ll_calibration_set_target(soc_timg0_calibration_clk_src_t clk_sel)
{
switch (clk_sel) {
case CLK_CAL_RC_SLOW:
TIMERG0.rtccalicfg.rtc_cali_clk_sel = 0;
break;
case CLK_CAL_RC_FAST_D256:
TIMERG0.rtccalicfg.rtc_cali_clk_sel = 1;
break;
case CLK_CAL_32K_XTAL:
TIMERG0.rtccalicfg.rtc_cali_clk_sel = 2;
break;
default:
// Unsupported CLK_CAL mux input
abort();
}
}
/** /**
* @brief Select the clock source for RTC_SLOW_CLK * @brief Select the clock source for RTC_SLOW_CLK
* *

View File

@@ -484,6 +484,16 @@ typedef enum {
CLKOUT_SIG_INVALID = 0xFF, CLKOUT_SIG_INVALID = 0xFF,
} soc_clkout_sig_id_t; } soc_clkout_sig_id_t;
////////////////////////////////////////////RTC CALIBRATION///////////////////////////////////////////////////////////
/**
* @brief Clock frequency calibration source selection
*/
typedef enum {
CLK_CAL_RTC_SLOW, /*!< Select to calibrate RTC_SLOW_CLK */
CLK_CAL_RC_FAST_D256, /*!< Select to calibrate RC_FAST_D256_CLK */
CLK_CAL_32K_XTAL, /*!< Select to calibrate XTAL32K_CLK */
} soc_timg0_calibration_clk_src_t;
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -347,7 +347,7 @@ typedef union {
*/ */
uint32_t rtc_cali_start_cycling: 1; uint32_t rtc_cali_start_cycling: 1;
/** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 1; /** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 1;
* 0:rtcslowclock. 1:clk_80m. 2:xtal_32k. * 0:rtc_slow_clock. 1:rc_fast_div_clk. 2:xtal_32k.
*/ */
uint32_t rtc_cali_clk_sel: 2; uint32_t rtc_cali_clk_sel: 2;
/** rtc_cali_rdy : RO; bitpos: [15]; default: 0; /** rtc_cali_rdy : RO; bitpos: [15]; default: 0;

View File

@@ -325,6 +325,16 @@ typedef enum {
CLKOUT_SIG_INVALID = 0xFF, CLKOUT_SIG_INVALID = 0xFF,
} soc_clkout_sig_id_t; } soc_clkout_sig_id_t;
////////////////////////////////////////////RTC CALIBRATION///////////////////////////////////////////////////////////
/**
* @brief Clock frequency calibration source selection
*/
typedef enum {
CLK_CAL_RC_SLOW = 0, /*!< Select to calibrate RC_SLOW_CLK */
CLK_CAL_RC_FAST_D256, /*!< Select to calibrate RC_FAST_D256_CLK */
CLK_CAL_32K_OSC_SLOW, /*!< Select to calibrate OSC_SLOW_CLK (external slow clock) */
} soc_timg0_calibration_clk_src_t;
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -335,7 +335,7 @@ typedef union {
*/ */
uint32_t rtc_cali_start_cycling:1; uint32_t rtc_cali_start_cycling:1;
/** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 1; /** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 1;
* 0:rtc slow clock. 1:clk_8m, 2:xtal_32k. * 0:rc_slow_clk. 1:rc_fast_div_clk, 2:32k_osc_slow_clk.
*/ */
uint32_t rtc_cali_clk_sel:2; uint32_t rtc_cali_clk_sel:2;
/** rtc_cali_rdy : RO; bitpos: [15]; default: 0; /** rtc_cali_rdy : RO; bitpos: [15]; default: 0;

View File

@@ -394,6 +394,16 @@ typedef enum {
CLKOUT_SIG_INVALID = 0xFF, CLKOUT_SIG_INVALID = 0xFF,
} soc_clkout_sig_id_t; } soc_clkout_sig_id_t;
////////////////////////////////////////////RTC CALIBRATION///////////////////////////////////////////////////////////
/**
* @brief Clock frequency calibration source selection
*/
typedef enum {
CLK_CAL_RC_SLOW = 0, /*!< Select to calibrate RC_SLOW_CLK */
CLK_CAL_RC_FAST_D256, /*!< Select to calibrate RC_FAST_D256_CLK */
CLK_CAL_32K_XTAL, /*!< Select to calibrate XTAL32K_CLK */
} soc_timg0_calibration_clk_src_t;
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -339,7 +339,7 @@ typedef union {
*/ */
uint32_t rtc_cali_start_cycling: 1; uint32_t rtc_cali_start_cycling: 1;
/** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 1; /** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 1;
* 0:rtc slow clock. 1:clk_8m, 2:xtal_32k. * 0:rc_slow_clk. 1:rc_fast_div_clk. 2:xtal_32k.
*/ */
uint32_t rtc_cali_clk_sel: 2; uint32_t rtc_cali_clk_sel: 2;
/** rtc_cali_rdy : RO; bitpos: [15]; default: 0; /** rtc_cali_rdy : RO; bitpos: [15]; default: 0;

View File

@@ -558,6 +558,17 @@ typedef enum {
CLKOUT_SIG_RC_SLOW = 0x19, /*!< RC slow clock, depends on the RTC_CLK_SRC configuration */ CLKOUT_SIG_RC_SLOW = 0x19, /*!< RC slow clock, depends on the RTC_CLK_SRC configuration */
} soc_clkout_sig_id_t; } soc_clkout_sig_id_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_timg0_calibration_clk_src_t;
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -516,6 +516,18 @@ typedef enum {
CLKOUT_SIG_INVALID = 0xFF, CLKOUT_SIG_INVALID = 0xFF,
} soc_clkout_sig_id_t; } soc_clkout_sig_id_t;
////////////////////////////////////////////RTC CALIBRATION///////////////////////////////////////////////////////////
/**
* @brief Clock frequency calibration source selection
*/
typedef enum {
CLK_CAL_RC_SLOW = 0, /*!< Select to calibrate RC_SLOW_CLK */
CLK_CAL_RC32K, /*!< Select to calibrate RC32K_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_timg0_calibration_clk_src_t;
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -339,7 +339,7 @@ typedef union {
*/ */
uint32_t rtc_cali_start_cycling:1; uint32_t rtc_cali_start_cycling:1;
/** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 0; /** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 0;
* 0:rtc slow clock. 1:clk_8m, 2:xtal_32k. * 0/3:rc_slow_clk. 1:rc_fast_div_clk, 2:32k clock, which 32k depends on PCR.ctrl_32k_conf.clk_32k_sel.
*/ */
uint32_t rtc_cali_clk_sel:2; uint32_t rtc_cali_clk_sel:2;
/** rtc_cali_rdy : RO; bitpos: [15]; default: 0; /** rtc_cali_rdy : RO; bitpos: [15]; default: 0;

View File

@@ -396,6 +396,17 @@ typedef enum {
CLKOUT_SIG_RC_SLOW = 0x19, /*!< RC slow clock, depends on the RTC_CLK_SRC configuration */ CLKOUT_SIG_RC_SLOW = 0x19, /*!< RC slow clock, depends on the RTC_CLK_SRC configuration */
} soc_clkout_sig_id_t; } soc_clkout_sig_id_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_timg0_calibration_clk_src_t;
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -525,6 +525,18 @@ typedef enum {
CLKOUT_SIG_INVALID = 0xFF, CLKOUT_SIG_INVALID = 0xFF,
} soc_clkout_sig_id_t; } soc_clkout_sig_id_t;
////////////////////////////////////////////RTC CALIBRATION///////////////////////////////////////////////////////////
/**
* @brief Clock frequency calibration source selection
*/
typedef enum {
CLK_CAL_RC_SLOW = 0, /*!< Select to calibrate RC_SLOW_CLK */
CLK_CAL_RC32K, /*!< Select to calibrate RC32K_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_timg0_calibration_clk_src_t;
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -339,7 +339,7 @@ typedef union {
*/ */
uint32_t rtc_cali_start_cycling:1; uint32_t rtc_cali_start_cycling:1;
/** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 0; /** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 0;
* 0:rtc slow clock. 1:clk_8m, 2:xtal_32k. * 0/3:rc_slow_clk. 1:rc_fast_div_clk, 2:32k clock, which 32k depends on PCR.ctrl_32k_conf.clk_32k_sel.
*/ */
uint32_t rtc_cali_clk_sel:2; uint32_t rtc_cali_clk_sel:2;
/** rtc_cali_rdy : RO; bitpos: [15]; default: 0; /** rtc_cali_rdy : RO; bitpos: [15]; default: 0;

View File

@@ -347,7 +347,7 @@ typedef enum {
CLK_CAL_32K_XTAL, /*!< Select to calibrate XTAL32K_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_32K_OSC_SLOW, /*!< Select to calibrate OSC_SLOW_CLK (external slow clock) */
CLK_CAL_RC_FAST, /*!< Select to calibrate RC_FAST_CLK */ CLK_CAL_RC_FAST, /*!< Select to calibrate RC_FAST_CLK */
} soc_clk_calibration_clk_src_t; } soc_timg0_calibration_clk_src_t;
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -339,7 +339,7 @@ typedef union {
*/ */
uint32_t rtc_cali_start_cycling:1; uint32_t rtc_cali_start_cycling:1;
/** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 0; /** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 0;
* 0:rtc slow clock. 1:clk_8m, 2:xtal_32k. * 0:rc_slow_clk. 1:rc_fast_clk, 2:32k clk.
*/ */
uint32_t rtc_cali_clk_sel:2; uint32_t rtc_cali_clk_sel:2;
/** rtc_cali_rdy : RO; bitpos: [15]; default: 0; /** rtc_cali_rdy : RO; bitpos: [15]; default: 0;

View File

@@ -306,7 +306,7 @@ typedef enum {
CLK_CAL_GPSPI3_MST, /*!< Select to calibrate GPSPI3_MST_CLK */ CLK_CAL_GPSPI3_MST, /*!< Select to calibrate GPSPI3_MST_CLK */
CLK_CAL_GPSPI2_MST, /*!< Select to calibrate GPSPI2_MST_CLK */ CLK_CAL_GPSPI2_MST, /*!< Select to calibrate GPSPI2_MST_CLK */
CLK_CAL_EXT_IO, /*!< Select to calibrate an external clock from an IO */ CLK_CAL_EXT_IO, /*!< Select to calibrate an external clock from an IO */
} soc_clk_calibration_clk_src_t; } soc_timg0_calibration_clk_src_t;
/////////////////////////////////////////////////I2C//////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////I2C////////////////////////////////////////////////////////////////////
/** /**

View File

@@ -797,6 +797,25 @@ typedef enum {
CLKOUT_SIG_INVALID = 0xFF, CLKOUT_SIG_INVALID = 0xFF,
} soc_clkout_sig_id_t; } soc_clkout_sig_id_t;
////////////////////////////////////////////RTC CALIBRATION///////////////////////////////////////////////////////////
/**
* @brief Clock frequency calibration source selection
*/
typedef enum {
CLK_CAL_MPLL = 0, /*!< Select to calibrate MPLL_CLK */
CLK_CAL_SPLL, /*!< Select to calibrate SPLL_CLK */
CLK_CAL_CPLL, /*!< Select to calibrate CPLL_CLK */
CLK_CAL_APLL, /*!< Select to calibrate APLL_CLK */
CLK_CAL_SDIO_PLL0, /*!< Select to calibrate SDIO_PLL0_CLK */
CLK_CAL_SDIO_PLL1, /*!< Select to calibrate SDIO_PLL1_CLK */
CLK_CAL_SDIO_PLL2, /*!< Select to calibrate SDIO_PLL2_CLK */
CLK_CAL_RC_FAST, /*!< Select to calibrate RC_FAST_CLK */
CLK_CAL_RC_SLOW, /*!< Select to calibrate RC_SLOW_CLK */
CLK_CAL_RC32K, /*!< Select to calibrate RC32K_CLK */
CLK_CAL_32K_XTAL, /*!< Select to calibrate XTAL32K_CLK */
CLK_CAL_LP_PLL, /*!< Select to calibrate LP_PLL_CLK */
} soc_timg0_calibration_clk_src_t;
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -454,6 +454,16 @@ typedef enum {
CLKOUT_SIG_INVALID = 0xFF, CLKOUT_SIG_INVALID = 0xFF,
} soc_clkout_sig_id_t; } soc_clkout_sig_id_t;
////////////////////////////////////////////RTC CALIBRATION///////////////////////////////////////////////////////////
/**
* @brief Clock frequency calibration source selection
*/
typedef enum {
CLK_CAL_RC_SLOW = 0, /*!< Select to calibrate RC_SLOW_CLK */
CLK_CAL_RC_FAST_D256, /*!< Select to calibrate RC_FAST_D256_CLK */
CLK_CAL_32K_XTAL, /*!< Select to calibrate XTAL32K_CLK */
} soc_timg0_calibration_clk_src_t;
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -360,7 +360,7 @@ typedef union {
*/ */
uint32_t rtc_cali_start_cycling: 1; uint32_t rtc_cali_start_cycling: 1;
/** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 1; /** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 1;
* 0:rtcslowclock. 1:clk_80m. 2:xtal_32k. * 0:rc_slow_clk. 1:rc_fast_div_clk. 2:xtal_32k.
*/ */
uint32_t rtc_cali_clk_sel: 2; uint32_t rtc_cali_clk_sel: 2;
/** rtc_cali_rdy : RO; bitpos: [15]; default: 0; /** rtc_cali_rdy : RO; bitpos: [15]; default: 0;

View File

@@ -499,6 +499,16 @@ typedef enum {
CLKOUT_SIG_INVALID = 0xFF, CLKOUT_SIG_INVALID = 0xFF,
} soc_clkout_sig_id_t; } soc_clkout_sig_id_t;
////////////////////////////////////////////RTC CALIBRATION///////////////////////////////////////////////////////////
/**
* @brief Clock frequency calibration source selection
*/
typedef enum {
CLK_CAL_RC_SLOW = 0, /*!< Select to calibrate RC_SLOW_CLK */
CLK_CAL_RC_FAST_D256, /*!< Select to calibrate RC_FAST_D256_CLK */
CLK_CAL_32K_XTAL, /*!< Select to calibrate XTAL32K_CLK */
} soc_timg0_calibration_clk_src_t;
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -328,7 +328,7 @@ typedef union {
*/ */
uint32_t rtc_cali_start_cycling: 1; uint32_t rtc_cali_start_cycling: 1;
/** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 1; /** rtc_cali_clk_sel : R/W; bitpos: [14:13]; default: 1;
* 0:rtc slow clock. 1:clk_80m. 2:xtal_32k. * 0:rc_slow_clk. 1:rc_fast_div_clk. 2:xtal_32k.
*/ */
uint32_t rtc_cali_clk_sel: 2; uint32_t rtc_cali_clk_sel: 2;
/** rtc_cali_rdy : RO; bitpos: [15]; default: 0; /** rtc_cali_rdy : RO; bitpos: [15]; default: 0;