fix(clk): ESP32H21 uses RC_SLOW_D4 as RTC slow clock

This commit is contained in:
Song Ruo Jing
2025-07-10 16:35:58 +08:00
parent 28df79aee8
commit caa382047b
13 changed files with 104 additions and 87 deletions
@@ -18,6 +18,7 @@
#include "hal/log.h"
#include "esp32h21/rom/rtc.h"
#include "hal/misc.h"
#include "soc/timer_group_struct.h"
#ifdef __cplusplus
extern "C" {
@@ -410,40 +411,40 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_apb_get_divider(voi
}
/**
* @brief Select the calibration 32kHz clock source for timergroup0
* @brief Select the calibration clock source for timergroup0
*
* @param in_sel One of the 32kHz clock sources (XTAL32K_CLK, OSC_SLOW_CLK)
* @param clk_sel One of the clock sources in soc_clk_calibration_clk_src_t
*/
static inline __attribute__((always_inline)) void clk_ll_32k_calibration_set_target(soc_rtc_slow_clk_src_t in_sel)
static inline __attribute__((always_inline)) void clk_ll_calibration_set_target(soc_clk_calibration_clk_src_t clk_sel)
{
switch (in_sel) {
case SOC_RTC_SLOW_CLK_SRC_XTAL32K:
PCR.ctrl_32k_conf.clk_32k_sel = 1;
int timg_cali_clk_sel = -1;
int clk_32k_sel = -1;
switch (clk_sel) {
case CLK_CAL_32K_XTAL:
timg_cali_clk_sel = 2;
clk_32k_sel = 1;
break;
case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW:
PCR.ctrl_32k_conf.clk_32k_sel = 2;
case CLK_CAL_32K_OSC_SLOW:
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;
default:
// Unsupported 32K_SEL mux input
// Unsupported CLK_CAL mux input
abort();
}
}
/**
* @brief Get the calibration 32kHz clock source for timergroup0
*
* @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)
{
uint32_t clk_sel = PCR.ctrl_32k_conf.clk_32k_sel;
switch (clk_sel) {
case 1:
return SOC_RTC_SLOW_CLK_SRC_XTAL32K;
case 2:
return SOC_RTC_SLOW_CLK_SRC_OSC_SLOW;
default:
return SOC_RTC_SLOW_CLK_SRC_INVALID;
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;
}
}
@@ -455,7 +456,7 @@ static inline __attribute__((always_inline)) soc_rtc_slow_clk_src_t clk_ll_32k_c
static inline __attribute__((always_inline)) void clk_ll_rtc_slow_set_src(soc_rtc_slow_clk_src_t in_sel)
{
switch (in_sel) {
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW:
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4:
LP_CLKRST.lp_clk_conf.clkrst_slow_clk_sel = 0;
break;
case SOC_RTC_SLOW_CLK_SRC_XTAL32K:
@@ -480,7 +481,7 @@ static inline __attribute__((always_inline)) soc_rtc_slow_clk_src_t clk_ll_rtc_s
uint32_t clk_sel = LP_CLKRST.lp_clk_conf.clkrst_slow_clk_sel;
switch (clk_sel) {
case 0:
return SOC_RTC_SLOW_CLK_SRC_RC_SLOW;
return SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4;
case 1:
return SOC_RTC_SLOW_CLK_SRC_XTAL32K;
case 3:
@@ -559,14 +560,14 @@ static inline void clk_ll_rc_fast_tick_conf(void)
}
/**
* @brief Set RC_SLOW_CLK divider
* @brief Set RC_SLOW_CLK divider. The output from the divider is passed into rtc_slow_clk MUX.
*
* @param divider Divider of RC_SLOW_CLK. Usually this divider is set to 1 (reg. value is 0) in bootloader stage.
* @param divider Divider of RC_SLOW_CLK. Fixed the divider to 4 on the target.
*/
static inline __attribute__((always_inline)) void clk_ll_rc_slow_set_divider(uint32_t divider)
{
// No divider on the target
HAL_ASSERT(divider == 1);
// Register not exposed
HAL_ASSERT(divider == 4);
}
/************************** LP STORAGE REGISTER STORE/LOAD **************************/