mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
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:
parent
ede24b0440
commit
40f3bc2e57
1
Kconfig
1
Kconfig
@ -122,7 +122,6 @@ mainmenu "Espressif IoT Development Framework Configuration"
|
||||
default "y" if IDF_TARGET="esp32c5"
|
||||
select FREERTOS_UNICORE
|
||||
select IDF_TARGET_ARCH_RISCV
|
||||
select IDF_ENV_FPGA
|
||||
|
||||
config IDF_TARGET_ESP32P4
|
||||
bool
|
||||
|
@ -28,7 +28,6 @@
|
||||
#include "hal/mmu_ll.h"
|
||||
#include "hal/cache_hal.h"
|
||||
#include "hal/cache_ll.h"
|
||||
#include "hal/clk_tree_ll.h"
|
||||
|
||||
void bootloader_flash_update_id()
|
||||
{
|
||||
@ -204,11 +203,6 @@ static void bootloader_spi_flash_resume(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_spi_flash_resume();
|
||||
bootloader_flash_unlock();
|
||||
|
@ -53,18 +53,12 @@ __attribute__((weak)) void bootloader_clock_configure(void)
|
||||
|
||||
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
|
||||
// RTC_SLOW clock source will be switched according to Kconfig selection at application startup
|
||||
clk_cfg.slow_clk_src = rtc_clk_slow_src_get();
|
||||
if (clk_cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_INVALID) {
|
||||
clk_cfg.slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW;
|
||||
}
|
||||
#endif
|
||||
|
||||
// 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
|
||||
|
@ -89,11 +89,7 @@ static inline void bootloader_hardware_init(void)
|
||||
/* 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_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);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void bootloader_ana_reset_config(void)
|
||||
|
@ -159,7 +159,6 @@ if(NOT BOOTLOADER_BUILD)
|
||||
"sleep_modem.c" # TODO: [ESP32C5] IDF-8638
|
||||
"sleep_wake_stub.c" # TODO: [ESP32C5] IDF-8638
|
||||
"sleep_gpio.c" # TODO: [ESP32C5] IDF-8638
|
||||
"port/esp_clk_tree_common.c" # TODO: [ESP32C5] IDF-8638
|
||||
)
|
||||
endif()
|
||||
|
||||
|
@ -288,10 +288,7 @@ menu "Hardware Settings"
|
||||
# Invisible bringup bypass options for esp_hw_support component
|
||||
config ESP_BRINGUP_BYPASS_CPU_CLK_SETTING
|
||||
bool
|
||||
# TODO: [ESP32C5] IDF-8642 IDF_TARGET_ESP32C5 is added because clock
|
||||
# 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 y if !SOC_CLK_TREE_SUPPORTED
|
||||
default n
|
||||
help
|
||||
This option is only used for new chip bringup, when
|
||||
|
@ -96,7 +96,7 @@ int IRAM_ATTR esp_clk_cpu_freq(void)
|
||||
int IRAM_ATTR esp_clk_apb_freq(void)
|
||||
{
|
||||
// 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();
|
||||
#else
|
||||
return MIN(s_get_cpu_freq_mhz() * MHZ, APB_CLK_FREQ);
|
||||
|
@ -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:
|
||||
rtc_sleep (noflash_text)
|
||||
rtc_time (noflash_text)
|
||||
if SOC_PMU_SUPPORTED = y:
|
||||
if SOC_PMU_SUPPORTED = y && SOC_LIGHT_SLEEP_SUPPORTED = y:
|
||||
pmu_sleep (noflash)
|
||||
if SOC_USB_SERIAL_JTAG_SUPPORTED = y:
|
||||
sleep_console (noflash)
|
||||
|
@ -1,10 +1,11 @@
|
||||
set(srcs "rtc_clk_init.c"
|
||||
"rtc_time.c"
|
||||
"rtc_clk.c"
|
||||
"pmu_init.c"
|
||||
"pmu_param.c"
|
||||
"chip_info.c"
|
||||
)
|
||||
|
||||
|
||||
if(NOT BOOTLOADER_BUILD)
|
||||
list(APPEND srcs "sar_periph_ctrl.c"
|
||||
"esp_crypto_lock.c")
|
||||
|
@ -11,21 +11,22 @@
|
||||
#include "soc/rtc.h"
|
||||
#include "hal/clk_tree_hal.h"
|
||||
#include "hal/clk_tree_ll.h"
|
||||
// #include "esp_private/esp_clk_tree_common.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_private/esp_clk_tree_common.h"
|
||||
|
||||
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,
|
||||
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(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");
|
||||
|
||||
uint32_t clk_src_freq = 0;
|
||||
switch (clk_src) {
|
||||
case SOC_MOD_CLK_CPU:
|
||||
clk_src_freq = clk_hal_cpu_get_freq_hz();
|
||||
break;
|
||||
case SOC_MOD_CLK_XTAL:
|
||||
clk_src_freq = clk_hal_xtal_get_freq_mhz() * MHZ;
|
||||
break;
|
||||
@ -41,9 +42,17 @@ uint32_t *freq_value)
|
||||
case SOC_MOD_CLK_SPLL:
|
||||
clk_src_freq = CLK_LL_PLL_480M_FREQ_MHZ * MHZ;
|
||||
break;
|
||||
case SOC_MOD_CLK_RTC_SLOW:
|
||||
clk_src_freq = esp_clk_tree_lp_slow_get_freq_hz(precision);
|
||||
break;
|
||||
case SOC_MOD_CLK_RTC_FAST:
|
||||
clk_src_freq = esp_clk_tree_lp_fast_get_freq_hz(precision);
|
||||
break;
|
||||
case SOC_MOD_CLK_RC_FAST:
|
||||
// C5-beta3 unable to calibrate to get exact RC_FAST frequency
|
||||
clk_src_freq = SOC_CLK_RC_FAST_FREQ_APPROX;
|
||||
clk_src_freq = esp_clk_tree_rc_fast_get_freq_hz(precision);
|
||||
break;
|
||||
case SOC_MOD_CLK_XTAL32K:
|
||||
clk_src_freq = esp_clk_tree_xtal32k_get_freq_hz(precision);
|
||||
break;
|
||||
case SOC_MOD_CLK_XTAL_D2:
|
||||
clk_src_freq = (clk_hal_xtal_get_freq_mhz() * MHZ) >> 1;
|
||||
|
@ -50,10 +50,6 @@ extern "C" {
|
||||
|
||||
#define MHZ (1000000)
|
||||
|
||||
#define RTC_SLOW_CLK_150K_CAL_TIMEOUT_THRES(cycles) (cycles << 10)
|
||||
#define RTC_SLOW_CLK_32K_CAL_TIMEOUT_THRES(cycles) (cycles << 12)
|
||||
#define RTC_FAST_CLK_20M_CAL_TIMEOUT_THRES(cycles) (TIMG_RTC_CALI_TIMEOUT_THRES_V) // Just use the max timeout thres value
|
||||
|
||||
#define OTHER_BLOCKS_POWERUP 1
|
||||
#define OTHER_BLOCKS_WAIT 1
|
||||
|
||||
@ -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_3_3V 1 //!< TIEH field value for 3.3V VDDSDIO
|
||||
|
||||
|
||||
/**
|
||||
* @brief Clock source to be calibrated using rtc_clk_cal function
|
||||
*
|
||||
* @note On previous targets, the enum values somehow reflects the register field values of TIMG_RTC_CALI_CLK_SEL
|
||||
* However, this is not true on ESP32C5. The conversion to register field values is explicitly done in
|
||||
* rtc_clk_cal_internal
|
||||
* @note On ESP32C5, the enum values somehow reflects the register field values of PCR_32K_SEL.
|
||||
*/
|
||||
typedef enum {
|
||||
RTC_CAL_RTC_MUX = -1, //!< Currently selected RTC_SLOW_CLK
|
||||
// RTC_CAL_RC_SLOW = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, //!< Internal 150kHz RC oscillator
|
||||
RTC_CAL_RC32K = SOC_RTC_SLOW_CLK_SRC_RC32K, //!< Internal 32kHz RC oscillator, as one type of 32k clock
|
||||
RTC_CAL_32K_XTAL = SOC_RTC_SLOW_CLK_SRC_XTAL32K, //!< External 32kHz XTAL, as one type of 32k clock
|
||||
RTC_CAL_32K_OSC_SLOW = SOC_RTC_SLOW_CLK_SRC_OSC_SLOW, //!< External slow clock signal input by lp_pad_gpio0, as one type of 32k clock
|
||||
RTC_CAL_RC_FAST //!< Internal 20MHz RC oscillator
|
||||
RTC_CAL_RTC_MUX = -1, //!< Currently selected RTC_SLOW_CLK
|
||||
RTC_CAL_RC32K = 0, //!< 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_OSC_SLOW = 2, //!< 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 = 4, //!< Internal 20MHz RC oscillator
|
||||
RTC_CAL_INVALID_CLK, //!< Clock not available to calibrate
|
||||
} rtc_cal_sel_t;
|
||||
|
||||
/**
|
||||
@ -160,7 +154,7 @@ typedef struct {
|
||||
.xtal_freq = CONFIG_XTAL_FREQ, \
|
||||
.cpu_freq_mhz = 80, \
|
||||
.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_8m_clk_div = 0, \
|
||||
.slow_clk_dcap = RTC_CNTL_SCK_DCAP_DEFAULT, \
|
||||
|
@ -23,13 +23,13 @@ typedef struct {
|
||||
const pmu_hp_system_power_param_t *power;
|
||||
const pmu_hp_system_clock_param_t *clock;
|
||||
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;
|
||||
} pmu_hp_system_param_t;
|
||||
|
||||
typedef struct {
|
||||
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_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;
|
||||
}
|
||||
|
||||
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_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);
|
||||
}
|
||||
|
||||
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_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)
|
||||
{
|
||||
assert (param->analog);
|
||||
|
||||
param->power = pmu_hp_system_power_param_default(mode);
|
||||
param->clock = pmu_hp_system_clock_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);
|
||||
|
||||
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)
|
||||
{
|
||||
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++) {
|
||||
pmu_hp_system_analog_param_t analog = {};
|
||||
pmu_hp_system_param_t param = {.analog = &analog};
|
||||
|
||||
pmu_hp_system_param_default(mode, ¶m);
|
||||
pmu_hp_system_init(ctx, mode, ¶m);
|
||||
}
|
||||
@ -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)
|
||||
{
|
||||
assert (param->analog);
|
||||
|
||||
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)
|
||||
{
|
||||
assert(ctx);
|
||||
pmu_lp_system_param_t param;
|
||||
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, ¶m);
|
||||
pmu_lp_system_init(ctx, mode, ¶m);
|
||||
}
|
||||
@ -195,10 +211,6 @@ void pmu_init(void)
|
||||
/* 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_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_lp_system_init_default(PMU_instance());
|
||||
|
@ -211,7 +211,7 @@ const pmu_hp_system_digital_param_t * pmu_hp_system_digital_param_default(pmu_hp
|
||||
.xpd = 1, \
|
||||
.slp_mem_dbias = 0, \
|
||||
.slp_logic_dbias = 0, \
|
||||
.dbias = HP_CALI_DBIAS \
|
||||
.dbias = HP_CALI_DBIAS_DEFAULT \
|
||||
}, \
|
||||
.regulator1 = { \
|
||||
.drv_b = 0x0 \
|
||||
@ -231,7 +231,7 @@ const pmu_hp_system_digital_param_t * pmu_hp_system_digital_param_default(pmu_hp
|
||||
.xpd = 1, \
|
||||
.slp_mem_dbias = 0, \
|
||||
.slp_logic_dbias = 0, \
|
||||
.dbias = HP_CALI_DBIAS \
|
||||
.dbias = HP_CALI_DBIAS_DEFAULT \
|
||||
}, \
|
||||
.regulator1 = { \
|
||||
.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, \
|
||||
.xpd = 1, \
|
||||
.slp_dbias = 0, \
|
||||
.dbias = LP_CALI_DBIAS \
|
||||
.dbias = LP_CALI_DBIAS_DEFAULT \
|
||||
}, \
|
||||
.regulator1 = { \
|
||||
.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));
|
||||
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;
|
||||
}
|
||||
|
@ -168,11 +168,11 @@ const pmu_sleep_config_t* pmu_sleep_config_default(
|
||||
if (!(pd_flags & PMU_SLEEP_PD_XTAL)){
|
||||
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.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.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;
|
||||
|
@ -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
|
@ -19,9 +19,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define HP_CALI_DBIAS 25
|
||||
#define LP_CALI_DBIAS 26
|
||||
#define HP_CALI_DBIAS_DEFAULT 28
|
||||
#define LP_CALI_DBIAS_DEFAULT 28
|
||||
|
||||
// FOR XTAL FORCE PU IN SLEEP
|
||||
#define PMU_PD_CUR_SLEEP_ON 0
|
||||
@ -51,6 +50,9 @@ extern "C" {
|
||||
#define PMU_DBG_ATTEN_DEEPSLEEP_DEFAULT 12
|
||||
#define PMU_LP_DBIAS_DEEPSLEEP_0V7 23
|
||||
|
||||
uint32_t get_act_hp_dbias(void);
|
||||
uint32_t get_act_lp_dbias(void);
|
||||
|
||||
typedef struct {
|
||||
pmu_hp_dig_power_reg_t dig_power;
|
||||
pmu_hp_clk_power_reg_t clk_power;
|
||||
@ -412,7 +414,7 @@ typedef struct {
|
||||
|
||||
typedef struct pmu_sleep_machine_constant {
|
||||
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 reserved0;
|
||||
uint16_t reserved1;
|
||||
@ -424,7 +426,7 @@ typedef struct pmu_sleep_machine_constant {
|
||||
uint16_t power_up_wait_time_us; /* (unit: microsecond) */
|
||||
} lp;
|
||||
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 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) */
|
||||
|
@ -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);
|
||||
/* WAIT CALIBRATION DONE */
|
||||
while(!regi2c_ctrl_ll_bbpll_calibration_is_done());
|
||||
esp_rom_delay_us(10); // wait for true stop
|
||||
/* BBPLL CALIBRATION STOP */
|
||||
regi2c_ctrl_ll_bbpll_calibration_stop();
|
||||
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)
|
||||
{
|
||||
clk_ll_ahb_set_ls_divider(div);
|
||||
clk_ll_cpu_set_ls_divider(div);
|
||||
// let f_cpu = f_ahb
|
||||
clk_ll_cpu_set_divider(div);
|
||||
clk_ll_ahb_set_divider(div);
|
||||
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_XTAL);
|
||||
clk_ll_bus_update();
|
||||
esp_rom_set_cpu_ticks_per_us(cpu_freq);
|
||||
}
|
||||
|
||||
static void rtc_clk_cpu_freq_to_8m(void)
|
||||
{
|
||||
clk_ll_ahb_set_ls_divider(1);
|
||||
clk_ll_cpu_set_ls_divider(1);
|
||||
clk_ll_cpu_set_divider(1);
|
||||
clk_ll_ahb_set_divider(1);
|
||||
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_RC_FAST);
|
||||
clk_ll_bus_update();
|
||||
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.
|
||||
* @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);
|
||||
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL);
|
||||
// f_hp_root = 240MHz
|
||||
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);
|
||||
}
|
||||
|
||||
@ -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 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;
|
||||
real_freq_mhz = (xtal_freq + divider / 2) / divider; /* round */
|
||||
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 = SOC_CPU_CLK_SRC_XTAL;
|
||||
} else if (freq_mhz == 80) {
|
||||
} else if (freq_mhz == 240) {
|
||||
real_freq_mhz = freq_mhz;
|
||||
source = SOC_CPU_CLK_SRC_PLL;
|
||||
source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ;
|
||||
divider = 6;
|
||||
} 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;
|
||||
source = SOC_CPU_CLK_SRC_PLL_F240M;
|
||||
source_freq_mhz = CLK_LL_PLL_240M_FREQ_MHZ;
|
||||
divider = 1;
|
||||
} else if (freq_mhz == 160) {
|
||||
real_freq_mhz = freq_mhz;
|
||||
source = SOC_CPU_CLK_SRC_PLL;
|
||||
source_freq_mhz = CLK_LL_PLL_480M_FREQ_MHZ;
|
||||
divider = 3;
|
||||
source = SOC_CPU_CLK_SRC_PLL_F160M;
|
||||
source_freq_mhz = CLK_LL_PLL_160M_FREQ_MHZ;
|
||||
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 {
|
||||
// unsupported frequency
|
||||
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();
|
||||
if (config->source == SOC_CPU_CLK_SRC_XTAL) {
|
||||
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
|
||||
if ((old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL) && !s_bbpll_digi_consumers_ref_count) {
|
||||
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
|
||||
rtc_clk_bbpll_disable();
|
||||
}
|
||||
} else if (config->source == SOC_CPU_CLK_SRC_PLL) {
|
||||
if (old_cpu_clk_src != 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_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(), 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);
|
||||
} else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) {
|
||||
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
|
||||
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();
|
||||
uint32_t source_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 hs_div = clk_ll_cpu_get_hs_divider();
|
||||
uint32_t div = clk_ll_cpu_get_divider(); // div = freq of SOC_ROOT_CLK / freq of CPU_CLK
|
||||
switch (source) {
|
||||
case SOC_CPU_CLK_SRC_XTAL: {
|
||||
source_freq_mhz = (uint32_t)rtc_clk_xtal_freq_get();
|
||||
freq_mhz = source_freq_mhz / div;
|
||||
break;
|
||||
}
|
||||
case SOC_CPU_CLK_SRC_PLL: {
|
||||
source_freq_mhz = clk_ll_bbpll_get_freq_mhz();
|
||||
freq_mhz = source_freq_mhz / hs_div;
|
||||
case SOC_CPU_CLK_SRC_PLL_F160M: {
|
||||
source_freq_mhz = CLK_LL_PLL_160M_FREQ_MHZ;
|
||||
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;
|
||||
}
|
||||
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) {
|
||||
rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
|
||||
} else if (
|
||||
config->source == SOC_CPU_CLK_SRC_PLL &&
|
||||
s_cur_pll_freq == config->source_freq_mhz
|
||||
) {
|
||||
rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz);
|
||||
} else if (config->source == SOC_CPU_CLK_SRC_PLL_F160M &&
|
||||
s_cur_pll_freq == CLK_LL_PLL_480M_FREQ_MHZ) {
|
||||
rtc_clk_cpu_freq_to_pll_160_mhz(config->freq_mhz);
|
||||
} else if (config->source == SOC_CPU_CLK_SRC_PLL_F240M &&
|
||||
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) {
|
||||
rtc_clk_cpu_freq_to_8m();
|
||||
} 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)
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
@ -375,15 +428,19 @@ static uint32_t rtc_clk_ahb_freq_get(void)
|
||||
switch (source) {
|
||||
case SOC_CPU_CLK_SRC_XTAL:
|
||||
soc_root_freq_mhz = rtc_clk_xtal_freq_get();
|
||||
divider = clk_ll_ahb_get_ls_divider();
|
||||
divider = clk_ll_ahb_get_divider();
|
||||
break;
|
||||
case SOC_CPU_CLK_SRC_PLL:
|
||||
soc_root_freq_mhz = clk_ll_bbpll_get_freq_mhz();
|
||||
divider = clk_ll_ahb_get_hs_divider();
|
||||
case SOC_CPU_CLK_SRC_PLL_F160M:
|
||||
soc_root_freq_mhz = CLK_LL_PLL_160M_FREQ_MHZ;
|
||||
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;
|
||||
case SOC_CPU_CLK_SRC_RC_FAST:
|
||||
soc_root_freq_mhz = 20;
|
||||
divider = clk_ll_ahb_get_ls_divider();
|
||||
divider = clk_ll_ahb_get_divider();
|
||||
break;
|
||||
default:
|
||||
// Unknown SOC_ROOT clock source
|
||||
|
@ -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);
|
||||
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_RTC_DREG, 1);
|
||||
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_DIG_DREG, 1);
|
||||
REG_SET_FIELD(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, HP_CALI_DBIAS);
|
||||
REG_SET_FIELD(PMU_HP_SLEEP_LP_REGULATOR0_REG, PMU_HP_SLEEP_LP_REGULATOR_DBIAS, LP_CALI_DBIAS);
|
||||
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);
|
||||
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
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "hal/clk_tree_ll.h"
|
||||
#include "hal/timer_ll.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "soc/pcr_reg.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "assert.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.
|
||||
* This feature counts the number of XTAL clock cycles within a given number of
|
||||
* RTC_SLOW_CLK cycles.
|
||||
*
|
||||
* Slow clock calibration feature has two modes of operation: one-off and cycling.
|
||||
* In cycling mode (which is enabled by default on SoC reset), counting of XTAL
|
||||
* cycles within RTC_SLOW_CLK cycle is done continuously. Cycling mode is enabled
|
||||
* using TIMG_RTC_CALI_START_CYCLING bit. In one-off mode counting is performed
|
||||
* once, and TIMG_RTC_CALI_RDY bit is set when counting is done. One-off mode is
|
||||
* enabled using TIMG_RTC_CALI_START bit.
|
||||
*/
|
||||
|
||||
/* On ESP32C5, TIMG_RTC_CALI_CLK_SEL can config to 0, 1, 2, 3
|
||||
* 0 or 3: calibrate RC_SLOW clock
|
||||
* 1: calibrate RC_FAST clock
|
||||
* 2: calibrate 32K clock, which 32k depends on reg_32k_sel: 0: Internal 32 kHz RC oscillator, 1: External 32 kHz XTAL, 2: External 32kHz clock input by lp_pad_gpio0
|
||||
*/
|
||||
#define TIMG_RTC_CALI_CLK_SEL_RC_SLOW 0
|
||||
#define TIMG_RTC_CALI_CLK_SEL_RC_FAST 1
|
||||
#define TIMG_RTC_CALI_CLK_SEL_32K 2
|
||||
#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))
|
||||
|
||||
/**
|
||||
* @brief Clock calibration function used by rtc_clk_cal
|
||||
*
|
||||
* Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0.
|
||||
* This feature counts the number of XTAL clock cycles within a given number of
|
||||
* RTC_SLOW_CLK cycles.
|
||||
*
|
||||
* Slow clock calibration feature has two modes of operation: one-off and cycling.
|
||||
* In cycling mode (which is enabled by default on SoC reset), counting of XTAL
|
||||
* cycles within RTC_SLOW_CLK cycle is done continuously. Cycling mode is enabled
|
||||
* using TIMG_RTC_CALI_START_CYCLING bit. In one-off mode counting is performed
|
||||
* once, and TIMG_RTC_CALI_RDY bit is set when counting is done. One-off mode is
|
||||
* enabled using TIMG_RTC_CALI_START bit.
|
||||
*
|
||||
* @param cal_clk which clock to calibrate
|
||||
* @param slowclk_cycles number of slow clock cycles to count
|
||||
* @return number of XTAL clock cycles within the given number of slow clock cycles
|
||||
*/
|
||||
static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
||||
{
|
||||
assert(slowclk_cycles < TIMG_RTC_CALI_MAX_V);
|
||||
|
||||
uint32_t cali_clk_sel = 0;
|
||||
soc_rtc_slow_clk_src_t slow_clk_src = rtc_clk_slow_src_get();
|
||||
soc_rtc_slow_clk_src_t old_32k_cal_clk_sel = clk_ll_32k_calibration_get_target();
|
||||
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 == RTC_CAL_RC_FAST) {
|
||||
// cali_clk_sel = TIMG_RTC_CALI_CLK_SEL_RC_FAST;
|
||||
// } else if (cal_clk == RTC_CAL_RC_SLOW) {
|
||||
// cali_clk_sel = TIMG_RTC_CALI_CLK_SEL_RC_SLOW;
|
||||
// } else
|
||||
{
|
||||
cali_clk_sel = TIMG_RTC_CALI_CLK_SEL_32K;
|
||||
clk_ll_32k_calibration_set_target((soc_rtc_slow_clk_src_t)cal_clk);
|
||||
if (cal_clk < 0 || cal_clk >= RTC_CAL_INVALID_CLK) {
|
||||
ESP_EARLY_LOGE(TAG, "clock not supported to be calibrated");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* 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
|
||||
// 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();
|
||||
}
|
||||
|
||||
// bool rc_fast_enabled = clk_ll_rc_fast_is_enabled();
|
||||
// bool dig_rc_fast_enabled = clk_ll_rc_fast_digi_is_enabled();
|
||||
// if (cal_clk == RTC_CAL_RC_FAST) {
|
||||
// if (!rc_fast_enabled) {
|
||||
// rtc_clk_8m_enable(true);
|
||||
// }
|
||||
// if (!dig_rc_fast_enabled) {
|
||||
// rtc_dig_clk8m_enable();
|
||||
// }
|
||||
// }
|
||||
bool rc_fast_enabled = clk_ll_rc_fast_is_enabled();
|
||||
bool dig_rc_fast_enabled = clk_ll_rc_fast_digi_is_enabled();
|
||||
if (cal_clk == RTC_CAL_RC_FAST) {
|
||||
if (!rc_fast_enabled) {
|
||||
rtc_clk_8m_enable(true);
|
||||
}
|
||||
if (!dig_rc_fast_enabled) {
|
||||
rtc_dig_clk8m_enable();
|
||||
}
|
||||
}
|
||||
|
||||
bool rc32k_enabled = clk_ll_rc32k_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 */
|
||||
// calibration clock source is set by PCR register: PCR_32K_SEL
|
||||
// REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cali_clk_sel);
|
||||
REG_SET_FIELD(PCR_CTRL_32K_CONF_REG, PCR_32K_SEL, cal_clk);
|
||||
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);
|
||||
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles);
|
||||
/* Figure out how long to wait for calibration to finish */
|
||||
|
||||
/* Set timeout reg and expect time delay*/
|
||||
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, CLK_CAL_TIMEOUT_THRES(cal_clk, slowclk_cycles));
|
||||
uint32_t expected_freq;
|
||||
if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_32K) {
|
||||
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_32K_CAL_TIMEOUT_THRES(slowclk_cycles));
|
||||
if (cal_clk == RTC_CAL_RC32K || cal_clk == RTC_CAL_32K_XTAL || cal_clk == RTC_CAL_32K_OSC_SLOW) {
|
||||
expected_freq = SOC_CLK_XTAL32K_FREQ_APPROX;
|
||||
} 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));
|
||||
expected_freq = SOC_CLK_RC_FAST_FREQ_APPROX;
|
||||
} else if (cal_clk == RTC_CAL_RC_FAST) {
|
||||
expected_freq = SOC_CLK_RC_FAST_FREQ_APPROX >> CLK_LL_RC_FAST_TICK_DIV_BITS;
|
||||
} 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;
|
||||
}
|
||||
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)) {
|
||||
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 32.
|
||||
// So we need to multiply the frequency of the FOSC by 32 times.*/
|
||||
// if (cal_clk == RTC_CAL_RC_FAST) {
|
||||
// cal_val = cal_val >> 5;
|
||||
// }
|
||||
/*The Fosc CLK of calibration circuit is divided by a factor, k.
|
||||
So we need to multiply the frequency of the FOSC by k times.*/
|
||||
if (cal_clk == RTC_CAL_RC_FAST) {
|
||||
cal_val = cal_val >> CLK_LL_RC_FAST_TICK_DIV_BITS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
// if (cal_clk == RTC_CAL_RC_FAST) {
|
||||
// if (!dig_rc_fast_enabled) {
|
||||
// rtc_dig_clk8m_disable();
|
||||
// }
|
||||
// if (!rc_fast_enabled) {
|
||||
// rtc_clk_8m_enable(false);
|
||||
// }
|
||||
// }
|
||||
if (cal_clk == RTC_CAL_RC_FAST) {
|
||||
if (!dig_rc_fast_enabled) {
|
||||
rtc_dig_clk8m_disable();
|
||||
}
|
||||
if (!rc_fast_enabled) {
|
||||
rtc_clk_8m_enable(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (cal_clk == RTC_CAL_RC32K) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -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)
|
||||
{
|
||||
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.
|
||||
// So we need to divide the calibrate cycles of the FOSC by 32 to
|
||||
// avoid excessive calibration time.*/
|
||||
// if (cal_clk == RTC_CAL_RC_FAST) {
|
||||
// slowclk_cycles = slowclk_cycles >> 5;
|
||||
// }
|
||||
|
||||
/*The Fosc CLK of calibration circuit is divided by a factor, k.
|
||||
So we need to divide the calibrate cycles of the FOSC by k to
|
||||
avoid excessive calibration time.*/
|
||||
if (cal_clk == RTC_CAL_RC_FAST) {
|
||||
slowclk_cycles = slowclk_cycles >> CLK_LL_RC_FAST_TICK_DIV_BITS;
|
||||
}
|
||||
|
||||
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)) {
|
||||
@ -246,8 +208,7 @@ uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period)
|
||||
|
||||
uint64_t rtc_time_get(void)
|
||||
{
|
||||
ESP_EARLY_LOGW(TAG, "rtc_timer has not been implemented yet");
|
||||
return 0;
|
||||
return lp_timer_hal_get_cycle_count();
|
||||
}
|
||||
|
||||
uint32_t rtc_clk_freq_cal(uint32_t cal_val)
|
||||
|
@ -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_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;
|
||||
esp_rom_output_tx_wait_idle(0);
|
||||
rtc_clk_xtal_freq_update(xtal_freq);
|
||||
|
@ -125,6 +125,9 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
|
||||
|
||||
/* Prepare calibration */
|
||||
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cali_clk_sel);
|
||||
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);
|
||||
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles);
|
||||
/* 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) {
|
||||
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;
|
||||
if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) {
|
||||
expected_freq = expected_freq >> CLK_LL_RC_FAST_TICK_DIV_BITS;
|
||||
}
|
||||
} 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;
|
||||
@ -160,7 +166,7 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
|
||||
calibration. */
|
||||
if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -221,7 +227,7 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
||||
avoid excessive calibration time.*/
|
||||
if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) {
|
||||
if (cal_clk == RTC_CAL_RC_FAST) {
|
||||
slowclk_cycles = slowclk_cycles >> 5;
|
||||
slowclk_cycles = slowclk_cycles >> CLK_LL_RC_FAST_TICK_DIV_BITS;
|
||||
SET_PERI_REG_MASK(PCR_CTRL_TICK_CONF_REG, PCR_TICK_ENABLE);
|
||||
}
|
||||
}
|
||||
|
@ -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_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;
|
||||
esp_rom_output_tx_wait_idle(0);
|
||||
rtc_clk_xtal_freq_update(xtal_freq);
|
||||
|
@ -125,6 +125,9 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
|
||||
|
||||
/* Prepare calibration */
|
||||
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cali_clk_sel);
|
||||
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);
|
||||
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles);
|
||||
/* 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) {
|
||||
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;
|
||||
if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 2)) {
|
||||
expected_freq = expected_freq >> CLK_LL_RC_FAST_TICK_DIV_BITS;
|
||||
}
|
||||
} 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;
|
||||
@ -160,7 +166,7 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc
|
||||
calibration. */
|
||||
if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 2)) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -221,7 +227,7 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
||||
avoid excessive calibration time.*/
|
||||
if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 2)) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,9 @@ static esp_clk_tree_calibrated_freq_t s_calibrated_freq = {};
|
||||
#define DEFAULT_32K_CLK_CAL_CYCLES 100
|
||||
/* 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
|
||||
// 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
|
||||
case SOC_RTC_FAST_CLK_SRC_LP_PLL:
|
||||
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
|
||||
default:
|
||||
// Invalid clock source
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include "esp_attr.h"
|
||||
#include "soc/i2c_ana_mst_reg.h"
|
||||
#include "modem/modem_lpcon_reg.h"
|
||||
#include "soc/pmu_reg.h"
|
||||
|
||||
#define REGI2C_BIAS_MST_SEL (BIT(8))
|
||||
#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;
|
||||
|
||||
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. */
|
||||
switch (block) {
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include "esp_private/esp_pmu.h"
|
||||
#include "esp_rom_uart.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "ocode_init.h"
|
||||
|
||||
/* 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
|
||||
@ -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";
|
||||
|
||||
// TODO: [ESP32C5] IDF-8642
|
||||
void esp_rtc_init(void)
|
||||
{
|
||||
#if !CONFIG_IDF_ENV_FPGA
|
||||
#if SOC_PMU_SUPPORTED
|
||||
pmu_init();
|
||||
#endif
|
||||
if (esp_rom_get_reset_reason(0) == RESET_REASON_CHIP_POWER_ON) {
|
||||
esp_ocode_calib_init();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// TODO: [ESP32C5] IDF-8642
|
||||
__attribute__((weak)) void esp_clk_init(void)
|
||||
{
|
||||
#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.
|
||||
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);
|
||||
}
|
||||
|
||||
@ -195,7 +187,8 @@ void rtc_clk_select_rtc_slow_clk(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();
|
||||
/* During system initialization, the low-power clock source of the modem
|
||||
* (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
|
||||
: MODEM_CLOCK_LPCLK_SRC_RC32K);
|
||||
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");
|
||||
#if 0 // TODO: [ESP32C5] IDF-8844
|
||||
|
@ -3,8 +3,9 @@ menu "Serial flasher config"
|
||||
|
||||
config ESPTOOLPY_NO_STUB
|
||||
bool "Disable download stub"
|
||||
default "y" if IDF_ENV_FPGA || IDF_ENV_BRINGUP
|
||||
default "n"
|
||||
default y if IDF_ENV_FPGA || IDF_ENV_BRINGUP
|
||||
default y if IDF_TARGET_ESP32C5 # TODO: IDF-8631 to be removed
|
||||
default n
|
||||
|
||||
help
|
||||
The flasher tool sends a precompiled download stub first by default. That stub allows things
|
||||
|
@ -56,7 +56,7 @@ if(NOT BOOTLOADER_BUILD)
|
||||
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")
|
||||
endif()
|
||||
|
||||
|
@ -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) {
|
||||
case SOC_CPU_CLK_SRC_XTAL:
|
||||
return clk_hal_xtal_get_freq_mhz();
|
||||
case SOC_CPU_CLK_SRC_PLL:
|
||||
return clk_ll_bbpll_get_freq_mhz();
|
||||
case SOC_CPU_CLK_SRC_PLL_F160M:
|
||||
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:
|
||||
return SOC_CLK_RC_FAST_FREQ_APPROX / MHZ;
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
uint32_t clk_hal_ahb_get_freq_hz(void)
|
||||
{
|
||||
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
|
||||
uint32_t divider = (source == SOC_CPU_CLK_SRC_PLL) ? clk_ll_ahb_get_hs_divider() : clk_ll_ahb_get_ls_divider();
|
||||
|
||||
uint32_t divider = clk_ll_ahb_get_divider();
|
||||
return clk_hal_soc_root_get_freq_mhz(source) * MHZ / divider;
|
||||
}
|
||||
|
||||
|
@ -40,12 +40,8 @@ extern "C" {
|
||||
.dbuf = 1, \
|
||||
}
|
||||
|
||||
/*
|
||||
Set the frequency division factor of ref_tick
|
||||
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?
|
||||
// Fix default division factor for the RC_FAST clock for calibration to be 32
|
||||
#define CLK_LL_RC_FAST_TICK_DIV_BITS 5
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
@ -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 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 dr1;
|
||||
uint8_t dr3;
|
||||
uint8_t dchgp;
|
||||
uint8_t dbias;
|
||||
uint8_t dcur;
|
||||
uint8_t dchgp = 5;
|
||||
uint8_t dbias = 3;
|
||||
uint8_t href = 3;
|
||||
uint8_t lref = 1;
|
||||
|
||||
/* Configure 480M PLL */
|
||||
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:
|
||||
default:
|
||||
div_ref = 0;
|
||||
div7_0 = 8;
|
||||
div_ref = 1;
|
||||
div7_0 = 12;
|
||||
dr1 = 0;
|
||||
dr3 = 0;
|
||||
break;
|
||||
default:
|
||||
div_ref = 1;
|
||||
div7_0 = 12;
|
||||
dr1 = 0;
|
||||
dr3 = 0;
|
||||
dchgp = 5;
|
||||
dcur = 3;
|
||||
dbias = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref);
|
||||
uint8_t i2c_bbpll_div_7_0 = div7_0;
|
||||
uint8_t i2c_bbpll_dcur = (1 << I2C_BBPLL_OC_DLREF_SEL_LSB ) | (3 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur;
|
||||
|
||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref);
|
||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0);
|
||||
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1);
|
||||
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR3, dr3);
|
||||
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DCUR, i2c_bbpll_dcur);
|
||||
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
*
|
||||
@ -354,12 +366,15 @@ static inline __attribute__((always_inline)) void clk_ll_cpu_set_src(soc_cpu_clk
|
||||
case SOC_CPU_CLK_SRC_XTAL:
|
||||
PCR.sysclk_conf.soc_clk_sel = 0;
|
||||
break;
|
||||
case SOC_CPU_CLK_SRC_PLL:
|
||||
case SOC_CPU_CLK_SRC_RC_FAST:
|
||||
PCR.sysclk_conf.soc_clk_sel = 1;
|
||||
break;
|
||||
case SOC_CPU_CLK_SRC_RC_FAST:
|
||||
case SOC_CPU_CLK_SRC_PLL_F160M:
|
||||
PCR.sysclk_conf.soc_clk_sel = 2;
|
||||
break;
|
||||
case SOC_CPU_CLK_SRC_PLL_F240M:
|
||||
PCR.sysclk_conf.soc_clk_sel = 3;
|
||||
break;
|
||||
default:
|
||||
// Unsupported SOC_CLK mux input sel
|
||||
abort();
|
||||
@ -378,9 +393,11 @@ static inline __attribute__((always_inline)) soc_cpu_clk_src_t clk_ll_cpu_get_sr
|
||||
case 0:
|
||||
return SOC_CPU_CLK_SRC_XTAL;
|
||||
case 1:
|
||||
return SOC_CPU_CLK_SRC_PLL;
|
||||
case 2:
|
||||
return SOC_CPU_CLK_SRC_RC_FAST;
|
||||
case 2:
|
||||
return SOC_CPU_CLK_SRC_PLL_F160M;
|
||||
case 3:
|
||||
return SOC_CPU_CLK_SRC_PLL_F240M;
|
||||
default:
|
||||
// Invalid SOC_CLK_SEL value
|
||||
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
|
||||
// (1) not configurable for the target (HRO register field: PCR_HS_DIV_NUM)
|
||||
// Fixed at 3 for HS clock source
|
||||
// Corresponding register field value is PCR_HS_DIV_NUM=2
|
||||
// (2) configurable
|
||||
// HS divider option: 1, 2, 4 (PCR_CPU_HS_DIV_NUM=0, 1, 3)
|
||||
|
||||
HAL_ASSERT(divider == 3 || divider == 4 || divider == 6 || divider == 12);
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.cpu_freq_conf, cpu_div_num, (divider / 3) - 1);
|
||||
|
||||
// 120MHz CPU freq cannot be achieved through divider, need to set force_120m
|
||||
// This field is only valid if PCR_CPU_HS_DIV_NUM=0 and PCR_SOC_CLK_SEL=SOC_CPU_CLK_SRC_PLL
|
||||
// bool force_120m = (divider == 4) ? 1 : 0;
|
||||
// PCR.cpu_freq_conf.cpu_hs_120m_force = force_120m;
|
||||
HAL_ASSERT(divider >= 1);
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.cpu_freq_conf, cpu_div_num, (divider) - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
// (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);
|
||||
return HAL_FORCE_READ_U32_REG_FIELD(PCR.cpu_freq_conf, cpu_div_num) + 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).
|
||||
*/
|
||||
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
|
||||
* Constraint: f_ahb <= 48 MHz, f_cpu = n * f_ahb
|
||||
*
|
||||
* @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);
|
||||
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_ASSERT(divider >= 1);
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ahb_freq_conf, ahb_div_num, divider - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get AHB_CLK's high-speed divider
|
||||
* @brief Get AHB_CLK'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);
|
||||
uint32_t hp_root_hs_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.sysclk_conf, hs_div_num);
|
||||
return (hp_root_hs_div + 1) * (ahb_hs_div + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get AHB_CLK's low-speed divider
|
||||
*
|
||||
* @return Divider. Divider = (PCR_LS_DIV_NUM + 1) * (PCR_AHB_LS_DIV_NUM + 1).
|
||||
*/
|
||||
static inline __attribute__((always_inline)) uint32_t clk_ll_ahb_get_ls_divider(void)
|
||||
{
|
||||
uint32_t ahb_ls_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.ahb_freq_conf, ahb_div_num);
|
||||
uint32_t hp_root_ls_div = HAL_FORCE_READ_U32_REG_FIELD(PCR.sysclk_conf, ls_div_num);
|
||||
return (hp_root_ls_div + 1) * (ahb_ls_div + 1);
|
||||
return HAL_FORCE_READ_U32_REG_FIELD(PCR.ahb_freq_conf, ahb_div_num) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
*
|
||||
@ -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:
|
||||
LP_CLKRST.lp_clk_conf.fast_clk_sel = 1;
|
||||
break;
|
||||
case SOC_RTC_FAST_CLK_SRC_XTAL:
|
||||
LP_CLKRST.lp_clk_conf.fast_clk_sel = 2;
|
||||
break;
|
||||
default:
|
||||
// Unsupported RTC_FAST_CLK mux input sel
|
||||
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;
|
||||
case 1:
|
||||
return SOC_RTC_FAST_CLK_SRC_XTAL_D2;
|
||||
case 2:
|
||||
return SOC_RTC_FAST_CLK_SRC_XTAL;
|
||||
default:
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
*
|
||||
@ -753,49 +604,6 @@ static inline __attribute__((always_inline)) void clk_ll_rc_slow_set_divider(uin
|
||||
}
|
||||
|
||||
/************************** 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
|
||||
*
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
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
|
||||
}
|
||||
#endif
|
||||
|
@ -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,
|
||||
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
|
||||
@ -810,7 +811,7 @@ Set the frequency division factor of ref_tick
|
||||
*/
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
|
@ -808,7 +808,7 @@ 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;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.ctrl_32k_conf, fosc_tick_num, REG_FOSC_TICK_NUM); // divider = (REG_FOSC_TICK_NUM + 1) = 256
|
||||
}
|
||||
|
||||
|
||||
|
@ -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,
|
||||
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
|
||||
@ -746,7 +747,7 @@ Set the frequency division factor of ref_tick
|
||||
*/
|
||||
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
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -131,6 +131,10 @@ config SOC_SECURE_BOOT_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PMU_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_LP_TIMER_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
@ -139,6 +143,10 @@ config SOC_LP_PERIPHERALS_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_CLK_TREE_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_SPI_FLASH_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
@ -847,6 +855,14 @@ config SOC_UART_BITRATE_MAX
|
||||
int
|
||||
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
|
||||
bool
|
||||
default y
|
||||
@ -895,6 +911,10 @@ config SOC_PM_SUPPORT_RTC_PERIPH_PD
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_CLK_RC_FAST_SUPPORT_CALIBRATION
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_MODEM_CLOCK_IS_INDEPENDENT
|
||||
bool
|
||||
default y
|
||||
@ -911,6 +931,10 @@ config SOC_CLK_RC32K_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_CLK_LP_FAST_SUPPORT_XTAL
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_RCC_IS_INDEPENDENT
|
||||
bool
|
||||
default y
|
||||
|
@ -19,7 +19,7 @@ extern "C" {
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
@ -45,7 +45,6 @@ extern "C" {
|
||||
* 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% */
|
||||
#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 */
|
||||
@ -60,10 +59,10 @@ extern "C" {
|
||||
/**
|
||||
* @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_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_INT_RC32K, /*!< Internal 32kHz RC oscillator */
|
||||
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
|
||||
* @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_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_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_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
|
||||
* @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_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 */
|
||||
@ -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
|
||||
* @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_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` */
|
||||
@ -125,7 +123,7 @@ typedef enum {
|
||||
*
|
||||
* @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
|
||||
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
|
||||
@ -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_XTAL32K, /*!< XTAL32K_CLK comes from the external 32kHz crystal, passing a clock gating to the peripherals */
|
||||
SOC_MOD_CLK_RC_FAST, /*!< RC_FAST_CLK comes from the internal 20MHz rc oscillator, passing a clock gating to the peripherals */
|
||||
SOC_MOD_CLK_XTAL, /*!< XTAL_CLK comes from the external 40MHz crystal */
|
||||
SOC_MOD_CLK_XTAL, /*!< XTAL_CLK comes from the external 48MHz crystal */
|
||||
// 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_module_clk_t;
|
||||
@ -548,7 +546,7 @@ typedef enum { // TODO: [ESP32C5] IDF-8649
|
||||
} soc_periph_mspi_clk_src_t;
|
||||
|
||||
//////////////////////////////////////////////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_XTAL = 5, /*!< Main crystal oscillator clock */
|
||||
CLKOUT_SIG_PLL_F80M = 13, /*!< From PLL, usually be 80MHz */
|
||||
|
@ -1902,21 +1902,6 @@ extern "C" {
|
||||
* SYSCLK configuration register
|
||||
*/
|
||||
#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;
|
||||
* Configures to select the clock source of HP_ROOT_CLK.\\
|
||||
* 0 (default): XTAL_CLK\\
|
||||
|
@ -1642,15 +1642,7 @@ typedef union {
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
/** ls_div_num : HRO; bitpos: [7:0]; default: 0;
|
||||
* clk_hproot is div1 of low-speed clock-source if clck-source is a low-speed
|
||||
* clock-source such as XTAL/FOSC.
|
||||
*/
|
||||
uint32_t ls_div_num:8;
|
||||
/** hs_div_num : HRO; bitpos: [15:8]; default: 2;
|
||||
* clk_hproot is div3 of SPLL if the clock-source is high-speed clock SPLL.
|
||||
*/
|
||||
uint32_t hs_div_num:8;
|
||||
uint32_t reserved_0:16;
|
||||
/** soc_clk_sel : R/W; bitpos: [17:16]; default: 0;
|
||||
* Configures to select the clock source of HP_ROOT_CLK.\\
|
||||
* 0 (default): XTAL_CLK\\
|
||||
@ -1706,7 +1698,7 @@ typedef union {
|
||||
typedef union {
|
||||
struct {
|
||||
/** 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
|
||||
* clock-source such as XTAL/FOSC, and should be used together with PCR_AHB_DIV_NUM.
|
||||
*/
|
||||
@ -1722,7 +1714,7 @@ typedef union {
|
||||
typedef union {
|
||||
struct {
|
||||
/** 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
|
||||
* low-speed clock-source such as XTAL/FOSC, and should be used together with
|
||||
* PCR_CPU_DIV_NUM.
|
||||
@ -1749,7 +1741,7 @@ typedef union {
|
||||
*/
|
||||
uint32_t apb_decrease_div_num:8;
|
||||
/** 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.
|
||||
*/
|
||||
uint32_t apb_div_num:8;
|
||||
@ -1764,47 +1756,47 @@ typedef union {
|
||||
typedef union {
|
||||
struct {
|
||||
/** 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.
|
||||
*/
|
||||
uint32_t pll_240m_clk_en: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.
|
||||
*/
|
||||
uint32_t pll_160m_clk_en: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.
|
||||
*/
|
||||
uint32_t pll_120m_clk_en: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.
|
||||
*/
|
||||
uint32_t pll_80m_clk_en: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.
|
||||
*/
|
||||
uint32_t pll_60m_clk_en: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.
|
||||
*/
|
||||
uint32_t pll_48m_clk_en: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.
|
||||
*/
|
||||
uint32_t pll_40m_clk_en: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.
|
||||
*/
|
||||
uint32_t pll_20m_clk_en: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.
|
||||
*/
|
||||
uint32_t pll_12m_clk_en:1;
|
||||
|
@ -58,14 +58,14 @@
|
||||
#define SOC_SECURE_BOOT_SUPPORTED 1
|
||||
// #define SOC_BOD_SUPPORTED 1 // TODO: [ESP32C5] IDF-8647
|
||||
// #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_LP_TIMER_SUPPORTED 1
|
||||
// #define SOC_LP_AON_SUPPORTED 1 // TODO: [ESP32C5] IDF-8638
|
||||
#define SOC_LP_PERIPHERALS_SUPPORTED 1
|
||||
// #define SOC_LP_I2C_SUPPORTED 1 // TODO: [ESP32C5] IDF-8634
|
||||
// #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_WDT_SUPPORTED 1 // TODO: [ESP32C5] IDF-8650
|
||||
#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_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_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_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 */
|
||||
#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_HAS_LP_UART (1) /*!< Support LP UART */
|
||||
@ -545,12 +545,13 @@
|
||||
// #define SOC_PM_PAU_LINK_NUM (4)
|
||||
|
||||
/*-------------------------- 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_CLK_XTAL32K_SUPPORTED (1) /*!< Support to connect an external low frequency crystal */
|
||||
#define SOC_CLK_OSC_SLOW_SUPPORTED (1) /*!< Support to connect an external oscillator, not a crystal */
|
||||
#define SOC_CLK_RC32K_SUPPORTED (1) /*!< Support an internal 32kHz RC oscillator */
|
||||
#define SOC_CLK_LP_FAST_SUPPORT_XTAL (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 */
|
||||
|
||||
|
@ -97,7 +97,6 @@ api-reference/peripherals/lcd.rst
|
||||
api-reference/peripherals/ana_cmpr.rst
|
||||
api-reference/peripherals/temp_sensor.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_override_driver.rst
|
||||
api-reference/peripherals/spi_flash/spi_flash_optional_feature.rst
|
||||
|
@ -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_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"}
|
||||
|
||||
|
@ -166,7 +166,7 @@ The source clock can also limit the PWM frequency. The higher the source clock f
|
||||
- ~ 17.5 MHz
|
||||
- Dynamic Frequency Scaling compatible, Light sleep compatible
|
||||
* - XTAL_CLK
|
||||
- 48/40 MHz
|
||||
- 48 MHz
|
||||
- Dynamic Frequency Scaling compatible
|
||||
|
||||
.. only:: esp32c6
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
{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"}
|
||||
|
||||
|
@ -166,7 +166,7 @@ LED PWM 控制器可在无需 CPU 干预的情况下自动改变占空比,实
|
||||
- ~ 17.5 MHz
|
||||
- 支持动态调频 (DFS) 功能,支持 Light-sleep 模式
|
||||
* - XTAL_CLK
|
||||
- 48/40 MHz
|
||||
- 48 MHz
|
||||
- 支持动态调频 (DFS) 功能
|
||||
|
||||
.. only:: esp32c6
|
||||
|
Loading…
Reference in New Issue
Block a user