feat(clk): Add basic clock support for esp32h4

This commit is contained in:
Song Ruo Jing
2025-06-25 17:30:46 +08:00
parent ce92b0ab60
commit 28df79aee8
71 changed files with 697 additions and 937 deletions

View File

@@ -147,7 +147,6 @@ mainmenu "Espressif IoT Development Framework Configuration"
bool
default "y" if IDF_TARGET="esp32h4"
select IDF_TARGET_ARCH_RISCV
select IDF_ENV_FPGA
select IDF_ENV_BRINGUP
config IDF_TARGET_LINUX

View File

@@ -39,6 +39,14 @@ menu "Bootloader config"
orsource "Kconfig.log"
config BOOTLOADER_CPU_CLK_FREQ_MHZ
int
default 64 if IDF_TARGET_ESP32H2 || IDF_TARGET_ESP32H21 || IDF_TARGET_ESP32H4
default 90 if IDF_TARGET_ESP32P4
default 80
help
The CPU clock frequency to be at least raised to in 2nd bootloader. Invisible for users.
menu "Serial Flash Configurations"
config BOOTLOADER_SPI_CUSTOM_WP_PIN
bool "Use custom SPI Flash WP Pin when flash pins set in eFuse (read help)"

View File

@@ -34,7 +34,7 @@ __attribute__((weak)) void bootloader_clock_configure(void)
esp_rom_output_tx_wait_idle(0);
/* Set CPU to a higher certain frequency. Keep other clocks unmodified. */
int cpu_freq_mhz = CPU_CLK_FREQ_MHZ_BTLD;
int cpu_freq_mhz = CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ;
#if CONFIG_IDF_TARGET_ESP32
/* On ESP32 rev 0, switching to 80/160 MHz if clock was previously set to
@@ -57,7 +57,7 @@ __attribute__((weak)) void bootloader_clock_configure(void)
// RTC_SLOW clock source will be switched according to Kconfig selection at application startup
clk_cfg.slow_clk_src = rtc_clk_slow_src_get();
if (clk_cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_INVALID) {
clk_cfg.slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW;
clk_cfg.slow_clk_src = SOC_RTC_SLOW_CLK_SRC_DEFAULT;
}
// Use RTC_FAST clock source sel register field's default value, XTAL_DIV, for 2nd stage bootloader

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2010-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -26,16 +26,16 @@
#if !defined CONFIG_IDF_TARGET_ESP32S3
#if (defined CONFIG_IDF_TARGET_ESP32C6 || defined CONFIG_IDF_TARGET_ESP32H2)
#define RNG_CPU_WAIT_CYCLE_NUM (80 * 16) // Keep the byte sampling frequency in the ~62KHz range which has been
#define RNG_CPU_WAIT_CYCLE_NUM (CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ * 16) // Keep the byte sampling frequency in the ~62KHz range which has been
// tested.
#elif CONFIG_IDF_TARGET_ESP32P4
// bootloader tested with around 63 KHz bytes reading frequency
#define RNG_CPU_WAIT_CYCLE_NUM (CPU_CLK_FREQ_MHZ_BTLD * 16)
#define RNG_CPU_WAIT_CYCLE_NUM (CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ * 16)
#else
#define RNG_CPU_WAIT_CYCLE_NUM (80 * 32 * 2) /* extra factor of 2 is precautionary */
#define RNG_CPU_WAIT_CYCLE_NUM (CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ * 32 * 2) /* extra factor of 2 is precautionary */
#endif
#else
#define RNG_CPU_WAIT_CYCLE_NUM (80 * 23) /* 45 KHz reading frequency is the maximum we have tested so far on S3 */
#define RNG_CPU_WAIT_CYCLE_NUM (CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ * 23) /* 45 KHz reading frequency is the maximum we have tested so far on S3 */
#endif
__attribute__((weak)) void bootloader_fill_random(void *buffer, size_t length)

View File

@@ -13,11 +13,9 @@
#include "esp_rom_efuse.h"
#include "esp_rom_serial_output.h"
#include "esp_rom_sys.h"
#include "esp_rom_spiflash.h"
#include "soc/gpio_sig_map.h"
#include "esp_cpu.h"
#include "soc/rtc.h"
#include "soc/spi_periph.h"
#include "soc/cache_reg.h"
#include "soc/io_mux_reg.h"
#include "soc/pcr_reg.h"
@@ -28,8 +26,6 @@
#include "bootloader_flash_config.h"
#include "bootloader_mem.h"
#include "esp_private/regi2c_ctrl.h"
// #include "soc/regi2c_lp_bias.h"
// #include "soc/regi2c_bias.h"
#include "soc/hp_system_reg.h"
#include "bootloader_console.h"
#include "bootloader_flash_priv.h"
@@ -83,39 +79,18 @@ static void bootloader_super_wdt_auto_feed(void)
REG_WRITE(LP_WDT_SWD_WPROTECT_REG, 0);
}
void spi_flash_din_num_set(uint8_t spi_num, uint8_t din_num)
{
uint32_t reg_val = (REG_READ(SPI_MEM_DIN_NUM_REG(spi_num)) & (~(SPI_MEM_DIN0_NUM_M | SPI_MEM_DIN1_NUM_M | SPI_MEM_DIN2_NUM_M | SPI_MEM_DIN3_NUM_M | SPI_MEM_DIN4_NUM_M | SPI_MEM_DIN5_NUM_M | SPI_MEM_DIN6_NUM_M | SPI_MEM_DIN7_NUM_M | SPI_MEM_DINS_NUM_M)))
| (din_num << SPI_MEM_DIN0_NUM_S) | (din_num << SPI_MEM_DIN1_NUM_S) | (din_num << SPI_MEM_DIN2_NUM_S) | (din_num << SPI_MEM_DIN3_NUM_S)
| (din_num << SPI_MEM_DIN4_NUM_S) | (din_num << SPI_MEM_DIN5_NUM_S) | (din_num << SPI_MEM_DIN6_NUM_S) | (din_num << SPI_MEM_DIN7_NUM_S) | (din_num << SPI_MEM_DINS_NUM_S);
REG_WRITE(SPI_MEM_DIN_NUM_REG(spi_num), reg_val);
REG_SET_BIT(SPI_MEM_TIMING_CALI_REG(spi_num), SPI_MEM_TIMING_CALI_UPDATE);
}
void spi_flash_extra_dummy_set(uint8_t spi_num, uint8_t extra_dummy)
{
rom_spiflash_legacy_data->dummy_len_plus[spi_num] = extra_dummy;
}
/*
* din mode din_num dummy
1 0 1
0 0 0
1 0 2
0 0 1
1 0 3
0 0 2
1 0 4
0 0 3
*/
static inline void bootloader_hardware_init(void)
{
// TODO: IDF-12285 RF disable?
/* Disable RF pll by default */
CLEAR_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_RFPLL);
SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_FORCE_RFPLL);
#if !CONFIG_IDF_ENV_FPGA
/* Enable analog i2c master clock */
_regi2c_ctrl_ll_master_enable_clock(true); // keep ana i2c mst clock always enabled in bootloader
regi2c_ctrl_ll_master_force_enable_clock(true); // TODO: IDF-12285 Remove this?
regi2c_ctrl_ll_master_force_enable_clock(true); // TODO: IDF-12313 Remove this?
regi2c_ctrl_ll_master_configure_clock();
#endif
}
static inline void bootloader_ana_reset_config(void)

View File

@@ -116,7 +116,7 @@ typedef struct rtc_clk_config_s {
*/
#define RTC_CLK_CONFIG_DEFAULT() { \
.xtal_freq = CONFIG_XTAL_FREQ, \
.cpu_freq_mhz = 80, \
.cpu_freq_mhz = CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ, \
.fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \
.slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \
.clk_8m_div = 0, \

View File

@@ -186,7 +186,7 @@ typedef struct {
*/
#define RTC_CLK_CONFIG_DEFAULT() { \
.xtal_freq = CONFIG_XTAL_FREQ, \
.cpu_freq_mhz = 80, \
.cpu_freq_mhz = CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ, \
.fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \
.slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \
.clk_rtc_clk_div = 0, \

View File

@@ -186,7 +186,7 @@ typedef struct {
*/
#define RTC_CLK_CONFIG_DEFAULT() { \
.xtal_freq = CONFIG_XTAL_FREQ, \
.cpu_freq_mhz = 80, \
.cpu_freq_mhz = CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ, \
.fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \
.slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \
.clk_rtc_clk_div = 0, \

View File

@@ -147,7 +147,7 @@ typedef struct {
*/
#define RTC_CLK_CONFIG_DEFAULT() { \
.xtal_freq = CONFIG_XTAL_FREQ, \
.cpu_freq_mhz = 80, \
.cpu_freq_mhz = CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ, \
.fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \
.slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \
.clk_rtc_clk_div = 0, \

View File

@@ -157,7 +157,7 @@ typedef struct {
*/
#define RTC_CLK_CONFIG_DEFAULT() { \
.xtal_freq = CONFIG_XTAL_FREQ, \
.cpu_freq_mhz = 80, \
.cpu_freq_mhz = CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ, \
.fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \
.slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \
.clk_rtc_clk_div = 0, \

View File

@@ -147,7 +147,7 @@ typedef struct {
*/
#define RTC_CLK_CONFIG_DEFAULT() { \
.xtal_freq = CONFIG_XTAL_FREQ, \
.cpu_freq_mhz = 80, \
.cpu_freq_mhz = CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ, \
.fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \
.slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \
.clk_rtc_clk_div = 0, \

View File

@@ -159,7 +159,7 @@ typedef struct {
*/
#define RTC_CLK_CONFIG_DEFAULT() { \
.xtal_freq = CONFIG_XTAL_FREQ, \
.cpu_freq_mhz = 96, \
.cpu_freq_mhz = CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ, \
.fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \
.slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \
.clk_rtc_clk_div = 0, \

View File

@@ -110,8 +110,9 @@ esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable)
{
switch (clk_src) {
case SOC_MOD_CLK_XTAL_X2_F64M:
// later, here should handle ref count for PLL_F64M clock gating, then also handle XTAL_X2 circuit enable/disable
// later, here should handle ref count for XTAL_X2_F64M clock gating, then also handle XTAL_X2 circuit enable/disable
esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_XTAL_X2, enable);
break;
default:
break;
}

View File

@@ -93,15 +93,6 @@ extern "C" {
// #define RTC_CNTL_PD_CUR_SLEEP_DEFAULT 1
// #define RTC_CNTL_DG_VDD_DRV_B_SLP_DEFAULT 254
// /*
// The follow value is used to get a reasonable rtc voltage dbias value according to digital dbias & some other value
// storing in efuse
// */
// #define K_RTC_MID_MUL10000 215
// #define K_DIG_MID_MUL10000 213
// #define V_RTC_MID_MUL10000 10800
// #define V_DIG_MID_MUL10000 10860
/**
* @brief CPU clock configuration structure
*/
@@ -114,9 +105,6 @@ typedef struct rtc_cpu_freq_config_s {
#define RTC_CLK_CAL_FRACT 19 //!< Number of fractional bits in values returned by rtc_clk_cal
#define RTC_VDDSDIO_TIEH_1_8V 0 //!< TIEH field value for 1.8V VDDSDIO
#define RTC_VDDSDIO_TIEH_3_3V 1 //!< TIEH field value for 3.3V VDDSDIO
/**
* @brief Clock source to be calibrated using rtc_clk_cal function
*
@@ -151,7 +139,7 @@ typedef struct {
*/
#define RTC_CLK_CONFIG_DEFAULT() { \
.xtal_freq = CONFIG_XTAL_FREQ, \
.cpu_freq_mhz = 64, \
.cpu_freq_mhz = CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ, \
.fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \
.slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \
.clk_rtc_clk_div = 0, \

View File

@@ -322,31 +322,27 @@ void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config)
{
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
uint32_t source_freq_mhz;
uint32_t div = clk_ll_cpu_get_divider(); // div = freq of SOC_ROOT_CLK / freq of CPU_CLK
uint32_t freq_mhz;
switch (source) {
case SOC_CPU_CLK_SRC_XTAL: {
source_freq_mhz = (uint32_t)rtc_clk_xtal_freq_get();
freq_mhz = source_freq_mhz / div;
break;
}
case SOC_CPU_CLK_SRC_PLL: {
source_freq_mhz = clk_ll_bbpll_get_freq_mhz();
freq_mhz = source_freq_mhz / div;
break;
}
case SOC_CPU_CLK_SRC_RC_FAST:
source_freq_mhz = 20;
freq_mhz = source_freq_mhz / div;
break;
case SOC_CPU_CLK_SRC_XTAL_X2:
source_freq_mhz = clk_ll_xtal_x2_get_freq_mhz();
freq_mhz = source_freq_mhz / div;
break;
default:
ESP_HW_LOGE(TAG, "unsupported frequency configuration");
abort();
}
uint32_t div = clk_ll_cpu_get_divider();
uint32_t freq_mhz = source_freq_mhz / div; // freq of CPU_CLK = freq of SOC_ROOT_CLK / cpu_div
*out_config = (rtc_cpu_freq_config_t) {
.source = source,
.source_freq_mhz = source_freq_mhz,

View File

@@ -16,7 +16,6 @@
#include "soc/lp_clkrst_reg.h"
#include "soc/regi2c_pmu.h"
#include "esp_hw_log.h"
#include "sdkconfig.h"
#include "hal/clk_tree_ll.h"
#include "soc/pmu_reg.h"
#include "pmu_param.h"

View File

@@ -56,7 +56,7 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
}
/* Enable requested clock (150k clock is always on) */
/* Enable requested clock (rc_slow clock is always on) */
// All clocks on/off takes time to be stable, so we shouldn't frequently enable/disable the clock
// 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

View File

@@ -1,11 +1,11 @@
set(srcs "rtc_clk.c"
"rtc_time.c"
"chip_info.c"
"rtc_clk_init.c"
)
if(CONFIG_SOC_PMU_SUPPORTED)
list(APPEND srcs
# "rtc_clk_init.c" //TODO: IDF-12313
"pmu_param.c"
"pmu_init.c"
"pmu_sleep.c"

View File

@@ -1,27 +1,25 @@
choice RTC_CLK_SRC
prompt "RTC clock source"
default RTC_CLK_SRC_INT_RC
default RTC_CLK_SRC_INT_RC_D4
help
Choose which clock is used as RTC clock source.
config RTC_CLK_SRC_INT_RC
bool "Internal 136kHz RC oscillator"
config RTC_CLK_SRC_INT_RC_D4
bool "Internal 600kHz RC oscillator, divide by 4"
config RTC_CLK_SRC_EXT_CRYS
bool "External 32kHz crystal"
select ESP_SYSTEM_RTC_EXT_XTAL
config RTC_CLK_SRC_EXT_OSC
bool "External 32kHz oscillator at 32K_XP pin"
select ESP_SYSTEM_RTC_EXT_OSC
config RTC_CLK_SRC_INT_RC32K
bool "Internal 32kHz RC oscillator"
endchoice
config RTC_CLK_CAL_CYCLES
int "Number of cycles for RTC_SLOW_CLK calibration"
default 3000 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC || RTC_CLK_SRC_INT_RC32K
default 1024 if RTC_CLK_SRC_INT_RC
range 0 27000 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC || RTC_CLK_SRC_INT_RC32K
range 0 32766 if RTC_CLK_SRC_INT_RC
default 3000 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC
default 1024 if RTC_CLK_SRC_INT_RC_D4
range 0 8190 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC
range 0 32766 if RTC_CLK_SRC_INT_RC_D4
help
When the startup code initializes RTC_SLOW_CLK, it can perform
calibration by comparing the RTC_SLOW_CLK frequency with main XTAL
@@ -33,7 +31,7 @@ config RTC_CLK_CAL_CYCLES
When this option is set to 0, clock calibration will not be performed at
startup, and approximate clock frequencies will be assumed:
- 136000 Hz if internal RC oscillator is used as clock source. For this use value 1024.
- 150000 Hz if internal RC oscillator is used as clock source. For this use value 1024.
- 32768 Hz if the 32k crystal oscillator is used. For this use value 3000 or more.
In case more value will help improve the definition of the launch of the crystal.
If the crystal could not start, it will be switched to internal RC.

View File

@@ -13,8 +13,6 @@
#include "hal/clk_tree_ll.h"
#include "esp_private/esp_clk_tree_common.h"
//TODO: [ESP32H4] IDF-12285
static const char *TAG = "esp_clk_tree";
esp_err_t esp_clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, esp_clk_tree_src_freq_precision_t precision,
@@ -26,18 +24,36 @@ uint32_t *freq_value)
uint32_t clk_src_freq = 0;
switch (clk_src) {
case SOC_MOD_CLK_CPU:
clk_src_freq = clk_hal_cpu_get_freq_hz();
break;
case SOC_MOD_CLK_XTAL:
clk_src_freq = SOC_XTAL_FREQ_32M * MHZ;
clk_src_freq = clk_hal_xtal_get_freq_mhz() * MHZ;
break;
case SOC_MOD_CLK_XTAL_X2_F32M:
clk_src_freq = CLK_LL_PLL_32M_FREQ_MHZ * MHZ;
break;
case SOC_MOD_CLK_PLL_F48M:
clk_src_freq = CLK_LL_PLL_48M_FREQ_MHZ * MHZ;
break;
case SOC_MOD_CLK_PLL_F64M:
case SOC_MOD_CLK_XTAL_X2_F64M:
clk_src_freq = CLK_LL_PLL_64M_FREQ_MHZ * MHZ;
break;
case SOC_MOD_CLK_PLL_F96M:
clk_src_freq = CLK_LL_PLL_96M_FREQ_MHZ * MHZ;
break;
case SOC_MOD_CLK_RTC_SLOW:
clk_src_freq = esp_clk_tree_lp_slow_get_freq_hz(precision);
break;
case SOC_MOD_CLK_RTC_FAST:
clk_src_freq = esp_clk_tree_lp_fast_get_freq_hz(precision);
break;
case SOC_MOD_CLK_RC_FAST:
clk_src_freq = esp_clk_tree_rc_fast_get_freq_hz(precision);
break;
case SOC_MOD_CLK_XTAL32K:
clk_src_freq = esp_clk_tree_xtal32k_get_freq_hz(precision);
break;
default:
break;
}
@@ -47,24 +63,66 @@ uint32_t *freq_value)
return ESP_OK;
}
static int16_t s_xtal_x2_ref_cnt = 0;
void esp_clk_tree_initialize(void)
{
// TODO: IDF-12388
// // In bootloader, flash clock source will always be switched to use XTAL_X2 clock
// s_xtal_x2_ref_cnt++;
if (clk_ll_cpu_get_src() == SOC_CPU_CLK_SRC_XTAL_X2) {
s_xtal_x2_ref_cnt++;
}
}
bool esp_clk_tree_is_power_on(soc_root_clk_circuit_t clk_circuit)
{
(void)clk_circuit;
switch (clk_circuit) {
case SOC_ROOT_CIRCUIT_CLK_XTAL_X2:
return s_xtal_x2_ref_cnt > 0;
default:
break;
}
return false;
}
esp_err_t esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool enable)
{
(void)clk_circuit; (void)enable;
return ESP_OK; // TODO: PM-354
switch (clk_circuit) {
case SOC_ROOT_CIRCUIT_CLK_XTAL_X2:
if (enable) {
s_xtal_x2_ref_cnt++;
} else {
s_xtal_x2_ref_cnt--;
}
if (s_xtal_x2_ref_cnt == 1) {
clk_ll_xtal_x2_enable();
} else if (s_xtal_x2_ref_cnt == 0) {
clk_ll_xtal_x2_disable();
}
assert(s_xtal_x2_ref_cnt >= 0);
break;
default:
break;
}
return ESP_OK; // TODO: PM-456
}
esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable)
{
(void)clk_src; (void)enable;
return ESP_ERR_NOT_SUPPORTED;
switch (clk_src) {
case SOC_MOD_CLK_XTAL_X2_F32M:
// later, here should handle ref count for XTAL_X2_F32M clock gating, then also handle XTAL_X2 circuit enable/disable
esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_XTAL_X2, enable);
break;
case SOC_MOD_CLK_XTAL_X2_F64M:
// later, here should handle ref count for XTAL_X2_F64M clock gating, then also handle XTAL_X2 circuit enable/disable
esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_XTAL_X2, enable);
break;
default:
break;
}
return ESP_OK; // TODO: PM-456
}

View File

@@ -50,10 +50,6 @@ extern "C" {
#define MHZ (1000000)
#define RTC_SLOW_CLK_150K_CAL_TIMEOUT_THRES(cycles) (cycles << 10)
#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 OTHER_BLOCKS_POWERUP 1
#define OTHER_BLOCKS_WAIT 1
@@ -64,16 +60,14 @@ extern "C" {
#define SOC_DELAY_RTC_SLOW_CLK_SWITCH 300
#define SOC_DELAY_RC_FAST_ENABLE 50
#define SOC_DELAY_RC_FAST_DIGI_SWITCH 5
#define SOC_DELAY_RC32K_ENABLE 300
#define RTC_CNTL_PLL_BUF_WAIT_DEFAULT 20
#define RTC_CNTL_XTL_BUF_WAIT_DEFAULT 100
#define RTC_CNTL_CK8M_WAIT_DEFAULT 20
#define RTC_CK8M_ENABLE_WAIT_DEFAULT 5
// TODO: IDF-12313 check all following values!
#define RTC_CNTL_CK8M_DFREQ_DEFAULT 100
#define RTC_CNTL_SCK_DCAP_DEFAULT 128
#define RTC_CNTL_RC32K_DFREQ_DEFAULT 700
#define RTC_CNTL_SCK_DCAP_DEFAULT 28
/* Various delays to be programmed into power control state machines */
#define RTC_CNTL_XTL_BUF_WAIT_SLP_US (250)
@@ -84,29 +78,20 @@ extern "C" {
#define RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES (1)
#define RTC_CNTL_MIN_SLP_VAL_MIN (2)
/*
set sleep_init default param
*/
#define RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT 5
#define RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_NODROP 0
#define RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT 15
#define RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT 0
#define RTC_CNTL_BIASSLP_MONITOR_DEFAULT 0
#define RTC_CNTL_BIASSLP_SLEEP_ON 0
#define RTC_CNTL_BIASSLP_SLEEP_DEFAULT 1
#define RTC_CNTL_PD_CUR_MONITOR_DEFAULT 0
#define RTC_CNTL_PD_CUR_SLEEP_ON 0
#define RTC_CNTL_PD_CUR_SLEEP_DEFAULT 1
#define RTC_CNTL_DG_VDD_DRV_B_SLP_DEFAULT 254
/*
The follow value is used to get a reasonable rtc voltage dbias value according to digital dbias & some other value
storing in efuse (based on ATE 5k ECO3 chips)
*/
#define K_RTC_MID_MUL10000 215
#define K_DIG_MID_MUL10000 213
#define V_RTC_MID_MUL10000 10800
#define V_DIG_MID_MUL10000 10860
// /*
// set sleep_init default param
// */
// #define RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT 5
// #define RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_NODROP 0
// #define RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT 15
// #define RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT 0
// #define RTC_CNTL_BIASSLP_MONITOR_DEFAULT 0
// #define RTC_CNTL_BIASSLP_SLEEP_ON 0
// #define RTC_CNTL_BIASSLP_SLEEP_DEFAULT 1
// #define RTC_CNTL_PD_CUR_MONITOR_DEFAULT 0
// #define RTC_CNTL_PD_CUR_SLEEP_ON 0
// #define RTC_CNTL_PD_CUR_SLEEP_DEFAULT 1
// #define RTC_CNTL_DG_VDD_DRV_B_SLP_DEFAULT 254
/**
* @brief CPU clock configuration structure
@@ -120,23 +105,18 @@ typedef struct rtc_cpu_freq_config_s {
#define RTC_CLK_CAL_FRACT 19 //!< Number of fractional bits in values returned by rtc_clk_cal
#define RTC_VDDSDIO_TIEH_1_8V 0 //!< TIEH field value for 1.8V VDDSDIO
#define RTC_VDDSDIO_TIEH_3_3V 1 //!< TIEH field value for 3.3V VDDSDIO
/**
* @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 ESP32H4. The conversion to register field values is explicitly done in
* rtc_clk_cal_internal
* However, this is not true on ESP32H4. The conversion to register field values is explicitly done internally
*/
typedef enum {
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_RC32K = SOC_RTC_SLOW_CLK_SRC_RC32K, //!< Internal 32kHz RC oscillator, as one type of 32k clock
RTC_CAL_32K_XTAL = SOC_RTC_SLOW_CLK_SRC_XTAL32K, //!< External 32kHz XTAL, as one type of 32k clock
RTC_CAL_32K_OSC_SLOW = SOC_RTC_SLOW_CLK_SRC_OSC_SLOW, //!< External slow clock signal input by lp_pad_gpio0, as one type of 32k clock
RTC_CAL_RC_FAST //!< Internal 20MHz RC oscillator
RTC_CAL_RC_SLOW = CLK_CAL_RC_SLOW, //!< Internal 600kHz RC oscillator
RTC_CAL_32K_XTAL = CLK_CAL_32K_XTAL, //!< External 32kHz XTAL, as one type of 32k clock
RTC_CAL_32K_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_FAST = CLK_CAL_RC_FAST, //!< Internal 20MHz RC oscillator
} rtc_cal_sel_t;
/**
@@ -150,8 +130,7 @@ typedef struct {
uint32_t clk_rtc_clk_div : 8;
uint32_t clk_8m_clk_div : 3; //!< RC_FAST clock divider (division is by clk_8m_div+1, i.e. 0 means ~20MHz frequency)
uint32_t slow_clk_dcap : 8; //!< RC_SLOW clock adjustment parameter (higher value leads to lower frequency)
uint32_t clk_8m_dfreq : 10; //!< RC_FAST clock adjustment parameter (higher value leads to higher frequency)
uint32_t rc32k_dfreq : 10; //!< Internal RC32K clock adjustment parameter (higher value leads to higher frequency)
uint32_t clk_8m_dfreq : 10; //!< RC_FAST clock adjustment parameter (higher value leads to higher frequency)
} rtc_clk_config_t;
/**
@@ -159,18 +138,17 @@ typedef struct {
*/
#define RTC_CLK_CONFIG_DEFAULT() { \
.xtal_freq = CONFIG_XTAL_FREQ, \
.cpu_freq_mhz = 96, \
.cpu_freq_mhz = CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ, \
.fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \
.slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \
.clk_rtc_clk_div = 0, \
.slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4, \
.clk_rtc_clk_div = 3, \
.clk_8m_clk_div = 0, \
.slow_clk_dcap = RTC_CNTL_SCK_DCAP_DEFAULT, \
.clk_8m_dfreq = RTC_CNTL_CK8M_DFREQ_DEFAULT, \
.rc32k_dfreq = RTC_CNTL_RC32K_DFREQ_DEFAULT, \
}
/**
* Initialize clocks and set CPU frequency
* @brief Initialize clocks and set CPU frequency
*
* @param cfg clock configuration as rtc_clk_config_t
*/
@@ -179,23 +157,10 @@ void rtc_clk_init(rtc_clk_config_t cfg);
/**
* @brief Get main XTAL frequency
*
* This is the value stored in RTC register RTC_XTAL_FREQ_REG by the bootloader. As passed to
* rtc_clk_init function
*
* @return XTAL frequency, one of soc_xtal_freq_t
*/
soc_xtal_freq_t rtc_clk_xtal_freq_get(void);
/**
* @brief Update XTAL frequency
*
* Updates the XTAL value stored in RTC_XTAL_FREQ_REG. Usually this value is ignored
* after startup.
*
* @param xtal_freq New frequency value
*/
void rtc_clk_xtal_freq_update(soc_xtal_freq_t xtal_freq);
/**
* @brief Enable or disable 32 kHz XTAL oscillator
* @param en true to enable, false to disable
@@ -230,12 +195,6 @@ bool rtc_clk_32k_enabled(void);
*/
void rtc_clk_32k_bootstrap(uint32_t cycle);
/**
* @brief Enable or disable 32 kHz internal rc oscillator
* @param en true to enable, false to disable
*/
void rtc_clk_rc32k_enable(bool enable);
/**
* @brief Enable or disable 8 MHz internal oscillator
*
@@ -264,9 +223,8 @@ soc_rtc_slow_clk_src_t rtc_clk_slow_src_get(void);
/**
* @brief Get the approximate frequency of RTC_SLOW_CLK, in Hz
*
* - if SOC_RTC_SLOW_CLK_SRC_RC_SLOW is selected, returns 136000
* - if SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4 is selected, returns 150000
* - if SOC_RTC_SLOW_CLK_SRC_XTAL32K is selected, returns 32768
* - if SOC_RTC_SLOW_CLK_SRC_RC32K is selected, returns 32768
* - if SOC_RTC_SLOW_CLK_SRC_OSC_SLOW is selected, returns 32768
*
* rtc_clk_cal function can be used to get more precise value by comparing
@@ -345,8 +303,9 @@ void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config);
* rtc_clk_cpu_freq_set_config when a switch to XTAL is needed.
* Assumes that XTAL frequency has been determined — don't call in startup code.
*
* @note On ESP32H4, this function will check whether BBPLL can be disabled. If there is no consumer, then BBPLL will be
* turned off. The behaviour is the same as using rtc_clk_cpu_freq_set_config to switch cpu clock source to XTAL.
* @note This function always disables BBPLL after switching the CPU clock source to XTAL for power saving purpose.
* If this is unwanted, please use rtc_clk_cpu_freq_set_config. It helps to check whether USB Serial JTAG is in use,
* if so, then BBPLL will not be turned off.
*/
void rtc_clk_cpu_freq_set_xtal(void);

View File

@@ -14,6 +14,8 @@
#include "hal/pmu_hal.h"
#include "pmu_param.h"
#include "esp_private/esp_pmu.h"
#include "soc/regi2c_dcdc.h"
#include "regi2c_ctrl.h"
static __attribute__((unused)) const char *TAG = "pmu_init";
@@ -227,21 +229,24 @@ static void pmu_lp_system_init_default(pmu_context_t *ctx)
void pmu_init(void)
{
#if 0 // TODO: IDF-12313
/* Peripheral reg i2c power up */
SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C);
SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_RFTX_I2C);
SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_RFRX_I2C);
SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_RFPLL);
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_RTC_DREG, 1);
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_DIG_DREG, 1);
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_RTC_REG, 0);
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_DIG_REG, 0);
#endif
/* No peripheral reg i2c power up required on the target */
pmu_hp_system_init_default(PMU_instance());
pmu_lp_system_init_default(PMU_instance());
pmu_power_domain_force_default(PMU_instance());
// default ccm mode
REG_SET_FIELD(PMU_DCM_CTRL_REG, PMU_DCDC_CCM_SW_EN, 1);
REG_SET_FIELD(PMU_HP_ACTIVE_BIAS_REG, PMU_HP_ACTIVE_DCDC_CCM_ENB, 0);
#if !CONFIG_IDF_ENV_FPGA
REGI2C_WRITE_MASK(I2C_DCDC, I2C_DCDC_CCM_DREG0, 24);
REGI2C_WRITE_MASK(I2C_DCDC, I2C_DCDC_CCM_PCUR_LIMIT0, 4);
REGI2C_WRITE_MASK(I2C_DCDC, I2C_DCDC_VCM_PCUR_LIMIT0, 1);
REGI2C_WRITE_MASK(I2C_DCDC, I2C_DCDC_XPD_TRX, 0);
#endif
// close rfpll to decrease mslp_cur
REG_SET_FIELD(PMU_RF_PWC_REG, PMU_XPD_FORCE_RFPLL, 1);
REG_SET_FIELD(PMU_RF_PWC_REG, PMU_XPD_RFPLL, 0);
}

View File

@@ -16,8 +16,8 @@
extern "C" {
#endif
#define HP_CALI_DBIAS_DEFAULT 25
#define LP_CALI_DBIAS_DEFAULT 26
#define HP_CALI_DBIAS_DEFAULT 0
#define LP_CALI_DBIAS_DEFAULT 0
// FOR XTAL FORCE PU IN SLEEP
#define PMU_PD_CUR_SLEEP_ON 0

View File

@@ -10,7 +10,7 @@
#include <assert.h>
#include <stdlib.h>
#include "sdkconfig.h"
#include "rom/rtc.h"
#include "esp32h4/rom/rtc.h"
#include "soc/rtc.h"
#include "esp_private/rtc_clk.h"
#include "esp_hw_log.h"
@@ -18,9 +18,9 @@
#include "hal/clk_tree_ll.h"
#include "hal/gpio_ll.h"
#include "hal/regi2c_ctrl_ll.h"
#include "hal/gpio_ll.h"
#include "soc/lp_aon_reg.h"
#include "esp_private/sleep_event.h"
#include "esp_private/esp_clk_tree_common.h"
static const char *TAG = "rtc_clk";
@@ -76,16 +76,6 @@ bool rtc_clk_32k_enabled(void)
return clk_ll_xtal32k_is_enabled();
}
void rtc_clk_rc32k_enable(bool enable)
{
if (enable) {
clk_ll_rc32k_enable();
esp_rom_delay_us(SOC_DELAY_RC32K_ENABLE);
} else {
clk_ll_rc32k_disable();
}
}
void rtc_clk_8m_enable(bool clk_8m_en)
{
if (clk_8m_en) {
@@ -115,9 +105,8 @@ soc_rtc_slow_clk_src_t rtc_clk_slow_src_get(void)
uint32_t rtc_clk_slow_freq_get_hz(void)
{
switch (rtc_clk_slow_src_get()) {
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW: return SOC_CLK_RC_SLOW_FREQ_APPROX;
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4: return SOC_CLK_RC_SLOW_FREQ_APPROX / 4;
case SOC_RTC_SLOW_CLK_SRC_XTAL32K: return SOC_CLK_XTAL32K_FREQ_APPROX;
case SOC_RTC_SLOW_CLK_SRC_RC32K: return SOC_CLK_RC32K_FREQ_APPROX;
case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW: return SOC_CLK_OSC_SLOW_FREQ_APPROX;
default: return 0;
}
@@ -149,15 +138,18 @@ static void rtc_clk_bbpll_configure(soc_xtal_freq_t xtal_freq, int pll_freq)
{
/* Digital part */
clk_ll_bbpll_set_freq_mhz(pll_freq);
/* Analog part */
/* Analog part */
ANALOG_CLOCK_ENABLE();
/* BBPLL CALIBRATION START */
regi2c_ctrl_ll_bbpll_calibration_start();
clk_ll_bbpll_set_config(pll_freq, xtal_freq);
/* WAIT CALIBRATION DONE */
while (!regi2c_ctrl_ll_bbpll_calibration_is_done());
esp_rom_delay_us(10); // wait for true stop
/* BBPLL CALIBRATION STOP */
regi2c_ctrl_ll_bbpll_calibration_stop();
ANALOG_CLOCK_DISABLE();
s_cur_pll_freq = pll_freq;
}
@@ -169,18 +161,22 @@ static void rtc_clk_bbpll_configure(soc_xtal_freq_t xtal_freq, int pll_freq)
*/
static void rtc_clk_cpu_freq_to_xtal(int cpu_freq, int div)
{
clk_ll_ahb_set_ls_divider(div);
clk_ll_cpu_set_ls_divider(div);
// let f_cpu = f_ahb
clk_ll_ahb_set_divider(1);
clk_ll_cpu_set_divider(div);
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_XTAL);
clk_ll_bus_update();
esp_rom_set_cpu_ticks_per_us(cpu_freq);
}
static void rtc_clk_cpu_freq_to_rc_fast(void)
{
clk_ll_ahb_set_ls_divider(1);
clk_ll_cpu_set_ls_divider(1);
// let f_cpu = f_ahb
clk_ll_ahb_set_divider(1);
clk_ll_cpu_set_divider(1);
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_RC_FAST);
esp_rom_set_cpu_ticks_per_us(20);
clk_ll_bus_update();
esp_rom_set_cpu_ticks_per_us(8);
}
/**
@@ -190,8 +186,32 @@ static void rtc_clk_cpu_freq_to_rc_fast(void)
*/
static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
{
clk_ll_cpu_set_hs_divider(CLK_LL_PLL_96M_FREQ_MHZ / cpu_freq_mhz);
// f_hp_root = 96MHz
uint32_t cpu_divider = CLK_LL_PLL_96M_FREQ_MHZ / cpu_freq_mhz; // must be a power of 2
clk_ll_cpu_set_divider(cpu_divider);
// Constraint: f_ahb <= 32MHz
uint32_t ahb_divider = (cpu_divider == 1) ? 3 :
(cpu_divider == 2) ? 2 : 1;
clk_ll_ahb_set_divider(ahb_divider);
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL);
clk_ll_bus_update();
esp_rom_set_cpu_ticks_per_us(cpu_freq_mhz);
}
/**
* Switch to XTAL_X2 as cpu clock source.
* On ESP32H4, XTAL_X2 frequency is 64MHz.
* XTAL_X2 circuit must already been enabled.
*/
static void rtc_clk_cpu_freq_to_xtal_x2(uint32_t cpu_freq_mhz, uint32_t cpu_divider)
{
// f_hp_root = 64MHz
clk_ll_cpu_set_divider(cpu_divider);
// Constraint: f_ahb <= 32MHz
uint32_t ahb_divider = (cpu_divider == 1) ? 2 : 1;
clk_ll_ahb_set_divider(ahb_divider);
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_XTAL_X2);
clk_ll_bus_update();
esp_rom_set_cpu_ticks_per_us(cpu_freq_mhz);
}
@@ -213,21 +233,21 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *ou
source_freq_mhz = xtal_freq;
source = SOC_CPU_CLK_SRC_XTAL;
} else if (freq_mhz == 16) {
} else if (freq_mhz == 96) {
real_freq_mhz = freq_mhz;
source = SOC_CPU_CLK_SRC_PLL;
source_freq_mhz = CLK_LL_PLL_96M_FREQ_MHZ;
divider = 6;
} else if (freq_mhz == 24) {
divider = 1;
} else if (freq_mhz == 64) {
real_freq_mhz = freq_mhz;
source = SOC_CPU_CLK_SRC_XTAL_X2;
source_freq_mhz = CLK_LL_PLL_64M_FREQ_MHZ;
divider = 1;
} else if (freq_mhz == 48) {
real_freq_mhz = freq_mhz;
source = SOC_CPU_CLK_SRC_PLL;
source_freq_mhz = CLK_LL_PLL_96M_FREQ_MHZ;
divider = 4;
} else if (freq_mhz == 32) {
real_freq_mhz = freq_mhz;
source = SOC_CPU_CLK_SRC_PLL;
source_freq_mhz = CLK_LL_PLL_96M_FREQ_MHZ;
divider = 3;
divider = 2;
} else {
// unsupported frequency
return false;
@@ -245,29 +265,55 @@ __attribute__((weak)) void rtc_clk_set_cpu_switch_to_bbpll(int event_id)
{
}
static void rtc_clk_cpu_src_clk_enable(soc_cpu_clk_src_t new_src, uint32_t new_src_freq_mhz)
{
if (new_src == SOC_CPU_CLK_SRC_PLL) {
rtc_clk_bbpll_enable();
rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), new_src_freq_mhz);
} else if (new_src == SOC_CPU_CLK_SRC_XTAL_X2) {
#if BOOTLOADER_BUILD
clk_ll_xtal_x2_enable();
#else
esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_XTAL_X2, true);
#endif
}
}
static void rtc_clk_cpu_src_clk_disable(soc_cpu_clk_src_t old_src)
{
if ((old_src == SOC_CPU_CLK_SRC_PLL) && !s_bbpll_digi_consumers_ref_count) {
rtc_clk_bbpll_disable();
} else if (old_src == SOC_CPU_CLK_SRC_XTAL_X2) {
#if BOOTLOADER_BUILD
clk_ll_xtal_x2_disable();
#else
esp_clk_tree_enable_power(SOC_ROOT_CIRCUIT_CLK_XTAL_X2, false);
#endif
}
}
void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config)
{
soc_cpu_clk_src_t old_cpu_clk_src = clk_ll_cpu_get_src();
if (old_cpu_clk_src != config->source) {
rtc_clk_cpu_src_clk_enable(config->source, config->source_freq_mhz);
}
if (config->source == SOC_CPU_CLK_SRC_XTAL) {
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
if ((old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL) && !s_bbpll_digi_consumers_ref_count) {
// We don't turn off the bbpll if some consumers depend on bbpll
rtc_clk_bbpll_disable();
}
} else if (config->source == SOC_CPU_CLK_SRC_PLL) {
if (old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL) {
rtc_clk_set_cpu_switch_to_bbpll(SLEEP_EVENT_HW_PLL_EN_START);
rtc_clk_bbpll_enable();
rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), config->source_freq_mhz);
}
rtc_clk_set_cpu_switch_to_bbpll(SLEEP_EVENT_HW_PLL_EN_START);
rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz);
rtc_clk_set_cpu_switch_to_bbpll(SLEEP_EVENT_HW_PLL_EN_STOP);
} else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) {
rtc_clk_cpu_freq_to_rc_fast();
if ((old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL) && !s_bbpll_digi_consumers_ref_count) {
// We don't turn off the bbpll if some consumers depend on bbpll
rtc_clk_bbpll_disable();
}
} else if (config->source == SOC_CPU_CLK_SRC_XTAL_X2) {
rtc_clk_cpu_freq_to_xtal_x2(config->freq_mhz, config->div);
}
if (old_cpu_clk_src != config->source) {
rtc_clk_cpu_src_clk_disable(old_cpu_clk_src);
}
}
@@ -275,30 +321,27 @@ void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config)
{
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
uint32_t source_freq_mhz;
uint32_t div; // div = freq of SOC_ROOT_CLK / freq of CPU_CLK
uint32_t freq_mhz;
switch (source) {
case SOC_CPU_CLK_SRC_XTAL: {
div = clk_ll_cpu_get_ls_divider();
source_freq_mhz = (uint32_t)rtc_clk_xtal_freq_get();
freq_mhz = source_freq_mhz / div;
break;
}
case SOC_CPU_CLK_SRC_PLL: {
div = clk_ll_cpu_get_hs_divider();
source_freq_mhz = clk_ll_bbpll_get_freq_mhz();
freq_mhz = source_freq_mhz / div;
break;
}
case SOC_CPU_CLK_SRC_RC_FAST:
div = clk_ll_cpu_get_ls_divider();
source_freq_mhz = 20;
freq_mhz = source_freq_mhz / div;
source_freq_mhz = 8;
break;
case SOC_CPU_CLK_SRC_XTAL_X2:
source_freq_mhz = clk_ll_xtal_x2_get_freq_mhz();
break;
default:
ESP_HW_LOGE(TAG, "unsupported frequency configuration");
abort();
}
uint32_t div = clk_ll_cpu_get_divider();
uint32_t freq_mhz = source_freq_mhz / div; // freq of CPU_CLK = freq of SOC_ROOT_CLK / cpu_div
*out_config = (rtc_cpu_freq_config_t) {
.source = source,
.source_freq_mhz = source_freq_mhz,
@@ -316,6 +359,9 @@ void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config)
rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz);
} else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) {
rtc_clk_cpu_freq_to_rc_fast();
} else if (config->source == SOC_CPU_CLK_SRC_XTAL_X2
&& esp_clk_tree_is_power_on(SOC_ROOT_CIRCUIT_CLK_XTAL_X2)) {
rtc_clk_cpu_freq_to_xtal_x2(config->freq_mhz, config->div);
} else {
/* fallback */
rtc_clk_cpu_freq_set_config(config);
@@ -325,10 +371,7 @@ void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config)
void rtc_clk_cpu_freq_set_xtal(void)
{
rtc_clk_cpu_set_to_default_config();
// We don't turn off the bbpll if some consumers depend on bbpll
if (!s_bbpll_digi_consumers_ref_count) {
rtc_clk_bbpll_disable();
}
rtc_clk_bbpll_disable();
}
void rtc_clk_cpu_set_to_default_config(void)
@@ -336,6 +379,7 @@ void rtc_clk_cpu_set_to_default_config(void)
int freq_mhz = (int)rtc_clk_xtal_freq_get();
rtc_clk_cpu_freq_to_xtal(freq_mhz, 1);
s_cur_pll_freq = 0; // no disable PLL, but set freq to 0 to trigger a PLL calibration after wake-up from sleep
}
void rtc_clk_cpu_freq_set_xtal_for_sleep(void)
@@ -345,55 +389,47 @@ void rtc_clk_cpu_freq_set_xtal_for_sleep(void)
void rtc_clk_cpu_freq_to_pll_and_pll_lock_release(int cpu_freq_mhz)
{
rtc_clk_cpu_freq_to_pll_mhz(cpu_freq_mhz);
if (cpu_freq_mhz == 96 || cpu_freq_mhz == 48) {
rtc_clk_cpu_freq_to_pll_mhz(cpu_freq_mhz);
} else { // cpu_freq_mhz == 64
rtc_clk_cpu_freq_to_xtal_x2(cpu_freq_mhz, 1);
}
clk_ll_cpu_clk_src_lock_release();
}
soc_xtal_freq_t rtc_clk_xtal_freq_get(void)
{
#if !CONFIG_IDF_ENV_FPGA
uint32_t xtal_freq_mhz = clk_ll_xtal_load_freq_mhz();
if (xtal_freq_mhz == 0) {
ESP_HW_LOGW(TAG, "invalid RTC_XTAL_FREQ_REG value, assume 32MHz");
return SOC_XTAL_FREQ_32M;
}
uint32_t xtal_freq_mhz = clk_ll_xtal_get_freq_mhz();
assert(xtal_freq_mhz == SOC_XTAL_FREQ_32M);
return (soc_xtal_freq_t)xtal_freq_mhz;
#else
return SOC_XTAL_FREQ_32M;
#endif
}
void rtc_clk_xtal_freq_update(soc_xtal_freq_t xtal_freq)
{
clk_ll_xtal_store_freq_mhz(xtal_freq);
}
static uint32_t rtc_clk_ahb_freq_get(void)
{
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
uint32_t soc_root_freq_mhz;
uint32_t divider;
uint32_t cpu_divider = clk_ll_cpu_get_divider();
uint32_t ahb_divider = clk_ll_ahb_get_divider();
switch (source) {
case SOC_CPU_CLK_SRC_XTAL:
soc_root_freq_mhz = rtc_clk_xtal_freq_get();
divider = clk_ll_ahb_get_ls_divider();
break;
case SOC_CPU_CLK_SRC_PLL:
soc_root_freq_mhz = clk_ll_bbpll_get_freq_mhz();
divider = clk_ll_ahb_get_hs_divider();
break;
case SOC_CPU_CLK_SRC_RC_FAST:
soc_root_freq_mhz = 20;
divider = clk_ll_ahb_get_ls_divider();
soc_root_freq_mhz = 8;
break;
case SOC_CPU_CLK_SRC_XTAL_X2:
soc_root_freq_mhz = clk_ll_xtal_x2_get_freq_mhz();
break;
default:
// Unknown SOC_ROOT clock source
soc_root_freq_mhz = 0;
divider = 1;
ESP_HW_LOGE(TAG, "Invalid SOC_ROOT_CLK");
break;
}
return soc_root_freq_mhz / divider;
return soc_root_freq_mhz / cpu_divider / ahb_divider;
}
uint32_t rtc_clk_apb_freq_get(void)

View File

@@ -9,16 +9,12 @@
#include <stddef.h>
#include <stdlib.h>
#include "rom/ets_sys.h"
#include "rom/rtc.h"
#include "rom/uart.h"
#include "esp32h4/rom/rtc.h"
#include "soc/rtc.h"
#include "esp_cpu.h"
#include "regi2c_ctrl.h"
#include "soc/lp_clkrst_reg.h"
#include "soc/regi2c_dig_reg.h"
#include "esp_hw_log.h"
#include "sdkconfig.h"
#include "esp_rom_serial_output.h"
#include "esp_private/esp_pmu.h"
#include "hal/clk_tree_ll.h"
#include "hal/pmu_ll.h"
@@ -31,30 +27,25 @@ void rtc_clk_init(rtc_clk_config_t cfg)
{
rtc_cpu_freq_config_t old_config, new_config;
/* Set tuning parameters for RC_FAST, RC_SLOW, and RC32K clocks.
/* Set tuning parameters for RC_FAST and RC_SLOW clocks.
* Note: this doesn't attempt to set the clocks to precise frequencies.
* Instead, we calibrate these clocks against XTAL frequency later, when necessary.
* - SCK_DCAP value controls tuning of RC_SLOW clock.
* The higher the value of DCAP is, the lower is the frequency.
* - CK8M_DFREQ value controls tuning of RC_FAST clock.
* CLK_8M_DFREQ constant gives the best temperature characteristics.
* - RC32K_DFREQ value controls tuning of RC32K clock.
*/
REG_SET_FIELD(LP_CLKRST_FOSC_CNTL_REG, LP_CLKRST_FOSC_DFREQ, cfg.clk_8m_dfreq);
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_SCK_DCAP, cfg.slow_clk_dcap);
REG_SET_FIELD(LP_CLKRST_RC32K_CNTL_REG, LP_CLKRST_RC32K_DFREQ, cfg.rc32k_dfreq);
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_RTC_DREG, 1);
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_DIG_DREG, 1);
REG_SET_FIELD(LP_CLKRST_RC32K_CNTL_REG, LP_CLKRST_RC32K_DFREQ, cfg.slow_clk_dcap); // h4 specific workaround (RC32K_DFREQ is used for RC_SLOW clock tuning) TODO: IDF-12313
uint32_t hp_cali_dbias = get_act_hp_dbias();
uint32_t lp_cali_dbias = get_act_lp_dbias();
REG_SET_FIELD(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, hp_cali_dbias);
REG_SET_FIELD(PMU_HP_SLEEP_LP_REGULATOR0_REG, PMU_HP_SLEEP_LP_REGULATOR_DBIAS, lp_cali_dbias);
clk_ll_rc_fast_tick_conf();
// XTAL freq can be directly informed from register field PCR_CLK_XTAL_FREQ
soc_xtal_freq_t xtal_freq = cfg.xtal_freq;
esp_rom_output_tx_wait_idle(0);
rtc_clk_xtal_freq_update(xtal_freq);
// No need to wait UART0 TX idle since its default clock source is XTAL, should not be affected by system clock configuration
/* Set CPU frequency */
rtc_clk_cpu_freq_get_config(&old_config);
@@ -77,8 +68,6 @@ void rtc_clk_init(rtc_clk_config_t cfg)
rtc_clk_32k_enable(true);
} else if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) {
rtc_clk_32k_enable_external();
} else if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) {
rtc_clk_rc32k_enable(true);
}
rtc_clk_8m_enable(need_rc_fast_en);
rtc_clk_fast_src_set(cfg.fast_clk_src);

View File

@@ -5,81 +5,51 @@
*/
#include <stdint.h>
#include "rom/ets_sys.h"
#include "esp32h4/rom/ets_sys.h"
#include "soc/rtc.h"
#include "soc/lp_timer_reg.h"
#include "hal/lp_timer_hal.h"
#include "hal/clk_tree_ll.h"
#include "hal/timer_ll.h"
#include "soc/timer_group_reg.h"
#include "esp_rom_sys.h"
#include "assert.h"
#include "hal/efuse_hal.h"
#include "soc/chip_revision.h"
#include "esp_private/periph_ctrl.h"
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.
*/
#define RTC_SLOW_CLK_600K_CAL_TIMEOUT_THRES(cycles) (cycles << 10)
#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
/* On ESP32H4, TIMG_RTC_CALI_CLK_SEL can config to 0, 1, 2
* 0: 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
// 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:
#define CLK_CAL_DIV_VAL(cal_clk) \
((cal_clk == RTC_CAL_RC_FAST) ? 32 : 1)
/**
* @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
*/
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);
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();
soc_clk_calibration_clk_src_t cali_clk_sel = (soc_clk_calibration_clk_src_t)cal_clk;
if (cal_clk == RTC_CAL_RTC_MUX) {
cal_clk = (rtc_cal_sel_t)slow_clk_src;
}
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);
switch (slow_clk_src) {
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4:
cali_clk_sel = CLK_CAL_RC_SLOW;
break;
case SOC_RTC_SLOW_CLK_SRC_XTAL32K:
cali_clk_sel = CLK_CAL_32K_XTAL;
break;
case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW:
cali_clk_sel = CLK_CAL_32K_OSC_SLOW;
break;
default:
ESP_EARLY_LOGE(TAG, "clock not supported to be calibrated");
return 0; // Invalid RTC_SLOW_CLK source
}
}
/* Enable requested clock (150k clock is always on) */
/* Enable requested clock (rc_slow clock is always on) */
// All clocks on/off takes time to be stable, so we shouldn't frequently enable/disable the clock
// 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
@@ -99,17 +69,6 @@ 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 dig_rc32k_enabled = clk_ll_rc32k_digi_is_enabled();
if (cal_clk == RTC_CAL_RC32K) {
if (!rc32k_enabled) {
rtc_clk_rc32k_enable(true);
}
if (!dig_rc32k_enabled) {
clk_ll_rc32k_digi_enable();
}
}
/* There may be another calibration process already running during we call this function,
* so we should wait the last process is done.
*/
@@ -124,23 +83,26 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
}
/* 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);
uint32_t clk_cal_divider = CLK_CAL_DIV_VAL(cal_clk);
clk_ll_calibration_set_divider(clk_cal_divider);
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);
/* Figure out how long to wait for calibration to finish */
/* Set timeout reg and expect time delay*/
uint32_t expected_freq;
if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_32K) {
if (cali_clk_sel == CLK_CAL_32K_XTAL || cali_clk_sel == CLK_CAL_32K_OSC_SLOW) {
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_32K_CAL_TIMEOUT_THRES(slowclk_cycles));
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));
expected_freq = SOC_CLK_RC_FAST_FREQ_APPROX;
} else {
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_150K_CAL_TIMEOUT_THRES(slowclk_cycles));
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_600K_CAL_TIMEOUT_THRES(slowclk_cycles));
expected_freq = SOC_CLK_RC_SLOW_FREQ_APPROX;
}
expected_freq /= clk_cal_divider;
uint32_t us_time_estimate = (uint32_t) (((uint64_t) slowclk_cycles) * MHZ / expected_freq);
/* Start calibration */
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
@@ -152,15 +114,7 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
while (true) {
if (GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY)) {
cal_val = REG_GET_FIELD(TIMG_RTCCALICFG1_REG(0), TIMG_RTC_CALI_VALUE);
/*The Fosc CLK of calibration circuit is divided by 32 for ECO1.
So we need to multiply the frequency of the Fosc for ECO1 and above chips by 32 times.
And ensure that this modification will not affect ECO0.*/
if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) {
if (cal_clk == RTC_CAL_RC_FAST) {
cal_val = cal_val >> 5;
}
}
cal_val /= clk_cal_divider;
break;
}
if (GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT)) {
@@ -169,6 +123,7 @@ 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);
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 (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
@@ -184,18 +139,9 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
}
}
if (cal_clk == RTC_CAL_RC32K) {
if (!dig_rc32k_enabled) {
clk_ll_rc32k_digi_disable();
}
if (!rc32k_enabled) {
rtc_clk_rc32k_enable(false);
}
}
// 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);
if (cal_clk == RTC_CAL_RTC_MUX && slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4) {
// calibration was done on RC_SLOW clock, but rtc_slow_clk src is RC_SLOW_D4, so we need to multiply the cal_val by 4
cal_val *= 4;
}
return cal_val;
@@ -210,20 +156,12 @@ 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)
{
slowclk_cycles /= (cal_clk == RTC_CAL_RTC_MUX) ? 1 : CLK_CAL_DIV_VAL(cal_clk);
assert(slowclk_cycles);
soc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get();
/*The Fosc CLK of calibration circuit is divided by 32 for ECO1.
So we need to divide the calibrate cycles of the FOSC for ECO1 and above chips by 32 to
avoid excessive calibration time.*/
if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) {
if (cal_clk == RTC_CAL_RC_FAST) {
slowclk_cycles = slowclk_cycles >> 5;
}
}
uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles);
if (cal_clk == RTC_CAL_32K_XTAL && !rtc_clk_cal_32k_valid(xtal_freq, slowclk_cycles, xtal_cycles)) {
if (cal_clk == RTC_CAL_32K_XTAL && !rtc_clk_cal_32k_valid((uint32_t)xtal_freq, slowclk_cycles, xtal_cycles)) {
return 0;
}
@@ -235,9 +173,10 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period)
{
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
* TODO: fix overflow.
*/
assert(period);
if (time_in_us > (UINT64_MAX >> RTC_CLK_CAL_FRACT)) {
return ((time_in_us / period) << RTC_CLK_CAL_FRACT) + ((time_in_us % period) << RTC_CLK_CAL_FRACT) / period;
}
return (time_in_us << RTC_CLK_CAL_FRACT) / period;
}
@@ -248,10 +187,7 @@ uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period)
uint64_t rtc_time_get(void)
{
ESP_EARLY_LOGW(TAG, "rtc_timer has not been implemented yet");
return 0;
//TODO: [ESP32H4] IDF-11548
// return lp_timer_hal_get_cycle_count();
return lp_timer_hal_get_cycle_count();
}
uint32_t rtc_clk_freq_cal(uint32_t cal_val)

View File

@@ -191,7 +191,7 @@ typedef struct {
*/
#define RTC_CLK_CONFIG_DEFAULT() { \
.xtal_freq = CONFIG_XTAL_FREQ, \
.cpu_freq_mhz = 90, \
.cpu_freq_mhz = CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ, \
.fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \
.slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \
.clk_rtc_clk_div = 0, \

View File

@@ -188,7 +188,7 @@ typedef struct {
*/
#define RTC_CLK_CONFIG_DEFAULT() { \
.xtal_freq = CONFIG_XTAL_FREQ, \
.cpu_freq_mhz = 80, \
.cpu_freq_mhz = CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ, \
.fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \
.slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \
.clk_rtc_clk_div = 0, \

View File

@@ -190,7 +190,7 @@ typedef struct {
*/
#define RTC_CLK_CONFIG_DEFAULT() { \
.xtal_freq = CONFIG_XTAL_FREQ, \
.cpu_freq_mhz = 80, \
.cpu_freq_mhz = CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ, \
.fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \
.slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \
.clk_rtc_clk_div = 0, \

View File

@@ -1,2 +1,2 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- |

View File

@@ -327,8 +327,8 @@ TEST_CASE("Test starting 'External 32kHz XTAL' on the board without it.", "[rtc_
"will switch to the internal RC circuit. If the switch to the internal RC circuit "
"was successful then the test succeeded.\n");
start_freq(SOC_RTC_SLOW_CLK_SRC_RC_SLOW, 200);
start_freq(SOC_RTC_SLOW_CLK_SRC_RC_SLOW, 0);
start_freq(SOC_RTC_SLOW_CLK_SRC_DEFAULT, 200);
start_freq(SOC_RTC_SLOW_CLK_SRC_DEFAULT, 0);
}
#endif // !defined(CONFIG_IDF_CI_BUILD) || !CONFIG_SPIRAM_BANKSWITCH_ENABLE

View File

@@ -8,8 +8,8 @@
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include "esp_assert.h"
#include "soc/soc.h"
#include "soc/lp_aon_reg.h"
#include "soc/reset_reasons.h"
@@ -18,8 +18,6 @@
extern "C" {
#endif
//TODO: [ESP32H4] IDF-12313 inherit from verification branch, need check
/** \defgroup rtc_apis, rtc registers and memory related apis
* @brief rtc apis
*/
@@ -44,29 +42,35 @@ extern "C" {
*
*************************************************************************************
* RTC store registers usage
* LP_AON_STORE0_REG Reserved
* LP_AON_STORE0_REG RTC fix us, high 32 bits
* LP_AON_STORE1_REG RTC_SLOW_CLK calibration value
* LP_AON_STORE2_REG Boot time, low word
* LP_AON_STORE3_REG Boot time, high word
* LP_AON_STORE4_REG External XTAL frequency
* LP_AON_STORE4_REG Status of whether to disable LOG from ROM at bit[0]
* LP_AON_STORE5_REG FAST_RTC_MEMORY_LENGTH
* LP_AON_STORE6_REG FAST_RTC_MEMORY_ENTRY
* LP_AON_STORE7_REG FAST_RTC_MEMORY_CRC
* LP_AON_STORE7_REG RTC fix us, low 32 bits
* LP_AON_STORE8_REG Store light sleep wake stub addr
* LP_AON_STORE9_REG Store the sleep mode at bit[0] (0:light sleep 1:deep sleep)
*************************************************************************************
*
* Since esp32h4 does not support RTC mem, so use LP_AON store regs to record rtc time:
*
* |------------------------|----------------------------------------|
* | LP_AON_STORE0_REG | LP_AON_STORE7_REG |
* | rtc_fix_us(MSB) | rtc_fix_us(LSB) |
* |------------------------|----------------------------------------|
*/
#define RTC_FIX_US_HIGH_REG LP_AON_STORE0_REG
#define RTC_SLOW_CLK_CAL_REG LP_AON_STORE1_REG
#define RTC_BOOT_TIME_LOW_REG LP_AON_STORE2_REG
#define RTC_BOOT_TIME_HIGH_REG LP_AON_STORE3_REG
#define RTC_XTAL_FREQ_REG LP_AON_STORE4_REG
#define RTC_ENTRY_LENGTH_REG LP_AON_STORE5_REG
#define RTC_ENTRY_ADDR_REG LP_AON_STORE6_REG
#define RTC_RESET_CAUSE_REG LP_AON_STORE6_REG
#define RTC_FIX_US_LOW_REG LP_AON_STORE7_REG
#define LIGHT_SLEEP_WAKE_STUB_ADDR_REG LP_AON_STORE8_REG
#define SLEEP_MODE_REG LP_AON_STORE9_REG
#define RTC_SLEEP_WAKE_STUB_ADDR_REG LP_AON_STORE8_REG
#define RTC_SLEEP_MODE_REG LP_AON_STORE9_REG
#define RTC_DISABLE_ROM_LOG ((1 << 0) | (1 << 16)) //!< Disable logging from the ROM code.
@@ -215,7 +219,7 @@ void esp_rom_set_rtc_wake_addr(esp_rom_wake_func_t entry_addr, size_t length);
static inline void rtc_suppress_rom_log(void)
{
/* To disable logging in the ROM, only the least significant bit of the register is used,
* but since this register is also used to store the frequency of the main crystal (RTC_XTAL_FREQ_REG),
* but this register was also used to store the frequency of the main crystal (RTC_XTAL_FREQ_REG) on old targets,
* you need to write to this register in the same format.
* Namely, the upper 16 bits and lower should be the same.
*/

View File

@@ -7,6 +7,7 @@
#include "esp_attr.h"
#include "soc/i2c_ana_mst_reg.h"
#include "hal/regi2c_ctrl_ll.h"
#include "sdkconfig.h"
/* SLAVE */
#define REGI2C_BBPLL (0x66)
@@ -26,7 +27,9 @@ void esp_rom_regi2c_write_mask(uint8_t block, uint8_t host_id, uint8_t reg_add,
static IRAM_ATTR uint8_t regi2c_enable_block(uint8_t block)
{
uint32_t i2c_sel = 0;
#if !CONFIG_IDF_ENV_FPGA // on FPGA, unable to manipulate modem registers, skip the check
assert(regi2c_ctrl_ll_master_is_clock_enabled());
#endif
/* Before config I2C register, enable corresponding slave. */
switch (block) {

View File

@@ -1,17 +1,27 @@
choice ESP_DEFAULT_CPU_FREQ_MHZ
prompt "CPU frequency"
default ESP_DEFAULT_CPU_FREQ_MHZ_32 if IDF_ENV_FPGA
default ESP_DEFAULT_CPU_FREQ_MHZ_32 if IDF_ENV_FPGA || ESP_BRINGUP_BYPASS_CPU_CLK_SETTING
default ESP_DEFAULT_CPU_FREQ_MHZ_96
help
CPU frequency to be set on application startup.
config ESP_DEFAULT_CPU_FREQ_MHZ_32
bool "32 MHz"
depends on IDF_ENV_FPGA
depends on IDF_ENV_FPGA || ESP_BRINGUP_BYPASS_CPU_CLK_SETTING
config ESP_DEFAULT_CPU_FREQ_MHZ_48
bool "48 MHz"
depends on !IDF_ENV_FPGA
config ESP_DEFAULT_CPU_FREQ_MHZ_64
bool "64 MHz"
depends on !IDF_ENV_FPGA
config ESP_DEFAULT_CPU_FREQ_MHZ_96
bool "96 MHz"
depends on !IDF_ENV_FPGA
endchoice
config ESP_DEFAULT_CPU_FREQ_MHZ
int
default 32 if ESP_DEFAULT_CPU_FREQ_MHZ_32
default 48 if ESP_DEFAULT_CPU_FREQ_MHZ_48
default 64 if ESP_DEFAULT_CPU_FREQ_MHZ_64
default 96 if ESP_DEFAULT_CPU_FREQ_MHZ_96

View File

@@ -17,7 +17,6 @@
#include "soc/soc.h"
#include "soc/rtc.h"
#include "soc/rtc_periph.h"
#include "soc/i2s_reg.h"
#include "esp_cpu.h"
#include "hal/wdt_hal.h"
#include "esp_private/periph_ctrl.h"
@@ -26,8 +25,6 @@
#include "esp_rom_serial_output.h"
#include "esp_rom_sys.h"
//TODO: [ESP32H4] IDF-12285 inherited from verification branch, need check
/* Number of cycles to wait from the 32k XTAL oscillator to consider it running.
* Larger values increase startup delay. Smaller values may cause false positive
* detection (i.e. oscillator runs for a few cycles and then stops).
@@ -40,11 +37,18 @@ static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src);
static const char *TAG = "clk";
void esp_rtc_init(void)
{
#if SOC_PMU_SUPPORTED && !CONFIG_IDF_ENV_FPGA
pmu_init();
#endif
}
__attribute__((weak)) void esp_clk_init(void)
{
#if !CONFIG_IDF_ENV_FPGA
pmu_init();
assert(rtc_clk_xtal_freq_get() == RTC_XTAL_FREQ_40M);
assert(rtc_clk_xtal_freq_get() == SOC_XTAL_FREQ_32M);
rtc_clk_8m_enable(true);
rtc_clk_fast_src_set(SOC_RTC_FAST_CLK_SRC_RC_FAST);
@@ -57,7 +61,7 @@ __attribute__((weak)) void esp_clk_init(void)
// This prevents excessive delay before resetting in case the supply voltage is drawdown.
// (If frequency is changed from 150kHz to 32kHz then WDT timeout will increased to 1.6sec * 150/32 = 7.5 sec).
wdt_hal_context_t rtc_wdt_ctx = RWDT_HAL_CONTEXT_DEFAULT();
uint32_t stage_timeout_ticks = (uint32_t)(1600ULL * rtc_clk_slow_freq_get_hz() / 1000ULL);
uint32_t stage_timeout_ticks = (uint32_t)(2000ULL * rtc_clk_slow_freq_get_hz() / 1000ULL);
wdt_hal_write_protect_disable(&rtc_wdt_ctx);
wdt_hal_feed(&rtc_wdt_ctx);
//Bootloader has enabled RTC WDT until now. We're only modifying timeout, so keep the stage and timeout action the same
@@ -69,10 +73,8 @@ __attribute__((weak)) void esp_clk_init(void)
select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_XTAL32K);
#elif defined(CONFIG_RTC_CLK_SRC_EXT_OSC)
select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_OSC_SLOW);
#elif defined(CONFIG_RTC_CLK_SRC_INT_RC32K)
select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_RC32K);
#else
select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_RC_SLOW);
select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4);
#endif
#ifdef CONFIG_BOOTLOADER_WDT_ENABLE
@@ -94,9 +96,11 @@ __attribute__((weak)) void esp_clk_init(void)
// Wait for UART TX to finish, otherwise some UART output will be lost
// when switching APB frequency
esp_rom_output_tx_wait_idle(CONFIG_ESP_CONSOLE_UART_NUM);
if (CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM != -1) {
esp_rom_output_tx_wait_idle(CONFIG_ESP_CONSOLE_UART_NUM);
}
if (res) {
if (res) {
rtc_clk_cpu_freq_set_config(&new_config);
}
@@ -138,17 +142,18 @@ static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src)
continue;
}
ESP_EARLY_LOGW(TAG, "32 kHz clock not found, switching to internal 150 kHz oscillator");
rtc_slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW;
rtc_slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4;
}
}
} else if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) {
rtc_clk_rc32k_enable(true);
}
rtc_clk_slow_src_set(rtc_slow_clk_src);
// Disable unused clock sources after clock source switching is complete.
// Regardless of the clock source selection, the internal 600k clock source will always keep on.
if ((rtc_slow_clk_src != SOC_RTC_SLOW_CLK_SRC_XTAL32K) && (rtc_slow_clk_src != SOC_RTC_SLOW_CLK_SRC_OSC_SLOW)) {
rtc_clk_32k_enable(false);
rtc_clk_32k_disable_external();
}
if (SLOW_CLK_CAL_CYCLES > 0) {
/* TODO: 32k XTAL oscillator has some frequency drift at startup.
* Improve calibration routine to wait until the frequency is stable.
@@ -176,6 +181,5 @@ void rtc_clk_select_rtc_slow_clk(void)
*/
__attribute__((weak)) void esp_perip_clk_init(void)
{
ESP_EARLY_LOGW(TAG, "esp_perip_clk_init() has not been implemented yet");
}

View File

@@ -6,13 +6,7 @@
#include "hal/clk_tree_hal.h"
#include "hal/clk_tree_ll.h"
#include "soc/rtc.h"
#include "hal/assert.h"
#include "hal/log.h"
//TODO: [ESP32H4] IDF-12285 inherited from verification branch, need check
static const char *CLK_HAL_TAG = "clk_hal";
uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src)
{
@@ -23,6 +17,8 @@ uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src)
return clk_ll_bbpll_get_freq_mhz();
case SOC_CPU_CLK_SRC_RC_FAST:
return SOC_CLK_RC_FAST_FREQ_APPROX / MHZ;
case SOC_CPU_CLK_SRC_XTAL_X2:
return clk_ll_xtal_x2_get_freq_mhz();
default:
// Unknown CPU_CLK mux input
HAL_ASSERT(false);
@@ -33,15 +29,12 @@ uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src)
uint32_t clk_hal_cpu_get_freq_hz(void)
{
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
uint32_t divider = (source == SOC_CPU_CLK_SRC_PLL) ? clk_ll_cpu_get_hs_divider() : clk_ll_cpu_get_ls_divider();
return clk_hal_soc_root_get_freq_mhz(source) * MHZ / divider;
return clk_hal_soc_root_get_freq_mhz(source) * MHZ / clk_ll_cpu_get_divider();
}
uint32_t clk_hal_ahb_get_freq_hz(void)
{
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
uint32_t divider = (source == SOC_CPU_CLK_SRC_PLL) ? clk_ll_ahb_get_hs_divider() : clk_ll_ahb_get_ls_divider();
return clk_hal_soc_root_get_freq_mhz(source) * MHZ / divider;
return clk_hal_cpu_get_freq_hz() / clk_ll_ahb_get_divider();
}
uint32_t clk_hal_apb_get_freq_hz(void)
@@ -52,14 +45,12 @@ uint32_t clk_hal_apb_get_freq_hz(void)
uint32_t clk_hal_lp_slow_get_freq_hz(void)
{
switch (clk_ll_rtc_slow_get_src()) {
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW:
return SOC_CLK_RC_SLOW_FREQ_APPROX;
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4:
return SOC_CLK_RC_SLOW_FREQ_APPROX / 4;
case SOC_RTC_SLOW_CLK_SRC_XTAL32K:
return SOC_CLK_XTAL32K_FREQ_APPROX;
case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW:
return SOC_CLK_OSC_SLOW_FREQ_APPROX;
case SOC_RTC_SLOW_CLK_SRC_RC32K:
return SOC_CLK_RC32K_FREQ_APPROX;
default:
// Unknown RTC_SLOW_CLK mux input
HAL_ASSERT(false);
@@ -69,10 +60,7 @@ uint32_t clk_hal_lp_slow_get_freq_hz(void)
uint32_t clk_hal_xtal_get_freq_mhz(void)
{
uint32_t freq = clk_ll_xtal_load_freq_mhz();
if (freq == 0) {
HAL_LOGW(CLK_HAL_TAG, "invalid SOC_XTAL_FREQ_32M value, assume 32MHz");
return (uint32_t)SOC_XTAL_FREQ_32M;
}
uint32_t freq = clk_ll_xtal_get_freq_mhz();
HAL_ASSERT(freq == SOC_XTAL_FREQ_32M);
return freq;
}

View File

@@ -9,18 +9,16 @@
#include <stdint.h>
#include "soc/soc.h"
#include "soc/clk_tree_defs.h"
#include "rom/rtc.h"
#include "soc/pcr_struct.h"
#include "soc/lp_clkrst_struct.h"
#include "soc/pmu_reg.h"
#include "hal/regi2c_ctrl.h"
#include "soc/regi2c_bbpll.h"
#include "esp32h4/rom/rtc.h"
#include "hal/assert.h"
#include "hal/log.h"
#include "hal/misc.h"
//TODO: [ESP32H4] IDF-12285 inherited from verification branch, need check
#ifdef __cplusplus
extern "C" {
#endif
@@ -28,6 +26,7 @@ extern "C" {
#define MHZ (1000000)
#define CLK_LL_PLL_8M_FREQ_MHZ (8)
#define CLK_LL_PLL_32M_FREQ_MHZ (32)
#define CLK_LL_PLL_48M_FREQ_MHZ (48)
#define CLK_LL_PLL_64M_FREQ_MHZ (64)
#define CLK_LL_PLL_96M_FREQ_MHZ (96)
@@ -39,13 +38,6 @@ extern "C" {
.dbuf = 1, \
}
/*
Set the frequency division factor of ref_tick
The FOSC of rtc calibration uses the 32 frequency division clock for ECO1,
So the frequency division factor of ref_tick must be greater than or equal to 32
*/
#define REG_FOSC_TICK_NUM 255
/**
* @brief XTAL32K_CLK enable modes
*/
@@ -70,8 +62,7 @@ typedef struct {
*/
static inline __attribute__((always_inline)) void clk_ll_bbpll_enable(void)
{
SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_XPD_BB_I2C |
PMU_TIE_HIGH_XPD_BBPLL | PMU_TIE_HIGH_XPD_BBPLL_I2C);
SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_XPD_BB_I2C | PMU_TIE_HIGH_XPD_BBPLL | PMU_TIE_HIGH_XPD_BBPLL_I2C);
SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_GLOBAL_BBPLL_ICG);
}
@@ -92,6 +83,27 @@ static inline __attribute__((always_inline)) void clk_ll_cpu_clk_src_lock_releas
SET_PERI_REG_MASK(PMU_IMM_SLEEP_SYSCLK_REG, PMU_UPDATE_DIG_SYS_CLK_SEL);
}
/**
* @brief Power up XTAL_X2 circuit
*/
static inline __attribute__((always_inline)) void clk_ll_xtal_x2_enable(void)
{
CLEAR_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_LOW_XPD_XTALX2);
CLEAR_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_LOW_GLOBAL_XTALX2_ICG);
SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_XTALX2);
SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_GLOBAL_XTALX2_ICG);
}
/**
* @brief Power down XTAL_X2 circuit
*/
static inline __attribute__((always_inline)) void clk_ll_xtal_x2_disable(void)
{
CLEAR_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_XTALX2 | PMU_TIE_HIGH_GLOBAL_XTALX2_ICG);
SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_LOW_XPD_XTALX2);
SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_LOW_GLOBAL_XTALX2_ICG);
}
/**
* @brief Enable the 32kHz crystal oscillator
*
@@ -132,34 +144,6 @@ static inline __attribute__((always_inline)) bool clk_ll_xtal32k_is_enabled(void
return REG_GET_FIELD(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_XTAL32K) == 1;
}
/**
* @brief Enable the internal oscillator output for RC32K_CLK
*/
static inline __attribute__((always_inline)) void clk_ll_rc32k_enable(void)
{
// Enable rc32k xpd status
SET_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_RC32K);
}
/**
* @brief Disable the internal oscillator output for RC32K_CLK
*/
static inline __attribute__((always_inline)) void clk_ll_rc32k_disable(void)
{
// Disable rc32k xpd status
CLEAR_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_RC32K);
}
/**
* @brief Get the state of the internal oscillator for RC32K_CLK
*
* @return True if the oscillator is enabled
*/
static inline __attribute__((always_inline)) bool clk_ll_rc32k_is_enabled(void)
{
return REG_GET_FIELD(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_RC32K) == 1;
}
/**
* @brief Enable the internal oscillator output for RC_FAST_CLK
*/
@@ -239,29 +223,13 @@ static inline __attribute__((always_inline)) bool clk_ll_xtal32k_digi_is_enabled
}
/**
* @brief Enable the digital RC32K_CLK, which is used to support peripherals.
*/
static inline __attribute__((always_inline)) void clk_ll_rc32k_digi_enable(void)
{
LP_CLKRST.clk_to_hp.icg_hp_osc32k = 1;
}
/**
* @brief Disable the digital RC32K_CLK, which is used to support peripherals.
*/
static inline __attribute__((always_inline)) void clk_ll_rc32k_digi_disable(void)
{
LP_CLKRST.clk_to_hp.icg_hp_osc32k = 0;
}
/**
* @brief Get the state of the digital RC32K_CLK
* @brief Get XTAL_CLK frequency
*
* @return True if the digital RC32K_CLK is enabled
* @return Main XTAL clock frequency, in MHz.
*/
static inline __attribute__((always_inline)) bool clk_ll_rc32k_digi_is_enabled(void)
static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_get_freq_mhz(void)
{
return LP_CLKRST.clk_to_hp.icg_hp_osc32k;
return PCR.sysclk_conf.clk_xtal_freq;
}
/**
@@ -295,37 +263,43 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_set_freq_mhz(uint
*/
static inline __attribute__((always_inline)) void clk_ll_bbpll_set_config(uint32_t pll_freq_mhz, uint32_t xtal_freq_mhz)
{
// HAL_ASSERT(pll_freq_mhz == CLK_LL_PLL_96M_FREQ_MHZ);
// uint8_t div_ref;
// uint8_t div7_0;
// uint8_t dr1;
// uint8_t dr3;
// uint8_t dchgp;
// uint8_t dcur;
// uint8_t dbias;
HAL_ASSERT(xtal_freq_mhz == SOC_XTAL_FREQ_32M);
HAL_ASSERT(pll_freq_mhz == CLK_LL_PLL_96M_FREQ_MHZ);
uint8_t oc_ref_div;
uint8_t oc_div;
uint8_t oc_dhref_sel;
uint8_t oc_dlref_sel;
// /* Configure 480M PLL */
// switch (xtal_freq_mhz) {
// case SOC_XTAL_FREQ_32M:
// default:
// div_ref = 0;
// div7_0 = 8;
// dr1 = 0;
// dr3 = 0;
// dchgp = 5;
// dcur = 3;
// dbias = 2;
// break;
// }
// uint8_t i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref);
// uint8_t i2c_bbpll_div_7_0 = div7_0;
// uint8_t i2c_bbpll_dcur = (1 << I2C_BBPLL_OC_DLREF_SEL_LSB ) | (3 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur;
// REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref);
// REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0);
// REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1);
// REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR3, dr3);
// REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DCUR, i2c_bbpll_dcur);
// REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_VCO_DBIAS, dbias);
oc_ref_div = 8;
oc_div = 24;
oc_dhref_sel = 3;
oc_dlref_sel = 1;
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, oc_ref_div);
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DIV, oc_div);
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DHREF_SEL, oc_dhref_sel);
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DLREF_SEL, oc_dlref_sel);
}
/**
* @brief Get XTAL_X2_CLK frequency
*
* @return XTAL_X2 clock frequency, in MHz
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_x2_get_freq_mhz(void)
{
return SOC_XTAL_FREQ_32M * 2;
}
/**
* @brief To enable the change of soc_clk_sel, cpu_div_num, ahb_div_num, apb_div_num
*
* If the group of the parameters are invalid, the bus may get stuck.
*/
static inline __attribute__((always_inline)) void clk_ll_bus_update(void)
{
PCR.bus_clk_update.bus_clock_update = 1;
while (PCR.bus_clk_update.bus_clock_update);
}
/**
@@ -339,12 +313,15 @@ static inline __attribute__((always_inline)) void clk_ll_cpu_set_src(soc_cpu_clk
case SOC_CPU_CLK_SRC_XTAL:
PCR.sysclk_conf.soc_clk_sel = 0;
break;
case SOC_CPU_CLK_SRC_PLL:
case SOC_CPU_CLK_SRC_RC_FAST:
PCR.sysclk_conf.soc_clk_sel = 1;
break;
case SOC_CPU_CLK_SRC_RC_FAST:
case SOC_CPU_CLK_SRC_XTAL_X2:
PCR.sysclk_conf.soc_clk_sel = 2;
break;
case SOC_CPU_CLK_SRC_PLL:
PCR.sysclk_conf.soc_clk_sel = 3;
break;
default:
// Unsupported SOC_CLK mux input sel
abort();
@@ -363,9 +340,11 @@ static inline __attribute__((always_inline)) soc_cpu_clk_src_t clk_ll_cpu_get_sr
case 0:
return SOC_CPU_CLK_SRC_XTAL;
case 1:
return SOC_CPU_CLK_SRC_PLL;
case 2:
return SOC_CPU_CLK_SRC_RC_FAST;
case 2:
return SOC_CPU_CLK_SRC_XTAL_X2;
case 3:
return SOC_CPU_CLK_SRC_PLL;
default:
// Invalid SOC_CLK_SEL value
return SOC_CPU_CLK_SRC_INVALID;
@@ -373,129 +352,48 @@ static inline __attribute__((always_inline)) soc_cpu_clk_src_t clk_ll_cpu_get_sr
}
/**
* @brief Set CPU_CLK's high-speed divider (valid when SOC_ROOT clock source is PLL)
* @brief Set CPU_CLK divider
*
* @param divider Divider. (PCR_HS_DIV_NUM + 1) * (PCR_CPU_HS_DIV_NUM + 1) = divider.
* @param divider Divider. PRE_DIV_CNT = divider - 1.
*/
static inline __attribute__((always_inline)) void clk_ll_cpu_set_hs_divider(uint32_t divider)
static inline __attribute__((always_inline)) void clk_ll_cpu_set_divider(uint32_t divider)
{
// SOC_ROOT_CLK ---(1)---> HP_ROOT_CLK ---(2)---> CPU_CLK
// (1) not configurable for the target (HRO register field: PCR_HS_DIV_NUM)
// Fixed at 3 for HS clock source
// Corresponding register field value is PCR_HS_DIV_NUM=2
// (2) configurable
// HS divider option: 1, 2, 4 (PCR_CPU_HS_DIV_NUM=0, 1, 3)
HAL_ASSERT(divider == 3 || divider == 4 || divider == 6 || divider == 12);
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.cpu_freq_conf, cpu_div_num, (divider / 3) - 1);
// 120MHz CPU freq cannot be achieved through divider, need to set force_120m
// This field is only valid if PCR_CPU_HS_DIV_NUM=0 and PCR_SOC_CLK_SEL=SOC_CPU_CLK_SRC_PLL
// bool force_120m = (divider == 4) ? 1 : 0;
// PCR.cpu_freq_conf.cpu_hs_120m_force = force_120m;
}
/**
* @brief Set CPU_CLK's low-speed divider (valid when SOC_ROOT clock source is XTAL/RC_FAST)
*
* @param divider Divider. (PCR_LS_DIV_NUM + 1) * (PCR_CPU_LS_DIV_NUM + 1) = divider.
*/
static inline __attribute__((always_inline)) void clk_ll_cpu_set_ls_divider(uint32_t divider)
{
// SOC_ROOT_CLK ---(1)---> HP_ROOT_CLK ---(2)---> CPU_CLK
// (1) not configurable for the target (HRO register field: PCR_LS_DIV_NUM)
// Fixed at 1 for LS clock source
// Corresponding register field value is PCR_LS_DIV_NUM=0
// (2) configurable
// LS divider option: 1, 2, 4, 8, 16, 32 (PCR_CPU_LS_DIV_NUM=0, 1, 3, 7, 15, 31)
HAL_ASSERT((divider > 0) && ((divider & (divider - 1)) == 0));
// HP_ROOT_CLK ------> CPU_CLK
// f_hp_root = 2 ^ n * f_cpu
HAL_ASSERT(divider >= 1 && ((divider & (divider - 1)) == 0));
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.cpu_freq_conf, cpu_div_num, divider - 1);
}
/**
* @brief Get CPU_CLK's high-speed divider
* @brief Get CPU_CLK divider
*
* @return Divider. Divider = (PCR_HS_DIV_NUM + 1) * (PCR_CPU_HS_DIV_NUM + 1).
* @return Divider. Divider = (PRE_DIV_CNT + 1).
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_hs_divider(void)
static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_divider(void)
{
// uint32_t force_120m = PCR.cpu_freq_conf.cpu_hs_120m_force;
uint32_t cpu_hs_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.cpu_freq_conf, cpu_div_num);
if (cpu_hs_div == 0) {
return 4;
}
uint32_t hp_root_hs_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.sysclk_conf, hs_div_num);
return (hp_root_hs_div + 1) * (cpu_hs_div + 1);
return HAL_FORCE_READ_U32_REG_FIELD(PCR.cpu_freq_conf, cpu_div_num) + 1;
}
/**
* @brief Get CPU_CLK's low-speed divider
* @brief Set AHB_CLK divider
*
* @return Divider. Divider = (PCR_LS_DIV_NUM + 1) * (PCR_CPU_LS_DIV_NUM + 1).
* @param divider Divider. PRE_DIV_CNT = divider - 1.
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_ls_divider(void)
static inline __attribute__((always_inline)) void clk_ll_ahb_set_divider(uint32_t divider)
{
uint32_t cpu_ls_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.cpu_freq_conf, cpu_div_num);
uint32_t hp_root_ls_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.sysclk_conf, ls_div_num);
return (hp_root_ls_div + 1) * (cpu_ls_div + 1);
}
/**
* @brief Set AHB_CLK's high-speed divider (valid when SOC_ROOT clock source is PLL)
*
* @param divider Divider. (PCR_HS_DIV_NUM + 1) * (PCR_AHB_HS_DIV_NUM + 1) = divider.
*/
static inline __attribute__((always_inline)) void clk_ll_ahb_set_hs_divider(uint32_t divider)
{
// SOC_ROOT_CLK ---(1)---> HP_ROOT_CLK ---(2)---> AHB_CLK
// (1) not configurable for the target (HRO register field: PCR_HS_DIV_NUM)
// Fixed at 3 for HS clock source
// Corresponding register field value is PCR_HS_DIV_NUM=2
// (2) configurable
// HS divider option: 4, 8, 16 (PCR_AHB_HS_DIV_NUM=3, 7, 15)
HAL_ASSERT(divider == 12 || divider == 24 || divider == 48);
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ahb_freq_conf, ahb_div_num, (divider / 3) - 1);
}
/**
* @brief Set AHB_CLK's low-speed divider (valid when SOC_ROOT clock source is XTAL/RC_FAST)
*
* @param divider Divider. (PCR_LS_DIV_NUM + 1) * (PCR_AHB_LS_DIV_NUM + 1) = divider.
*/
static inline __attribute__((always_inline)) void clk_ll_ahb_set_ls_divider(uint32_t divider)
{
// SOC_ROOT_CLK ---(1)---> HP_ROOT_CLK ---(2)---> AHB_CLK
// (1) not configurable for the target (HRO register field: PCR_LS_DIV_NUM)
// Fixed at 1 for LS clock source
// Corresponding register field value is PCR_LS_DIV_NUM=0
// (2) configurable
// LS divider option: 1, 2, 4, 8, 16, 32 (PCR_CPU_LS_DIV_NUM=0, 1, 3, 7, 15, 31)
HAL_ASSERT((divider > 0) && ((divider & (divider - 1)) == 0));
// CPU_CLK ------> AHB_CLK
HAL_ASSERT(divider >= 1);
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ahb_freq_conf, ahb_div_num, divider - 1);
}
/**
* @brief Get AHB_CLK's high-speed divider
* @brief Get AHB_CLK divider
*
* @return Divider. Divider = (PCR_HS_DIV_NUM + 1) * (PCR_AHB_HS_DIV_NUM + 1).
* @return Divider. Divider = (PRE_DIV_CNT + 1).
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_ahb_get_hs_divider(void)
static inline __attribute__((always_inline)) uint32_t clk_ll_ahb_get_divider(void)
{
uint32_t ahb_hs_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.ahb_freq_conf, ahb_div_num);
uint32_t hp_root_hs_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.sysclk_conf, hs_div_num);
return (hp_root_hs_div + 1) * (ahb_hs_div + 1);
}
/**
* @brief Get AHB_CLK's low-speed divider
*
* @return Divider. Divider = (PCR_LS_DIV_NUM + 1) * (PCR_AHB_LS_DIV_NUM + 1).
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_ahb_get_ls_divider(void)
{
uint32_t ahb_ls_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.ahb_freq_conf, ahb_div_num);
uint32_t hp_root_ls_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.sysclk_conf, ls_div_num);
return (hp_root_ls_div + 1) * (ahb_ls_div + 1);
return HAL_FORCE_READ_U32_REG_FIELD(PCR.ahb_freq_conf, ahb_div_num) + 1;
}
/**
@@ -522,100 +420,95 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_apb_get_divider(voi
}
/**
* @brief Set MSPI_FAST_CLK's high-speed divider (valid when SOC_ROOT clock source is PLL)
* @brief Select the calibration clock source for timergroup0
*
* @param divider Divider.
* @param clk_sel One of the clock sources in soc_clk_calibration_clk_src_t
*/
static inline __attribute__((always_inline)) void clk_ll_mspi_fast_set_hs_divider(uint32_t divider)
static inline __attribute__((always_inline)) void clk_ll_calibration_set_target(soc_clk_calibration_clk_src_t clk_sel)
{
// SOC_ROOT_CLK ------> MSPI_FAST_CLK
// HS divider option: 4, 5, 6 (PCR_MSPI_FAST_HS_DIV_NUM=3, 4, 5)
uint32_t div_num = 0;
switch (divider) {
case 4:
div_num = 3;
break;
case 5:
div_num = 4;
break;
case 6:
div_num = 5;
break;
default:
// Unsupported HS MSPI_FAST divider
abort();
}
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.mspi_clk_conf, mspi_fast_div_num, div_num);
}
int timg_cali_clk_sel = -1;
int timg_secure_clk_sel = -1;
/**
* @brief Set MSPI_FAST_CLK's low-speed divider (valid when SOC_ROOT clock source is XTAL/RC_FAST)
*
* @param divider Divider.
*/
static inline __attribute__((always_inline)) void clk_ll_mspi_fast_set_ls_divider(uint32_t divider)
{
// SOC_ROOT_CLK ------> MSPI_FAST_CLK
// LS divider option: 1, 2, 4 (PCR_MSPI_FAST_LS_DIV_NUM=0, 1, 2)
uint32_t div_num = 0;
switch (divider) {
case 1:
div_num = 0;
break;
case 2:
div_num = 1;
break;
case 4:
div_num = 2;
break;
default:
// Unsupported LS MSPI_FAST divider
abort();
}
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.mspi_clk_conf, mspi_fast_div_num, div_num);
}
/**
* @brief Select the calibration 32kHz clock source for timergroup0
*
* @param in_sel One of the 32kHz clock sources (RC32K_CLK, XTAL32K_CLK, OSC_SLOW_CLK)
*/
static inline __attribute__((always_inline)) void clk_ll_32k_calibration_set_target(soc_rtc_slow_clk_src_t in_sel)
{
switch (in_sel) {
case SOC_RTC_SLOW_CLK_SRC_RC32K:
PCR.timg_cali_clk_conf.timg_cali_clk_sel = 0;
break;
case SOC_RTC_SLOW_CLK_SRC_XTAL32K:
PCR.timg_cali_clk_conf.timg_cali_clk_sel = 1;
break;
case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW:
PCR.timg_cali_clk_conf.timg_cali_clk_sel = 2;
break;
default:
// Unsupported 32K_SEL 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.timg_cali_clk_conf.timg_cali_clk_sel;
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;
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_EXT_IO:
timg_cali_clk_sel = 4;
timg_secure_clk_sel = 0;
break;
case CLK_CAL_CPU:
timg_cali_clk_sel = 4;
timg_secure_clk_sel = 1;
break;
case CLK_CAL_AHB:
timg_cali_clk_sel = 4;
timg_secure_clk_sel = 2;
break;
case CLK_CAL_APB:
timg_cali_clk_sel = 4;
timg_secure_clk_sel = 3;
break;
case CLK_CAL_SEC:
timg_cali_clk_sel = 4;
timg_secure_clk_sel = 4;
break;
case CLK_CAL_MSPI:
timg_cali_clk_sel = 4;
timg_secure_clk_sel = 5;
break;
case CLK_CAL_IOMUX:
timg_cali_clk_sel = 4;
timg_secure_clk_sel = 6;
break;
case CLK_CAL_PARLIO_RX:
timg_cali_clk_sel = 4;
timg_secure_clk_sel = 7;
break;
case CLK_CAL_PARLIO_TX:
timg_cali_clk_sel = 4;
timg_secure_clk_sel = 8;
break;
case CLK_CAL_GPSPI3_MST:
timg_cali_clk_sel = 4;
timg_secure_clk_sel = 9;
break;
case CLK_CAL_GPSPI2_MST:
timg_cali_clk_sel = 4;
timg_secure_clk_sel = 10;
break;
case CLK_CAL_RC_FAST:
timg_cali_clk_sel = 4;
timg_secure_clk_sel = 11;
break;
default:
return SOC_RTC_SLOW_CLK_SRC_INVALID;
// Unsupported CLK_CAL mux input
abort();
}
if (timg_cali_clk_sel >= 0) {
PCR.timg_cali_clk_conf.timg_cali_clk_sel = timg_cali_clk_sel;
}
if (timg_secure_clk_sel >= 0) {
PCR.timg_cali_clk_conf.timg_secure_clk_sel = timg_secure_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(PCR.timg_cali_clk_conf, timg_secure_clk_div_num, divider - 1);
}
/**
@@ -626,15 +519,12 @@ 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.slow_clk_sel = 0;
break;
case SOC_RTC_SLOW_CLK_SRC_XTAL32K:
LP_CLKRST.lp_clk_conf.slow_clk_sel = 1;
break;
case SOC_RTC_SLOW_CLK_SRC_RC32K:
LP_CLKRST.lp_clk_conf.slow_clk_sel = 2;
break;
case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW:
LP_CLKRST.lp_clk_conf.slow_clk_sel = 3;
break;
@@ -654,11 +544,9 @@ static inline __attribute__((always_inline)) soc_rtc_slow_clk_src_t clk_ll_rtc_s
uint32_t clk_sel = LP_CLKRST.lp_clk_conf.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 2:
return SOC_RTC_SLOW_CLK_SRC_RC32K;
case 3:
return SOC_RTC_SLOW_CLK_SRC_OSC_SLOW;
default:
@@ -729,56 +617,15 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_rc_fast_get_divider
/**
* @brief Set RC_SLOW_CLK divider
*
* @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 **************************/
/**
* @brief Store XTAL_CLK frequency in RTC storage register
*
* Value of RTC_XTAL_FREQ_REG is stored as two copies in lower and upper 16-bit
* halves. These are the routines to work with that representation.
*
* @param xtal_freq_mhz XTAL frequency, in MHz. The frequency must necessarily be even,
* otherwise there will be a conflict with the low bit, which is used to disable logs
* in the ROM code.
*/
static inline __attribute__((always_inline)) void clk_ll_xtal_store_freq_mhz(uint32_t xtal_freq_mhz)
{
// Read the status of whether disabling logging from ROM code
uint32_t reg = READ_PERI_REG(RTC_XTAL_FREQ_REG) & RTC_DISABLE_ROM_LOG;
// If so, need to write back this setting
if (reg == RTC_DISABLE_ROM_LOG) {
xtal_freq_mhz |= 1;
}
WRITE_PERI_REG(RTC_XTAL_FREQ_REG, (xtal_freq_mhz & UINT16_MAX) | ((xtal_freq_mhz & UINT16_MAX) << 16));
}
/**
* @brief Load XTAL_CLK frequency from RTC storage register
*
* Value of RTC_XTAL_FREQ_REG is stored as two copies in lower and upper 16-bit
* halves. These are the routines to work with that representation.
*
* @return XTAL frequency, in MHz. Returns 0 if value in reg is invalid.
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_load_freq_mhz(void)
{
// Read from RTC storage register
uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG);
if ((xtal_freq_reg & 0xFFFF) == ((xtal_freq_reg >> 16) & 0xFFFF) &&
xtal_freq_reg != 0 && xtal_freq_reg != UINT32_MAX) {
return xtal_freq_reg & ~RTC_DISABLE_ROM_LOG & UINT16_MAX;
}
// If the format in reg is invalid
return 0;
}
/**
* @brief Store RTC_SLOW_CLK calibration value in RTC storage register
*
@@ -804,15 +651,6 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_rtc_slow_load_cal(v
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)
{
PCR.timg_cali_clk_conf.timg_secure_clk_div_num = REG_FOSC_TICK_NUM;
}
/**
* @brief Store rtc_fix_us in RTC storage register
*

View File

@@ -85,10 +85,10 @@ static inline uint32_t lp_aon_ll_ext1_get_wakeup_pins(void)
static inline void lp_aon_ll_inform_wakeup_type(bool dslp)
{
if (dslp) {
REG_SET_BIT(SLEEP_MODE_REG, BIT(0)); /* Tell rom to run deep sleep wake stub */
REG_SET_BIT(RTC_SLEEP_MODE_REG, BIT(0)); /* Tell rom to run deep sleep wake stub */
} else {
REG_CLR_BIT(SLEEP_MODE_REG, BIT(0)); /* Tell rom to run light sleep wake stub */
REG_CLR_BIT(RTC_SLEEP_MODE_REG, BIT(0)); /* Tell rom to run light sleep wake stub */
}
}
#ifdef __cplusplus

View File

@@ -86,6 +86,8 @@ typedef enum {
SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 = 2, /*!< Select RC_FAST_D256_CLK (referred as FOSC_DIV or 8m_d256/8md256 in TRM and reg. description) as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_DEFAULT = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, /*!< RC_SLOW_CLK is the default clock source for RTC_SLOW_CLK */
} soc_rtc_slow_clk_src_t;
/**

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2010-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -153,17 +153,9 @@
//}}
//Periheral Clock {{
#define APB_CLK_FREQ_ROM ( 26*1000000 )
#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM
#define CPU_CLK_FREQ_MHZ_BTLD (80) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration
#define APB_CLK_FREQ ( 80*1000000 ) //unit: Hz
#define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 )
#define REF_CLK_FREQ ( 1000000 )
#define UART_CLK_FREQ APB_CLK_FREQ
#define WDT_CLK_FREQ APB_CLK_FREQ
#define TIMER_CLK_FREQ (80000000>>4) //80MHz divided by 16
#define SPI_CLK_DIV 4
#define TICKS_PER_US_ROM 26 // CPU is 80MHz
//}}
/* Overall memory map */

View File

@@ -84,6 +84,8 @@ typedef enum {
SOC_RTC_SLOW_CLK_SRC_OSC_SLOW = 1, /*!< Select OSC_SLOW_CLK (external slow clock) as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 = 2, /*!< Select RC_FAST_D256_CLK (referred as FOSC_DIV or 8m_d256/8md256 in TRM and reg. description) as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_DEFAULT = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, /*!< RC_SLOW_CLK is the default clock source for RTC_SLOW_CLK */
} soc_rtc_slow_clk_src_t;
/**

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -140,17 +140,9 @@
//}}
//Periheral Clock {{
#define APB_CLK_FREQ_ROM ( 40*1000000 )
#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM
#define CPU_CLK_FREQ_MHZ_BTLD (80) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration
#define APB_CLK_FREQ (SOC_XTAL_FREQ_MHZ * 1000000 )
#define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 )
#define REF_CLK_FREQ ( 1000000 )
#define UART_CLK_FREQ APB_CLK_FREQ
#define WDT_CLK_FREQ APB_CLK_FREQ
#define TIMER_CLK_FREQ (80000000>>4) //80MHz divided by 4
#define SPI_CLK_DIV 4
#define TICKS_PER_US_ROM 40 // CPU is 40MHz
//}}
/* Overall memory map */

View File

@@ -82,6 +82,8 @@ typedef enum {
SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 = 2, /*!< Select RC_FAST_D256_CLK (referred as FOSC_DIV or 8m_d256/8md256 in TRM and reg. description) as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_DEFAULT = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, /*!< RC_SLOW_CLK is the default clock source for RTC_SLOW_CLK */
} soc_rtc_slow_clk_src_t;
/**

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -134,18 +134,9 @@
//}}
//Periheral Clock {{
#define APB_CLK_FREQ_ROM ( 40*1000000 )
#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM
#define CPU_CLK_FREQ_MHZ_BTLD (80) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration
#define APB_CLK_FREQ ( 80*1000000 )
#define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 )
#define REF_CLK_FREQ ( 1000000 )
#define XTAL_CLK_FREQ (40*1000000)
#define UART_CLK_FREQ APB_CLK_FREQ
#define WDT_CLK_FREQ APB_CLK_FREQ
#define TIMER_CLK_FREQ (80000000>>4) //80MHz divided by 16
#define SPI_CLK_DIV 4
#define TICKS_PER_US_ROM 40 // CPU is 80MHz
//}}
/* Overall memory map */

View File

@@ -127,6 +127,8 @@ typedef enum {
SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_OSC_SLOW = 3, /*!< Select OSC_SLOW_CLK (external slow clock) as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_DEFAULT = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, /*!< RC_SLOW_CLK is the default clock source for RTC_SLOW_CLK */
} soc_rtc_slow_clk_src_t;
/**

View File

@@ -133,7 +133,6 @@
//}}
//Periheral Clock {{
#define CPU_CLK_FREQ_MHZ_BTLD (80) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration
#define APB_CLK_FREQ ( 40*1000000 )
#define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 )
#define REF_CLK_FREQ ( 1000000 )

View File

@@ -97,6 +97,8 @@ typedef enum {
SOC_RTC_SLOW_CLK_SRC_RC32K = 2, /*!< Select RC32K_CLK as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_OSC_SLOW = 3, /*!< Select OSC_SLOW_CLK (external slow clock) as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_DEFAULT = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, /*!< RC_SLOW_CLK is the default clock source for RTC_SLOW_CLK */
} soc_rtc_slow_clk_src_t;
/**

View File

@@ -136,13 +136,9 @@
//}}
//Periheral Clock {{
#define APB_CLK_FREQ_ROM ( 40*1000000 )
#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM
#define CPU_CLK_FREQ_MHZ_BTLD (80) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration
#define APB_CLK_FREQ ( 40*1000000 )
#define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 )
#define REF_CLK_FREQ ( 1000000 )
#define XTAL_CLK_FREQ (40*1000000)
//}}
/* Overall memory map */

View File

@@ -90,6 +90,8 @@ typedef enum {
SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_OSC_SLOW = 3, /*!< Select OSC_SLOW_CLK (external slow clock) as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_DEFAULT = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, /*!< RC_SLOW_CLK is the default clock source for RTC_SLOW_CLK */
} soc_rtc_slow_clk_src_t;
/**

View File

@@ -132,7 +132,6 @@
//}}
//Periheral Clock {{
#define CPU_CLK_FREQ_MHZ_BTLD (80) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration
#define APB_CLK_FREQ ( 40*1000000 )
#define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 )
#define REF_CLK_FREQ ( 1000000 )

View File

@@ -98,6 +98,8 @@ typedef enum {
SOC_RTC_SLOW_CLK_SRC_RC32K = 2, /*!< Select RC32K_CLK as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_OSC_SLOW = 3, /*!< Select OSC_SLOW_CLK (external slow clock) as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_DEFAULT = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, /*!< RC_SLOW_CLK is the default clock source for RTC_SLOW_CLK */
} soc_rtc_slow_clk_src_t;
/**

View File

@@ -134,13 +134,9 @@
//}}
//Periheral Clock {{
#define APB_CLK_FREQ_ROM ( 32*1000000 )
#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM
#define CPU_CLK_FREQ_MHZ_BTLD (64) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration
#define APB_CLK_FREQ ( 32*1000000 )
#define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 32*1000000 )
#define REF_CLK_FREQ ( 1000000 )
#define XTAL_CLK_FREQ (32*1000000)
//}}
/* Overall memory map */

View File

@@ -92,6 +92,8 @@ typedef enum {
SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_OSC_SLOW = 3, /*!< Select OSC_SLOW_CLK (external slow clock) as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_DEFAULT = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, /*!< RC_SLOW_CLK is the default clock source for RTC_SLOW_CLK */
} soc_rtc_slow_clk_src_t;
/**
@@ -132,7 +134,7 @@ typedef enum {
SOC_MOD_CLK_RTC_SLOW, /*!< RTC_SLOW_CLK can be sourced from RC_SLOW, XTAL32K, OSC_SLOW, or RC32K by configuring soc_rtc_slow_clk_src_t */
// For digital domain: peripherals, BLE
SOC_MOD_CLK_PLL_F48M, /*!< PLL_F48M_CLK is derived from PLL (clock gating + fixed divider of 2), it has a fixed frequency of 48MHz */
SOC_MOD_CLK_XTAL_X2_F64M, /*!< PLL_F64M_CLK is derived from XTAL_X2 (clock gating), it has a fixed frequency of 64MHz */
SOC_MOD_CLK_XTAL_X2_F64M, /*!< XTAL_X2_F64M_CLK is derived from XTAL_X2 (clock gating), it has a fixed frequency of 64MHz */
SOC_MOD_CLK_PLL_F96M, /*!< PLL_F96M_CLK is derived from PLL (clock gating), it has a fixed frequency of 96MHz */
SOC_MOD_CLK_XTAL32K, /*!< XTAL32K_CLK comes from the external 32kHz crystal, passing a clock gating to the peripherals */
SOC_MOD_CLK_RC_FAST, /*!< RC_FAST_CLK comes from the internal 20MHz rc oscillator, passing a clock gating to the peripherals */

View File

@@ -135,7 +135,6 @@
//}}
//Periheral Clock {{
#define CPU_CLK_FREQ_MHZ_BTLD (64) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration
#define APB_CLK_FREQ ( 32*1000000 )
#define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 32*1000000 )
#define REF_CLK_FREQ ( 1000000 )

View File

@@ -59,6 +59,10 @@ config SOC_REG_I2C_SUPPORTED
bool
default y
config SOC_CLK_TREE_SUPPORTED
bool
default y
config SOC_WDT_SUPPORTED
bool
default y
@@ -547,6 +551,10 @@ config SOC_PM_RETENTION_MODULE_NUM
int
default 32
config SOC_CLK_RC_FAST_SUPPORT_CALIBRATION
bool
default y
config SOC_MODEM_CLOCK_IS_INDEPENDENT
bool
default y
@@ -559,7 +567,7 @@ config SOC_CLK_OSC_SLOW_SUPPORTED
bool
default y
config SOC_CLK_RC32K_SUPPORTED
config SOC_CLK_LP_FAST_SUPPORT_XTAL_D2
bool
default y

View File

@@ -9,37 +9,31 @@
extern "C" {
#endif
// TODO: [ESP32H4] IDF-12285 inherit from verify code, need check
/*
************************* ESP32H4 Root Clock Source ****************************
* 1) Internal 17.5MHz RC Oscillator: RC_FAST (may also referred as FOSC in TRM and reg. description)
* 1) Internal 20MHz RC Oscillator: RC_FAST (may also referred as FOSC in TRM and reg. description)
*
* This RC oscillator generates a ~17.5MHz clock signal output as the RC_FAST_CLK.
* This RC oscillator generates a ~20MHz clock signal output as the RC_FAST_CLK.
*
* The exact frequency of RC_FAST_CLK can be computed in runtime through calibration.
*
* 2) External 32MHz Crystal Clock: XTAL
*
* 3) Internal 136kHz RC Oscillator: RC_SLOW (may also referred as SOSC in TRM or reg. description)
* 3) Internal 600kHz RC Oscillator: RC_SLOW (may also referred as SOSC in TRM or reg. description)
*
* This RC oscillator generates a ~136kHz clock signal output as the RC_SLOW_CLK. The exact frequency of this clock
* This RC oscillator generates a ~600kHz clock signal output as the RC_SLOW_CLK. The exact frequency of this clock
* can be computed in runtime through calibration.
*
* 4) Internal 32kHz RC Oscillator: RC32K
*
* The exact frequency of this clock can be computed in runtime through calibration.
*
* 5) External 32kHz Crystal Clock (optional): XTAL32K
* 4) External 32kHz Crystal Clock (optional): XTAL32K
*
* The clock source for this XTAL32K_CLK should be a 32kHz crystal connecting to the XTAL_32K_P and XTAL_32K_N
* pins.
*
* XTAL32K_CLK can also be calibrated to get its exact frequency.
*
* 6) External Slow Clock (optional): OSC_SLOW
* 5) External Slow Clock (optional): OSC_SLOW
*
* A slow clock signal generated by an external circuit can be connected to GPIO0 to be the clock source for the
* A slow clock signal generated by an external circuit can be connected to GPIO5 to be the clock source for the
* RTC_SLOW_CLK.
*
* OSC_SLOW_CLK can also be calibrated to get its exact frequency.
@@ -48,10 +42,9 @@ extern "C" {
/* The pin number to connect the external slow clock (OSC_SLOW_CLK), XTAL_32K_P */
#define SOC_EXT_OSC_SLOW_GPIO_NUM 5
/* With the default value of FOSC_DFREQ = 100, RC_FAST clock frequency is 17.5 MHz +/- 7% */
#define SOC_CLK_RC_FAST_FREQ_APPROX 17500000 /*!< Approximate RC_FAST_CLK frequency in Hz */
#define SOC_CLK_RC_SLOW_FREQ_APPROX 136000 /*!< Approximate RC_SLOW_CLK frequency in Hz */
#define SOC_CLK_RC32K_FREQ_APPROX 32768 /*!< Approximate RC32K_CLK frequency in Hz */
/* With the default value of FOSC_DFREQ = 100, RC_FAST clock frequency is 20 MHz +/- 7% */
#define SOC_CLK_RC_FAST_FREQ_APPROX 20000000 /*!< Approximate RC_FAST_CLK frequency in Hz */
#define SOC_CLK_RC_SLOW_FREQ_APPROX 600000 /*!< Approximate RC_SLOW_CLK frequency in Hz */
#define SOC_CLK_XTAL32K_FREQ_APPROX 32768 /*!< Approximate XTAL32K_CLK frequency in Hz */
#define SOC_CLK_OSC_SLOW_FREQ_APPROX 32768 /*!< Approximate OSC_SLOW_CLK (external slow clock) frequency in Hz */
@@ -63,12 +56,11 @@ extern "C" {
* @brief Root clock
*/
typedef enum {
SOC_ROOT_CLK_INT_RC_FAST, /*!< Internal 17.5MHz RC oscillator */
SOC_ROOT_CLK_INT_RC_SLOW, /*!< Internal 136kHz RC oscillator */
SOC_ROOT_CLK_INT_RC_FAST, /*!< Internal 20MHz RC oscillator */
SOC_ROOT_CLK_INT_RC_SLOW, /*!< Internal 600kHz RC oscillator */
SOC_ROOT_CLK_EXT_XTAL, /*!< External 32MHz crystal */
SOC_ROOT_CLK_EXT_XTAL32K, /*!< External 32kHz crystal */
SOC_ROOT_CLK_INT_RC32K, /*!< Internal 32kHz RC oscillator */
SOC_ROOT_CLK_EXT_OSC_SLOW, /*!< External slow clock signal at pin0 */
SOC_ROOT_CLK_EXT_OSC_SLOW, /*!< External slow clock signal at pin5 */
} soc_root_clk_t;
/**
@@ -76,6 +68,7 @@ typedef enum {
*/
typedef enum {
SOC_ROOT_CIRCUIT_CLK_BBPLL, /*!< BBPLL_CLK is the output of the PLL generator circuit */
SOC_ROOT_CIRCUIT_CLK_XTAL_X2, /*!< XTAL_X2_CLK is the output of the XTAL_X2 generator circuit */
} soc_root_clk_circuit_t;
/**
@@ -84,8 +77,9 @@ typedef enum {
*/
typedef enum {
SOC_CPU_CLK_SRC_XTAL = 0, /*!< Select XTAL_CLK as CPU_CLK source */
SOC_CPU_CLK_SRC_PLL = 1, /*!< Select PLL_CLK as CPU_CLK source (PLL_CLK is the output of 32MHz crystal oscillator frequency multiplier, 96MHz) */
SOC_CPU_CLK_SRC_RC_FAST = 2, /*!< Select RC_FAST_CLK as CPU_CLK source */
SOC_CPU_CLK_SRC_RC_FAST = 1, /*!< Select RC_FAST_CLK as CPU_CLK source */
SOC_CPU_CLK_SRC_XTAL_X2 = 2, /*!< Select XTAL_X2_CLK as CPU_CLK source (XTAL_X2_CLK is the other output of 32MHz crystal oscillator frequency multiplier, 64MHz) */
SOC_CPU_CLK_SRC_PLL = 3, /*!< Select PLL_CLK as CPU_CLK source (PLL_CLK is the output of 32MHz crystal oscillator frequency multiplier, 96MHz) */
SOC_CPU_CLK_SRC_INVALID, /*!< Invalid CPU_CLK source */
} soc_cpu_clk_src_t;
@@ -94,11 +88,12 @@ typedef enum {
* @note Enum values are matched with the register field values on purpose
*/
typedef enum {
SOC_RTC_SLOW_CLK_SRC_RC_SLOW = 0, /*!< Select RC_SLOW_CLK as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4 = 0, /*!< Select RC_SLOW_D4_CLK as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_RC32K = 2, /*!< Select RC32K_CLK as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_OSC_SLOW = 3, /*!< Select OSC_SLOW_CLK (external slow clock) as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_DEFAULT = SOC_RTC_SLOW_CLK_SRC_RC_SLOW_D4, /*!< RC_SLOW_D4_CLK is the default clock source for RTC_SLOW_CLK */
} soc_rtc_slow_clk_src_t;
/**
@@ -134,19 +129,18 @@ typedef enum {
*/
typedef enum {
// For CPU domain
SOC_MOD_CLK_CPU = 1, /*!< CPU_CLK can be sourced from XTAL, PLL, or RC_FAST by configuring soc_cpu_clk_src_t */
SOC_MOD_CLK_CPU = 1, /*!< CPU_CLK can be sourced from XTAL, PLL, RC_FAST, or XTAL_X2 by configuring soc_cpu_clk_src_t */
// For RTC domain
SOC_MOD_CLK_RTC_FAST, /*!< RTC_FAST_CLK can be sourced from XTAL_D2 or RC_FAST by configuring soc_rtc_fast_clk_src_t */
SOC_MOD_CLK_RTC_SLOW, /*!< RTC_SLOW_CLK can be sourced from RC_SLOW, XTAL32K, RC32K, or OSC_SLOW by configuring soc_rtc_slow_clk_src_t */
SOC_MOD_CLK_RTC_SLOW, /*!< RTC_SLOW_CLK can be sourced from RC_SLOW_D4, XTAL32K, or OSC_SLOW by configuring soc_rtc_slow_clk_src_t */
// For digital domain: peripherals, BLE
SOC_MOD_CLK_XTAL_X2_F32M, /*!< XTAL_X2_F32M_CLK is derived from XTAL_X2 (clock gating + fixed divider of 2), it has a fixed frequency of 32MHz */
SOC_MOD_CLK_PLL_F48M, /*!< PLL_F48M_CLK is derived from PLL (clock gating + fixed divider of 2), it has a fixed frequency of 48MHz */
SOC_MOD_CLK_PLL_F64M, /*!< PLL_F64M_CLK is derived from FLASH_PLL (clock gating), it has a fixed frequency of 64MHz */
SOC_MOD_CLK_XTAL_X2_F64M, /*!< XTAL_X2_F64M_CLK is derived from XTAL_X2 (clock gating), it has a fixed frequency of 64MHz */
SOC_MOD_CLK_PLL_F96M, /*!< PLL_F96M_CLK is derived from PLL (clock gating), it has a fixed frequency of 96MHz */
SOC_MOD_CLK_XTAL32K, /*!< XTAL32K_CLK comes from the external 32kHz crystal, passing a clock gating to the peripherals */
SOC_MOD_CLK_RC_FAST, /*!< RC_FAST_CLK comes from the internal 20MHz rc oscillator, passing a clock gating to the peripherals */
SOC_MOD_CLK_XTAL, /*!< XTAL_CLK comes from the external 32MHz crystal */
// For LP peripherals
SOC_MOD_CLK_XTAL_D2, /*!< XTAL_D2_CLK comes from the external 32MHz crystal, passing a div of 2 to the LP peripherals */
SOC_MOD_CLK_INVALID, /*!< Indication of the end of the available module clock sources */
} soc_module_clk_t;
@@ -217,15 +211,6 @@ typedef enum {
UART_SCLK_DEFAULT = SOC_MOD_CLK_PLL_F48M, /*!< UART source clock default choice is PLL_F48M */
} soc_periph_uart_clk_src_legacy_t;
/**
* @brief Type of LP_UART clock source
*/
typedef enum {
LP_UART_SCLK_LP_FAST = SOC_MOD_CLK_RTC_FAST, /*!< LP_UART source clock is LP(RTC)_FAST */
LP_UART_SCLK_XTAL_D2 = SOC_MOD_CLK_XTAL_D2, /*!< LP_UART source clock is XTAL_D2 */
LP_UART_SCLK_DEFAULT = SOC_MOD_CLK_RTC_FAST, /*!< LP_UART source clock default choice is LP(RTC)_FAST */
} soc_periph_lp_uart_clk_src_t;
/////////////////////////////////////////////////SPI////////////////////////////////////////////////////////////////////
/**
@@ -271,10 +256,34 @@ typedef enum {
typedef enum {
FLASH_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
FLASH_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
FLASH_CLK_SRC_REF_F64M = SOC_MOD_CLK_XTAL_X2_F64M, /*!< Select XTAL_X2_F64M as the source clock */
FLASH_CLK_SRC_REF_F48M = SOC_MOD_CLK_PLL_F48M, /*!< Select PLL_F48M as the source clock */
FLASH_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default clock choice */
FLASH_CLK_SRC_ROM_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as ROM default clock source */
} soc_periph_flash_clk_src_t;
////////////////////////////////////////////RTC CALIBRATION///////////////////////////////////////////////////////////
/**
* @brief Clock frequency calibration source selection
*/
typedef enum {
CLK_CAL_RC_SLOW = 0, /*!< Select to calibrate RC_SLOW_CLK */
CLK_CAL_32K_XTAL, /*!< Select to calibrate XTAL32K_CLK */
CLK_CAL_32K_OSC_SLOW, /*!< Select to calibrate OSC_SLOW_CLK (external slow clock) */
CLK_CAL_RC_FAST, /*!< Select to calibrate RC_FAST_CLK */
CLK_CAL_CPU, /*!< Select to calibrate CPU_CLK */
CLK_CAL_AHB, /*!< Select to calibrate AHB_CLK */
CLK_CAL_APB, /*!< Select to calibrate APB_CLK */
CLK_CAL_SEC, /*!< Select to calibrate SEC_CLK */
CLK_CAL_MSPI, /*!< Select to calibrate MSPI_CLK */
CLK_CAL_IOMUX, /*!< Select to calibrate IOMUX_CLK */
CLK_CAL_PARLIO_RX, /*!< Select to calibrate PARLIO_RX_CLK */
CLK_CAL_PARLIO_TX, /*!< Select to calibrate PARLIO_TX_CLK */
CLK_CAL_GPSPI3_MST, /*!< Select to calibrate GPSPI3_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 */
} soc_clk_calibration_clk_src_t;
#ifdef __cplusplus
}
#endif

View File

@@ -6,7 +6,7 @@
#pragma once
#define TIMER_IN_IDX 0 // TODO: [ESP32H4] IDF-12499 need check
#define TIMER_IN_IDX 0
#define LEDC_LS_SIG_OUT0_IDX 0
#define LEDC_LS_SIG_OUT1_IDX 1
#define LEDC_LS_SIG_OUT2_IDX 2

View File

@@ -15,6 +15,10 @@
#define I2C_DCDC 0x6D
#define I2C_DCDC_HOSTID 0
#define I2C_DCDC_XPD_TRX 1
#define I2C_DCDC_XPD_TRX_MSB 7
#define I2C_DCDC_XPD_TRX_LSB 7
#define I2C_DCDC_CCM_DREG0 7
#define I2C_DCDC_CCM_DREG0_MSB 4
#define I2C_DCDC_CCM_DREG0_LSB 0

View File

@@ -124,11 +124,9 @@
//}}
//Periheral Clock {{
#define CPU_CLK_FREQ_MHZ_BTLD (80) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration
#define APB_CLK_FREQ ( 40*1000000 )
#define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 )
#define APB_CLK_FREQ ( 32*1000000 )
#define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 32*1000000 )
#define REF_CLK_FREQ ( 1000000 )
#define XTAL_CLK_FREQ (40*1000000)
//}}
/* Overall memory map */

View File

@@ -76,7 +76,7 @@
// #define SOC_LP_I2C_SUPPORTED 1 // TODO: [ESP32H4] IDF-12449
// #define SOC_ULP_LP_UART_SUPPORTED 1 // TODO: [ESP32H4] IDF-12445 IDF-12451
#define SOC_REG_I2C_SUPPORTED 1
// #define SOC_CLK_TREE_SUPPORTED 1 // TODO: [ESP32H4] IDF-12285
#define SOC_CLK_TREE_SUPPORTED 1
// #define SOC_ASSIST_DEBUG_SUPPORTED 1 // TODO: [ESP32H4] IDF-12310
#define SOC_WDT_SUPPORTED 1
#define SOC_SPI_FLASH_SUPPORTED 1 // TODO: [ESP32H4] IDF-12388
@@ -536,12 +536,14 @@
#define SOC_PM_RETENTION_MODULE_NUM (32)
/*-------------------------- CLOCK SUBSYSTEM CAPS ----------------------------------------*/
// #define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION (1) // TODO: [ESP32H4] IDF-12285
#define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION (1)
#define SOC_MODEM_CLOCK_IS_INDEPENDENT (1)
#define SOC_CLK_XTAL32K_SUPPORTED (1) /*!< Support to connect an external low frequency crystal */
#define SOC_CLK_OSC_SLOW_SUPPORTED (1) /*!< Support to connect an external oscillator, not a crystal */
#define SOC_CLK_RC32K_SUPPORTED (1) /*!< Support an internal 32kHz RC oscillator */
#define SOC_CLK_LP_FAST_SUPPORT_XTAL_D2 (1) /*!< Support XTAL_D2 clock as the LP_FAST clock source */
#define SOC_RCC_IS_INDEPENDENT 1 /*!< Reset and Clock Control is independent, thanks to the PCR registers */

View File

@@ -1992,21 +1992,6 @@ extern "C" {
* SYSCLK configuration register
*/
#define PCR_SYSCLK_CONF_REG (DR_REG_PCR_BASE + 0x114)
/** PCR_LS_DIV_NUM : HRO; bitpos: [7:0]; default: 0;
* clk_hproot is div1 of low-speed clock-source if clck-source is a low-speed
* clock-source such as XTAL/FOSC.
*/
#define PCR_LS_DIV_NUM 0x000000FFU
#define PCR_LS_DIV_NUM_M (PCR_LS_DIV_NUM_V << PCR_LS_DIV_NUM_S)
#define PCR_LS_DIV_NUM_V 0x000000FFU
#define PCR_LS_DIV_NUM_S 0
/** PCR_HS_DIV_NUM : HRO; bitpos: [15:8]; default: 2;
* clk_hproot is div3 of SPLL if the clock-source is high-speed clock SPLL.
*/
#define PCR_HS_DIV_NUM 0x000000FFU
#define PCR_HS_DIV_NUM_M (PCR_HS_DIV_NUM_V << PCR_HS_DIV_NUM_S)
#define PCR_HS_DIV_NUM_V 0x000000FFU
#define PCR_HS_DIV_NUM_S 8
/** PCR_SOC_CLK_SEL : R/W; bitpos: [17:16]; default: 0;
* Configures to select the clock source of HP_ROOT_CLK.
* 0 (default): XTAL_CLK
@@ -2267,16 +2252,18 @@ extern "C" {
#define PCR_TIMG_CALI_CLK_SEL_S 0
/** PCR_TIMG_SECURE_CLK_SEL : R/W; bitpos: [7:4]; default: 7;
* Configures the clock source for the TIMG_SECURE_CLK.
* 0 (default):CPU_CLK
* 1: AHB_CLK
* 2: APB_CLK
* 3: sec function clock
* 4: mspi function clock
* 5: iomux function clock
* 6: parl io rx function clock
* 7: parl io tx function clock
* 8: spi2 function clock
* 0: EXT_IO_CLK
* 1: CPU_CLK
* 2: AHB_CLK
* 3: APB_CLK
* 4: sec function clock
* 5: mspi function clock
* 6: iomux function clock
* 7: parl io rx function clock
* 8: parl io tx function clock
* 9: spi3 function clock
* 10: spi2 function clock
* 11: RC_FAST_CLK
*/
#define PCR_TIMG_SECURE_CLK_SEL 0x0000000FU
#define PCR_TIMG_SECURE_CLK_SEL_M (PCR_TIMG_SECURE_CLK_SEL_V << PCR_TIMG_SECURE_CLK_SEL_S)

View File

@@ -1679,15 +1679,7 @@ typedef union {
*/
typedef union {
struct {
/** ls_div_num : HRO; bitpos: [7:0]; default: 0;
* clk_hproot is div1 of low-speed clock-source if clck-source is a low-speed
* clock-source such as XTAL/FOSC.
*/
uint32_t ls_div_num:8;
/** hs_div_num : HRO; bitpos: [15:8]; default: 2;
* clk_hproot is div3 of SPLL if the clock-source is high-speed clock SPLL.
*/
uint32_t hs_div_num:8;
uint32_t reserved_0:16;
/** soc_clk_sel : R/W; bitpos: [17:16]; default: 0;
* Configures to select the clock source of HP_ROOT_CLK.
* 0 (default): XTAL_CLK
@@ -1891,16 +1883,18 @@ typedef union {
uint32_t reserved_3:1;
/** timg_secure_clk_sel : R/W; bitpos: [7:4]; default: 7;
* Configures the clock source for the TIMG_SECURE_CLK.
* 0 (default):CPU_CLK
* 1: AHB_CLK
* 2: APB_CLK
* 3: sec function clock
* 4: mspi function clock
* 5: iomux function clock
* 6: parl io rx function clock
* 7: parl io tx function clock
* 8: spi2 function clock
* 0: EXT_IO_CLK
* 1: CPU_CLK
* 2: AHB_CLK
* 3: APB_CLK
* 4: sec function clock
* 5: mspi function clock
* 6: iomux function clock
* 7: parl io rx function clock
* 8: parl io tx function clock
* 9: spi3 function clock
* 10: spi2 function clock
* 11: RC_FAST_CLK
*/
uint32_t timg_secure_clk_sel:4;
/** timg_secure_clk_div_num : R/W; bitpos: [15:8]; default: 7;

View File

@@ -106,6 +106,8 @@ typedef enum {
SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_RC32K = 2, /*!< Select RC32K_CLK as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_DEFAULT = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, /*!< RC_SLOW_CLK is the default clock source for RTC_SLOW_CLK */
} soc_rtc_slow_clk_src_t;
/**

View File

@@ -136,12 +136,8 @@
//}}
//Periheral Clock {{
#define APB_CLK_FREQ_ROM ( 10*1000000 )
#define CPU_CLK_FREQ_ROM ( 40*1000000 )
#define CPU_CLK_FREQ_MHZ_BTLD (90) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration
#define APB_CLK_FREQ ( 90*1000000 )
#define REF_CLK_FREQ ( 1000000 )
#define XTAL_CLK_FREQ (40*1000000)
//}}
/* Overall memory map */

View File

@@ -84,6 +84,8 @@ typedef enum {
SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 = 2, /*!< Select RC_FAST_D256_CLK (referred as FOSC_DIV or 8m_d256/8md256 in TRM and reg. description) as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_DEFAULT = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, /*!< RC_SLOW_CLK is the default clock source for RTC_SLOW_CLK */
} soc_rtc_slow_clk_src_t;
/**

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2010-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -141,17 +141,9 @@
#endif /* !ULP_RISCV_REGISTER_OPS */
//Periheral Clock {{
#define APB_CLK_FREQ_ROM ( 40*1000000 )
#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM
#define CPU_CLK_FREQ_MHZ_BTLD (80) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration
#define APB_CLK_FREQ ( 80*1000000 ) //unit: Hz
#define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 )
#define REF_CLK_FREQ ( 1000000 )
#define UART_CLK_FREQ APB_CLK_FREQ
#define WDT_CLK_FREQ APB_CLK_FREQ
#define TIMER_CLK_FREQ (80000000>>4) //80MHz divided by 16
#define SPI_CLK_DIV 4
#define TICKS_PER_US_ROM 40 // CPU is 80MHz
//}}
/* Overall memory map */

View File

@@ -82,6 +82,8 @@ typedef enum {
SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 = 2, /*!< Select RC_FAST_D256_CLK (referred as FOSC_DIV or 8m_d256/8md256 in TRM and reg. description) as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_DEFAULT = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, /*!< RC_SLOW_CLK is the default clock source for RTC_SLOW_CLK */
} soc_rtc_slow_clk_src_t;
/**

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2010-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -149,18 +149,9 @@
#endif /* !ULP_RISCV_REGISTER_OPS */
//Periheral Clock {{
#define APB_CLK_FREQ_ROM (40*1000000)
#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM
#define CPU_CLK_FREQ_MHZ_BTLD (80) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration
#define APB_CLK_FREQ (80*1000000)
#define MODEM_REQUIRED_MIN_APB_CLK_FREQ (80*1000000)
#define REF_CLK_FREQ (1000000)
#define XTAL_CLK_FREQ (40*1000000)
#define UART_CLK_FREQ APB_CLK_FREQ
#define WDT_CLK_FREQ APB_CLK_FREQ
#define TIMER_CLK_FREQ (80000000>>4) //80MHz divided by 16
#define SPI_CLK_DIV 4
#define TICKS_PER_US_ROM 40 // CPU is 80MHz
//}}
/* Overall memory map */

View File

@@ -146,7 +146,6 @@ api-reference/peripherals/i2c.rst
api-reference/peripherals/jpeg.rst
api-reference/peripherals/mcpwm.rst
api-reference/peripherals/usb_host.rst
api-reference/peripherals/clk_tree.rst
api-reference/peripherals/camera_driver.rst
api-reference/peripherals/spi_master.rst
api-reference/peripherals/adc_oneshot.rst

View File

@@ -3,15 +3,15 @@ Clock Tree
:link_to_translation:`zh_CN:[中文]`
{IDF_TARGET_RC_FAST_VAGUE_FREQ: default="17.5", esp32="8", esp32s2="8", esp32h2="8", esp32h21="20"}
{IDF_TARGET_RC_FAST_VAGUE_FREQ: default="17.5", esp32="8", esp32s2="8", esp32h2="8", esp32h21="20", esp32h4="20"}
{IDF_TARGET_RC_FAST_ADJUSTED_FREQ: default="17.5", esp32="8.5", esp32s2="8.5", esp32h2="8.5", esp32h21="20"}
{IDF_TARGET_RC_FAST_ADJUSTED_FREQ: default="17.5", esp32="8.5", esp32s2="8.5", esp32h2="8.5", esp32h21="20", esp32h4="20"}
{IDF_TARGET_XTAL_FREQ: default="40", esp32="2 ~ 40", esp32c2="40/26", esp32h2="32", esp32c5="48", esp32h21="32"}
{IDF_TARGET_XTAL_FREQ: default="40", esp32="2 ~ 40", esp32c2="40/26", esp32h2="32", esp32c5="48", esp32h21="32", esp32h4="32"}
{IDF_TARGET_RC_SLOW_VAGUE_FREQ: default="136", esp32="150", esp32s2="90", esp32h21="600"}
{IDF_TARGET_RC_SLOW_VAGUE_FREQ: default="136", esp32="150", esp32s2="90", esp32h21="600", esp32h4="600"}
{IDF_TARGET_OSC_SLOW_PIN: default="GPIO0", esp32c2="pin0 (when its frequency is no more than 136 kHz)", "esp32c6="GPIO0", esp32h2="GPIO13", esp32h21="GPIO11"}
{IDF_TARGET_OSC_SLOW_PIN: default="GPIO0", esp32c2="pin0 (when its frequency is no more than 136 kHz)", "esp32c6="GPIO0", esp32h2="GPIO13", esp32h21="GPIO11", esp32h4="GPIO5"}
The clock subsystem of {IDF_TARGET_NAME} is used to source and distribute system/module clocks from a range of root clocks. The clock tree driver maintains the basic functionality of the system clock and the intricate relationship among module clocks.

View File

@@ -3,15 +3,15 @@
:link_to_translation:`en:[English]`
{IDF_TARGET_RC_FAST_VAGUE_FREQ: default="17.5", esp32="8", esp32s2="8", esp32h2="8", esp32h21="20"}
{IDF_TARGET_RC_FAST_VAGUE_FREQ: default="17.5", esp32="8", esp32s2="8", esp32h2="8", esp32h21="20", esp32h4="20"}
{IDF_TARGET_RC_FAST_ADJUSTED_FREQ: default="17.5", esp32="8.5", esp32s2="8.5", esp32h2="8.5", esp32h21="20"}
{IDF_TARGET_RC_FAST_ADJUSTED_FREQ: default="17.5", esp32="8.5", esp32s2="8.5", esp32h2="8.5", esp32h21="20", esp32h4="20"}
{IDF_TARGET_XTAL_FREQ: default="40", esp32="2 ~ 40", esp32c2="40/26", esp32h2="32", esp32c5="48", esp32h21="32"}
{IDF_TARGET_XTAL_FREQ: default="40", esp32="2 ~ 40", esp32c2="40/26", esp32h2="32", esp32c5="48", esp32h21="32", esp32h4="32"}
{IDF_TARGET_RC_SLOW_VAGUE_FREQ: default="136", esp32="150", esp32s2="90", esp32h21="600"}
{IDF_TARGET_RC_SLOW_VAGUE_FREQ: default="136", esp32="150", esp32s2="90", esp32h21="600", esp32h4="600"}
{IDF_TARGET_OSC_SLOW_PIN: default="GPIO0", esp32c2="pin0时钟信号频率不超过 136 kHz 时)", "esp32c6="GPIO0", esp32h2="GPIO13", esp32h21="GPIO11"}
{IDF_TARGET_OSC_SLOW_PIN: default="GPIO0", esp32c2="pin0时钟信号频率不超过 136 kHz 时)", "esp32c6="GPIO0", esp32h2="GPIO13", esp32h21="GPIO11", esp32h4="GPIO5"}
{IDF_TARGET_NAME} 的时钟子系统用于从一系列根时钟中提取并分配系统/模块时钟。时钟树驱动程序负责维护系统时钟的基本功能,并管理模块时钟间的复杂关系。