feat(clk): Add basic clock support for esp32c5 mp

- Support SOC ROOT clock source switch
- Support CPU frequency change
- Support RTC SLOW clock source switch
- Support RTC SLOW clock + RC FAST calibration
- Remove FPGA build
This commit is contained in:
Song Ruo Jing
2024-06-14 16:46:48 +08:00
parent ede24b0440
commit 40f3bc2e57
43 changed files with 449 additions and 595 deletions

View File

@ -122,7 +122,6 @@ mainmenu "Espressif IoT Development Framework Configuration"
default "y" if IDF_TARGET="esp32c5" default "y" if IDF_TARGET="esp32c5"
select FREERTOS_UNICORE select FREERTOS_UNICORE
select IDF_TARGET_ARCH_RISCV select IDF_TARGET_ARCH_RISCV
select IDF_ENV_FPGA
config IDF_TARGET_ESP32P4 config IDF_TARGET_ESP32P4
bool bool

View File

@ -28,7 +28,6 @@
#include "hal/mmu_ll.h" #include "hal/mmu_ll.h"
#include "hal/cache_hal.h" #include "hal/cache_hal.h"
#include "hal/cache_ll.h" #include "hal/cache_ll.h"
#include "hal/clk_tree_ll.h"
void bootloader_flash_update_id() void bootloader_flash_update_id()
{ {
@ -204,11 +203,6 @@ static void bootloader_spi_flash_resume(void)
esp_err_t bootloader_init_spi_flash(void) esp_err_t bootloader_init_spi_flash(void)
{ {
// On ESP32C5, MSPI source clock's default HS divider leads to 120MHz, which is unusable before calibration
// Therefore, before switching SOC_ROOT_CLK to HS, we need to set MSPI source clock HS divider to make it run at
// 80MHz after the switch. PLL = 480MHz, so divider is 6.
clk_ll_mspi_fast_set_hs_divider(6);
bootloader_init_flash_configure(); bootloader_init_flash_configure();
bootloader_spi_flash_resume(); bootloader_spi_flash_resume();
bootloader_flash_unlock(); bootloader_flash_unlock();

View File

@ -53,18 +53,12 @@ __attribute__((weak)) void bootloader_clock_configure(void)
clk_cfg.cpu_freq_mhz = cpu_freq_mhz; clk_cfg.cpu_freq_mhz = cpu_freq_mhz;
#if CONFIG_IDF_TARGET_ESP32C5
// TODO: [ESP32C5] IDF-9009 Check whether SOC_RTC_SLOW_CLK_SRC_RC_SLOW can be used on C5 MP
// RC150K can't do calibrate on ESP32C5MPW so not use it
clk_cfg.slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC32K;
#else
// Use RTC_SLOW clock source sel register field's default value, RC_SLOW, for 2nd stage bootloader // Use RTC_SLOW clock source sel register field's default value, RC_SLOW, for 2nd stage bootloader
// RTC_SLOW clock source will be switched according to Kconfig selection at application startup // RTC_SLOW clock source will be switched according to Kconfig selection at application startup
clk_cfg.slow_clk_src = rtc_clk_slow_src_get(); clk_cfg.slow_clk_src = rtc_clk_slow_src_get();
if (clk_cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_INVALID) { 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_RC_SLOW;
} }
#endif
// Use RTC_FAST clock source sel register field's default value, XTAL_DIV, for 2nd stage bootloader // Use RTC_FAST clock source sel register field's default value, XTAL_DIV, for 2nd stage bootloader
// RTC_FAST clock source will be switched to RC_FAST at application startup // RTC_FAST clock source will be switched to RC_FAST at application startup

View File

@ -89,11 +89,7 @@ static inline void bootloader_hardware_init(void)
/* Enable analog i2c master clock */ /* Enable analog i2c master clock */
SET_PERI_REG_MASK(MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN); SET_PERI_REG_MASK(MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN);
SET_PERI_REG_MASK(MODEM_LPCON_CLK_CONF_FORCE_ON_REG, MODEM_LPCON_CLK_I2C_MST_FO); // TODO: IDF-8667 Remove this? SET_PERI_REG_MASK(MODEM_LPCON_CLK_CONF_FORCE_ON_REG, MODEM_LPCON_CLK_I2C_MST_FO); // TODO: IDF-8667 Remove this?
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
SET_PERI_REG_MASK(MODEM_LPCON_I2C_MST_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_SEL_160M);
#else // CONFIG_IDF_TARGET_ESP32C5_MP_VERSION
SET_PERI_REG_MASK(MODEM_SYSCON_CLK_CONF_REG, MODEM_SYSCON_CLK_I2C_MST_SEL_160M); SET_PERI_REG_MASK(MODEM_SYSCON_CLK_CONF_REG, MODEM_SYSCON_CLK_I2C_MST_SEL_160M);
#endif
} }
static inline void bootloader_ana_reset_config(void) static inline void bootloader_ana_reset_config(void)

View File

@ -159,7 +159,6 @@ if(NOT BOOTLOADER_BUILD)
"sleep_modem.c" # TODO: [ESP32C5] IDF-8638 "sleep_modem.c" # TODO: [ESP32C5] IDF-8638
"sleep_wake_stub.c" # TODO: [ESP32C5] IDF-8638 "sleep_wake_stub.c" # TODO: [ESP32C5] IDF-8638
"sleep_gpio.c" # TODO: [ESP32C5] IDF-8638 "sleep_gpio.c" # TODO: [ESP32C5] IDF-8638
"port/esp_clk_tree_common.c" # TODO: [ESP32C5] IDF-8638
) )
endif() endif()

View File

@ -288,10 +288,7 @@ menu "Hardware Settings"
# Invisible bringup bypass options for esp_hw_support component # Invisible bringup bypass options for esp_hw_support component
config ESP_BRINGUP_BYPASS_CPU_CLK_SETTING config ESP_BRINGUP_BYPASS_CPU_CLK_SETTING
bool bool
# TODO: [ESP32C5] IDF-8642 IDF_TARGET_ESP32C5 is added because clock default y if !SOC_CLK_TREE_SUPPORTED
# is required when bringup on C5 beta3, remove it when clock tree is
# supported
default y if !SOC_CLK_TREE_SUPPORTED && !IDF_TARGET_ESP32C5
default n default n
help help
This option is only used for new chip bringup, when This option is only used for new chip bringup, when

View File

@ -96,7 +96,7 @@ int IRAM_ATTR esp_clk_cpu_freq(void)
int IRAM_ATTR esp_clk_apb_freq(void) int IRAM_ATTR esp_clk_apb_freq(void)
{ {
// TODO: IDF-5173 Require cleanup, implementation should be unified // TODO: IDF-5173 Require cleanup, implementation should be unified
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C61 #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32C61
return rtc_clk_apb_freq_get(); return rtc_clk_apb_freq_get();
#else #else
return MIN(s_get_cpu_freq_mhz() * MHZ, APB_CLK_FREQ); return MIN(s_get_cpu_freq_mhz() * MHZ, APB_CLK_FREQ);

View File

@ -19,7 +19,7 @@ entries:
if IDF_TARGET_ESP32 = y || IDF_TARGET_ESP32S2 = y || IDF_TARGET_ESP32S3 = y || IDF_TARGET_ESP32C2 = y || IDF_TARGET_ESP32C3 = y: if IDF_TARGET_ESP32 = y || IDF_TARGET_ESP32S2 = y || IDF_TARGET_ESP32S3 = y || IDF_TARGET_ESP32C2 = y || IDF_TARGET_ESP32C3 = y:
rtc_sleep (noflash_text) rtc_sleep (noflash_text)
rtc_time (noflash_text) rtc_time (noflash_text)
if SOC_PMU_SUPPORTED = y: if SOC_PMU_SUPPORTED = y && SOC_LIGHT_SLEEP_SUPPORTED = y:
pmu_sleep (noflash) pmu_sleep (noflash)
if SOC_USB_SERIAL_JTAG_SUPPORTED = y: if SOC_USB_SERIAL_JTAG_SUPPORTED = y:
sleep_console (noflash) sleep_console (noflash)

View File

@ -1,10 +1,11 @@
set(srcs "rtc_clk_init.c" set(srcs "rtc_clk_init.c"
"rtc_time.c" "rtc_time.c"
"rtc_clk.c" "rtc_clk.c"
"pmu_init.c"
"pmu_param.c"
"chip_info.c" "chip_info.c"
) )
if(NOT BOOTLOADER_BUILD) if(NOT BOOTLOADER_BUILD)
list(APPEND srcs "sar_periph_ctrl.c" list(APPEND srcs "sar_periph_ctrl.c"
"esp_crypto_lock.c") "esp_crypto_lock.c")

View File

@ -11,21 +11,22 @@
#include "soc/rtc.h" #include "soc/rtc.h"
#include "hal/clk_tree_hal.h" #include "hal/clk_tree_hal.h"
#include "hal/clk_tree_ll.h" #include "hal/clk_tree_ll.h"
// #include "esp_private/esp_clk_tree_common.h" #include "esp_private/esp_clk_tree_common.h"
#include "sdkconfig.h"
static const char *TAG = "esp_clk_tree"; 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, esp_err_t esp_clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, esp_clk_tree_src_freq_precision_t precision,
uint32_t *freq_value) uint32_t *freq_value)
{ {
// TODO: [ESP32C5] IDF-8642 check again for MP version
ESP_RETURN_ON_FALSE(clk_src > 0 && clk_src < SOC_MOD_CLK_INVALID, ESP_ERR_INVALID_ARG, TAG, "unknown clk src"); ESP_RETURN_ON_FALSE(clk_src > 0 && clk_src < SOC_MOD_CLK_INVALID, ESP_ERR_INVALID_ARG, TAG, "unknown clk src");
ESP_RETURN_ON_FALSE(precision < ESP_CLK_TREE_SRC_FREQ_PRECISION_INVALID, ESP_ERR_INVALID_ARG, TAG, "unknown precision"); ESP_RETURN_ON_FALSE(precision < ESP_CLK_TREE_SRC_FREQ_PRECISION_INVALID, ESP_ERR_INVALID_ARG, TAG, "unknown precision");
ESP_RETURN_ON_FALSE(freq_value, ESP_ERR_INVALID_ARG, TAG, "null pointer"); ESP_RETURN_ON_FALSE(freq_value, ESP_ERR_INVALID_ARG, TAG, "null pointer");
uint32_t clk_src_freq = 0; uint32_t clk_src_freq = 0;
switch (clk_src) { switch (clk_src) {
case SOC_MOD_CLK_CPU:
clk_src_freq = clk_hal_cpu_get_freq_hz();
break;
case SOC_MOD_CLK_XTAL: case SOC_MOD_CLK_XTAL:
clk_src_freq = clk_hal_xtal_get_freq_mhz() * MHZ; clk_src_freq = clk_hal_xtal_get_freq_mhz() * MHZ;
break; break;
@ -41,9 +42,17 @@ uint32_t *freq_value)
case SOC_MOD_CLK_SPLL: case SOC_MOD_CLK_SPLL:
clk_src_freq = CLK_LL_PLL_480M_FREQ_MHZ * MHZ; clk_src_freq = CLK_LL_PLL_480M_FREQ_MHZ * MHZ;
break; 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: case SOC_MOD_CLK_RC_FAST:
// C5-beta3 unable to calibrate to get exact RC_FAST frequency clk_src_freq = esp_clk_tree_rc_fast_get_freq_hz(precision);
clk_src_freq = SOC_CLK_RC_FAST_FREQ_APPROX; break;
case SOC_MOD_CLK_XTAL32K:
clk_src_freq = esp_clk_tree_xtal32k_get_freq_hz(precision);
break; break;
case SOC_MOD_CLK_XTAL_D2: case SOC_MOD_CLK_XTAL_D2:
clk_src_freq = (clk_hal_xtal_get_freq_mhz() * MHZ) >> 1; clk_src_freq = (clk_hal_xtal_get_freq_mhz() * MHZ) >> 1;

View File

@ -50,10 +50,6 @@ extern "C" {
#define MHZ (1000000) #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_POWERUP 1
#define OTHER_BLOCKS_WAIT 1 #define OTHER_BLOCKS_WAIT 1
@ -121,21 +117,19 @@ typedef struct rtc_cpu_freq_config_s {
#define RTC_VDDSDIO_TIEH_1_8V 0 //!< TIEH field value for 1.8V VDDSDIO #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 #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 * @brief Clock source to be calibrated using rtc_clk_cal function
* *
* @note On previous targets, the enum values somehow reflects the register field values of TIMG_RTC_CALI_CLK_SEL * @note On ESP32C5, the enum values somehow reflects the register field values of PCR_32K_SEL.
* However, this is not true on ESP32C5. The conversion to register field values is explicitly done in
* rtc_clk_cal_internal
*/ */
typedef enum { typedef enum {
RTC_CAL_RTC_MUX = -1, //!< Currently selected RTC_SLOW_CLK RTC_CAL_RTC_MUX = -1, //!< Currently selected RTC_SLOW_CLK
// RTC_CAL_RC_SLOW = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, //!< Internal 150kHz RC oscillator RTC_CAL_RC32K = 0, //!< Internal 32kHz RC oscillator, as one type of 32k clock
RTC_CAL_RC32K = SOC_RTC_SLOW_CLK_SRC_RC32K, //!< Internal 32kHz RC oscillator, as one type of 32k clock RTC_CAL_32K_XTAL = 1, //!< External 32kHz XTAL, 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 = 2, //!< External slow clock signal input by lp_pad_gpio0, 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_SLOW = 3, //!< Internal 150kHz RC oscillator
RTC_CAL_RC_FAST //!< Internal 20MHz RC oscillator RTC_CAL_RC_FAST = 4, //!< Internal 20MHz RC oscillator
RTC_CAL_INVALID_CLK, //!< Clock not available to calibrate
} rtc_cal_sel_t; } rtc_cal_sel_t;
/** /**
@ -160,7 +154,7 @@ typedef struct {
.xtal_freq = CONFIG_XTAL_FREQ, \ .xtal_freq = CONFIG_XTAL_FREQ, \
.cpu_freq_mhz = 80, \ .cpu_freq_mhz = 80, \
.fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \ .fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST, \
.slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC32K, \ .slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, \
.clk_rtc_clk_div = 0, \ .clk_rtc_clk_div = 0, \
.clk_8m_clk_div = 0, \ .clk_8m_clk_div = 0, \
.slow_clk_dcap = RTC_CNTL_SCK_DCAP_DEFAULT, \ .slow_clk_dcap = RTC_CNTL_SCK_DCAP_DEFAULT, \

View File

@ -23,13 +23,13 @@ typedef struct {
const pmu_hp_system_power_param_t *power; const pmu_hp_system_power_param_t *power;
const pmu_hp_system_clock_param_t *clock; const pmu_hp_system_clock_param_t *clock;
const pmu_hp_system_digital_param_t *digital; const pmu_hp_system_digital_param_t *digital;
const pmu_hp_system_analog_param_t *analog; pmu_hp_system_analog_param_t *analog; //param determined at runtime
const pmu_hp_system_retention_param_t *retent; const pmu_hp_system_retention_param_t *retent;
} pmu_hp_system_param_t; } pmu_hp_system_param_t;
typedef struct { typedef struct {
const pmu_lp_system_power_param_t *power; const pmu_lp_system_power_param_t *power;
const pmu_lp_system_analog_param_t *analog; pmu_lp_system_analog_param_t *analog; //param determined at runtime
} pmu_lp_system_param_t; } pmu_lp_system_param_t;
pmu_context_t * __attribute__((weak)) IRAM_ATTR PMU_instance(void) pmu_context_t * __attribute__((weak)) IRAM_ATTR PMU_instance(void)
@ -42,7 +42,7 @@ pmu_context_t * __attribute__((weak)) IRAM_ATTR PMU_instance(void)
return &pmu_context; return &pmu_context;
} }
void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, pmu_hp_system_param_t *param) void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, const pmu_hp_system_param_t *param)
{ {
const pmu_hp_system_power_param_t *power = param->power; const pmu_hp_system_power_param_t *power = param->power;
const pmu_hp_system_clock_param_t *clock = param->clock; const pmu_hp_system_clock_param_t *clock = param->clock;
@ -101,7 +101,7 @@ void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, pmu_hp_system_pa
pmu_ll_hp_set_sleep_protect_mode(ctx->hal->dev, PMU_SLEEP_PROTECT_HP_LP_SLEEP); pmu_ll_hp_set_sleep_protect_mode(ctx->hal->dev, PMU_SLEEP_PROTECT_HP_LP_SLEEP);
} }
void pmu_lp_system_init(pmu_context_t *ctx, pmu_lp_mode_t mode, pmu_lp_system_param_t *param) void pmu_lp_system_init(pmu_context_t *ctx, pmu_lp_mode_t mode, const pmu_lp_system_param_t *param)
{ {
const pmu_lp_system_power_param_t *power = param->power; const pmu_lp_system_power_param_t *power = param->power;
const pmu_lp_system_analog_param_t *anlg = param->analog; const pmu_lp_system_analog_param_t *anlg = param->analog;
@ -157,18 +157,26 @@ static inline void pmu_power_domain_force_default(pmu_context_t *ctx)
static inline void pmu_hp_system_param_default(pmu_hp_mode_t mode, pmu_hp_system_param_t *param) static inline void pmu_hp_system_param_default(pmu_hp_mode_t mode, pmu_hp_system_param_t *param)
{ {
assert (param->analog);
param->power = pmu_hp_system_power_param_default(mode); param->power = pmu_hp_system_power_param_default(mode);
param->clock = pmu_hp_system_clock_param_default(mode); param->clock = pmu_hp_system_clock_param_default(mode);
param->digital = pmu_hp_system_digital_param_default(mode); param->digital = pmu_hp_system_digital_param_default(mode);
param->analog = pmu_hp_system_analog_param_default(mode); *param->analog = *pmu_hp_system_analog_param_default(mode); //copy default value
param->retent = pmu_hp_system_retention_param_default(mode); param->retent = pmu_hp_system_retention_param_default(mode);
if (mode == PMU_MODE_HP_ACTIVE || mode == PMU_MODE_HP_MODEM) {
param->analog->regulator0.dbias = get_act_hp_dbias();
}
} }
static void pmu_hp_system_init_default(pmu_context_t *ctx) static void pmu_hp_system_init_default(pmu_context_t *ctx)
{ {
assert(ctx); assert(ctx);
pmu_hp_system_param_t param = { 0 };
for (pmu_hp_mode_t mode = PMU_MODE_HP_ACTIVE; mode < PMU_MODE_HP_MAX; mode++) { for (pmu_hp_mode_t mode = PMU_MODE_HP_ACTIVE; mode < PMU_MODE_HP_MAX; mode++) {
pmu_hp_system_analog_param_t analog = {};
pmu_hp_system_param_t param = {.analog = &analog};
pmu_hp_system_param_default(mode, &param); pmu_hp_system_param_default(mode, &param);
pmu_hp_system_init(ctx, mode, &param); pmu_hp_system_init(ctx, mode, &param);
} }
@ -176,15 +184,23 @@ static void pmu_hp_system_init_default(pmu_context_t *ctx)
static inline void pmu_lp_system_param_default(pmu_lp_mode_t mode, pmu_lp_system_param_t *param) static inline void pmu_lp_system_param_default(pmu_lp_mode_t mode, pmu_lp_system_param_t *param)
{ {
assert (param->analog);
param->power = pmu_lp_system_power_param_default(mode); param->power = pmu_lp_system_power_param_default(mode);
param->analog = pmu_lp_system_analog_param_default(mode); *param->analog = *pmu_lp_system_analog_param_default(mode); //copy default value
if (mode == PMU_MODE_LP_ACTIVE) {
param->analog->regulator0.dbias = get_act_lp_dbias();
}
} }
static void pmu_lp_system_init_default(pmu_context_t *ctx) static void pmu_lp_system_init_default(pmu_context_t *ctx)
{ {
assert(ctx); assert(ctx);
pmu_lp_system_param_t param;
for (pmu_lp_mode_t mode = PMU_MODE_LP_ACTIVE; mode < PMU_MODE_LP_MAX; mode++) { for (pmu_lp_mode_t mode = PMU_MODE_LP_ACTIVE; mode < PMU_MODE_LP_MAX; mode++) {
pmu_lp_system_analog_param_t analog = {};
pmu_lp_system_param_t param = {.analog = &analog};
pmu_lp_system_param_default(mode, &param); pmu_lp_system_param_default(mode, &param);
pmu_lp_system_init(ctx, mode, &param); pmu_lp_system_init(ctx, mode, &param);
} }
@ -195,10 +211,6 @@ void pmu_init(void)
/* Peripheral reg i2c power up */ /* Peripheral reg i2c power up */
SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_PERIF_I2C_RSTB); SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_PERIF_I2C_RSTB);
SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C); SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C);
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);
pmu_hp_system_init_default(PMU_instance()); pmu_hp_system_init_default(PMU_instance());
pmu_lp_system_init_default(PMU_instance()); pmu_lp_system_init_default(PMU_instance());

View File

@ -211,7 +211,7 @@ const pmu_hp_system_digital_param_t * pmu_hp_system_digital_param_default(pmu_hp
.xpd = 1, \ .xpd = 1, \
.slp_mem_dbias = 0, \ .slp_mem_dbias = 0, \
.slp_logic_dbias = 0, \ .slp_logic_dbias = 0, \
.dbias = HP_CALI_DBIAS \ .dbias = HP_CALI_DBIAS_DEFAULT \
}, \ }, \
.regulator1 = { \ .regulator1 = { \
.drv_b = 0x0 \ .drv_b = 0x0 \
@ -231,7 +231,7 @@ const pmu_hp_system_digital_param_t * pmu_hp_system_digital_param_default(pmu_hp
.xpd = 1, \ .xpd = 1, \
.slp_mem_dbias = 0, \ .slp_mem_dbias = 0, \
.slp_logic_dbias = 0, \ .slp_logic_dbias = 0, \
.dbias = HP_CALI_DBIAS \ .dbias = HP_CALI_DBIAS_DEFAULT \
}, \ }, \
.regulator1 = { \ .regulator1 = { \
.drv_b = 0x0 \ .drv_b = 0x0 \
@ -413,7 +413,7 @@ const pmu_lp_system_power_param_t * pmu_lp_system_power_param_default(pmu_lp_mod
.slp_xpd = 0, \ .slp_xpd = 0, \
.xpd = 1, \ .xpd = 1, \
.slp_dbias = 0, \ .slp_dbias = 0, \
.dbias = LP_CALI_DBIAS \ .dbias = LP_CALI_DBIAS_DEFAULT \
}, \ }, \
.regulator1 = { \ .regulator1 = { \
.drv_b = 0x0 \ .drv_b = 0x0 \
@ -447,3 +447,53 @@ const pmu_lp_system_analog_param_t * pmu_lp_system_analog_param_default(pmu_lp_m
assert(mode < ARRAY_SIZE(lp_analog)); assert(mode < ARRAY_SIZE(lp_analog));
return &lp_analog[mode]; return &lp_analog[mode];
} }
uint32_t get_act_hp_dbias(void)
{
/* hp_cali_dbias is read from efuse to ensure that the hp_active_voltage is close to 1.15V
*/
uint32_t hp_cali_dbias = HP_CALI_DBIAS_DEFAULT;
// uint32_t blk_version = efuse_hal_blk_version();
// if (blk_version >= 3) {
// hp_cali_dbias = efuse_ll_get_active_hp_dbias();
// if (hp_cali_dbias != 0) {
// //efuse dbias need to add 2 to meet the CPU frequency switching
// if (hp_cali_dbias + 2 > 31) {
// hp_cali_dbias = 31;
// } else {
// hp_cali_dbias += 2;
// }
// } else {
// hp_cali_dbias = HP_CALI_DBIAS_DEFAULT;
// ESP_HW_LOGD(TAG, "hp_cali_dbias not burnt in efuse or wrong value was burnt in blk version: %" PRIu32 "\n", blk_version);
// }
// }
return hp_cali_dbias;
}
uint32_t get_act_lp_dbias(void)
{
/* lp_cali_dbias is read from efuse to ensure that the lp_active_voltage is close to 1.15V
*/
uint32_t lp_cali_dbias = LP_CALI_DBIAS_DEFAULT;
// uint32_t blk_version = efuse_hal_blk_version();
// if (blk_version >= 3) {
// lp_cali_dbias = efuse_ll_get_active_lp_dbias();
// if (lp_cali_dbias != 0) {
// //efuse dbias need to add 2 to meet the CPU frequency switching
// if (lp_cali_dbias + 2 > 31) {
// lp_cali_dbias = 31;
// } else {
// lp_cali_dbias += 2;
// }
// } else {
// lp_cali_dbias = LP_CALI_DBIAS_DEFAULT;
// ESP_HW_LOGD(TAG, "lp_cali_dbias not burnt in efuse or wrong value was burnt in blk version: %" PRIu32 "\n", blk_version);
// }
// } else {
// ESP_HW_LOGD(TAG, "blk_version is less than 3, act dbias not burnt in efuse\n");
// }
return lp_cali_dbias;
}

View File

@ -168,11 +168,11 @@ const pmu_sleep_config_t* pmu_sleep_config_default(
if (!(pd_flags & PMU_SLEEP_PD_XTAL)){ if (!(pd_flags & PMU_SLEEP_PD_XTAL)){
analog_default.hp_sys.analog.pd_cur = PMU_PD_CUR_SLEEP_ON; analog_default.hp_sys.analog.pd_cur = PMU_PD_CUR_SLEEP_ON;
analog_default.hp_sys.analog.bias_sleep = PMU_BIASSLP_SLEEP_ON; analog_default.hp_sys.analog.bias_sleep = PMU_BIASSLP_SLEEP_ON;
analog_default.hp_sys.analog.dbias = HP_CALI_DBIAS; analog_default.hp_sys.analog.dbias = HP_CALI_DBIAS_DEFAULT;
analog_default.lp_sys[LP(SLEEP)].analog.pd_cur = PMU_PD_CUR_SLEEP_ON; analog_default.lp_sys[LP(SLEEP)].analog.pd_cur = PMU_PD_CUR_SLEEP_ON;
analog_default.lp_sys[LP(SLEEP)].analog.bias_sleep = PMU_BIASSLP_SLEEP_ON; analog_default.lp_sys[LP(SLEEP)].analog.bias_sleep = PMU_BIASSLP_SLEEP_ON;
analog_default.lp_sys[LP(SLEEP)].analog.dbias = LP_CALI_DBIAS; analog_default.lp_sys[LP(SLEEP)].analog.dbias = LP_CALI_DBIAS_DEFAULT;
} }
config->analog = analog_default; config->analog = analog_default;

View File

@ -1,21 +0,0 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initialize OCode
*
*/
void esp_ocode_calib_init(void);
#ifdef __cplusplus
}
#endif

View File

@ -19,9 +19,8 @@
extern "C" { extern "C" {
#endif #endif
#define HP_CALI_DBIAS_DEFAULT 28
#define HP_CALI_DBIAS 25 #define LP_CALI_DBIAS_DEFAULT 28
#define LP_CALI_DBIAS 26
// FOR XTAL FORCE PU IN SLEEP // FOR XTAL FORCE PU IN SLEEP
#define PMU_PD_CUR_SLEEP_ON 0 #define PMU_PD_CUR_SLEEP_ON 0
@ -51,6 +50,9 @@ extern "C" {
#define PMU_DBG_ATTEN_DEEPSLEEP_DEFAULT 12 #define PMU_DBG_ATTEN_DEEPSLEEP_DEFAULT 12
#define PMU_LP_DBIAS_DEEPSLEEP_0V7 23 #define PMU_LP_DBIAS_DEEPSLEEP_0V7 23
uint32_t get_act_hp_dbias(void);
uint32_t get_act_lp_dbias(void);
typedef struct { typedef struct {
pmu_hp_dig_power_reg_t dig_power; pmu_hp_dig_power_reg_t dig_power;
pmu_hp_clk_power_reg_t clk_power; pmu_hp_clk_power_reg_t clk_power;
@ -412,7 +414,7 @@ typedef struct {
typedef struct pmu_sleep_machine_constant { typedef struct pmu_sleep_machine_constant {
struct { struct {
uint16_t min_slp_time_us; /* Mininum sleep protection time (unit: microsecond) */ uint16_t min_slp_time_us; /* Minimum sleep protection time (unit: microsecond) */
uint8_t wakeup_wait_cycle; /* Modem wakeup signal (WiFi MAC and BEACON wakeup) waits for the slow & fast clock domain synchronization and the wakeup signal triggers the PMU FSM switching wait cycle (unit: slow clock cycle) */ uint8_t wakeup_wait_cycle; /* Modem wakeup signal (WiFi MAC and BEACON wakeup) waits for the slow & fast clock domain synchronization and the wakeup signal triggers the PMU FSM switching wait cycle (unit: slow clock cycle) */
uint8_t reserved0; uint8_t reserved0;
uint16_t reserved1; uint16_t reserved1;
@ -424,7 +426,7 @@ typedef struct pmu_sleep_machine_constant {
uint16_t power_up_wait_time_us; /* (unit: microsecond) */ uint16_t power_up_wait_time_us; /* (unit: microsecond) */
} lp; } lp;
struct { struct {
uint16_t min_slp_time_us; /* Mininum sleep protection time (unit: microsecond) */ uint16_t min_slp_time_us; /* Minimum sleep protection time (unit: microsecond) */
uint16_t clock_domain_sync_time_us; /* The Slow OSC clock domain synchronizes time with the Fast OSC domain, at least 4 slow clock cycles (unit: microsecond) */ uint16_t clock_domain_sync_time_us; /* The Slow OSC clock domain synchronizes time with the Fast OSC domain, at least 4 slow clock cycles (unit: microsecond) */
uint16_t system_dfs_up_work_time_us; /* System DFS up scaling work time (unit: microsecond) */ uint16_t system_dfs_up_work_time_us; /* System DFS up scaling work time (unit: microsecond) */
uint16_t analog_wait_time_us; /* HP LDO power up wait time (unit: microsecond) */ uint16_t analog_wait_time_us; /* HP LDO power up wait time (unit: microsecond) */

View File

@ -172,6 +172,7 @@ static void rtc_clk_bbpll_configure(soc_xtal_freq_t xtal_freq, int pll_freq)
clk_ll_bbpll_set_config(pll_freq, xtal_freq); clk_ll_bbpll_set_config(pll_freq, xtal_freq);
/* WAIT CALIBRATION DONE */ /* WAIT CALIBRATION DONE */
while(!regi2c_ctrl_ll_bbpll_calibration_is_done()); while(!regi2c_ctrl_ll_bbpll_calibration_is_done());
esp_rom_delay_us(10); // wait for true stop
/* BBPLL CALIBRATION STOP */ /* BBPLL CALIBRATION STOP */
regi2c_ctrl_ll_bbpll_calibration_stop(); regi2c_ctrl_ll_bbpll_calibration_stop();
rtc_clk_enable_i2c_ana_master_clock(false); rtc_clk_enable_i2c_ana_master_clock(false);
@ -185,29 +186,60 @@ 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) static void rtc_clk_cpu_freq_to_xtal(int cpu_freq, int div)
{ {
clk_ll_ahb_set_ls_divider(div); // let f_cpu = f_ahb
clk_ll_cpu_set_ls_divider(div); clk_ll_cpu_set_divider(div);
clk_ll_ahb_set_divider(div);
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_XTAL); clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_XTAL);
clk_ll_bus_update();
esp_rom_set_cpu_ticks_per_us(cpu_freq); esp_rom_set_cpu_ticks_per_us(cpu_freq);
} }
static void rtc_clk_cpu_freq_to_8m(void) static void rtc_clk_cpu_freq_to_8m(void)
{ {
clk_ll_ahb_set_ls_divider(1); clk_ll_cpu_set_divider(1);
clk_ll_cpu_set_ls_divider(1); clk_ll_ahb_set_divider(1);
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_RC_FAST); clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_RC_FAST);
clk_ll_bus_update();
esp_rom_set_cpu_ticks_per_us(20); esp_rom_set_cpu_ticks_per_us(20);
} }
/** /**
* Switch to one of PLL-based frequencies. Current frequency can be XTAL or PLL. * Switch to PLL_F240M as cpu clock source.
* PLL must already be enabled. * PLL must already be enabled.
* @param cpu_freq new CPU frequency * @param cpu_freq new CPU frequency
*/ */
static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz) static void rtc_clk_cpu_freq_to_pll_240_mhz(int cpu_freq_mhz)
{ {
clk_ll_cpu_set_hs_divider(CLK_LL_PLL_480M_FREQ_MHZ / cpu_freq_mhz); // f_hp_root = 240MHz
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL); uint32_t cpu_divider = CLK_LL_PLL_240M_FREQ_MHZ / cpu_freq_mhz;
clk_ll_cpu_set_divider(cpu_divider);
// Constraint: f_ahb <= 48MHz; f_cpu = N * f_ahb (N = 1, 2, 3...)
// let f_ahb = 40MHz
const uint32_t ahb_divider = 6;
assert((cpu_divider <= ahb_divider) && (ahb_divider % cpu_divider == 0));
clk_ll_ahb_set_divider(ahb_divider);
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL_F240M);
clk_ll_bus_update();
esp_rom_set_cpu_ticks_per_us(cpu_freq_mhz);
}
/**
* Switch to PLL_F160M as cpu clock source.
* PLL must already be enabled.
* @param cpu_freq new CPU frequency
*/
static void rtc_clk_cpu_freq_to_pll_160_mhz(int cpu_freq_mhz)
{
// f_hp_root = 160MHz
uint32_t cpu_divider = CLK_LL_PLL_160M_FREQ_MHZ / cpu_freq_mhz;
clk_ll_cpu_set_divider(cpu_divider);
// Constraint: f_ahb <= 48MHz; f_cpu = N * f_ahb (N = 1, 2, 3...)
// let f_ahb = 40MHz
const uint32_t ahb_divider = 4;
assert((cpu_divider <= ahb_divider) && (ahb_divider % cpu_divider == 0));
clk_ll_ahb_set_divider(ahb_divider);
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL_F160M);
clk_ll_bus_update();
esp_rom_set_cpu_ticks_per_us(cpu_freq_mhz); esp_rom_set_cpu_ticks_per_us(cpu_freq_mhz);
} }
@ -219,7 +251,14 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *ou
uint32_t real_freq_mhz; uint32_t real_freq_mhz;
uint32_t xtal_freq = (uint32_t)rtc_clk_xtal_freq_get(); uint32_t xtal_freq = (uint32_t)rtc_clk_xtal_freq_get();
if (freq_mhz <= xtal_freq && freq_mhz != 0) { // To maintain APB_MAX (40MHz) while lowering CPU frequency when using a 48MHz XTAL, have to let CPU frequnecy be
// 40MHz with PLL_F160M or PLL_F240M clock source. This is a special case, has to handle separately.
if (xtal_freq == SOC_XTAL_FREQ_48M && freq_mhz == 40) {
real_freq_mhz = freq_mhz;
source = SOC_CPU_CLK_SRC_PLL_F160M;
source_freq_mhz = CLK_LL_PLL_160M_FREQ_MHZ;
divider = 4;
} else if (freq_mhz <= xtal_freq && freq_mhz != 0) {
divider = xtal_freq / freq_mhz; divider = xtal_freq / freq_mhz;
real_freq_mhz = (xtal_freq + divider / 2) / divider; /* round */ real_freq_mhz = (xtal_freq + divider / 2) / divider; /* round */
if (real_freq_mhz != freq_mhz) { if (real_freq_mhz != freq_mhz) {
@ -229,21 +268,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_freq_mhz = xtal_freq;
source = SOC_CPU_CLK_SRC_XTAL; source = SOC_CPU_CLK_SRC_XTAL;
} else if (freq_mhz == 80) { } else if (freq_mhz == 240) {
real_freq_mhz = freq_mhz; real_freq_mhz = freq_mhz;
source = SOC_CPU_CLK_SRC_PLL; source = SOC_CPU_CLK_SRC_PLL_F240M;
source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ; source_freq_mhz = CLK_LL_PLL_240M_FREQ_MHZ;
divider = 6; divider = 1;
} else if (freq_mhz == 120) {
real_freq_mhz = freq_mhz;
source = SOC_CPU_CLK_SRC_PLL;
source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ;
divider = 4;
} else if (freq_mhz == 160) { } else if (freq_mhz == 160) {
real_freq_mhz = freq_mhz; real_freq_mhz = freq_mhz;
source = SOC_CPU_CLK_SRC_PLL; source = SOC_CPU_CLK_SRC_PLL_F160M;
source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ; source_freq_mhz = CLK_LL_PLL_160M_FREQ_MHZ;
divider = 3; divider = 1;
} else if (freq_mhz == 80) {
real_freq_mhz = freq_mhz;
source = SOC_CPU_CLK_SRC_PLL_F160M;
source_freq_mhz = CLK_LL_PLL_160M_FREQ_MHZ;
divider = 2;
} else { } else {
// unsupported frequency // unsupported frequency
return false; return false;
@ -266,21 +305,29 @@ 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(); soc_cpu_clk_src_t old_cpu_clk_src = clk_ll_cpu_get_src();
if (config->source == SOC_CPU_CLK_SRC_XTAL) { if (config->source == SOC_CPU_CLK_SRC_XTAL) {
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div); 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) { if (((old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL_F160M) || (old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL_F240M)) && !s_bbpll_digi_consumers_ref_count) {
// We don't turn off the bbpll if some consumers depend on bbpll // We don't turn off the bbpll if some consumers depend on bbpll
rtc_clk_bbpll_disable(); rtc_clk_bbpll_disable();
} }
} else if (config->source == SOC_CPU_CLK_SRC_PLL) { } else if (config->source == SOC_CPU_CLK_SRC_PLL_F240M) {
if (old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL) { if (old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL_F240M && old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL_F160M) {
rtc_clk_set_cpu_switch_to_pll(SLEEP_EVENT_HW_PLL_EN_START); rtc_clk_set_cpu_switch_to_pll(SLEEP_EVENT_HW_PLL_EN_START);
rtc_clk_bbpll_enable(); rtc_clk_bbpll_enable();
rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), config->source_freq_mhz); rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), CLK_LL_PLL_480M_FREQ_MHZ);
} }
rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz); rtc_clk_cpu_freq_to_pll_240_mhz(config->freq_mhz);
rtc_clk_set_cpu_switch_to_pll(SLEEP_EVENT_HW_PLL_EN_STOP);
} else if (config->source == SOC_CPU_CLK_SRC_PLL_F160M) {
if (old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL_F240M && old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL_F160M) {
rtc_clk_set_cpu_switch_to_pll(SLEEP_EVENT_HW_PLL_EN_START);
rtc_clk_bbpll_enable();
rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), CLK_LL_PLL_480M_FREQ_MHZ);
}
rtc_clk_cpu_freq_to_pll_160_mhz(config->freq_mhz);
rtc_clk_set_cpu_switch_to_pll(SLEEP_EVENT_HW_PLL_EN_STOP); rtc_clk_set_cpu_switch_to_pll(SLEEP_EVENT_HW_PLL_EN_STOP);
} else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) { } else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) {
rtc_clk_cpu_freq_to_8m(); rtc_clk_cpu_freq_to_8m();
if ((old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL) && !s_bbpll_digi_consumers_ref_count) { if (((old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL_F160M) || (old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL_F240M)) && !s_bbpll_digi_consumers_ref_count) {
// We don't turn off the bbpll if some consumers depend on bbpll // We don't turn off the bbpll if some consumers depend on bbpll
rtc_clk_bbpll_disable(); rtc_clk_bbpll_disable();
} }
@ -292,17 +339,21 @@ 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(); soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
uint32_t source_freq_mhz; uint32_t source_freq_mhz;
uint32_t freq_mhz; uint32_t freq_mhz;
uint32_t div = clk_ll_cpu_get_ls_divider(); // div = freq of SOC_ROOT_CLK / freq of CPU_CLK uint32_t div = clk_ll_cpu_get_divider(); // div = freq of SOC_ROOT_CLK / freq of CPU_CLK
uint32_t hs_div = clk_ll_cpu_get_hs_divider();
switch (source) { switch (source) {
case SOC_CPU_CLK_SRC_XTAL: { case SOC_CPU_CLK_SRC_XTAL: {
source_freq_mhz = (uint32_t)rtc_clk_xtal_freq_get(); source_freq_mhz = (uint32_t)rtc_clk_xtal_freq_get();
freq_mhz = source_freq_mhz / div; freq_mhz = source_freq_mhz / div;
break; break;
} }
case SOC_CPU_CLK_SRC_PLL: { case SOC_CPU_CLK_SRC_PLL_F160M: {
source_freq_mhz = clk_ll_bbpll_get_freq_mhz(); source_freq_mhz = CLK_LL_PLL_160M_FREQ_MHZ;
freq_mhz = source_freq_mhz / hs_div; freq_mhz = source_freq_mhz / div;
break;
}
case SOC_CPU_CLK_SRC_PLL_F240M: {
source_freq_mhz = CLK_LL_PLL_240M_FREQ_MHZ;
freq_mhz = source_freq_mhz / div;
break; break;
} }
case SOC_CPU_CLK_SRC_RC_FAST: case SOC_CPU_CLK_SRC_RC_FAST:
@ -325,11 +376,12 @@ void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config)
{ {
if (config->source == SOC_CPU_CLK_SRC_XTAL) { if (config->source == SOC_CPU_CLK_SRC_XTAL) {
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div); rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
} else if ( } else if (config->source == SOC_CPU_CLK_SRC_PLL_F160M &&
config->source == SOC_CPU_CLK_SRC_PLL && s_cur_pll_freq == CLK_LL_PLL_480M_FREQ_MHZ) {
s_cur_pll_freq == config->source_freq_mhz rtc_clk_cpu_freq_to_pll_160_mhz(config->freq_mhz);
) { } else if (config->source == SOC_CPU_CLK_SRC_PLL_F240M &&
rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz); s_cur_pll_freq == CLK_LL_PLL_480M_FREQ_MHZ) {
rtc_clk_cpu_freq_to_pll_240_mhz(config->freq_mhz);
} else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) { } else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) {
rtc_clk_cpu_freq_to_8m(); rtc_clk_cpu_freq_to_8m();
} else { } else {
@ -356,7 +408,8 @@ void rtc_clk_cpu_set_to_default_config(void)
void rtc_clk_cpu_freq_to_pll_and_pll_lock_release(int cpu_freq_mhz) 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); // TODO: IDF-8641 CPU_MAX_FREQ don't know what to do... pll_240 or pll_160...
rtc_clk_cpu_freq_to_pll_240_mhz(cpu_freq_mhz);
clk_ll_cpu_clk_src_lock_release(); clk_ll_cpu_clk_src_lock_release();
} }
@ -375,15 +428,19 @@ static uint32_t rtc_clk_ahb_freq_get(void)
switch (source) { switch (source) {
case SOC_CPU_CLK_SRC_XTAL: case SOC_CPU_CLK_SRC_XTAL:
soc_root_freq_mhz = rtc_clk_xtal_freq_get(); soc_root_freq_mhz = rtc_clk_xtal_freq_get();
divider = clk_ll_ahb_get_ls_divider(); divider = clk_ll_ahb_get_divider();
break; break;
case SOC_CPU_CLK_SRC_PLL: case SOC_CPU_CLK_SRC_PLL_F160M:
soc_root_freq_mhz = clk_ll_bbpll_get_freq_mhz(); soc_root_freq_mhz = CLK_LL_PLL_160M_FREQ_MHZ;
divider = clk_ll_ahb_get_hs_divider(); divider = clk_ll_ahb_get_divider();
break;
case SOC_CPU_CLK_SRC_PLL_F240M:
soc_root_freq_mhz = CLK_LL_PLL_240M_FREQ_MHZ;
divider = clk_ll_ahb_get_divider();
break; break;
case SOC_CPU_CLK_SRC_RC_FAST: case SOC_CPU_CLK_SRC_RC_FAST:
soc_root_freq_mhz = 20; soc_root_freq_mhz = 20;
divider = clk_ll_ahb_get_ls_divider(); divider = clk_ll_ahb_get_divider();
break; break;
default: default:
// Unknown SOC_ROOT clock source // Unknown SOC_ROOT clock source

View File

@ -79,10 +79,14 @@ void rtc_clk_init(rtc_clk_config_t cfg)
REG_SET_FIELD(LP_CLKRST_RC32K_CNTL_REG, LP_CLKRST_RC32K_DFREQ, cfg.rc32k_dfreq); 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_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_ENIF_DIG_DREG, 1);
REG_SET_FIELD(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, HP_CALI_DBIAS); REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_RTC_REG, 0);
REG_SET_FIELD(PMU_HP_SLEEP_LP_REGULATOR0_REG, PMU_HP_SLEEP_LP_REGULATOR_DBIAS, LP_CALI_DBIAS); REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_DIG_REG, 0);
uint32_t hp_cali_dbias = get_act_hp_dbias();
uint32_t lp_cali_dbias = get_act_lp_dbias();
clk_ll_rc_fast_tick_conf(); // TODO: IDF-8642 Unnecessary or not? SET_PERI_REG_BITS(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, hp_cali_dbias, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS_S);
SET_PERI_REG_BITS(PMU_HP_MODEM_HP_REGULATOR0_REG, PMU_HP_MODEM_HP_REGULATOR_DBIAS, hp_cali_dbias, PMU_HP_MODEM_HP_REGULATOR_DBIAS_S);
SET_PERI_REG_BITS(PMU_HP_SLEEP_LP_REGULATOR0_REG, PMU_HP_SLEEP_LP_REGULATOR_DBIAS, lp_cali_dbias, PMU_HP_SLEEP_LP_REGULATOR_DBIAS_S);
// XTAL freq determined by efuse, and can be directly informed from register field PCR_CLK_XTAL_FREQ // XTAL freq determined by efuse, and can be directly informed from register field PCR_CLK_XTAL_FREQ

View File

@ -12,6 +12,7 @@
#include "hal/clk_tree_ll.h" #include "hal/clk_tree_ll.h"
#include "hal/timer_ll.h" #include "hal/timer_ll.h"
#include "soc/timer_group_reg.h" #include "soc/timer_group_reg.h"
#include "soc/pcr_reg.h"
#include "esp_rom_sys.h" #include "esp_rom_sys.h"
#include "assert.h" #include "assert.h"
#include "hal/efuse_hal.h" #include "hal/efuse_hal.h"
@ -23,64 +24,31 @@ __attribute__((unused)) static const char *TAG = "rtc_time";
/* Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0. /* 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 * This feature counts the number of XTAL clock cycles within a given number of
* RTC_SLOW_CLK cycles. * RTC_SLOW_CLK cycles.
*
* Slow clock calibration feature has two modes of operation: one-off and cycling.
* In cycling mode (which is enabled by default on SoC reset), counting of XTAL
* cycles within RTC_SLOW_CLK cycle is done continuously. Cycling mode is enabled
* using TIMG_RTC_CALI_START_CYCLING bit. In one-off mode counting is performed
* once, and TIMG_RTC_CALI_RDY bit is set when counting is done. One-off mode is
* enabled using TIMG_RTC_CALI_START bit.
*/ */
/* On ESP32C5, TIMG_RTC_CALI_CLK_SEL can config to 0, 1, 2, 3 #define CLK_CAL_TIMEOUT_THRES(cal_clk, cycles) ((cal_clk == RTC_CAL_RC32K || cal_clk == RTC_CAL_32K_XTAL || cal_clk == RTC_CAL_32K_OSC_SLOW) ? (cycles << 12) : (cycles << 10))
* 0 or 3: calibrate RC_SLOW clock
* 1: calibrate RC_FAST clock
* 2: calibrate 32K clock, which 32k depends on reg_32k_sel: 0: Internal 32 kHz RC oscillator, 1: External 32 kHz XTAL, 2: External 32kHz clock input by lp_pad_gpio0
*/
#define TIMG_RTC_CALI_CLK_SEL_RC_SLOW 0
#define TIMG_RTC_CALI_CLK_SEL_RC_FAST 1
#define TIMG_RTC_CALI_CLK_SEL_32K 2
/**
* @brief Clock calibration function used by rtc_clk_cal
*
* 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) static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
{ {
assert(slowclk_cycles < TIMG_RTC_CALI_MAX_V); assert(slowclk_cycles < TIMG_RTC_CALI_MAX_V);
uint32_t cali_clk_sel = 0;
soc_rtc_slow_clk_src_t slow_clk_src = rtc_clk_slow_src_get();
soc_rtc_slow_clk_src_t old_32k_cal_clk_sel = clk_ll_32k_calibration_get_target();
if (cal_clk == RTC_CAL_RTC_MUX) { if (cal_clk == RTC_CAL_RTC_MUX) {
cal_clk = (rtc_cal_sel_t)slow_clk_src; soc_rtc_slow_clk_src_t slow_clk_src = rtc_clk_slow_src_get();
if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) {
cal_clk = RTC_CAL_RC_SLOW;
} else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
cal_clk = RTC_CAL_32K_XTAL;
} else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) {
cal_clk = RTC_CAL_RC32K;
} else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) {
cal_clk = RTC_CAL_32K_OSC_SLOW;
}
} }
// TODO: [ESP32C5] IDF-8642 Seems RC_SLOW, RC_FAST can't be calibrated on beta3 if (cal_clk < 0 || cal_clk >= RTC_CAL_INVALID_CLK) {
// if (cal_clk == RTC_CAL_RC_FAST) { ESP_EARLY_LOGE(TAG, "clock not supported to be calibrated");
// cali_clk_sel = TIMG_RTC_CALI_CLK_SEL_RC_FAST; return 0;
// } else if (cal_clk == RTC_CAL_RC_SLOW) {
// cali_clk_sel = TIMG_RTC_CALI_CLK_SEL_RC_SLOW;
// } else
{
cali_clk_sel = TIMG_RTC_CALI_CLK_SEL_32K;
clk_ll_32k_calibration_set_target((soc_rtc_slow_clk_src_t)cal_clk);
} }
/* Enable requested clock (150k clock is always on) */ /* Enable requested clock (150k clock is always on) */
// All clocks on/off takes time to be stable, so we shouldn't frequently enable/disable the clock // All clocks on/off takes time to be stable, so we shouldn't frequently enable/disable the clock
// Only enable if originally was disabled, and set back to the disable state after calibration is done // Only enable if originally was disabled, and set back to the disable state after calibration is done
@ -90,16 +58,16 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
clk_ll_xtal32k_digi_enable(); clk_ll_xtal32k_digi_enable();
} }
// bool rc_fast_enabled = clk_ll_rc_fast_is_enabled(); bool rc_fast_enabled = clk_ll_rc_fast_is_enabled();
// bool dig_rc_fast_enabled = clk_ll_rc_fast_digi_is_enabled(); bool dig_rc_fast_enabled = clk_ll_rc_fast_digi_is_enabled();
// if (cal_clk == RTC_CAL_RC_FAST) { if (cal_clk == RTC_CAL_RC_FAST) {
// if (!rc_fast_enabled) { if (!rc_fast_enabled) {
// rtc_clk_8m_enable(true); rtc_clk_8m_enable(true);
// } }
// if (!dig_rc_fast_enabled) { if (!dig_rc_fast_enabled) {
// rtc_dig_clk8m_enable(); rtc_dig_clk8m_enable();
// } }
// } }
bool rc32k_enabled = clk_ll_rc32k_is_enabled(); bool rc32k_enabled = clk_ll_rc32k_is_enabled();
bool dig_rc32k_enabled = clk_ll_rc32k_digi_is_enabled(); bool dig_rc32k_enabled = clk_ll_rc32k_digi_is_enabled();
@ -126,22 +94,22 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
} }
/* Prepare calibration */ /* Prepare calibration */
// calibration clock source is set by PCR register: PCR_32K_SEL REG_SET_FIELD(PCR_CTRL_32K_CONF_REG, PCR_32K_SEL, cal_clk);
// REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cali_clk_sel); if (cal_clk == RTC_CAL_RC_FAST) {
clk_ll_rc_fast_tick_conf();
}
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING); CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING);
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles); REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles);
/* Figure out how long to wait for calibration to finish */ /* Figure out how long to wait for calibration to finish */
/* Set timeout reg and expect time delay*/ /* Set timeout reg and expect time delay*/
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, CLK_CAL_TIMEOUT_THRES(cal_clk, slowclk_cycles));
uint32_t expected_freq; uint32_t expected_freq;
if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_32K) { if (cal_clk == RTC_CAL_RC32K || cal_clk == RTC_CAL_32K_XTAL || cal_clk == RTC_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; expected_freq = SOC_CLK_XTAL32K_FREQ_APPROX;
} else if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_RC_FAST) { } else if (cal_clk == RTC_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 >> CLK_LL_RC_FAST_TICK_DIV_BITS;
expected_freq = SOC_CLK_RC_FAST_FREQ_APPROX;
} else { } else {
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_150K_CAL_TIMEOUT_THRES(slowclk_cycles));
expected_freq = SOC_CLK_RC_SLOW_FREQ_APPROX; expected_freq = SOC_CLK_RC_SLOW_FREQ_APPROX;
} }
uint32_t us_time_estimate = (uint32_t) (((uint64_t) slowclk_cycles) * MHZ / expected_freq); uint32_t us_time_estimate = (uint32_t) (((uint64_t) slowclk_cycles) * MHZ / expected_freq);
@ -156,12 +124,11 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
if (GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY)) { 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); cal_val = REG_GET_FIELD(TIMG_RTCCALICFG1_REG(0), TIMG_RTC_CALI_VALUE);
// TODO: IDF-8642 Check whether this workaround still need for C5 /*The Fosc CLK of calibration circuit is divided by a factor, k.
// /*The Fosc CLK of calibration circuit is divided by 32. So we need to multiply the frequency of the FOSC by k times.*/
// So we need to multiply the frequency of the FOSC by 32 times.*/ if (cal_clk == RTC_CAL_RC_FAST) {
// if (cal_clk == RTC_CAL_RC_FAST) { cal_val = cal_val >> CLK_LL_RC_FAST_TICK_DIV_BITS;
// cal_val = cal_val >> 5; }
// }
break; break;
} }
if (GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT)) { if (GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT)) {
@ -176,14 +143,14 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
clk_ll_xtal32k_digi_disable(); clk_ll_xtal32k_digi_disable();
} }
// if (cal_clk == RTC_CAL_RC_FAST) { if (cal_clk == RTC_CAL_RC_FAST) {
// if (!dig_rc_fast_enabled) { if (!dig_rc_fast_enabled) {
// rtc_dig_clk8m_disable(); rtc_dig_clk8m_disable();
// } }
// if (!rc_fast_enabled) { if (!rc_fast_enabled) {
// rtc_clk_8m_enable(false); rtc_clk_8m_enable(false);
// } }
// } }
if (cal_clk == RTC_CAL_RC32K) { if (cal_clk == RTC_CAL_RC32K) {
if (!dig_rc32k_enabled) { if (!dig_rc32k_enabled) {
@ -194,11 +161,6 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
} }
} }
// Always set back the calibration 32kHz clock selection
if (old_32k_cal_clk_sel != SOC_RTC_SLOW_CLK_SRC_INVALID) {
clk_ll_32k_calibration_set_target(old_32k_cal_clk_sel);
}
return cal_val; return cal_val;
} }
@ -212,13 +174,13 @@ static bool rtc_clk_cal_32k_valid(uint32_t xtal_freq, uint32_t slowclk_cycles, u
uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
{ {
soc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get(); soc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get();
// TODO: IDF-8642 Check whether this workaround still need for C5
// /*The Fosc CLK of calibration circuit is divided by 32. /*The Fosc CLK of calibration circuit is divided by a factor, k.
// So we need to divide the calibrate cycles of the FOSC by 32 to So we need to divide the calibrate cycles of the FOSC by k to
// avoid excessive calibration time.*/ avoid excessive calibration time.*/
// if (cal_clk == RTC_CAL_RC_FAST) { if (cal_clk == RTC_CAL_RC_FAST) {
// slowclk_cycles = slowclk_cycles >> 5; slowclk_cycles = slowclk_cycles >> CLK_LL_RC_FAST_TICK_DIV_BITS;
// } }
uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles); uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles);
if (cal_clk == RTC_CAL_32K_XTAL && !rtc_clk_cal_32k_valid((uint32_t)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)) {
@ -246,8 +208,7 @@ uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period)
uint64_t rtc_time_get(void) uint64_t rtc_time_get(void)
{ {
ESP_EARLY_LOGW(TAG, "rtc_timer has not been implemented yet"); return lp_timer_hal_get_cycle_count();
return 0;
} }
uint32_t rtc_clk_freq_cal(uint32_t cal_val) uint32_t rtc_clk_freq_cal(uint32_t cal_val)

View File

@ -84,8 +84,6 @@ void rtc_clk_init(rtc_clk_config_t cfg)
SET_PERI_REG_BITS(PMU_HP_MODEM_HP_REGULATOR0_REG, PMU_HP_MODEM_HP_REGULATOR_DBIAS, hp_cali_dbias, PMU_HP_MODEM_HP_REGULATOR_DBIAS_S); SET_PERI_REG_BITS(PMU_HP_MODEM_HP_REGULATOR0_REG, PMU_HP_MODEM_HP_REGULATOR_DBIAS, hp_cali_dbias, PMU_HP_MODEM_HP_REGULATOR_DBIAS_S);
SET_PERI_REG_BITS(PMU_HP_SLEEP_LP_REGULATOR0_REG, PMU_HP_SLEEP_LP_REGULATOR_DBIAS, lp_cali_dbias, PMU_HP_SLEEP_LP_REGULATOR_DBIAS_S); SET_PERI_REG_BITS(PMU_HP_SLEEP_LP_REGULATOR0_REG, PMU_HP_SLEEP_LP_REGULATOR_DBIAS, lp_cali_dbias, PMU_HP_SLEEP_LP_REGULATOR_DBIAS_S);
clk_ll_rc_fast_tick_conf();
soc_xtal_freq_t xtal_freq = cfg.xtal_freq; soc_xtal_freq_t xtal_freq = cfg.xtal_freq;
esp_rom_output_tx_wait_idle(0); esp_rom_output_tx_wait_idle(0);
rtc_clk_xtal_freq_update(xtal_freq); rtc_clk_xtal_freq_update(xtal_freq);

View File

@ -125,6 +125,9 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
/* Prepare calibration */ /* Prepare calibration */
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cali_clk_sel); REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cali_clk_sel);
if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_RC_FAST) {
clk_ll_rc_fast_tick_conf();
}
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING); CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING);
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles); REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles);
/* Figure out how long to wait for calibration to finish */ /* Figure out how long to wait for calibration to finish */
@ -137,6 +140,9 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
} else if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_RC_FAST) { } else if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_RC_FAST) {
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_FAST_CLK_20M_CAL_TIMEOUT_THRES(slowclk_cycles)); REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_FAST_CLK_20M_CAL_TIMEOUT_THRES(slowclk_cycles));
expected_freq = SOC_CLK_RC_FAST_FREQ_APPROX; expected_freq = SOC_CLK_RC_FAST_FREQ_APPROX;
if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) {
expected_freq = expected_freq >> CLK_LL_RC_FAST_TICK_DIV_BITS;
}
} else { } 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_150K_CAL_TIMEOUT_THRES(slowclk_cycles));
expected_freq = SOC_CLK_RC_SLOW_FREQ_APPROX; expected_freq = SOC_CLK_RC_SLOW_FREQ_APPROX;
@ -160,7 +166,7 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
calibration. */ calibration. */
if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) { if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) {
if (cal_clk == RTC_CAL_RC_FAST) { if (cal_clk == RTC_CAL_RC_FAST) {
cal_val = cal_val >> 5; cal_val = cal_val >> CLK_LL_RC_FAST_TICK_DIV_BITS;
CLEAR_PERI_REG_MASK(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE); CLEAR_PERI_REG_MASK(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE);
} }
} }
@ -221,7 +227,7 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
avoid excessive calibration time.*/ avoid excessive calibration time.*/
if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) { if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) {
if (cal_clk == RTC_CAL_RC_FAST) { if (cal_clk == RTC_CAL_RC_FAST) {
slowclk_cycles = slowclk_cycles >> 5; slowclk_cycles = slowclk_cycles >> CLK_LL_RC_FAST_TICK_DIV_BITS;
SET_PERI_REG_MASK(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE); SET_PERI_REG_MASK(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE);
} }
} }

View File

@ -52,8 +52,6 @@ void rtc_clk_init(rtc_clk_config_t cfg)
SET_PERI_REG_BITS(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, hp_cali_dbias, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS_S); SET_PERI_REG_BITS(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, hp_cali_dbias, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS_S);
SET_PERI_REG_BITS(PMU_HP_SLEEP_LP_REGULATOR0_REG, PMU_HP_SLEEP_LP_REGULATOR_DBIAS, lp_cali_dbias, PMU_HP_SLEEP_LP_REGULATOR_DBIAS_S); SET_PERI_REG_BITS(PMU_HP_SLEEP_LP_REGULATOR0_REG, PMU_HP_SLEEP_LP_REGULATOR_DBIAS, lp_cali_dbias, PMU_HP_SLEEP_LP_REGULATOR_DBIAS_S);
clk_ll_rc_fast_tick_conf();
soc_xtal_freq_t xtal_freq = cfg.xtal_freq; soc_xtal_freq_t xtal_freq = cfg.xtal_freq;
esp_rom_output_tx_wait_idle(0); esp_rom_output_tx_wait_idle(0);
rtc_clk_xtal_freq_update(xtal_freq); rtc_clk_xtal_freq_update(xtal_freq);

View File

@ -125,6 +125,9 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
/* Prepare calibration */ /* Prepare calibration */
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cali_clk_sel); REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cali_clk_sel);
if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_RC_FAST) {
clk_ll_rc_fast_tick_conf();
}
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING); CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING);
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles); REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles);
/* Figure out how long to wait for calibration to finish */ /* Figure out how long to wait for calibration to finish */
@ -137,6 +140,9 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
} else if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_RC_FAST) { } else if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_RC_FAST) {
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_FAST_CLK_8M_CAL_TIMEOUT_THRES(slowclk_cycles)); REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_FAST_CLK_8M_CAL_TIMEOUT_THRES(slowclk_cycles));
expected_freq = SOC_CLK_RC_FAST_FREQ_APPROX; expected_freq = SOC_CLK_RC_FAST_FREQ_APPROX;
if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 2)) {
expected_freq = expected_freq >> CLK_LL_RC_FAST_TICK_DIV_BITS;
}
} else { } 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_150K_CAL_TIMEOUT_THRES(slowclk_cycles));
expected_freq = SOC_CLK_RC_SLOW_FREQ_APPROX; expected_freq = SOC_CLK_RC_SLOW_FREQ_APPROX;
@ -160,7 +166,7 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
calibration. */ calibration. */
if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 2)) { if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 2)) {
if (cal_clk == RTC_CAL_RC_FAST) { if (cal_clk == RTC_CAL_RC_FAST) {
cal_val = cal_val >> 5; cal_val = cal_val >> CLK_LL_RC_FAST_TICK_DIV_BITS;
CLEAR_PERI_REG_MASK(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE); CLEAR_PERI_REG_MASK(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE);
} }
} }
@ -221,7 +227,7 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
avoid excessive calibration time.*/ avoid excessive calibration time.*/
if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 2)) { if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 2)) {
if (cal_clk == RTC_CAL_RC_FAST) { if (cal_clk == RTC_CAL_RC_FAST) {
slowclk_cycles = slowclk_cycles >> 5; slowclk_cycles = slowclk_cycles >> CLK_LL_RC_FAST_TICK_DIV_BITS;
SET_PERI_REG_MASK(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE); SET_PERI_REG_MASK(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE);
} }
} }

View File

@ -41,6 +41,9 @@ static esp_clk_tree_calibrated_freq_t s_calibrated_freq = {};
#define DEFAULT_32K_CLK_CAL_CYCLES 100 #define DEFAULT_32K_CLK_CAL_CYCLES 100
/* Number of cycles for RC_FAST calibration */ /* Number of cycles for RC_FAST calibration */
#define DEFAULT_RC_FAST_CAL_CYCLES 10000 // RC_FAST has a higher frequency, therefore, requires more cycles to get an accurate value #define DEFAULT_RC_FAST_CAL_CYCLES 10000 // RC_FAST has a higher frequency, therefore, requires more cycles to get an accurate value
// Usually we calibrate on the divider of the RC_FAST clock, the cal_cycles is divided by
// the divider factor internally in rtc_clk_cal, so the time to spend on calibrating RC_FAST
// is always (10000 / f_rc_fast)
/** /**
@ -187,6 +190,10 @@ uint32_t esp_clk_tree_lp_fast_get_freq_hz(esp_clk_tree_src_freq_precision_t prec
#if SOC_CLK_LP_FAST_SUPPORT_LP_PLL #if SOC_CLK_LP_FAST_SUPPORT_LP_PLL
case SOC_RTC_FAST_CLK_SRC_LP_PLL: case SOC_RTC_FAST_CLK_SRC_LP_PLL:
return clk_ll_lp_pll_get_freq_mhz() * MHZ; return clk_ll_lp_pll_get_freq_mhz() * MHZ;
#endif
#if SOC_CLK_LP_FAST_SUPPORT_XTAL
case SOC_RTC_FAST_CLK_SRC_XTAL:
return clk_hal_xtal_get_freq_mhz() * MHZ;
#endif #endif
default: default:
// Invalid clock source // Invalid clock source

View File

@ -7,7 +7,6 @@
#include "esp_attr.h" #include "esp_attr.h"
#include "soc/i2c_ana_mst_reg.h" #include "soc/i2c_ana_mst_reg.h"
#include "modem/modem_lpcon_reg.h" #include "modem/modem_lpcon_reg.h"
#include "soc/pmu_reg.h"
#define REGI2C_BIAS_MST_SEL (BIT(8)) #define REGI2C_BIAS_MST_SEL (BIT(8))
#define REGI2C_BBPLL_MST_SEL (BIT(9)) #define REGI2C_BBPLL_MST_SEL (BIT(9))
@ -77,8 +76,6 @@ static IRAM_ATTR uint8_t regi2c_enable_block(uint8_t block)
uint32_t i2c_sel = 0; uint32_t i2c_sel = 0;
REG_SET_BIT(MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN); REG_SET_BIT(MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN);
REG_SET_BIT(PMU_RF_PWC_REG, PMU_PERIF_I2C_RSTB); // TODO: IDF-8642 Move to pmu_init()
REG_SET_BIT(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C); // TODO: IDF-8642 Move to pmu_init()
/* Before config I2C register, enable corresponding slave. */ /* Before config I2C register, enable corresponding slave. */
switch (block) { switch (block) {

View File

@ -30,7 +30,6 @@
#include "esp_private/esp_pmu.h" #include "esp_private/esp_pmu.h"
#include "esp_rom_uart.h" #include "esp_rom_uart.h"
#include "esp_rom_sys.h" #include "esp_rom_sys.h"
#include "ocode_init.h"
/* Number of cycles to wait from the 32k XTAL oscillator to consider it running. /* 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 * Larger values increase startup delay. Smaller values may cause false positive
@ -44,20 +43,13 @@ static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src);
static const char *TAG = "clk"; static const char *TAG = "clk";
// TODO: [ESP32C5] IDF-8642
void esp_rtc_init(void) void esp_rtc_init(void)
{ {
#if !CONFIG_IDF_ENV_FPGA #if !CONFIG_IDF_ENV_FPGA
#if SOC_PMU_SUPPORTED
pmu_init(); pmu_init();
#endif
if (esp_rom_get_reset_reason(0) == RESET_REASON_CHIP_POWER_ON) {
esp_ocode_calib_init();
}
#endif #endif
} }
// TODO: [ESP32C5] IDF-8642
__attribute__((weak)) void esp_clk_init(void) __attribute__((weak)) void esp_clk_init(void)
{ {
#if !CONFIG_IDF_ENV_FPGA #if !CONFIG_IDF_ENV_FPGA
@ -122,7 +114,7 @@ __attribute__((weak)) void esp_clk_init(void)
// Re calculate the ccount to make time calculation correct. // Re calculate the ccount to make time calculation correct.
esp_cpu_set_cycle_count((uint64_t)esp_cpu_get_cycle_count() * new_freq_mhz / old_freq_mhz); esp_cpu_set_cycle_count((uint64_t)esp_cpu_get_cycle_count() * new_freq_mhz / old_freq_mhz);
// Set crypto clock (`clk_sec`) to use 160M SPLL clock // Set crypto clock (`clk_sec`) to use 480M SPLL clock
REG_SET_FIELD(PCR_SEC_CONF_REG, PCR_SEC_CLK_SEL, 0x2); REG_SET_FIELD(PCR_SEC_CONF_REG, PCR_SEC_CLK_SEL, 0x2);
} }
@ -195,7 +187,8 @@ void rtc_clk_select_rtc_slow_clk(void)
*/ */
__attribute__((weak)) void esp_perip_clk_init(void) __attribute__((weak)) void esp_perip_clk_init(void)
{ {
// TODO: [ESP32C5] IDF-8844 // TODO: [ESP32C5] IDF-8844
#if SOC_MODEM_CLOCK_SUPPORTED
// modem_clock_domain_pmu_state_icg_map_init(); // modem_clock_domain_pmu_state_icg_map_init();
/* During system initialization, the low-power clock source of the modem /* During system initialization, the low-power clock source of the modem
* (WiFi, BLE or Coexist) follows the configuration of the slow clock source * (WiFi, BLE or Coexist) follows the configuration of the slow clock source
@ -211,6 +204,7 @@ __attribute__((weak)) void esp_perip_clk_init(void)
: (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) ? MODEM_CLOCK_LPCLK_SRC_EXT32K : (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) ? MODEM_CLOCK_LPCLK_SRC_EXT32K
: MODEM_CLOCK_LPCLK_SRC_RC32K); : MODEM_CLOCK_LPCLK_SRC_RC32K);
modem_clock_select_lp_clock_source(PERIPH_WIFI_MODULE, modem_lpclk_src, 0); modem_clock_select_lp_clock_source(PERIPH_WIFI_MODULE, modem_lpclk_src, 0);
#endif
ESP_EARLY_LOGW(TAG, "esp_perip_clk_init() has not been implemented yet"); ESP_EARLY_LOGW(TAG, "esp_perip_clk_init() has not been implemented yet");
#if 0 // TODO: [ESP32C5] IDF-8844 #if 0 // TODO: [ESP32C5] IDF-8844

View File

@ -3,8 +3,9 @@ menu "Serial flasher config"
config ESPTOOLPY_NO_STUB config ESPTOOLPY_NO_STUB
bool "Disable download stub" bool "Disable download stub"
default "y" if IDF_ENV_FPGA || IDF_ENV_BRINGUP default y if IDF_ENV_FPGA || IDF_ENV_BRINGUP
default "n" default y if IDF_TARGET_ESP32C5 # TODO: IDF-8631 to be removed
default n
help help
The flasher tool sends a precompiled download stub first by default. That stub allows things The flasher tool sends a precompiled download stub first by default. That stub allows things

View File

@ -56,7 +56,7 @@ if(NOT BOOTLOADER_BUILD)
endif() endif()
endif() endif()
if(CONFIG_SOC_CLK_TREE_SUPPORTED OR CONFIG_IDF_TARGET_ESP32C5) # TODO: IDF-8642 if(CONFIG_SOC_CLK_TREE_SUPPORTED)
list(APPEND srcs "${target}/clk_tree_hal.c") list(APPEND srcs "${target}/clk_tree_hal.c")
endif() endif()

View File

@ -17,8 +17,10 @@ uint32_t clk_hal_soc_root_get_freq_mhz(soc_cpu_clk_src_t cpu_clk_src)
switch (cpu_clk_src) { switch (cpu_clk_src) {
case SOC_CPU_CLK_SRC_XTAL: case SOC_CPU_CLK_SRC_XTAL:
return clk_hal_xtal_get_freq_mhz(); return clk_hal_xtal_get_freq_mhz();
case SOC_CPU_CLK_SRC_PLL: case SOC_CPU_CLK_SRC_PLL_F160M:
return clk_ll_bbpll_get_freq_mhz(); return CLK_LL_PLL_160M_FREQ_MHZ;
case SOC_CPU_CLK_SRC_PLL_F240M:
return CLK_LL_PLL_240M_FREQ_MHZ;
case SOC_CPU_CLK_SRC_RC_FAST: case SOC_CPU_CLK_SRC_RC_FAST:
return SOC_CLK_RC_FAST_FREQ_APPROX / MHZ; return SOC_CLK_RC_FAST_FREQ_APPROX / MHZ;
default: default:
@ -31,16 +33,14 @@ 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) uint32_t clk_hal_cpu_get_freq_hz(void)
{ {
soc_cpu_clk_src_t source = clk_ll_cpu_get_src(); 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(); uint32_t divider = clk_ll_cpu_get_divider();
return clk_hal_soc_root_get_freq_mhz(source) * MHZ / divider; return clk_hal_soc_root_get_freq_mhz(source) * MHZ / divider;
} }
uint32_t clk_hal_ahb_get_freq_hz(void) uint32_t clk_hal_ahb_get_freq_hz(void)
{ {
soc_cpu_clk_src_t source = clk_ll_cpu_get_src(); 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(); uint32_t divider = clk_ll_ahb_get_divider();
return clk_hal_soc_root_get_freq_mhz(source) * MHZ / divider; return clk_hal_soc_root_get_freq_mhz(source) * MHZ / divider;
} }

View File

@ -40,12 +40,8 @@ extern "C" {
.dbuf = 1, \ .dbuf = 1, \
} }
/* // Fix default division factor for the RC_FAST clock for calibration to be 32
Set the frequency division factor of ref_tick #define CLK_LL_RC_FAST_TICK_DIV_BITS 5
The FOSC of rtc calibration uses the 32 frequency division clock,
So the frequency division factor of ref_tick must be greater than or equal to 32
*/
#define REG_FOSC_TICK_NUM 255 // TODO: IDF-8642 No need? Can calibrate on RC_FAST directly?
/** /**
* @brief XTAL32K_CLK enable modes * @brief XTAL32K_CLK enable modes
@ -289,7 +285,7 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_bbpll_get_freq_mhz(
} }
/** /**
* @brief Set BBPLL frequency from XTAL source (Digital part) * @brief Set SPLL frequency from XTAL source (Digital part)
* *
* @param pll_freq_mhz PLL frequency, in MHz * @param pll_freq_mhz PLL frequency, in MHz
*/ */
@ -301,7 +297,7 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_set_freq_mhz(uint
} }
/** /**
* @brief Set BBPLL frequency from XTAL source (Analog part) * @brief Set SPLL frequency from XTAL source (Analog part)
* *
* @param pll_freq_mhz PLL frequency, in MHz * @param pll_freq_mhz PLL frequency, in MHz
* @param xtal_freq_mhz XTAL frequency, in MHz * @param xtal_freq_mhz XTAL frequency, in MHz
@ -313,36 +309,52 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_set_config(uint32
uint8_t div7_0; uint8_t div7_0;
uint8_t dr1; uint8_t dr1;
uint8_t dr3; uint8_t dr3;
uint8_t dchgp; uint8_t dchgp = 5;
uint8_t dbias; uint8_t dbias = 3;
uint8_t dcur; uint8_t href = 3;
uint8_t lref = 1;
/* Configure 480M PLL */ /* Configure 480M PLL */
switch (xtal_freq_mhz) { switch (xtal_freq_mhz) {
case SOC_XTAL_FREQ_48M:
div_ref = 1;
div7_0 = 10;
dr1 = 1;
dr3 = 1;
break;
case SOC_XTAL_FREQ_40M: case SOC_XTAL_FREQ_40M:
default: div_ref = 1;
div_ref = 0; div7_0 = 12;
div7_0 = 8; dr1 = 0;
dr3 = 0;
break;
default:
div_ref = 1;
div7_0 = 12;
dr1 = 0; dr1 = 0;
dr3 = 0; dr3 = 0;
dchgp = 5;
dcur = 3;
dbias = 2;
break; break;
} }
uint8_t i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref); 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_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_REF_DIV, i2c_bbpll_lref);
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0); 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_DR1, dr1);
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR3, dr3); 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_DLREF_SEL, lref);
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DHREF_SEL, href);
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_VCO_DBIAS, dbias); REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_VCO_DBIAS, dbias);
} }
/**
* @brief To enable the change of soc_clk_sel, cpu_div_num, and ahb_div_num
*/
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);
}
/** /**
* @brief Select the clock source for CPU_CLK (SOC Clock Root) * @brief Select the clock source for CPU_CLK (SOC Clock Root)
* *
@ -354,12 +366,15 @@ static inline __attribute__((always_inline)) void clk_ll_cpu_set_src(soc_cpu_clk
case SOC_CPU_CLK_SRC_XTAL: case SOC_CPU_CLK_SRC_XTAL:
PCR.sysclk_conf.soc_clk_sel = 0; PCR.sysclk_conf.soc_clk_sel = 0;
break; break;
case SOC_CPU_CLK_SRC_PLL: case SOC_CPU_CLK_SRC_RC_FAST:
PCR.sysclk_conf.soc_clk_sel = 1; PCR.sysclk_conf.soc_clk_sel = 1;
break; break;
case SOC_CPU_CLK_SRC_RC_FAST: case SOC_CPU_CLK_SRC_PLL_F160M:
PCR.sysclk_conf.soc_clk_sel = 2; PCR.sysclk_conf.soc_clk_sel = 2;
break; break;
case SOC_CPU_CLK_SRC_PLL_F240M:
PCR.sysclk_conf.soc_clk_sel = 3;
break;
default: default:
// Unsupported SOC_CLK mux input sel // Unsupported SOC_CLK mux input sel
abort(); abort();
@ -378,9 +393,11 @@ static inline __attribute__((always_inline)) soc_cpu_clk_src_t clk_ll_cpu_get_sr
case 0: case 0:
return SOC_CPU_CLK_SRC_XTAL; return SOC_CPU_CLK_SRC_XTAL;
case 1: case 1:
return SOC_CPU_CLK_SRC_PLL;
case 2:
return SOC_CPU_CLK_SRC_RC_FAST; return SOC_CPU_CLK_SRC_RC_FAST;
case 2:
return SOC_CPU_CLK_SRC_PLL_F160M;
case 3:
return SOC_CPU_CLK_SRC_PLL_F240M;
default: default:
// Invalid SOC_CLK_SEL value // Invalid SOC_CLK_SEL value
return SOC_CPU_CLK_SRC_INVALID; return SOC_CPU_CLK_SRC_INVALID;
@ -388,129 +405,47 @@ 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's divider
* *
* @param divider Divider. (PCR_HS_DIV_NUM + 1) * (PCR_CPU_HS_DIV_NUM + 1) = divider. * @param divider Divider. (PCR_CPU_DIV_NUM + 1) = divider.
*/ */
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 HAL_ASSERT(divider >= 1);
// (1) not configurable for the target (HRO register field: PCR_HS_DIV_NUM) HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.cpu_freq_conf, cpu_div_num, (divider) - 1);
// 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) * @brief Get CPU_CLK's divider
* *
* @param divider Divider. (PCR_LS_DIV_NUM + 1) * (PCR_CPU_LS_DIV_NUM + 1) = divider. * @return Divider. Divider = (PCR_CPU_DIV_NUM + 1).
*/ */
static inline __attribute__((always_inline)) void clk_ll_cpu_set_ls_divider(uint32_t divider) static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_divider(void)
{ {
// SOC_ROOT_CLK ---(1)---> HP_ROOT_CLK ---(2)---> CPU_CLK return HAL_FORCE_READ_U32_REG_FIELD(PCR.cpu_freq_conf, cpu_div_num) + 1;
// (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));
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.cpu_freq_conf, cpu_div_num, divider - 1);
} }
/** /**
* @brief Get CPU_CLK's high-speed divider * @brief Set AHB_CLK's divider
* *
* @return Divider. Divider = (PCR_HS_DIV_NUM + 1) * (PCR_CPU_HS_DIV_NUM + 1). * Constraint: f_ahb <= 48 MHz, f_cpu = n * f_ahb
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_hs_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);
}
/**
* @brief Get CPU_CLK's low-speed divider
* *
* @return Divider. Divider = (PCR_LS_DIV_NUM + 1) * (PCR_CPU_LS_DIV_NUM + 1). * @param divider Divider. (PCR_AHB_DIV_NUM + 1) = divider.
*/ */
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); HAL_ASSERT(divider >= 1);
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));
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ahb_freq_conf, ahb_div_num, 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's divider
* *
* @return Divider. Divider = (PCR_HS_DIV_NUM + 1) * (PCR_AHB_HS_DIV_NUM + 1). * @return Divider. Divider = (PCR_AHB_DIV_NUM + 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); return HAL_FORCE_READ_U32_REG_FIELD(PCR.ahb_freq_conf, ahb_div_num) + 1;
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);
} }
/** /**
@ -536,103 +471,6 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_apb_get_divider(voi
return HAL_FORCE_READ_U32_REG_FIELD(PCR.apb_freq_conf, apb_div_num) + 1; return HAL_FORCE_READ_U32_REG_FIELD(PCR.apb_freq_conf, apb_div_num) + 1;
} }
/**
* @brief Set MSPI_FAST_CLK's high-speed divider (valid when SOC_ROOT clock source is PLL)
*
* @param divider Divider.
*/
static inline __attribute__((always_inline)) void clk_ll_mspi_fast_set_hs_divider(uint32_t divider)
{
// 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);
}
/**
* @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.ctrl_32k_conf.clk_32k_sel = 0;
break;
case SOC_RTC_SLOW_CLK_SRC_XTAL32K:
PCR.ctrl_32k_conf.clk_32k_sel = 1;
break;
case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW:
PCR.ctrl_32k_conf.clk_32k_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.ctrl_32k_conf.clk_32k_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;
default:
return SOC_RTC_SLOW_CLK_SRC_INVALID;
}
}
/** /**
* @brief Select the clock source for RTC_SLOW_CLK * @brief Select the clock source for RTC_SLOW_CLK
* *
@ -695,6 +533,9 @@ static inline __attribute__((always_inline)) void clk_ll_rtc_fast_set_src(soc_rt
case SOC_RTC_FAST_CLK_SRC_XTAL_D2: case SOC_RTC_FAST_CLK_SRC_XTAL_D2:
LP_CLKRST.lp_clk_conf.fast_clk_sel = 1; LP_CLKRST.lp_clk_conf.fast_clk_sel = 1;
break; break;
case SOC_RTC_FAST_CLK_SRC_XTAL:
LP_CLKRST.lp_clk_conf.fast_clk_sel = 2;
break;
default: default:
// Unsupported RTC_FAST_CLK mux input sel // Unsupported RTC_FAST_CLK mux input sel
abort(); abort();
@ -714,6 +555,8 @@ static inline __attribute__((always_inline)) soc_rtc_fast_clk_src_t clk_ll_rtc_f
return SOC_RTC_FAST_CLK_SRC_RC_FAST; return SOC_RTC_FAST_CLK_SRC_RC_FAST;
case 1: case 1:
return SOC_RTC_FAST_CLK_SRC_XTAL_D2; return SOC_RTC_FAST_CLK_SRC_XTAL_D2;
case 2:
return SOC_RTC_FAST_CLK_SRC_XTAL;
default: default:
return SOC_RTC_FAST_CLK_SRC_INVALID; return SOC_RTC_FAST_CLK_SRC_INVALID;
} }
@ -741,6 +584,14 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_rc_fast_get_divider
return 1; return 1;
} }
/**
* @brief Set the frequency division factor of RC_FAST clock
*/
static inline void clk_ll_rc_fast_tick_conf(void)
{
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ctrl_32k_conf, fosc_tick_num, (1 << CLK_LL_RC_FAST_TICK_DIV_BITS) - 1); // divider = 1 << CLK_LL_RC_FAST_TICK_DIV_BITS
}
/** /**
* @brief Set RC_SLOW_CLK divider * @brief Set RC_SLOW_CLK divider
* *
@ -753,49 +604,6 @@ static inline __attribute__((always_inline)) void clk_ll_rc_slow_set_divider(uin
} }
/************************** LP STORAGE REGISTER STORE/LOAD **************************/ /************************** LP STORAGE REGISTER STORE/LOAD **************************/
#if CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION
/**
* @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;
}
#endif
/** /**
* @brief Store RTC_SLOW_CLK calibration value in RTC storage register * @brief Store RTC_SLOW_CLK calibration value in RTC storage register
* *
@ -821,16 +629,6 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_rtc_slow_load_cal(v
return REG_READ(RTC_SLOW_CLK_CAL_REG); return REG_READ(RTC_SLOW_CLK_CAL_REG);
} }
/*
Set the frequency division factor of ref_tick
*/
static inline void clk_ll_rc_fast_tick_conf(void)
{
PCR.ctrl_32k_conf.fosc_tick_num = REG_FOSC_TICK_NUM;
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -44,7 +44,8 @@ Set the frequency division factor of ref_tick
The FOSC of rtc calibration uses the 32 frequency division clock for ECO1, 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 So the frequency division factor of ref_tick must be greater than or equal to 32
*/ */
#define REG_FOSC_TICK_NUM 255 #define CLK_LL_RC_FAST_TICK_DIV_BITS 5
#define REG_FOSC_TICK_NUM 255
/** /**
* @brief XTAL32K_CLK enable modes * @brief XTAL32K_CLK enable modes
@ -810,7 +811,7 @@ Set the frequency division factor of ref_tick
*/ */
static inline void clk_ll_rc_fast_tick_conf(void) static inline void clk_ll_rc_fast_tick_conf(void)
{ {
PCR.ctrl_tick_conf.fosc_tick_num = REG_FOSC_TICK_NUM; HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ctrl_tick_conf, fosc_tick_num, REG_FOSC_TICK_NUM); // enable a division of 32 to the fosc clock
} }

View File

@ -808,7 +808,7 @@ Set the frequency division factor of ref_tick
*/ */
static inline void clk_ll_rc_fast_tick_conf(void) static inline void clk_ll_rc_fast_tick_conf(void)
{ {
PCR.ctrl_32k_conf.fosc_tick_num = REG_FOSC_TICK_NUM; HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ctrl_32k_conf, fosc_tick_num, REG_FOSC_TICK_NUM); // divider = (REG_FOSC_TICK_NUM + 1) = 256
} }

View File

@ -43,7 +43,8 @@ Set the frequency division factor of ref_tick
The FOSC of rtc calibration uses the 32 frequency division clock for ECO2, The FOSC of rtc calibration uses the 32 frequency division clock for ECO2,
So the frequency division factor of ref_tick must be greater than or equal to 32 So the frequency division factor of ref_tick must be greater than or equal to 32
*/ */
#define REG_FOSC_TICK_NUM 255 #define CLK_LL_RC_FAST_TICK_DIV_BITS 5
#define REG_FOSC_TICK_NUM 255
/** /**
* @brief XTAL32K_CLK enable modes * @brief XTAL32K_CLK enable modes
@ -746,7 +747,7 @@ Set the frequency division factor of ref_tick
*/ */
static inline void clk_ll_rc_fast_tick_conf(void) static inline void clk_ll_rc_fast_tick_conf(void)
{ {
PCR.ctrl_tick_conf.fosc_tick_num = REG_FOSC_TICK_NUM; HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ctrl_tick_conf, fosc_tick_num, REG_FOSC_TICK_NUM); // enable a division of 32 to the fosc clock
} }
/* /*

View File

@ -131,6 +131,10 @@ config SOC_SECURE_BOOT_SUPPORTED
bool bool
default y default y
config SOC_PMU_SUPPORTED
bool
default y
config SOC_LP_TIMER_SUPPORTED config SOC_LP_TIMER_SUPPORTED
bool bool
default y default y
@ -139,6 +143,10 @@ config SOC_LP_PERIPHERALS_SUPPORTED
bool bool
default y default y
config SOC_CLK_TREE_SUPPORTED
bool
default y
config SOC_SPI_FLASH_SUPPORTED config SOC_SPI_FLASH_SUPPORTED
bool bool
default y default y
@ -847,6 +855,14 @@ config SOC_UART_BITRATE_MAX
int int
default 5000000 default 5000000
config SOC_UART_SUPPORT_PLL_F80M_CLK
bool
default y
config SOC_UART_SUPPORT_RTC_CLK
bool
default y
config SOC_UART_SUPPORT_XTAL_CLK config SOC_UART_SUPPORT_XTAL_CLK
bool bool
default y default y
@ -895,6 +911,10 @@ config SOC_PM_SUPPORT_RTC_PERIPH_PD
bool bool
default y default y
config SOC_CLK_RC_FAST_SUPPORT_CALIBRATION
bool
default y
config SOC_MODEM_CLOCK_IS_INDEPENDENT config SOC_MODEM_CLOCK_IS_INDEPENDENT
bool bool
default y default y
@ -911,6 +931,10 @@ config SOC_CLK_RC32K_SUPPORTED
bool bool
default y default y
config SOC_CLK_LP_FAST_SUPPORT_XTAL
bool
default y
config SOC_RCC_IS_INDEPENDENT config SOC_RCC_IS_INDEPENDENT
bool bool
default y default y

View File

@ -19,7 +19,7 @@ extern "C" {
* *
* The exact frequency of RC_FAST_CLK can be computed in runtime through calibration. * The exact frequency of RC_FAST_CLK can be computed in runtime through calibration.
* *
* 2) External 40/48MHz Crystal Clock: XTAL * 2) External 48MHz Crystal Clock: XTAL
* *
* 3) Internal 136kHz RC Oscillator: RC_SLOW (may also referred as SOSC in TRM or reg. description) * 3) Internal 136kHz RC Oscillator: RC_SLOW (may also referred as SOSC in TRM or reg. description)
* *
@ -45,7 +45,6 @@ extern "C" {
* OSC_SLOW_CLK can also be calibrated to get its exact frequency. * OSC_SLOW_CLK can also be calibrated to get its exact frequency.
*/ */
// TODO: [ESP32C5] IDF-8642 (inherit from C6)
/* With the default value of FOSC_DFREQ = 100, RC_FAST clock frequency is 17.5 MHz +/- 7% */ /* 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_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_RC_SLOW_FREQ_APPROX 136000 /*!< Approximate RC_SLOW_CLK frequency in Hz */
@ -60,10 +59,10 @@ extern "C" {
/** /**
* @brief Root clock * @brief Root clock
*/ */
typedef enum { // TODO: [ESP32C5] IDF-8642 (inherit from C6) typedef enum {
SOC_ROOT_CLK_INT_RC_FAST, /*!< Internal 17.5MHz RC oscillator */ 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_SLOW, /*!< Internal 136kHz RC oscillator */
SOC_ROOT_CLK_EXT_XTAL, /*!< External 40MHz crystal */ SOC_ROOT_CLK_EXT_XTAL, /*!< External 48MHz crystal */
SOC_ROOT_CLK_EXT_XTAL32K, /*!< External 32kHz crystal */ SOC_ROOT_CLK_EXT_XTAL32K, /*!< External 32kHz crystal */
SOC_ROOT_CLK_INT_RC32K, /*!< Internal 32kHz RC oscillator */ 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 pin0 */
@ -73,12 +72,11 @@ typedef enum { // TODO: [ESP32C5] IDF-8642 (inherit from C6)
* @brief CPU_CLK mux inputs, which are the supported clock sources for the CPU_CLK * @brief CPU_CLK mux inputs, which are the supported clock sources for the CPU_CLK
* @note Enum values are matched with the register field values on purpose * @note Enum values are matched with the register field values on purpose
*/ */
typedef enum { // TODO: [ESP32C5] IDF-8642 (inherit from C6) typedef enum {
SOC_CPU_CLK_SRC_XTAL = 0, /*!< Select XTAL_CLK as CPU_CLK source */ SOC_CPU_CLK_SRC_XTAL = 0, /*!< Select XTAL_CLK as CPU_CLK source */
SOC_CPU_CLK_SRC_RC_FAST = 1, /*!< 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_PLL_F160M = 2, /*!< Select PLL_F160M_CLK as CPU_CLK source (PLL_F160M_CLK is derived from SPLL (480MHz), which is the output of the main crystal oscillator frequency multiplier) */ SOC_CPU_CLK_SRC_PLL_F160M = 2, /*!< Select PLL_F160M_CLK as CPU_CLK source (PLL_F160M_CLK is derived from SPLL (480MHz), which is the output of the main crystal oscillator frequency multiplier) */
SOC_CPU_CLK_SRC_PLL_F240M = 3, /*!< Select PLL_F240M_CLK as CPU_CLK source (PLL_F240M_CLK is derived from SPLL (480MHz), which is the output of the main crystal oscillator frequency multiplier) */ SOC_CPU_CLK_SRC_PLL_F240M = 3, /*!< Select PLL_F240M_CLK as CPU_CLK source (PLL_F240M_CLK is derived from SPLL (480MHz), which is the output of the main crystal oscillator frequency multiplier) */
SOC_CPU_CLK_SRC_PLL = SOC_CPU_CLK_SRC_PLL_F240M, // TODO: [IDF-8642] remove this alias
SOC_CPU_CLK_SRC_INVALID, /*!< Invalid CPU_CLK source */ SOC_CPU_CLK_SRC_INVALID, /*!< Invalid CPU_CLK source */
} soc_cpu_clk_src_t; } soc_cpu_clk_src_t;
@ -86,7 +84,7 @@ typedef enum { // TODO: [ESP32C5] IDF-8642 (inherit from C6)
* @brief RTC_SLOW_CLK mux inputs, which are the supported clock sources for the RTC_SLOW_CLK * @brief RTC_SLOW_CLK mux inputs, which are the supported clock sources for the RTC_SLOW_CLK
* @note Enum values are matched with the register field values on purpose * @note Enum values are matched with the register field values on purpose
*/ */
typedef enum { // TODO: [ESP32C5] IDF-8642 (inherit from C6) 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 = 0, /*!< Select RC_SLOW_CLK as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */ SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_RC32K = 2, /*!< Select RC32K_CLK as RTC_SLOW_CLK source */ SOC_RTC_SLOW_CLK_SRC_RC32K = 2, /*!< Select RC32K_CLK as RTC_SLOW_CLK source */
@ -98,7 +96,7 @@ typedef enum { // TODO: [ESP32C5] IDF-8642 (inherit from C6)
* @brief RTC_FAST_CLK mux inputs, which are the supported clock sources for the RTC_FAST_CLK * @brief RTC_FAST_CLK mux inputs, which are the supported clock sources for the RTC_FAST_CLK
* @note Enum values are matched with the register field values on purpose * @note Enum values are matched with the register field values on purpose
*/ */
typedef enum { // TODO: [ESP32C5] IDF-8642 (inherit from C6) typedef enum {
SOC_RTC_FAST_CLK_SRC_RC_FAST = 0, /*!< Select RC_FAST_CLK as RTC_FAST_CLK source */ SOC_RTC_FAST_CLK_SRC_RC_FAST = 0, /*!< Select RC_FAST_CLK as RTC_FAST_CLK source */
SOC_RTC_FAST_CLK_SRC_XTAL_D2 = 1, /*!< Select XTAL_D2_CLK as RTC_FAST_CLK source */ SOC_RTC_FAST_CLK_SRC_XTAL_D2 = 1, /*!< Select XTAL_D2_CLK as RTC_FAST_CLK source */
SOC_RTC_FAST_CLK_SRC_XTAL_DIV = SOC_RTC_FAST_CLK_SRC_XTAL_D2, /*!< Alias name for `SOC_RTC_FAST_CLK_SRC_XTAL_D2` */ SOC_RTC_FAST_CLK_SRC_XTAL_DIV = SOC_RTC_FAST_CLK_SRC_XTAL_D2, /*!< Alias name for `SOC_RTC_FAST_CLK_SRC_XTAL_D2` */
@ -125,7 +123,7 @@ typedef enum {
* *
* @note enum starts from 1, to save 0 for special purpose * @note enum starts from 1, to save 0 for special purpose
*/ */
typedef enum { // TODO: [ESP32C5] IDF-8642 (inherit from C6) typedef enum {
// For CPU domain // 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, or RC_FAST by configuring soc_cpu_clk_src_t */
// For RTC domain // For RTC domain
@ -138,9 +136,9 @@ typedef enum { // TODO: [ESP32C5] IDF-8642 (inherit from C6)
SOC_MOD_CLK_SPLL, /*!< SPLL is from the main XTAL oscillator frequency multipliers, it has a "fixed" frequency of 480MHz */ SOC_MOD_CLK_SPLL, /*!< SPLL is from the main XTAL oscillator frequency multipliers, it has a "fixed" frequency of 480MHz */
SOC_MOD_CLK_XTAL32K, /*!< XTAL32K_CLK comes from the external 32kHz crystal, passing a clock gating to the peripherals */ 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_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 40MHz crystal */ SOC_MOD_CLK_XTAL, /*!< XTAL_CLK comes from the external 48MHz crystal */
// For LP peripherals // For LP peripherals
SOC_MOD_CLK_XTAL_D2, /*!< XTAL_D2_CLK comes from the external 40MHz crystal, passing a div of 2 to the LP peripherals */ SOC_MOD_CLK_XTAL_D2, /*!< XTAL_D2_CLK comes from the external 48MHz 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_MOD_CLK_INVALID, /*!< Indication of the end of the available module clock sources */
} soc_module_clk_t; } soc_module_clk_t;
@ -548,7 +546,7 @@ typedef enum { // TODO: [ESP32C5] IDF-8649
} soc_periph_mspi_clk_src_t; } soc_periph_mspi_clk_src_t;
//////////////////////////////////////////////CLOCK OUTPUT/////////////////////////////////////////////////////////// //////////////////////////////////////////////CLOCK OUTPUT///////////////////////////////////////////////////////////
typedef enum { // TODO: [ESP32C5] IDF-8642 (inherit from C6) typedef enum { // TODO
CLKOUT_SIG_PLL = 1, /*!< PLL_CLK is the output of crystal oscillator frequency multiplier */ CLKOUT_SIG_PLL = 1, /*!< PLL_CLK is the output of crystal oscillator frequency multiplier */
CLKOUT_SIG_XTAL = 5, /*!< Main crystal oscillator clock */ CLKOUT_SIG_XTAL = 5, /*!< Main crystal oscillator clock */
CLKOUT_SIG_PLL_F80M = 13, /*!< From PLL, usually be 80MHz */ CLKOUT_SIG_PLL_F80M = 13, /*!< From PLL, usually be 80MHz */

View File

@ -1902,21 +1902,6 @@ extern "C" {
* SYSCLK configuration register * SYSCLK configuration register
*/ */
#define PCR_SYSCLK_CONF_REG (DR_REG_PCR_BASE + 0x110) #define PCR_SYSCLK_CONF_REG (DR_REG_PCR_BASE + 0x110)
/** 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; /** PCR_SOC_CLK_SEL : R/W; bitpos: [17:16]; default: 0;
* Configures to select the clock source of HP_ROOT_CLK.\\ * Configures to select the clock source of HP_ROOT_CLK.\\
* 0 (default): XTAL_CLK\\ * 0 (default): XTAL_CLK\\

View File

@ -1642,15 +1642,7 @@ typedef union {
*/ */
typedef union { typedef union {
struct { struct {
/** ls_div_num : HRO; bitpos: [7:0]; default: 0; uint32_t reserved_0:16;
* 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;
/** soc_clk_sel : R/W; bitpos: [17:16]; default: 0; /** soc_clk_sel : R/W; bitpos: [17:16]; default: 0;
* Configures to select the clock source of HP_ROOT_CLK.\\ * Configures to select the clock source of HP_ROOT_CLK.\\
* 0 (default): XTAL_CLK\\ * 0 (default): XTAL_CLK\\
@ -1706,7 +1698,7 @@ typedef union {
typedef union { typedef union {
struct { struct {
/** cpu_div_num : R/W; bitpos: [7:0]; default: 0; /** cpu_div_num : R/W; bitpos: [7:0]; default: 0;
* Set this field to generate clk_cpu driven by clk_hproot. The clk_cpu is * Set this field to generate clk_cpu derived by clk_hproot. The clk_cpu is
* div1(default)/div2/div4 of clk_hproot. This field is only available for low-speed * div1(default)/div2/div4 of clk_hproot. This field is only available for low-speed
* clock-source such as XTAL/FOSC, and should be used together with PCR_AHB_DIV_NUM. * clock-source such as XTAL/FOSC, and should be used together with PCR_AHB_DIV_NUM.
*/ */
@ -1722,7 +1714,7 @@ typedef union {
typedef union { typedef union {
struct { struct {
/** ahb_div_num : R/W; bitpos: [7:0]; default: 0; /** ahb_div_num : R/W; bitpos: [7:0]; default: 0;
* Set this field to generate clk_ahb driven by clk_hproot. The clk_ahb is * Set this field to generate clk_ahb derived by clk_hproot. The clk_ahb is
* div1(default)/div2/div4/div8 of clk_hproot. This field is only available for * div1(default)/div2/div4/div8 of clk_hproot. This field is only available for
* low-speed clock-source such as XTAL/FOSC, and should be used together with * low-speed clock-source such as XTAL/FOSC, and should be used together with
* PCR_CPU_DIV_NUM. * PCR_CPU_DIV_NUM.
@ -1749,7 +1741,7 @@ typedef union {
*/ */
uint32_t apb_decrease_div_num:8; uint32_t apb_decrease_div_num:8;
/** apb_div_num : R/W; bitpos: [15:8]; default: 0; /** apb_div_num : R/W; bitpos: [15:8]; default: 0;
* Set as one within (0,1,3) to generate clk_apb driven by clk_ahb. The clk_apb is * Set as one within (0,1,3) to generate clk_apb derived by clk_ahb. The clk_apb is
* div1(default)/div2/div4 of clk_ahb. * div1(default)/div2/div4 of clk_ahb.
*/ */
uint32_t apb_div_num:8; uint32_t apb_div_num:8;
@ -1764,47 +1756,47 @@ typedef union {
typedef union { typedef union {
struct { struct {
/** pll_240m_clk_en : R/W; bitpos: [0]; default: 1; /** pll_240m_clk_en : R/W; bitpos: [0]; default: 1;
* This field is used to open 240 MHz clock (div2 of SPLL) driven from SPLL. 0: close, * This field is used to open 240 MHz clock (div2 of SPLL) derived from SPLL. 0: close,
* 1: open(default). Only available when high-speed clock-source SPLL is active. * 1: open(default). Only available when high-speed clock-source SPLL is active.
*/ */
uint32_t pll_240m_clk_en:1; uint32_t pll_240m_clk_en:1;
/** pll_160m_clk_en : R/W; bitpos: [1]; default: 1; /** pll_160m_clk_en : R/W; bitpos: [1]; default: 1;
* This field is used to open 160 MHz clock (div3 of SPLL) driven from SPLL. 0: close, * This field is used to open 160 MHz clock (div3 of SPLL) derived from SPLL. 0: close,
* 1: open(default). Only available when high-speed clock-source SPLL is active. * 1: open(default). Only available when high-speed clock-source SPLL is active.
*/ */
uint32_t pll_160m_clk_en:1; uint32_t pll_160m_clk_en:1;
/** pll_120m_clk_en : R/W; bitpos: [2]; default: 1; /** pll_120m_clk_en : R/W; bitpos: [2]; default: 1;
* This field is used to open 120 MHz clock (div4 of SPLL) driven from SPLL. 0: close, * This field is used to open 120 MHz clock (div4 of SPLL) derived from SPLL. 0: close,
* 1: open(default). Only available when high-speed clock-source SPLL is active. * 1: open(default). Only available when high-speed clock-source SPLL is active.
*/ */
uint32_t pll_120m_clk_en:1; uint32_t pll_120m_clk_en:1;
/** pll_80m_clk_en : R/W; bitpos: [3]; default: 1; /** pll_80m_clk_en : R/W; bitpos: [3]; default: 1;
* This field is used to open 80 MHz clock (div6 of SPLL) driven from SPLL. 0: close, * This field is used to open 80 MHz clock (div6 of SPLL) derived from SPLL. 0: close,
* 1: open(default). Only available when high-speed clock-source SPLL is active. * 1: open(default). Only available when high-speed clock-source SPLL is active.
*/ */
uint32_t pll_80m_clk_en:1; uint32_t pll_80m_clk_en:1;
/** pll_60m_clk_en : R/W; bitpos: [4]; default: 1; /** pll_60m_clk_en : R/W; bitpos: [4]; default: 1;
* This field is used to open 60 MHz clock (div8 of SPLL) driven from SPLL. 0: close, * This field is used to open 60 MHz clock (div8 of SPLL) derived from SPLL. 0: close,
* 1: open(default). Only available when high-speed clock-source SPLL is active. * 1: open(default). Only available when high-speed clock-source SPLL is active.
*/ */
uint32_t pll_60m_clk_en:1; uint32_t pll_60m_clk_en:1;
/** pll_48m_clk_en : R/W; bitpos: [5]; default: 1; /** pll_48m_clk_en : R/W; bitpos: [5]; default: 1;
* This field is used to open 48 MHz clock (div10 of SPLL) driven from SPLL. 0: close, * This field is used to open 48 MHz clock (div10 of SPLL) derived from SPLL. 0: close,
* 1: open(default). Only available when high-speed clock-source SPLL is active. * 1: open(default). Only available when high-speed clock-source SPLL is active.
*/ */
uint32_t pll_48m_clk_en:1; uint32_t pll_48m_clk_en:1;
/** pll_40m_clk_en : R/W; bitpos: [6]; default: 1; /** pll_40m_clk_en : R/W; bitpos: [6]; default: 1;
* This field is used to open 40 MHz clock (div12 of SPLL) driven from SPLL. 0: close, * This field is used to open 40 MHz clock (div12 of SPLL) derived from SPLL. 0: close,
* 1: open(default). Only available when high-speed clock-source SPLL is active. * 1: open(default). Only available when high-speed clock-source SPLL is active.
*/ */
uint32_t pll_40m_clk_en:1; uint32_t pll_40m_clk_en:1;
/** pll_20m_clk_en : R/W; bitpos: [7]; default: 1; /** pll_20m_clk_en : R/W; bitpos: [7]; default: 1;
* This field is used to open 20 MHz clock (div24 of SPLL) driven from SPLL. 0: close, * This field is used to open 20 MHz clock (div24 of SPLL) derived from SPLL. 0: close,
* 1: open(default). Only available when high-speed clock-source SPLL is active. * 1: open(default). Only available when high-speed clock-source SPLL is active.
*/ */
uint32_t pll_20m_clk_en:1; uint32_t pll_20m_clk_en:1;
/** pll_12m_clk_en : R/W; bitpos: [8]; default: 1; /** pll_12m_clk_en : R/W; bitpos: [8]; default: 1;
* This field is used to open 12 MHz clock (div40 of SPLL) driven from SPLL. 0: close, * This field is used to open 12 MHz clock (div40 of SPLL) derived from SPLL. 0: close,
* 1: open(default). Only available when high-speed clock-source SPLL is active. * 1: open(default). Only available when high-speed clock-source SPLL is active.
*/ */
uint32_t pll_12m_clk_en:1; uint32_t pll_12m_clk_en:1;

View File

@ -58,14 +58,14 @@
#define SOC_SECURE_BOOT_SUPPORTED 1 #define SOC_SECURE_BOOT_SUPPORTED 1
// #define SOC_BOD_SUPPORTED 1 // TODO: [ESP32C5] IDF-8647 // #define SOC_BOD_SUPPORTED 1 // TODO: [ESP32C5] IDF-8647
// #define SOC_APM_SUPPORTED 1 // TODO: [ESP32C5] IDF-8614, IDF-8615 // #define SOC_APM_SUPPORTED 1 // TODO: [ESP32C5] IDF-8614, IDF-8615
// #define SOC_PMU_SUPPORTED 1 // TODO: [ESP32C5] IDF-8667 #define SOC_PMU_SUPPORTED 1 // TODO: [ESP32C5] IDF-8667
// #define SOC_PAU_SUPPORTED 1 // TODO: [ESP32C5] IDF-8638 // #define SOC_PAU_SUPPORTED 1 // TODO: [ESP32C5] IDF-8638
#define SOC_LP_TIMER_SUPPORTED 1 #define SOC_LP_TIMER_SUPPORTED 1
// #define SOC_LP_AON_SUPPORTED 1 // TODO: [ESP32C5] IDF-8638 // #define SOC_LP_AON_SUPPORTED 1 // TODO: [ESP32C5] IDF-8638
#define SOC_LP_PERIPHERALS_SUPPORTED 1 #define SOC_LP_PERIPHERALS_SUPPORTED 1
// #define SOC_LP_I2C_SUPPORTED 1 // TODO: [ESP32C5] IDF-8634 // #define SOC_LP_I2C_SUPPORTED 1 // TODO: [ESP32C5] IDF-8634
// #define SOC_ULP_LP_UART_SUPPORTED 1 // TODO: [ESP32C5] IDF-8633 // #define SOC_ULP_LP_UART_SUPPORTED 1 // TODO: [ESP32C5] IDF-8633
// #define SOC_CLK_TREE_SUPPORTED 1 // TODO: [ESP32C5] IDF-8642 #define SOC_CLK_TREE_SUPPORTED 1
// #define SOC_ASSIST_DEBUG_SUPPORTED 1 // TODO: [ESP32C5] IDF-8663 // #define SOC_ASSIST_DEBUG_SUPPORTED 1 // TODO: [ESP32C5] IDF-8663
// #define SOC_WDT_SUPPORTED 1 // TODO: [ESP32C5] IDF-8650 // #define SOC_WDT_SUPPORTED 1 // TODO: [ESP32C5] IDF-8650
#define SOC_SPI_FLASH_SUPPORTED 1 // TODO: [ESP32C5] IDF-8715 #define SOC_SPI_FLASH_SUPPORTED 1 // TODO: [ESP32C5] IDF-8715
@ -493,8 +493,8 @@
#define SOC_UART_FIFO_LEN (128) /*!< The UART hardware FIFO length */ #define SOC_UART_FIFO_LEN (128) /*!< The UART hardware FIFO length */
#define SOC_LP_UART_FIFO_LEN (16) /*!< The LP UART hardware FIFO length */ #define SOC_LP_UART_FIFO_LEN (16) /*!< The LP UART hardware FIFO length */
#define SOC_UART_BITRATE_MAX (5000000) /*!< Max bit rate supported by UART */ #define SOC_UART_BITRATE_MAX (5000000) /*!< Max bit rate supported by UART */
// #define SOC_UART_SUPPORT_PLL_F80M_CLK (1) /*!< Support PLL_F80M as the clock source */ #define SOC_UART_SUPPORT_PLL_F80M_CLK (1) /*!< Support PLL_F80M as the clock source */
// #define SOC_UART_SUPPORT_RTC_CLK (1) /*!< Support RTC clock as the clock source */ // TODO: [ESP32C5] IDF-8642 #define SOC_UART_SUPPORT_RTC_CLK (1) /*!< Support RTC clock as the clock source */
#define SOC_UART_SUPPORT_XTAL_CLK (1) /*!< Support XTAL clock as the clock source */ #define SOC_UART_SUPPORT_XTAL_CLK (1) /*!< Support XTAL clock as the clock source */
#define SOC_UART_SUPPORT_WAKEUP_INT (1) /*!< Support UART wakeup interrupt */ #define SOC_UART_SUPPORT_WAKEUP_INT (1) /*!< Support UART wakeup interrupt */
#define SOC_UART_HAS_LP_UART (1) /*!< Support LP UART */ #define SOC_UART_HAS_LP_UART (1) /*!< Support LP UART */
@ -545,12 +545,13 @@
// #define SOC_PM_PAU_LINK_NUM (4) // #define SOC_PM_PAU_LINK_NUM (4)
/*-------------------------- CLOCK SUBSYSTEM CAPS ----------------------------------------*/ /*-------------------------- CLOCK SUBSYSTEM CAPS ----------------------------------------*/
// #define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION (1) // TODO: IDF-8642 #define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION (1)
#define SOC_MODEM_CLOCK_IS_INDEPENDENT (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_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_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_RC32K_SUPPORTED (1) /*!< Support an internal 32kHz RC oscillator */
#define SOC_CLK_LP_FAST_SUPPORT_XTAL (1) /*!< Support XTAL clock as the LP_FAST clock source */
#define SOC_RCC_IS_INDEPENDENT 1 /*!< Reset and Clock Control is independent, thanks to the PCR registers */ #define SOC_RCC_IS_INDEPENDENT 1 /*!< Reset and Clock Control is independent, thanks to the PCR registers */

View File

@ -97,7 +97,6 @@ api-reference/peripherals/lcd.rst
api-reference/peripherals/ana_cmpr.rst api-reference/peripherals/ana_cmpr.rst
api-reference/peripherals/temp_sensor.rst api-reference/peripherals/temp_sensor.rst
api-reference/peripherals/spi_features.rst api-reference/peripherals/spi_features.rst
api-reference/peripherals/clk_tree.rst
api-reference/peripherals/spi_flash/spi_flash_concurrency.rst api-reference/peripherals/spi_flash/spi_flash_concurrency.rst
api-reference/peripherals/spi_flash/spi_flash_override_driver.rst api-reference/peripherals/spi_flash/spi_flash_override_driver.rst
api-reference/peripherals/spi_flash/spi_flash_optional_feature.rst api-reference/peripherals/spi_flash/spi_flash_optional_feature.rst

View File

@ -7,7 +7,7 @@ Clock Tree
{IDF_TARGET_RC_FAST_ADJUSTED_FREQ: default="17.5", esp32="8.5", esp32s2="8.5", esp32h2="8.5"} {IDF_TARGET_RC_FAST_ADJUSTED_FREQ: default="17.5", esp32="8.5", esp32s2="8.5", esp32h2="8.5"}
{IDF_TARGET_XTAL_FREQ: default="40", esp32="2 ~ 40", esp32c2="40/26", esp32h2="32"} {IDF_TARGET_XTAL_FREQ: default="40", esp32="2 ~ 40", esp32c2="40/26", esp32h2="32", esp32c5="48"}
{IDF_TARGET_RC_SLOW_VAGUE_FREQ: default="136", esp32="150", esp32s2="90"} {IDF_TARGET_RC_SLOW_VAGUE_FREQ: default="136", esp32="150", esp32s2="90"}

View File

@ -166,7 +166,7 @@ The source clock can also limit the PWM frequency. The higher the source clock f
- ~ 17.5 MHz - ~ 17.5 MHz
- Dynamic Frequency Scaling compatible, Light sleep compatible - Dynamic Frequency Scaling compatible, Light sleep compatible
* - XTAL_CLK * - XTAL_CLK
- 48/40 MHz - 48 MHz
- Dynamic Frequency Scaling compatible - Dynamic Frequency Scaling compatible
.. only:: esp32c6 .. only:: esp32c6

View File

@ -7,7 +7,7 @@
{IDF_TARGET_RC_FAST_ADJUSTED_FREQ: default="17.5", esp32="8.5", esp32s2="8.5", esp32h2="8.5"} {IDF_TARGET_RC_FAST_ADJUSTED_FREQ: default="17.5", esp32="8.5", esp32s2="8.5", esp32h2="8.5"}
{IDF_TARGET_XTAL_FREQ: default="40", esp32="2 ~ 40", esp32c2="40/26", esp32h2="32"} {IDF_TARGET_XTAL_FREQ: default="40", esp32="2 ~ 40", esp32c2="40/26", esp32h2="32", esp32c5="48"}
{IDF_TARGET_RC_SLOW_VAGUE_FREQ: default="136", esp32="150", esp32s2="90"} {IDF_TARGET_RC_SLOW_VAGUE_FREQ: default="136", esp32="150", esp32s2="90"}

View File

@ -166,7 +166,7 @@ LED PWM 控制器可在无需 CPU 干预的情况下自动改变占空比,实
- ~ 17.5 MHz - ~ 17.5 MHz
- 支持动态调频 (DFS) 功能,支持 Light-sleep 模式 - 支持动态调频 (DFS) 功能,支持 Light-sleep 模式
* - XTAL_CLK * - XTAL_CLK
- 48/40 MHz - 48 MHz
- 支持动态调频 (DFS) 功能 - 支持动态调频 (DFS) 功能
.. only:: esp32c6 .. only:: esp32c6