Merge branch 'feature/esp32c6_clock_basic_support' into 'master'

clk: Add basic clock support for esp32c6

Closes IDF-5630, IDF-5973, IDF-5346, and IDF-6050

See merge request espressif/esp-idf!21149
This commit is contained in:
Song Ruo Jing 2022-12-14 02:22:49 +08:00
commit edd815af2e
59 changed files with 1223 additions and 675 deletions

View File

@ -13,7 +13,6 @@ mainmenu "Espressif IoT Development Framework Configuration"
config IDF_ENV_FPGA
# This option is for internal use only
bool
default "y" if IDF_TARGET_ESP32C6 # TODO: IDF-5630
option env="IDF_ENV_FPGA"
config IDF_CI_BUILD

View File

@ -52,15 +52,28 @@ __attribute__((weak)) void bootloader_clock_configure(void)
if (esp_rom_get_reset_reason(0) != RESET_REASON_CPU0_SW || rtc_clk_apb_freq_get() < APB_CLK_FREQ) {
rtc_clk_config_t clk_cfg = RTC_CLK_CONFIG_DEFAULT();
clk_cfg.cpu_freq_mhz = cpu_freq_mhz;
// 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;
}
#if CONFIG_IDF_TARGET_ESP32C6
// TODO: IDF-5781 Some of esp32c6 SOC_RTC_FAST_CLK_SRC_XTAL_D2 rtc_fast clock has timing issue
// Force to use SOC_RTC_FAST_CLK_SRC_RC_FAST since 2nd stage bootloader
clk_cfg.fast_clk_src = SOC_RTC_FAST_CLK_SRC_RC_FAST;
#else
// 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
clk_cfg.fast_clk_src = rtc_clk_fast_src_get();
if (clk_cfg.fast_clk_src == SOC_RTC_FAST_CLK_SRC_INVALID) {
clk_cfg.fast_clk_src = SOC_RTC_FAST_CLK_SRC_XTAL_DIV;
}
#endif
rtc_clk_init(clk_cfg);
}
@ -82,15 +95,15 @@ __attribute__((weak)) void bootloader_clock_configure(void)
CLEAR_PERI_REG_MASK(LP_TIMER_LP_INT_ENA_REG, LP_TIMER_MAIN_TIMER_LP_INT_ENA); /* MAIN_TIMER */
CLEAR_PERI_REG_MASK(LP_ANALOG_PERI_LP_ANA_LP_INT_ENA_REG, LP_ANALOG_PERI_LP_ANA_BOD_MODE0_LP_INT_ENA); /* BROWN_OUT */
CLEAR_PERI_REG_MASK(LP_WDT_INT_ENA_REG, LP_WDT_LP_WDT_INT_ENA); /* WDT */
CLEAR_PERI_REG_MASK(PMU_HP_INT_ENA_REG, PMU_SOC_WAKEUP_INT_ENA); /* SLP_REJECT */
CLEAR_PERI_REG_MASK(PMU_SOC_SLEEP_REJECT_INT_ENA, PMU_SOC_SLEEP_REJECT_INT_ENA); /* SLP_WAKEUP */
// CLEAR_PERI_REG_MASK(PMU_HP_INT_ENA_REG, PMU_SOC_WAKEUP_INT_ENA); // TODO: IDF-5348 /* SLP_REJECT */
// CLEAR_PERI_REG_MASK(PMU_SOC_SLEEP_REJECT_INT_ENA, PMU_SOC_SLEEP_REJECT_INT_ENA); /* SLP_WAKEUP */
// SET CLR
SET_PERI_REG_MASK(LP_WDT_INT_CLR_REG, LP_WDT_SUPER_WDT_INT_CLR); /* SWD */
SET_PERI_REG_MASK(LP_TIMER_LP_INT_CLR_REG, LP_TIMER_MAIN_TIMER_LP_INT_CLR); /* MAIN_TIMER */
SET_PERI_REG_MASK(LP_ANALOG_PERI_LP_ANA_LP_INT_CLR_REG, LP_ANALOG_PERI_LP_ANA_BOD_MODE0_LP_INT_CLR); /* BROWN_OUT */
SET_PERI_REG_MASK(LP_WDT_INT_CLR_REG, LP_WDT_LP_WDT_INT_CLR); /* WDT */
SET_PERI_REG_MASK(PMU_HP_INT_CLR_REG, PMU_SOC_WAKEUP_INT_CLR); /* SLP_REJECT */
SET_PERI_REG_MASK(PMU_SOC_SLEEP_REJECT_INT_CLR, PMU_SOC_SLEEP_REJECT_INT_CLR); /* SLP_WAKEUP */
// SET_PERI_REG_MASK(PMU_HP_INT_CLR_REG, PMU_SOC_WAKEUP_INT_CLR); // TODO: IDF-5348 /* SLP_REJECT */
// SET_PERI_REG_MASK(PMU_SOC_SLEEP_REJECT_INT_CLR, PMU_SOC_SLEEP_REJECT_INT_CLR); /* SLP_WAKEUP */
#else
REG_WRITE(RTC_CNTL_INT_ENA_REG, 0);
REG_WRITE(RTC_CNTL_INT_CLR_REG, UINT32_MAX);

View File

@ -227,7 +227,7 @@ static void bootloader_super_wdt_auto_feed(void)
static inline void bootloader_hardware_init(void)
{
// TODO: IDF-5990 need update, enable i2c mst clk by force on temporarily
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);
SET_PERI_REG_MASK(MODEM_LPCON_I2C_MST_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_SEL_160M);
}

View File

@ -97,6 +97,11 @@ esp_err_t timer_get_counter_time_sec(timer_group_t group_num, timer_idx_t timer_
case TIMER_SRC_CLK_PLL_F40M:
*time = (double)timer_val * div / (40 * 1000 * 1000);
break;
#endif
#if SOC_TIMER_GROUP_SUPPORT_PLL_F80M
case TIMER_SRC_CLK_PLL_F80M:
*time = (double)timer_val * div / (80 * 1000 * 1000);
break;
#endif
default:
ESP_RETURN_ON_FALSE(false, ESP_ERR_INVALID_ARG, TIMER_TAG, "invalid clock source");

View File

@ -411,6 +411,18 @@ static esp_err_t gptimer_select_periph_clock(gptimer_t *timer, gptimer_clock_sou
#endif
break;
#endif // SOC_TIMER_GROUP_SUPPORT_PLL_F40M
#if SOC_TIMER_GROUP_SUPPORT_PLL_F80M
case GPTIMER_CLK_SRC_PLL_F80M:
counter_src_hz = 80 * 1000 * 1000;
#if CONFIG_PM_ENABLE
sprintf(timer->pm_lock_name, "gptimer_%d_%d", timer->group->group_id, timer_id); // e.g. gptimer_0_0
// ESP32C6 PLL_F80M is available when SOC_ROOT_CLK switchs to XTAL
ret = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, timer->pm_lock_name, &timer->pm_lock);
ESP_RETURN_ON_ERROR(ret, TAG, "create NO_LIGHT_SLEEP lock failed");
ESP_LOGD(TAG, "install NO_LIGHT_SLEEP lock for timer (%d,%d)", timer->group->group_id, timer_id);
#endif
break;
#endif // SOC_TIMER_GROUP_SUPPORT_PLL_F80M
#if SOC_TIMER_GROUP_SUPPORT_AHB
case GPTIMER_CLK_SRC_AHB:
// TODO: decide which kind of PM lock we should use for such clock

View File

@ -488,8 +488,19 @@ uint32_t i2s_get_source_clk_freq(i2s_clock_src_t clk_src, uint32_t mclk_freq_hz)
(void)mclk_freq_hz;
return esp_clk_xtal_freq();
#endif
default: // I2S_CLK_SRC_PLL_160M
return esp_clk_apb_freq() * 2;
#if SOC_I2S_SUPPORTS_PLL_F160M
case I2S_CLK_SRC_PLL_160M:
(void)mclk_freq_hz;
return I2S_LL_PLL_F160M_CLK_FREQ;
#endif
#if SOC_I2S_SUPPORTS_PLL_F96M
case I2S_CLK_SRC_PLL_96M:
(void)mclk_freq_hz;
return I2S_LL_PLL_F96M_CLK_FREQ;
#endif
default:
// Invalid clock source
return 0;
}
}

View File

@ -535,10 +535,8 @@ TEST_CASE("LEDC timer select specific clock source", "[ledc]")
TEST_ESP_OK(ledc_channel_config(&ledc_ch_config));
if (test_speed_mode == LEDC_LOW_SPEED_MODE) {
#if !CONFIG_IDF_TARGET_ESP32C6 // Temporary. RC_FAST not able to calibrate currently. Can be removed once IDF-5346 done.
printf("Check LEDC_USE_RTC8M_CLK for a 100Hz signal\n");
timer_set_clk_src_and_freq_test(test_speed_mode, LEDC_USE_RTC8M_CLK, 10, 100);
#endif
#if SOC_LEDC_SUPPORT_XTAL_CLOCK
printf("Check LEDC_USE_XTAL_CLK for a 400Hz signal\n");
timer_set_clk_src_and_freq_test(test_speed_mode, LEDC_USE_XTAL_CLK, 13, 400);

View File

@ -123,6 +123,10 @@ TEST_CASE("GPIO flex glitch filter enable/disable", "[gpio_filter]")
printf("generate rising edge glitch signal\r\n");
asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
asm volatile("csrrci zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
// should timeout, because the glitch is filtered out
@ -133,6 +137,10 @@ TEST_CASE("GPIO flex glitch filter enable/disable", "[gpio_filter]")
printf("generate rising edge glitch signal again\r\n");
asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
asm volatile("csrrsi zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
asm volatile("csrrci zero, %0, 0x1" :: "i"(CSR_GPIO_OUT_USER));
// this time we should see the GPIO interrupt fired up

View File

@ -71,7 +71,12 @@ 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
return rtc_clk_apb_freq_get();
#else
return MIN(s_get_cpu_freq_mhz() * MHZ, APB_CLK_FREQ);
#endif
}
int IRAM_ATTR esp_clk_xtal_freq(void)

View File

@ -167,7 +167,7 @@ static void calibrate_ocode(void)
soc_rtc_slow_clk_src_t slow_clk_src = rtc_clk_slow_src_get();
rtc_cal_sel_t cal_clk = RTC_CAL_RTC_MUX;
if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) {
cal_clk = RTC_CAL_EXT_32K;
cal_clk = RTC_CAL_32K_OSC_SLOW;
} else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) {
cal_clk = RTC_CAL_8MD256;
}

View File

@ -40,14 +40,14 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
if (cal_clk == RTC_CAL_RTC_MUX) {
soc_rtc_slow_clk_src_t slow_clk_src = rtc_clk_slow_src_get();
if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) {
cal_clk = RTC_CAL_EXT_32K;
cal_clk = RTC_CAL_32K_OSC_SLOW;
} else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) {
cal_clk = RTC_CAL_8MD256;
}
}
/* Enable requested clock (150k clock is always on) */
bool dig_ext_clk_enabled = clk_ll_xtal32k_digi_is_enabled();
if (cal_clk == RTC_CAL_EXT_32K && !dig_ext_clk_enabled) {
if (cal_clk == RTC_CAL_32K_OSC_SLOW && !dig_ext_clk_enabled) {
clk_ll_xtal32k_digi_enable();
}
@ -78,7 +78,7 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
/* Set timeout reg and expect time delay*/
uint32_t expected_freq;
if (cal_clk == RTC_CAL_EXT_32K) {
if (cal_clk == RTC_CAL_32K_OSC_SLOW) {
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_X32K_CAL_TIMEOUT_THRES(slowclk_cycles));
expected_freq = SOC_CLK_OSC_SLOW_FREQ_APPROX;
} else if (cal_clk == RTC_CAL_8MD256) {
@ -109,7 +109,7 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
/* if dig_ext_clk was originally off and enabled due to calibration, then set back to off state */
if (cal_clk == RTC_CAL_EXT_32K && !dig_ext_clk_enabled) {
if (cal_clk == RTC_CAL_32K_OSC_SLOW && !dig_ext_clk_enabled) {
clk_ll_xtal32k_digi_disable();
}
@ -141,7 +141,7 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get();
uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles);
if ((cal_clk == RTC_CAL_EXT_32K) && !rtc_clk_cal_32k_valid(xtal_freq, slowclk_cycles, xtal_cycles)) {
if ((cal_clk == RTC_CAL_32K_OSC_SLOW) && !rtc_clk_cal_32k_valid(xtal_freq, slowclk_cycles, xtal_cycles)) {
return 0;
}

View File

@ -238,8 +238,8 @@ void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config)
div = clk_ll_cpu_get_divider();
source_freq_mhz = (uint32_t)rtc_clk_xtal_freq_get();
freq_mhz = source_freq_mhz / div;
break;
}
break;
case SOC_CPU_CLK_SRC_PLL: {
freq_mhz = clk_ll_cpu_get_freq_mhz_from_pll();
source_freq_mhz = clk_ll_bbpll_get_freq_mhz();

View File

@ -1,6 +1,6 @@
set(srcs "rtc_clk_init.c"
"rtc_clk.c"
# "rtc_init.c" // TODO: IDF-5645
"rtc_init.c"
# "rtc_pm.c" // TODO: IDF-5645
# "rtc_sleep.c" // TODO: IDF-5645
"rtc_time.c"

View File

@ -1,5 +1,4 @@
choice RTC_CLK_SRC
# TODO: IDF-5346
prompt "RTC clock source"
default RTC_CLK_SRC_INT_RC
help
@ -13,8 +12,8 @@ choice RTC_CLK_SRC
config RTC_CLK_SRC_EXT_OSC
bool "External 32kHz oscillator at 32K_XP pin"
select ESP_SYSTEM_RTC_EXT_OSC
config RTC_CLK_SRC_INT_8MD256
bool "Internal 17.5MHz oscillator, divided by 256"
config RTC_CLK_SRC_INT_RC32K
bool "Internal 32kHz RC oscillator"
endchoice
config RTC_CLK_CAL_CYCLES

View File

@ -15,98 +15,147 @@
#include "soc/rtc.h"
#include "esp_hw_log.h"
#include "esp_rom_sys.h"
#include "hal/usb_serial_jtag_ll.h"
#include "hal/clk_tree_ll.h"
#include "hal/regi2c_ctrl_ll.h"
#include "soc/lp_clkrst_reg.h"
#include "soc/io_mux_reg.h"
#include "soc/lp_aon_reg.h"
static const char *TAG = "rtc_clk";
// Current PLL frequency, in 480MHz. Zero if PLL is not enabled.
static int s_cur_pll_freq;
void rtc_clk_32k_enable(bool enable)
{
// TODO: IDF-5645
if (enable) {
clk_ll_xtal32k_enable(CLK_LL_XTAL32K_ENABLE_MODE_CRYSTAL);
} else {
clk_ll_xtal32k_disable();
}
}
void rtc_clk_32k_enable_external(void)
{
// TODO: IDF-5645
// EXT_OSC_SLOW_GPIO_NUM == GPIO_NUM_0
PIN_INPUT_ENABLE(IO_MUX_GPIO0_REG);
REG_SET_BIT(LP_AON_GPIO_HOLD0_REG, BIT(EXT_OSC_SLOW_GPIO_NUM));
clk_ll_xtal32k_enable(CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL);
}
void rtc_clk_32k_bootstrap(uint32_t cycle)
{
// TODO: IDF-5645
/* No special bootstrapping needed for ESP32-C6, 'cycle' argument is to keep the signature
* same as for the ESP32. Just enable the XTAL here.
*/
(void)cycle;
rtc_clk_32k_enable(true);
}
bool rtc_clk_32k_enabled(void)
{
// TODO: IDF-5645
return 0;
return clk_ll_xtal32k_is_enabled();
}
void rtc_clk_8m_enable(bool clk_8m_en, bool d256_en)
void rtc_clk_rc32k_enable(bool enable)
{
// TODO: IDF-5645
if (enable) {
clk_ll_rc32k_enable();
esp_rom_delay_us(SOC_DELAY_RC32K_ENABLE);
} else {
clk_ll_rc32k_disable();
}
}
void rtc_clk_8m_enable(bool clk_8m_en)
{
if (clk_8m_en) {
clk_ll_rc_fast_enable();
esp_rom_delay_us(SOC_DELAY_RC_FAST_ENABLE);
} else {
clk_ll_rc_fast_disable();
}
}
bool rtc_clk_8m_enabled(void)
{
// TODO: IDF-5645
return 0;
}
bool rtc_clk_8md256_enabled(void)
{
// TODO: IDF-5645
return 0;
return clk_ll_rc_fast_is_enabled();
}
void rtc_clk_slow_src_set(soc_rtc_slow_clk_src_t clk_src)
{
// TODO: IDF-5645
clk_ll_rtc_slow_set_src(clk_src);
esp_rom_delay_us(SOC_DELAY_RTC_SLOW_CLK_SWITCH);
}
soc_rtc_slow_clk_src_t rtc_clk_slow_src_get(void)
{
// TODO: IDF-5645
return REG_GET_FIELD(LP_CLKRST_LP_CLK_CONF_REG, LP_CLKRST_SLOW_CLK_SEL);
return clk_ll_rtc_slow_get_src();
}
uint32_t rtc_clk_slow_freq_get_hz(void)
{
// TODO: IDF-5645
switch (rtc_clk_slow_freq_get()) {
case RTC_SLOW_FREQ_RTC: return RTC_SLOW_CLK_FREQ_150K;
case RTC_SLOW_FREQ_32K_XTAL: return RTC_SLOW_CLK_FREQ_32K;
case RTC_SLOW_FREQ_8MD256: return RTC_SLOW_CLK_FREQ_8MD256;
default: return 0;
switch (rtc_clk_slow_src_get()) {
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW: return SOC_CLK_RC_SLOW_FREQ_APPROX;
case SOC_RTC_SLOW_CLK_SRC_XTAL32K: return SOC_CLK_XTAL32K_FREQ_APPROX;
case SOC_RTC_SLOW_CLK_SRC_RC32K: return SOC_CLK_RC32K_FREQ_APPROX;
case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW: return SOC_CLK_OSC_SLOW_FREQ_APPROX;
default: return 0;
}
}
void rtc_clk_fast_src_set(soc_rtc_fast_clk_src_t clk_src)
{
// TODO: IDF-5645
clk_ll_rtc_fast_set_src(clk_src);
esp_rom_delay_us(SOC_DELAY_RTC_FAST_CLK_SWITCH);
}
soc_rtc_fast_clk_src_t rtc_clk_fast_src_get(void)
{
// TODO: IDF-5645
return 0;
return clk_ll_rtc_fast_get_src();
}
#if 0
static void rtc_clk_bbpll_disable(void)
{
// TODO: IDF-5645
clk_ll_bbpll_disable();
s_cur_pll_freq = 0;
}
static void rtc_clk_bbpll_enable(void)
{
// TODO: IDF-5645
clk_ll_bbpll_enable();
}
static void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
{
// TODO: IDF-5645
/* Digital part */
clk_ll_bbpll_set_freq_mhz(pll_freq);
/* Analog part */
/* BBPLL CALIBRATION START */
regi2c_ctrl_ll_bbpll_calibration_start();
clk_ll_bbpll_set_config(pll_freq, xtal_freq);
/* WAIT CALIBRATION DONE */
while(!regi2c_ctrl_ll_bbpll_calibration_is_done());
/* BBPLL CALIBRATION STOP */
regi2c_ctrl_ll_bbpll_calibration_stop();
s_cur_pll_freq = pll_freq;
}
/**
* Switch to XTAL frequency. Does not disable the PLL.
*/
static void rtc_clk_cpu_freq_to_xtal(int freq, int div)
{
clk_ll_cpu_set_ls_divider(div);
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_XTAL);
ets_update_cpu_frequency(freq);
}
static void rtc_clk_cpu_freq_to_8m(void)
{
clk_ll_cpu_set_ls_divider(1);
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_RC_FAST);
ets_update_cpu_frequency(20);
}
/**
@ -116,110 +165,203 @@ static void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
*/
static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
{
// TODO: IDF-5645
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);
ets_update_cpu_frequency(cpu_freq_mhz);
}
#endif
bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *out_config)
{
// TODO: IDF-5645
return 0;
uint32_t source_freq_mhz;
soc_cpu_clk_src_t source;
uint32_t divider; // divider = freq of SOC_ROOT_CLK / freq of CPU_CLK
uint32_t real_freq_mhz;
uint32_t xtal_freq = (uint32_t)rtc_clk_xtal_freq_get();
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) {
// no suitable divider
return false;
}
source_freq_mhz = xtal_freq;
source = SOC_CPU_CLK_SRC_XTAL;
} else if (freq_mhz == 80) {
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;
} 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;
} else {
// unsupported frequency
return false;
}
*out_config = (rtc_cpu_freq_config_t) {
.source = source,
.div = divider,
.source_freq_mhz = source_freq_mhz,
.freq_mhz = real_freq_mhz
};
return true;
}
void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config)
{
// TODO: IDF-5645
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) {
rtc_clk_bbpll_disable();
}
} else if (config->source == SOC_CPU_CLK_SRC_PLL) {
if (old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL) {
rtc_clk_bbpll_enable();
rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), config->source_freq_mhz);
}
rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz);
} else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) {
rtc_clk_cpu_freq_to_8m();
if (old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL) {
rtc_clk_bbpll_disable();
}
}
}
void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config)
{
// TODO: IDF-5645
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
uint32_t source_freq_mhz;
uint32_t div; // div = freq of SOC_ROOT_CLK / freq of CPU_CLK
uint32_t freq_mhz;
switch (source) {
case SOC_CPU_CLK_SRC_XTAL: {
div = clk_ll_cpu_get_ls_divider();
source_freq_mhz = (uint32_t)rtc_clk_xtal_freq_get();
freq_mhz = source_freq_mhz / div;
break;
}
case SOC_CPU_CLK_SRC_PLL: {
div = clk_ll_cpu_get_hs_divider();
source_freq_mhz = clk_ll_bbpll_get_freq_mhz();
freq_mhz = source_freq_mhz / div;
break;
}
case SOC_CPU_CLK_SRC_RC_FAST:
div = clk_ll_cpu_get_ls_divider();
source_freq_mhz = 20;
freq_mhz = source_freq_mhz / div;
break;
default:
ESP_HW_LOGE(TAG, "unsupported frequency configuration");
abort();
}
*out_config = (rtc_cpu_freq_config_t) {
.source = source,
.source_freq_mhz = source_freq_mhz,
.div = div,
.freq_mhz = freq_mhz
};
}
void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config)
{
// TODO: IDF-5645
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_RC_FAST) {
rtc_clk_cpu_freq_to_8m();
} else {
/* fallback */
rtc_clk_cpu_freq_set_config(config);
}
}
void rtc_clk_cpu_freq_set_xtal(void)
{
ESP_EARLY_LOGW(TAG, "rtc_clk_cpu_freq_set_xtal() has not been implemented yet");
// TODO: IDF-5645
}
int freq_mhz = (int)rtc_clk_xtal_freq_get();
#if 0
/**
* Switch to XTAL frequency. Does not disable the PLL.
*/
static void rtc_clk_cpu_freq_to_xtal(int freq, int div)
{
// TODO: IDF-5645
rtc_clk_cpu_freq_to_xtal(freq_mhz, 1);
rtc_clk_bbpll_disable();
}
static void rtc_clk_cpu_freq_to_8m(void)
{
// TODO: IDF-5645
}
#endif
rtc_xtal_freq_t rtc_clk_xtal_freq_get(void)
{
ESP_EARLY_LOGW(TAG, "rtc_clk_xtal_freq_get() has not been implemented yet");
// TODO: IDF-5645
return 40;
uint32_t xtal_freq_mhz = clk_ll_xtal_load_freq_mhz();
if (xtal_freq_mhz == 0) {
ESP_HW_LOGW(TAG, "invalid RTC_XTAL_FREQ_REG value, assume 40MHz");
return RTC_XTAL_FREQ_40M;
}
return (rtc_xtal_freq_t)xtal_freq_mhz;
}
void rtc_clk_xtal_freq_update(rtc_xtal_freq_t xtal_freq)
{
// TODO: IDF-5645
clk_ll_xtal_store_freq_mhz(xtal_freq);
}
void rtc_clk_apb_freq_update(uint32_t apb_freq)
static uint32_t rtc_clk_ahb_freq_get(void)
{
// TODO: IDF-5645
soc_cpu_clk_src_t source = clk_ll_cpu_get_src();
uint32_t soc_root_freq_mhz;
uint32_t divider;
switch (source) {
case SOC_CPU_CLK_SRC_XTAL:
soc_root_freq_mhz = rtc_clk_xtal_freq_get();
divider = clk_ll_ahb_get_ls_divider();
break;
case SOC_CPU_CLK_SRC_PLL:
soc_root_freq_mhz = clk_ll_bbpll_get_freq_mhz();
divider = clk_ll_ahb_get_hs_divider();
break;
case SOC_CPU_CLK_SRC_RC_FAST:
soc_root_freq_mhz = 20;
divider = clk_ll_ahb_get_ls_divider();
break;
default:
// Unknown SOC_ROOT clock source
soc_root_freq_mhz = 0;
divider = 1;
ESP_HW_LOGE(TAG, "Invalid SOC_ROOT_CLK");
break;
}
return soc_root_freq_mhz / divider;
}
uint32_t rtc_clk_apb_freq_get(void)
{
ESP_EARLY_LOGW(TAG, "rtc_clk_apb_freq_get() has not been implemented yet");
// TODO: IDF-5645
return 0;
}
void rtc_clk_divider_set(uint32_t div)
{
// TODO: IDF-5645
}
void rtc_clk_8m_divider_set(uint32_t div)
{
// TODO: IDF-5645
return rtc_clk_ahb_freq_get() / clk_ll_apb_get_divider() * MHZ;
}
void rtc_dig_clk8m_enable(void)
{
// TODO: IDF-5645
clk_ll_rc_fast_digi_enable();
esp_rom_delay_us(SOC_DELAY_RC_FAST_DIGI_SWITCH);
}
void rtc_dig_clk8m_disable(void)
{
// TODO: IDF-5645
clk_ll_rc_fast_digi_disable();
esp_rom_delay_us(SOC_DELAY_RC_FAST_DIGI_SWITCH);
}
bool rtc_dig_8m_enabled(void)
{
// TODO: IDF-5645
return 0;
return clk_ll_rc_fast_digi_is_enabled();
}
#if 0
static bool rtc_clk_set_bbpll_always_on(void)
{
// TODO: IDF-5645
return 0;
}
#endif
/* Name used in libphy.a:phy_chip_v7.o
* TODO: update the library to use rtc_clk_xtal_freq_get
*/

View File

@ -13,45 +13,41 @@
#include "esp32c6/rom/uart.h"
#include "soc/rtc.h"
#include "esp_cpu.h"
#include "hal/regi2c_ctrl_ll.h"
#include "regi2c_ctrl.h"
#include "soc/lp_clkrst_reg.h"
#include "soc/regi2c_dig_reg.h"
#include "esp_hw_log.h"
#include "sdkconfig.h"
#include "esp_rom_uart.h"
#include "hal/clk_tree_ll.h"
static const char *TAG = "rtc_clk_init";
void rtc_clk_init(rtc_clk_config_t cfg)
{
ESP_HW_LOGW(TAG, "rtc_clk_init() has not been implemented yet");
#if 0 // TODO: IDF-5645
rtc_cpu_freq_config_t old_config, new_config;
/* Set tuning parameters for 8M and 150k clocks.
/* Set tuning parameters for RC_FAST, RC_SLOW, and RC32K clocks.
* Note: this doesn't attempt to set the clocks to precise frequencies.
* Instead, we calibrate these clocks against XTAL frequency later, when necessary.
* - SCK_DCAP value controls tuning of 150k clock.
* - SCK_DCAP value controls tuning of RC_SLOW clock.
* The higher the value of DCAP is, the lower is the frequency.
* - CK8M_DFREQ value controls tuning of 8M clock.
* - CK8M_DFREQ value controls tuning of RC_FAST clock.
* CLK_8M_DFREQ constant gives the best temperature characteristics.
* - RC32K_DFREQ value controls tuning of RC32K clock.
*/
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_SCK_DCAP, cfg.slow_clk_dcap);
REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_DFREQ, cfg.clk_8m_dfreq);
/* Configure 150k clock division */
rtc_clk_divider_set(cfg.clk_rtc_clk_div);
/* Configure 8M clock division */
rtc_clk_8m_divider_set(cfg.clk_8m_clk_div);
/* Reset (disable) i2c internal bus for all regi2c registers */
regi2c_ctrl_ll_i2c_reset(); // TODO: This should be move out from rtc_clk_init
/* Enable the internal bus used to configure BBPLL */
regi2c_ctrl_ll_i2c_bbpll_enable(); // TODO: This should be moved to bbpll_set_config
REG_SET_FIELD(LP_CLKRST_FOSC_CNTL_REG, LP_CLKRST_FOSC_DFREQ, cfg.clk_8m_dfreq);
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_SCK_DCAP, cfg.slow_clk_dcap);
REG_SET_FIELD(LP_CLKRST_RC32K_CNTL_REG, LP_CLKRST_RC32K_DFREQ, cfg.rc32k_dfreq);
rtc_xtal_freq_t xtal_freq = cfg.xtal_freq;
esp_rom_uart_tx_wait_idle(0);
rtc_clk_xtal_freq_update(xtal_freq);
rtc_clk_apb_freq_update(xtal_freq * MHZ);
// On ESP32C6, 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);
/* Set CPU frequency */
rtc_clk_cpu_freq_get_config(&old_config);
@ -70,14 +66,14 @@ void rtc_clk_init(rtc_clk_config_t cfg)
// We will not power off RC_FAST in bootloader stage even if it is not being used as any
// cpu / rtc_fast / rtc_slow clock sources, this is because RNG always needs it in the bootloader stage.
bool need_rc_fast_en = true;
bool need_rc_fast_d256_en = false;
if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
rtc_clk_32k_enable(true);
} else if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) {
need_rc_fast_d256_en = true;
} else if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) {
rtc_clk_32k_enable_external();
} else if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) {
rtc_clk_rc32k_enable(true);
}
rtc_clk_8m_enable(need_rc_fast_en, need_rc_fast_d256_en);
rtc_clk_8m_enable(need_rc_fast_en);
rtc_clk_fast_src_set(cfg.fast_clk_src);
rtc_clk_slow_src_set(cfg.slow_clk_src);
#endif
}

View File

@ -4,4 +4,21 @@
* SPDX-License-Identifier: Apache-2.0
*/
// TODO: IDF-5645
#include "soc/rtc.h"
#include "soc/pmu_reg.h"
#include "soc/regi2c_dig_reg.h"
#include "regi2c_ctrl.h"
// TODO: IDF-5781
void rtc_init(rtc_config_t cfg)
{
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);
REG_SET_FIELD(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, 25);
REG_SET_FIELD(PMU_HP_SLEEP_LP_REGULATOR0_REG, PMU_HP_SLEEP_LP_REGULATOR_DBIAS, 26);
}

View File

@ -7,10 +7,13 @@
#include <stdint.h>
#include "esp32c6/rom/ets_sys.h"
#include "soc/rtc.h"
// #include "soc/rtc_cntl_reg.h"
#include "soc/lp_timer_reg.h"
#include "hal/clk_tree_ll.h"
#include "soc/timer_group_reg.h"
#include "esp_rom_sys.h"
#include "assert.h"
static const char *TAG = "rtc_time";
/* Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0.
* This feature counts the number of XTAL clock cycles within a given number of
@ -24,55 +27,189 @@
* enabled using TIMG_RTC_CALI_START bit.
*/
/**
* @brief Clock calibration function used by rtc_clk_cal and rtc_clk_cal_ratio
* @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
/* On ESP32C6, TIMG_RTC_CALI_CLK_SEL can config to 0, 1, 2, 3
* 0 or 3: calibrate RC_SLOW clock
* 1: calibrate RC_FAST clock
* 2: calibrate 32K clock, which 32k depends on reg_32k_sel: 0: Internal 32 kHz RC oscillator, 1: External 32 kHz XTAL, 2: External 32kHz clock input by lp_pad_gpio0
*/
// TODO: IDF-5645
static const char *TAG = "rtc_time";
#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
uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
{
// TODO: IDF-5645
ESP_EARLY_LOGW(TAG, "rtc_clk_cal_internal() has not been implemented yet");
return 0;
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;
}
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);
}
/* 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 orignally was disabled, and set back to the disable state after calibration is done
// If the clock is already on, then do nothing
bool dig_32k_xtal_enabled = clk_ll_xtal32k_digi_is_enabled();
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
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 rc32k_enabled = clk_ll_rc32k_is_enabled();
bool dig_rc32k_enabled = clk_ll_rc32k_digi_is_enabled();
if (cal_clk == RTC_CAL_RC32K) {
if (!rc32k_enabled) {
rtc_clk_rc32k_enable(true);
}
if (!dig_rc32k_enabled) {
clk_ll_rc32k_digi_enable();
}
}
/* There may be another calibration process already running during we call this function,
* so we should wait the last process is done.
*/
if (GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING)) {
/**
* Set a small timeout threshold to accelerate the generation of timeout.
* The internal circuit will be reset when the timeout occurs and will not affect the next calibration.
*/
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, 1);
while (!GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY)
&& !GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT));
}
/* Prepare calibration */
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cali_clk_sel);
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING);
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles);
/* Figure out how long to wait for calibration to finish */
/* Set timeout reg and expect time delay*/
uint32_t expected_freq;
if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_32K) {
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_32K_CAL_TIMEOUT_THRES(slowclk_cycles));
expected_freq = SOC_CLK_XTAL32K_FREQ_APPROX;
} else if (cali_clk_sel == TIMG_RTC_CALI_CLK_SEL_RC_FAST) {
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_FAST_CLK_20M_CAL_TIMEOUT_THRES(slowclk_cycles));
expected_freq = SOC_CLK_RC_FAST_FREQ_APPROX;
} else {
REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES, RTC_SLOW_CLK_150K_CAL_TIMEOUT_THRES(slowclk_cycles));
expected_freq = SOC_CLK_RC_SLOW_FREQ_APPROX;
}
uint32_t us_time_estimate = (uint32_t) (((uint64_t) slowclk_cycles) * MHZ / expected_freq);
/* Start calibration */
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
SET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
/* Wait for calibration to finish up to another us_time_estimate */
esp_rom_delay_us(us_time_estimate);
uint32_t cal_val;
while (true) {
if (GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY)) {
cal_val = REG_GET_FIELD(TIMG_RTCCALICFG1_REG(0), TIMG_RTC_CALI_VALUE);
break;
}
if (GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT)) {
cal_val = 0;
break;
}
}
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START);
/* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */
if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) {
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_RC32K) {
if (!dig_rc32k_enabled) {
clk_ll_rc32k_digi_disable();
}
if (!rc32k_enabled) {
rtc_clk_rc32k_enable(false);
}
}
// Always set back the calibration 32kHz clock selection
if (old_32k_cal_clk_sel != SOC_RTC_SLOW_CLK_SRC_INVALID) {
clk_ll_32k_calibration_set_target(old_32k_cal_clk_sel);
}
return cal_val;
}
uint32_t rtc_clk_cal_ratio(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
static bool rtc_clk_cal_32k_valid(rtc_xtal_freq_t xtal_freq, uint32_t slowclk_cycles, uint64_t actual_xtal_cycles)
{
// TODO: IDF-5645
ESP_EARLY_LOGW(TAG, "rtc_clk_cal_ratio() has not been implemented yet");
return 0;
uint64_t expected_xtal_cycles = (xtal_freq * 1000000ULL * slowclk_cycles) >> 15; // xtal_freq(hz) * slowclk_cycles / 32768
uint64_t delta = expected_xtal_cycles / 2000; // 5/10000 = 0.05% error range
return (actual_xtal_cycles >= (expected_xtal_cycles - delta)) && (actual_xtal_cycles <= (expected_xtal_cycles + delta));
}
uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
{
// TODO: IDF-5645
ESP_EARLY_LOGW(TAG, "rtc_clk_cal() has not been implemented yet");
return 0;
rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get();
uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles);
if (cal_clk == RTC_CAL_32K_XTAL && !rtc_clk_cal_32k_valid(xtal_freq, slowclk_cycles, xtal_cycles)) {
return 0;
}
uint64_t divider = ((uint64_t)xtal_freq) * slowclk_cycles;
uint64_t period_64 = ((xtal_cycles << RTC_CLK_CAL_FRACT) + divider / 2 - 1) / divider;
uint32_t period = (uint32_t)(period_64 & UINT32_MAX);
return period;
}
uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period)
{
// TODO: IDF-5645
ESP_EARLY_LOGW(TAG, "rtc_time_us_to_slowclk() has not been implemented yet");
return 0;
/* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days.
* TODO: fix overflow.
*/
return (time_in_us << RTC_CLK_CAL_FRACT) / period;
}
uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period)
{
// TODO: IDF-5645
ESP_EARLY_LOGW(TAG, "rtc_time_slowclk_to_us() has not been implemented yet");
return 0;
return (rtc_cycles * period) >> RTC_CLK_CAL_FRACT;
}
uint64_t rtc_time_get(void)
{
// TODO: IDF-5645
ESP_EARLY_LOGW(TAG, "rtc_time_get() has not been implemented yet");
return 0;
SET_PERI_REG_MASK(LP_TIMER_UPDATE_REG, LP_TIMER_MAIN_TIMER_UPDATE);
uint64_t t = READ_PERI_REG(LP_TIMER_MAIN_BUF0_LOW_REG);
t |= ((uint64_t) READ_PERI_REG(LP_TIMER_MAIN_BUF0_HIGH_REG)) << 32;
return t;
}
uint64_t rtc_light_slp_time_get(void)
@ -84,20 +221,22 @@ uint64_t rtc_light_slp_time_get(void)
uint64_t rtc_deep_slp_time_get(void)
{
// TODO: IDF-5645
ESP_EARLY_LOGW(TAG, "rtc_deep_slp_time_get() has not been implemented yet");
return 0;
uint64_t t_slp = READ_PERI_REG(LP_TIMER_MAIN_BUF1_LOW_REG);
t_slp |= ((uint64_t) READ_PERI_REG(LP_TIMER_MAIN_BUF1_HIGH_REG)) << 32;
uint64_t t_wake = rtc_time_get();
return (t_wake - t_slp);
}
void rtc_clk_wait_for_slow_cycle(void) //This function may not by useful any more
{
// TODO: IDF-5645
// TODO: IDF-5781
ESP_EARLY_LOGW(TAG, "rtc_clk_wait_for_slow_cycle() has not been implemented yet");
}
uint32_t rtc_clk_freq_cal(uint32_t cal_val)
{
// TODO: IDF-5645
ESP_EARLY_LOGW(TAG, "rtc_clk_freq_cal() has not been implemented yet");
return 0;
if (cal_val == 0) {
return 0; // cal_val will be denominator, return 0 as the symbol of failure.
}
return 1000000ULL * (1 << RTC_CLK_CAL_FRACT) / cal_val;
}

View File

@ -101,7 +101,7 @@ out:
esp_err_t rtc_isr_register(intr_handler_t handler, void* handler_arg, uint32_t rtc_intr_mask, uint32_t flags)
{
#if CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5645
ESP_LOGW(TAG, "rtc_isr_register() has not been implemented yet");
ESP_EARLY_LOGW(TAG, "rtc_isr_register() has not been implemented yet");
return ESP_OK;
#else
esp_err_t err = rtc_isr_ensure_installed();
@ -132,7 +132,7 @@ esp_err_t rtc_isr_register(intr_handler_t handler, void* handler_arg, uint32_t r
esp_err_t rtc_isr_deregister(intr_handler_t handler, void* handler_arg)
{
#if CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5645
ESP_LOGW(TAG, "rtc_isr_deregister() has not been implemented yet");
ESP_EARLY_LOGW(TAG, "rtc_isr_deregister() has not been implemented yet");
return ESP_OK;
#else
rtc_isr_handler_t* it;

View File

@ -83,7 +83,7 @@ TEST_CASE("RTC_SLOW_CLK sources calibration", "[rtc_clk]")
CALIBRATE_ONE(RTC_CAL_8MD256);
#if CONFIG_IDF_TARGET_ESP32C2
uint32_t cal_ext_slow_clk = CALIBRATE_ONE(RTC_CAL_EXT_32K);
uint32_t cal_ext_slow_clk = CALIBRATE_ONE(RTC_CAL_32K_OSC_SLOW);
if (cal_ext_slow_clk == 0) {
printf("EXT CLOCK by PIN has not started up");
} else {
@ -93,7 +93,7 @@ TEST_CASE("RTC_SLOW_CLK sources calibration", "[rtc_clk]")
CALIBRATE_ONE(RTC_CAL_RTC_MUX);
CALIBRATE_ONE(RTC_CAL_8MD256);
CALIBRATE_ONE(RTC_CAL_EXT_32K);
CALIBRATE_ONE(RTC_CAL_32K_OSC_SLOW);
}
#else
uint32_t cal_32k = CALIBRATE_ONE(RTC_CAL_32K_XTAL);
@ -116,7 +116,7 @@ TEST_CASE("RTC_SLOW_CLK sources calibration", "[rtc_clk]")
CALIBRATE_ONE(RTC_CAL_RTC_MUX);
CALIBRATE_ONE(RTC_CAL_8MD256);
#if CONFIG_IDF_TARGET_ESP32C2
CALIBRATE_ONE(RTC_CAL_EXT_32K);
CALIBRATE_ONE(RTC_CAL_32K_OSC_SLOW);
#else
CALIBRATE_ONE(RTC_CAL_32K_XTAL);
#endif

View File

@ -1,138 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
ESP32C6 ECO3 ROM address table
Version 3 API's imported from the ROM
*/
esf_buf_alloc_dynamic = 0x400015c0;
esf_buf_recycle = 0x400015c4;
/*lmacTxDone = 0x4000162c;*/
/*ppMapTxQueue = 0x400016d8;*/
rcGetSched = 0x40001764;
wDevCheckBlockError = 0x400017b4;
/*ppProcTxDone = 0x40001804;*/
sta_input = rom_sta_input;
/***************************************
Group rom_phy
***************************************/
/* Functions */
rom_index_to_txbbgain = 0x40001964;
rom_pbus_xpd_tx_on = 0x400019b0;
rom_set_tx_dig_gain = 0x400019f0;
rom_set_txcap_reg = 0x400019f4;
rom_txbbgain_to_index = 0x40001a0c;
rom_agc_reg_init = 0x40001a54;
rom_bb_reg_init = 0x40001a58;
rom_set_pbus_reg = 0x40001a70;
rom_phy_xpd_rf = 0x40001a78;
rom_write_txrate_power_offset = 0x40001a8c;
rom_temp_to_power = 0x40001ab4;
rom_open_i2c_xpd = 0x40001af8;
rom_tsens_read_init = 0x40001b00;
rom_tsens_code_read = 0x40001b04;
rom_tsens_dac_cal = 0x40001b10;
rom_pll_vol_cal = 0x40001b28;
/***************************************
Group eco3_wifi
***************************************/
/* Functions */
wdev_is_data_in_rxlist = 0x40001b2c;
ppProcTxCallback = 0x40001b30;
ieee80211_gettid = 0x40001b34;
/***************************************
Group eco3_bluetooth
***************************************/
/* Functions */
r_lld_legacy_adv_dynamic_pti_get = 0x40001b38;
r_lld_legacy_adv_dynamic_pti_process = 0x40001b3c;
r_lld_ext_adv_dynamic_pti_get = 0x40001b40;
r_lld_ext_adv_dynamic_aux_pti_process = 0x40001b44;
r_lld_ext_adv_dynamic_pti_process = 0x40001b48;
r_lld_adv_ext_pkt_prepare_set = 0x40001b4c;
r_lld_adv_ext_chain_none_construct = 0x40001b50;
r_lld_adv_ext_chain_connectable_construct = 0x40001b54;
r_lld_adv_ext_chain_scannable_construct = 0x40001b58;
r_lld_adv_pkt_rx_connect_post = 0x40001b5c;
r_lld_adv_start_init_evt_param = 0x40001b60;
r_lld_adv_start_set_cs = 0x40001b64;
r_lld_adv_start_update_filter_policy = 0x40001b68;
r_lld_adv_start_schedule_asap = 0x40001b6c;
r_lld_con_tx_prog_new_packet_coex = 0x40001b70;
r_lld_con_tx_prog_new_packet = 0x40001b74;
r_lld_per_adv_dynamic_pti_get = 0x40001b78;
r_lld_per_adv_evt_start_chm_upd = 0x40001b7c;
r_lld_ext_scan_dynamic_pti_get = 0x40001b80;
r_lld_scan_try_sched = 0x40001b84;
r_lld_sync_insert = 0x40001b88;
r_sch_prog_ble_push = 0x40001b8c;
r_sch_prog_bt_push = 0x40001b90;
r_lld_init_evt_end_type_set = 0x40001b94;
r_lld_init_evt_end_type_get = 0x40001b98;
r_lld_adv_direct_adv_use_rpa_addr_state_set = 0x40001b9c;
r_lld_adv_direct_adv_use_rpa_addr_state_get = 0x40001ba0;
r_lld_init_evt_end_type_check_state_set = 0x40001ba4;
r_lld_init_evt_end_type_check_state_get = 0x40001ba8;
/***************************************
Group eco3_phy
***************************************/
/* Functions */
rom_wrtie_pll_cap = 0x40001bac;
rom_set_tx_gain_mem = 0x40001bb0;
rom_bt_tx_dig_gain = 0x40001bb4;
rom_bt_get_tx_gain = 0x40001bb8;
rom_get_chan_target_power = 0x40001bbc;
rom_get_tx_gain_value = 0x40001bc0;
rom_wifi_tx_dig_gain = 0x40001bc4;
rom_wifi_get_tx_gain = 0x40001bc8;
rom_fe_i2c_reg_renew = 0x40001bcc;
rom_wifi_agc_sat_gain = 0x40001bd0;
rom_i2c_master_reset = 0x40001bd4;
rom_bt_filter_reg = 0x40001bd8;
rom_phy_bbpll_cal = 0x40001bdc;
rom_i2c_sar2_init_code = 0x40001be0;
rom_phy_param_addr = 0x40001be4;
rom_phy_reg_init = 0x40001be8;
rom_set_chan_reg = 0x40001bec;
rom_phy_wakeup_init = 0x40001bf0;
rom_phy_i2c_init1 = 0x40001bf4;
rom_tsens_temp_read = 0x40001bf8;
rom_bt_track_pll_cap = 0x40001bfc;
rom_wifi_track_pll_cap = 0x40001c00;
rom_wifi_set_tx_gain = 0x40001c04;
rom_txpwr_cal_track = 0x40001c08;
rom_tx_pwctrl_background = 0x40001c0c;
rom_bt_set_tx_gain = 0x40001c10;
rom_noise_check_loop = 0x40001c14;
rom_phy_close_rf = 0x40001c18;
rom_phy_xpd_tsens = 0x40001c1c;
rom_phy_freq_mem_backup = 0x40001c20;
rom_phy_ant_init = 0x40001c24;
rom_bt_track_tx_power = 0x40001c28;
rom_wifi_track_tx_power = 0x40001c2c;
rom_phy_dig_reg_backup = 0x40001c30;
chip726_phyrom_version_num = 0x40001c34;
/* Data (.data, .bss, .rodata) */
phy_param_rom = 0x3fcdf830;
/***************************************
Group eco3_esp_flash
***************************************/
/* Functions */
PROVIDE( esp_flash_read_chip_id = 0x40001c38 );
PROVIDE( detect_spi_flash_chip = 0x40001c3c );
PROVIDE( esp_rom_spiflash_write_disable = 0x40001c40 );

View File

@ -149,7 +149,7 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk)
// When SLOW_CLK_CAL_CYCLES is set to 0, clock calibration will not be performed at startup.
if (SLOW_CLK_CAL_CYCLES > 0) {
cal_val = rtc_clk_cal(RTC_CAL_EXT_32K, SLOW_CLK_CAL_CYCLES);
cal_val = rtc_clk_cal(RTC_CAL_32K_OSC_SLOW, SLOW_CLK_CAL_CYCLES);
if (cal_val == 0) {
if (retry_ext_clk-- > 0) {
continue;

View File

@ -10,6 +10,8 @@ choice ESP_DEFAULT_CPU_FREQ_MHZ
depends on IDF_ENV_FPGA
config ESP_DEFAULT_CPU_FREQ_MHZ_80
bool "80 MHz"
config ESP_DEFAULT_CPU_FREQ_MHZ_120
bool "120 MHz"
config ESP_DEFAULT_CPU_FREQ_MHZ_160
bool "160 MHz"
endchoice
@ -18,4 +20,5 @@ config ESP_DEFAULT_CPU_FREQ_MHZ
int
default 40 if ESP_DEFAULT_CPU_FREQ_MHZ_40
default 80 if ESP_DEFAULT_CPU_FREQ_MHZ_80
default 120 if ESP_DEFAULT_CPU_FREQ_MHZ_120
default 160 if ESP_DEFAULT_CPU_FREQ_MHZ_160

View File

@ -14,7 +14,6 @@
#include "esp_clk_internal.h"
#include "esp32c6/rom/ets_sys.h"
#include "esp32c6/rom/uart.h"
// #include "soc/system_reg.h"
#include "soc/soc.h"
#include "soc/rtc.h"
#include "soc/rtc_periph.h"
@ -23,8 +22,6 @@
#include "hal/wdt_hal.h"
#include "esp_private/periph_ctrl.h"
#include "esp_private/esp_clk.h"
#include "bootloader_clock.h"
// #include "soc/syscon_reg.h"
#include "esp_rom_uart.h"
#include "esp_rom_sys.h"
@ -36,28 +33,7 @@
#define MHZ (1000000)
/* Lower threshold for a reasonably-looking calibration value for a 32k XTAL.
* The ideal value (assuming 32768 Hz frequency) is 1000000/32768*(2**19) = 16*10^6.
*/
#define MIN_32K_XTAL_CAL_VAL 15000000L
/* Indicates that this 32k oscillator gets input from external oscillator, rather
* than a crystal.
*/
#define EXT_OSC_FLAG BIT(3)
/* This is almost the same as soc_rtc_slow_clk_src_t, except that we define
* an extra enum member for the external 32k oscillator.
* For convenience, lower 2 bits should correspond to soc_rtc_slow_clk_src_t values.
*/
typedef enum {
SLOW_CLK_RTC = SOC_RTC_SLOW_CLK_SRC_RC_SLOW, //!< Internal 150 kHz RC oscillator
SLOW_CLK_32K_XTAL = SOC_RTC_SLOW_CLK_SRC_XTAL32K, //!< External 32 kHz XTAL
SLOW_CLK_8MD256 = SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256, //!< Internal 8 MHz RC oscillator, divided by 256
SLOW_CLK_32K_EXT_OSC = SOC_RTC_SLOW_CLK_SRC_XTAL32K | EXT_OSC_FLAG //!< External 32k oscillator connected to 32K_XP pin
} slow_clk_sel_t;
static void select_rtc_slow_clk(slow_clk_sel_t slow_clk);
static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src);
static const char *TAG = "clk";
@ -75,8 +51,7 @@ static const char *TAG = "clk";
assert(rtc_clk_xtal_freq_get() == RTC_XTAL_FREQ_40M);
bool rc_fast_d256_is_enabled = rtc_clk_8md256_enabled();
rtc_clk_8m_enable(true, rc_fast_d256_is_enabled);
rtc_clk_8m_enable(true);
rtc_clk_fast_src_set(SOC_RTC_FAST_CLK_SRC_RC_FAST);
#endif
@ -96,13 +71,13 @@ static const char *TAG = "clk";
#endif
#if defined(CONFIG_RTC_CLK_SRC_EXT_CRYS)
select_rtc_slow_clk(SLOW_CLK_32K_XTAL);
select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_XTAL32K);
#elif defined(CONFIG_RTC_CLK_SRC_EXT_OSC)
select_rtc_slow_clk(SLOW_CLK_32K_EXT_OSC);
#elif defined(CONFIG_RTC_CLK_SRC_INT_8MD256)
select_rtc_slow_clk(SLOW_CLK_8MD256);
select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_OSC_SLOW);
#elif defined(CONFIG_RTC_CLK_SRC_INT_RC32K)
select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_RC32K);
#else
select_rtc_slow_clk(SLOW_CLK_RTC);
select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_RC_SLOW);
#endif
#ifdef CONFIG_BOOTLOADER_WDT_ENABLE
@ -134,11 +109,8 @@ static const char *TAG = "clk";
esp_cpu_set_cycle_count( (uint64_t)esp_cpu_get_cycle_count() * new_freq_mhz / old_freq_mhz );
}
static void select_rtc_slow_clk(slow_clk_sel_t slow_clk)
static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src)
{
ESP_EARLY_LOGW(TAG, "select_rtc_slow_clk() has not been implemented yet");
#if 0 // TODO: IDF-5645
soc_rtc_slow_clk_src_t rtc_slow_clk_src = slow_clk & RTC_CNTL_ANA_CLK_RTC_SEL_V;
uint32_t cal_val = 0;
/* number of times to repeat 32k XTAL calibration
* before giving up and switching to the internal RC
@ -146,7 +118,7 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk)
int retry_32k_xtal = 3;
do {
if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K || rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) {
/* 32k XTAL oscillator needs to be enabled and running before it can
* be used. Hardware doesn't have a direct way of checking if the
* oscillator is running. Here we use rtc_clk_cal function to count
@ -155,24 +127,27 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk)
* will time out, returning 0.
*/
ESP_EARLY_LOGD(TAG, "waiting for 32k oscillator to start up");
if (slow_clk == SLOW_CLK_32K_XTAL) {
rtc_cal_sel_t cal_sel = 0;
if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
rtc_clk_32k_enable(true);
} else if (slow_clk == SLOW_CLK_32K_EXT_OSC) {
cal_sel = RTC_CAL_32K_XTAL;
} else if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) {
rtc_clk_32k_enable_external();
cal_sel = RTC_CAL_32K_OSC_SLOW;
}
// When SLOW_CLK_CAL_CYCLES is set to 0, clock calibration will not be performed at startup.
if (SLOW_CLK_CAL_CYCLES > 0) {
cal_val = rtc_clk_cal(RTC_CAL_32K_XTAL, SLOW_CLK_CAL_CYCLES);
if (cal_val == 0 || cal_val < MIN_32K_XTAL_CAL_VAL) {
cal_val = rtc_clk_cal(cal_sel, SLOW_CLK_CAL_CYCLES);
if (cal_val == 0) {
if (retry_32k_xtal-- > 0) {
continue;
}
ESP_EARLY_LOGW(TAG, "32 kHz XTAL not found, switching to internal 150 kHz oscillator");
ESP_EARLY_LOGW(TAG, "32 kHz clock not found, switching to internal 150 kHz oscillator");
rtc_slow_clk_src = SOC_RTC_SLOW_CLK_SRC_RC_SLOW;
}
}
} else if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) {
rtc_clk_8m_enable(true, true);
} else if (rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC32K) {
rtc_clk_rc32k_enable(true);
}
rtc_clk_slow_src_set(rtc_slow_clk_src);
@ -188,12 +163,11 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk)
} while (cal_val == 0);
ESP_EARLY_LOGD(TAG, "RTC_SLOW_CLK calibration value: %d", cal_val);
esp_clk_slowclk_cal_set(cal_val);
#endif
}
void rtc_clk_select_rtc_slow_clk(void)
{
select_rtc_slow_clk(SLOW_CLK_32K_XTAL);
select_rtc_slow_clk(SOC_RTC_SLOW_CLK_SRC_XTAL32K);
}
/* This function is not exposed as an API at this point.

View File

@ -88,7 +88,7 @@ menu "Serial flasher config"
choice ESPTOOLPY_FLASHFREQ
prompt "Flash SPI speed"
default ESPTOOLPY_FLASHFREQ_40M if IDF_TARGET_ESP32
default ESPTOOLPY_FLASHFREQ_80M if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C3
default ESPTOOLPY_FLASHFREQ_80M if ESPTOOLPY_FLASHFREQ_80M_DEFAULT
default ESPTOOLPY_FLASHFREQ_60M if IDF_TARGET_ESP32C2
default ESPTOOLPY_FLASHFREQ_48M if IDF_TARGET_ESP32H4
config ESPTOOLPY_FLASHFREQ_120M
@ -124,6 +124,12 @@ menu "Serial flasher config"
depends on SOC_MEMSPI_SRC_FREQ_15M_SUPPORTED
endchoice
config ESPTOOLPY_FLASHFREQ_80M_DEFAULT
bool
default y if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C6
help
This is an invisible item, used to define the targets that defaults to use 80MHz Flash SPI speed.
config ESPTOOLPY_FLASHFREQ
string
# On some of the ESP chips, max boot frequency would be equal to (or even lower than) 80m.

View File

@ -45,6 +45,8 @@ extern "C" {
#define I2S_LL_TX_EVENT_MASK I2S_LL_EVENT_TX_EOF
#define I2S_LL_RX_EVENT_MASK I2S_LL_EVENT_RX_EOF
#define I2S_LL_PLL_F160M_CLK_FREQ (160 * 1000000) // PLL_F160M_CLK: 160MHz
/* I2S clock configuration structure */
typedef struct {
uint16_t mclk_div; // I2S module clock divider, Fmclk = Fsclk /(mclk_div+b/a)

View File

@ -32,6 +32,8 @@ extern "C" {
#define I2S_LL_MCLK_DIVIDER_BIT_WIDTH (9)
#define I2S_LL_MCLK_DIVIDER_MAX ((1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1)
#define I2S_LL_PLL_F160M_CLK_FREQ (160 * 1000000) // PLL_F160M_CLK: 160MHz
/* I2S clock configuration structure */
typedef struct {
uint16_t mclk_div; // I2S module clock divider, Fmclk = Fsclk /(mclk_div+b/a)

View File

@ -10,7 +10,9 @@
#include "soc/soc.h"
#include "soc/clk_tree_defs.h"
#include "soc/rtc.h"
#include "soc/pcr_reg.h"
#include "soc/pcr_struct.h"
#include "soc/lp_clkrst_struct.h"
#include "soc/pmu_reg.h"
#include "hal/regi2c_ctrl.h"
#include "soc/regi2c_bbpll.h"
#include "hal/assert.h"
@ -24,9 +26,9 @@ extern "C" {
#define MHZ (1000000)
#define CLK_LL_PLL_80M_FREQ_MHZ (80)
#define CLK_LL_PLL_120M_FREQ_MHZ (120)
#define CLK_LL_PLL_160M_FREQ_MHZ (160)
#define CLK_LL_PLL_320M_FREQ_MHZ (320)
#define CLK_LL_PLL_480M_FREQ_MHZ (480)
#define CLK_LL_XTAL32K_CONFIG_DEFAULT() { \
@ -41,7 +43,7 @@ extern "C" {
*/
typedef enum {
CLK_LL_XTAL32K_ENABLE_MODE_CRYSTAL, //!< Enable the external 32kHz crystal for XTAL32K_CLK
CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL, //!< Enable the external clock signal for XTAL32K_CLK
CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL, //!< Enable the external clock signal for OSC_SLOW_CLK
CLK_LL_XTAL32K_ENABLE_MODE_BOOTSTRAP, //!< Bootstrap the crystal oscillator for faster XTAL32K_CLK start up */
} clk_ll_xtal32k_enable_mode_t;
@ -60,7 +62,9 @@ typedef struct {
*/
static inline __attribute__((always_inline)) void clk_ll_bbpll_enable(void)
{
// TODO: IDF-5645
SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_XPD_BB_I2C |
PMU_TIE_HIGH_XPD_BBPLL | PMU_TIE_HIGH_XPD_BBPLL_I2C);
SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_HIGH_GLOBAL_BBPLL_ICG) ;
}
/**
@ -68,7 +72,8 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_enable(void)
*/
static inline __attribute__((always_inline)) void clk_ll_bbpll_disable(void)
{
// TODO: IDF-5645
SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_LOW_GLOBAL_BBPLL_ICG) ;
SET_PERI_REG_MASK(PMU_IMM_HP_CK_POWER_REG, PMU_TIE_LOW_XPD_BBPLL | PMU_TIE_LOW_XPD_BBPLL_I2C);
}
/**
@ -78,7 +83,18 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_disable(void)
*/
static inline void clk_ll_xtal32k_enable(clk_ll_xtal32k_enable_mode_t mode)
{
// TODO: IDF-5645
if (mode == CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL) {
// No need to configure anything for OSC_SLOW_CLK
return;
}
// Configure xtal32k
clk_ll_xtal32k_config_t cfg = CLK_LL_XTAL32K_CONFIG_DEFAULT();
LP_CLKRST.xtal32k.dac_xtal32k = cfg.dac;
LP_CLKRST.xtal32k.dres_xtal32k = cfg.dres;
LP_CLKRST.xtal32k.dgm_xtal32k = cfg.dgm;
LP_CLKRST.xtal32k.dbuf_xtal32k = cfg.dbuf;
// Enable xtal32k xpd
SET_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_XTAL32K);
}
/**
@ -86,7 +102,8 @@ static inline void clk_ll_xtal32k_enable(clk_ll_xtal32k_enable_mode_t mode)
*/
static inline void clk_ll_xtal32k_disable(void)
{
// TODO: IDF-5645
// Disable xtal32k xpd
CLEAR_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_XTAL32K);
}
/**
@ -96,8 +113,35 @@ static inline void clk_ll_xtal32k_disable(void)
*/
static inline bool clk_ll_xtal32k_is_enabled(void)
{
// TODO: IDF-5645
return 0;
return REG_GET_FIELD(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_XTAL32K) == 1;
}
/**
* @brief Enable the internal oscillator output for RC32K_CLK
*/
static inline void clk_ll_rc32k_enable(void)
{
// Enable rc32k xpd status
SET_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_RC32K);
}
/**
* @brief Disable the internal oscillator output for RC32K_CLK
*/
static inline void clk_ll_rc32k_disable(void)
{
// Disable rc32k xpd status
CLEAR_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_RC32K);
}
/**
* @brief Get the state of the internal oscillator for RC32K_CLK
*
* @return True if the oscillator is enabled
*/
static inline bool clk_ll_rc32k_is_enabled(void)
{
return REG_GET_FIELD(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_RC32K) == 1;
}
/**
@ -105,7 +149,7 @@ static inline bool clk_ll_xtal32k_is_enabled(void)
*/
static inline __attribute__((always_inline)) void clk_ll_rc_fast_enable(void)
{
// TODO: IDF-5645
SET_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_FOSC_CLK);
}
/**
@ -113,7 +157,7 @@ static inline __attribute__((always_inline)) void clk_ll_rc_fast_enable(void)
*/
static inline __attribute__((always_inline)) void clk_ll_rc_fast_disable(void)
{
// TODO: IDF-5645
CLEAR_PERI_REG_MASK(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_FOSC_CLK);
}
/**
@ -123,43 +167,7 @@ static inline __attribute__((always_inline)) void clk_ll_rc_fast_disable(void)
*/
static inline bool clk_ll_rc_fast_is_enabled(void)
{
// TODO: IDF-5645
return 1;
}
/**
* @brief Enable the output from the internal oscillator to be passed into a configurable divider,
* which by default divides the input clock frequency by 256. i.e. RC_FAST_D256_CLK = RC_FAST_CLK / 256
*
* Divider values other than 256 may be configured, but this facility is not currently needed,
* so is not exposed in the code.
* The output of the divider, RC_FAST_D256_CLK, is referred as 8md256 or simply d256 in reg. descriptions.
*/
static inline void clk_ll_rc_fast_d256_enable(void)
{
// TODO: IDF-5645
}
/**
* @brief Disable the output from the internal oscillator to be passed into a configurable divider.
* i.e. RC_FAST_D256_CLK = RC_FAST_CLK / 256
*
* Disabling this divider could reduce power consumption.
*/
static inline void clk_ll_rc_fast_d256_disable(void)
{
// TODO: IDF-5645
}
/**
* @brief Get the state of the divider which is applied to the output from the internal oscillator (RC_FAST_CLK)
*
* @return True if the divided output is enabled
*/
static inline bool clk_ll_rc_fast_d256_is_enabled(void)
{
// TODO: IDF-5645
return 1;
return REG_GET_FIELD(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_FOSC_CLK) == 1;
}
/**
@ -167,7 +175,7 @@ static inline bool clk_ll_rc_fast_d256_is_enabled(void)
*/
static inline void clk_ll_rc_fast_digi_enable(void)
{
// TODO: IDF-5645
LP_CLKRST.clk_to_hp.icg_hp_fosc = 1;
}
/**
@ -175,7 +183,7 @@ static inline void clk_ll_rc_fast_digi_enable(void)
*/
static inline void clk_ll_rc_fast_digi_disable(void)
{
// TODO: IDF-5645
LP_CLKRST.clk_to_hp.icg_hp_fosc = 0;
}
/**
@ -185,24 +193,7 @@ static inline void clk_ll_rc_fast_digi_disable(void)
*/
static inline bool clk_ll_rc_fast_digi_is_enabled(void)
{
// TODO: IDF-5645
return 0;
}
/**
* @brief Enable the digital RC_FAST_D256_CLK, which is used to support peripherals.
*/
static inline void clk_ll_rc_fast_d256_digi_enable(void)
{
// TODO: IDF-5645
}
/**
* @brief Disable the digital RC_FAST_D256_CLK, which is used to support peripherals.
*/
static inline void clk_ll_rc_fast_d256_digi_disable(void)
{
// TODO: IDF-5645
return LP_CLKRST.clk_to_hp.icg_hp_fosc;
}
/**
@ -210,7 +201,7 @@ static inline void clk_ll_rc_fast_d256_digi_disable(void)
*/
static inline void clk_ll_xtal32k_digi_enable(void)
{
// TODO: IDF-5645
LP_CLKRST.clk_to_hp.icg_hp_xtal32k = 1;
}
/**
@ -218,7 +209,7 @@ static inline void clk_ll_xtal32k_digi_enable(void)
*/
static inline void clk_ll_xtal32k_digi_disable(void)
{
// TODO: IDF-5645
LP_CLKRST.clk_to_hp.icg_hp_xtal32k = 0;
}
/**
@ -228,8 +219,33 @@ static inline void clk_ll_xtal32k_digi_disable(void)
*/
static inline bool clk_ll_xtal32k_digi_is_enabled(void)
{
// TODO: IDF-5645
return 0;
return LP_CLKRST.clk_to_hp.icg_hp_xtal32k;
}
/**
* @brief Enable the digital RC32K_CLK, which is used to support peripherals.
*/
static inline void clk_ll_rc32k_digi_enable(void)
{
LP_CLKRST.clk_to_hp.icg_hp_osc32k = 1;
}
/**
* @brief Disable the digital RC32K_CLK, which is used to support peripherals.
*/
static inline void clk_ll_rc32k_digi_disable(void)
{
LP_CLKRST.clk_to_hp.icg_hp_osc32k = 0;
}
/**
* @brief Get the state of the digital RC32K_CLK
*
* @return True if the digital RC32K_CLK is enabled
*/
static inline bool clk_ll_rc32k_digi_is_enabled(void)
{
return LP_CLKRST.clk_to_hp.icg_hp_osc32k;
}
/**
@ -239,8 +255,8 @@ static inline bool clk_ll_xtal32k_digi_is_enabled(void)
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_bbpll_get_freq_mhz(void)
{
// TODO: IDF-5645
return 0;
// The target has a fixed 480MHz SPLL
return CLK_LL_PLL_480M_FREQ_MHZ;
}
/**
@ -250,7 +266,9 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_bbpll_get_freq_mhz(
*/
static inline __attribute__((always_inline)) void clk_ll_bbpll_set_freq_mhz(uint32_t pll_freq_mhz)
{
// TODO: IDF-5645
// The target SPLL is fixed to 480MHz
// Do nothing
HAL_ASSERT(pll_freq_mhz == CLK_LL_PLL_480M_FREQ_MHZ);
}
/**
@ -261,42 +279,70 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_set_freq_mhz(uint
*/
static inline __attribute__((always_inline)) void clk_ll_bbpll_set_config(uint32_t pll_freq_mhz, uint32_t xtal_freq_mhz)
{
// TODO: IDF-5645
HAL_ASSERT(pll_freq_mhz == CLK_LL_PLL_480M_FREQ_MHZ);
uint8_t div_ref;
uint8_t div7_0;
uint8_t dr1;
uint8_t dr3;
uint8_t dchgp;
uint8_t dcur;
uint8_t dbias;
/* Configure 480M PLL */
switch (xtal_freq_mhz) {
case RTC_XTAL_FREQ_40M:
default:
div_ref = 0;
div7_0 = 8;
dr1 = 0;
dr3 = 0;
dchgp = 5;
dcur = 3;
dbias = 2;
break;
}
uint8_t i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref);
uint8_t i2c_bbpll_div_7_0 = div7_0;
uint8_t i2c_bbpll_dcur = (1 << I2C_BBPLL_OC_DLREF_SEL_LSB ) | (3 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur;
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref);
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0);
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1);
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR3, dr3);
REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DCUR, i2c_bbpll_dcur);
REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_VCO_DBIAS, dbias);
}
/**
* @brief Select the clock source for CPU_CLK
* @brief Select the clock source for CPU_CLK (SOC Clock Root)
*
* @param in_sel One of the clock sources in soc_cpu_clk_src_t
*/
static inline __attribute__((always_inline)) void clk_ll_cpu_set_src(soc_cpu_clk_src_t in_sel)
{
// TODO: IDF-5645
switch (in_sel) {
case SOC_CPU_CLK_SRC_XTAL:
REG_SET_FIELD(PCR_SYSCLK_CONF_REG, PCR_SOC_CLK_SEL, 0);
PCR.sysclk_conf.soc_clk_sel = 0;
break;
case SOC_CPU_CLK_SRC_PLL:
REG_SET_FIELD(PCR_SYSCLK_CONF_REG, PCR_SOC_CLK_SEL, 1);
PCR.sysclk_conf.soc_clk_sel = 1;
break;
case SOC_CPU_CLK_SRC_RC_FAST:
REG_SET_FIELD(PCR_SYSCLK_CONF_REG, PCR_SOC_CLK_SEL, 2);
PCR.sysclk_conf.soc_clk_sel = 2;
break;
default:
// Unsupported CPU_CLK mux input sel
// Unsupported SOC_CLK mux input sel
abort();
}
}
/**
* @brief Get the clock source for CPU_CLK
* @brief Get the clock source for CPU_CLK (SOC Clock Root)
*
* @return Currently selected clock source (one of soc_cpu_clk_src_t values)
*/
static inline __attribute__((always_inline)) soc_cpu_clk_src_t clk_ll_cpu_get_src(void)
{
// TODO: IDF-5645
uint32_t clk_sel = REG_GET_FIELD(PCR_SYSCLK_CONF_REG, PCR_SOC_CLK_SEL);
uint32_t clk_sel = PCR.sysclk_conf.soc_clk_sel;
switch (clk_sel) {
case 0:
return SOC_CPU_CLK_SRC_XTAL;
@ -311,45 +357,238 @@ static inline __attribute__((always_inline)) soc_cpu_clk_src_t clk_ll_cpu_get_sr
}
/**
* @brief Set CPU frequency from PLL clock
* @brief Set CPU_CLK's high-speed divider (valid when SOC_ROOT clock source is PLL)
*
* @param cpu_mhz CPU frequency value, in MHz
* @param divider Divider. (PCR_HS_DIV_NUM + 1) * (PCR_CPU_HS_DIV_NUM + 1) = divider.
*/
static inline __attribute__((always_inline)) void clk_ll_cpu_set_freq_mhz_from_pll(uint32_t cpu_mhz)
static inline __attribute__((always_inline)) void clk_ll_cpu_set_hs_divider(uint32_t divider)
{
// TODO: IDF-5645
// 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);
PCR.cpu_freq_conf.cpu_hs_div_num = (divider / 3) - 1;
// 120MHz CPU freq cannot be achieved through divider, need to set force_120m
// This field is only valid if PCR_CPU_HS_DIV_NUM=0 and PCR_SOC_CLK_SEL=SOC_CPU_CLK_SRC_PLL
bool force_120m = (divider == 4) ? 1 : 0;
PCR.cpu_freq_conf.cpu_hs_120m_force = force_120m;
}
/**
* @brief Get CPU_CLK frequency from PLL_CLK source
* @brief Set CPU_CLK's low-speed divider (valid when SOC_ROOT clock source is XTAL/RC_FAST)
*
* @return CPU clock frequency, in MHz. Returns 0 if register field value is invalid.
* @param divider Divider. (PCR_LS_DIV_NUM + 1) * (PCR_CPU_LS_DIV_NUM + 1) = divider.
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_freq_mhz_from_pll(void)
static inline __attribute__((always_inline)) void clk_ll_cpu_set_ls_divider(uint32_t divider)
{
// TODO: IDF-5645
return 0;
// 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));
PCR.cpu_freq_conf.cpu_ls_div_num = divider - 1;
}
/**
* @brief Set CPU_CLK's XTAL/FAST_RC clock source path divider
* @brief Get CPU_CLK's high-speed divider
*
* @param divider Divider. Usually this divider is set to 1 in bootloader stage. PRE_DIV_CNT = divider - 1.
* @return Divider. Divider = (PCR_HS_DIV_NUM + 1) * (PCR_CPU_HS_DIV_NUM + 1).
*/
static inline __attribute__((always_inline)) void clk_ll_cpu_set_divider(uint32_t divider)
static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_hs_divider(void)
{
// TODO: IDF-5645 not configurable for 761, fixed at 3 for HS, 1 for LS
uint32_t force_120m = PCR.cpu_freq_conf.cpu_hs_120m_force;
uint32_t cpu_hs_div = PCR.cpu_freq_conf.cpu_hs_div_num;
if (cpu_hs_div == 0 && force_120m) {
return 4;
}
return (PCR.sysclk_conf.hs_div_num + 1) * (cpu_hs_div + 1);
}
/**
* @brief Get CPU_CLK's XTAL/FAST_RC clock source path divider
* @brief Get CPU_CLK's low-speed divider
*
* @return Divider. Divider = (PRE_DIV_CNT + 1).
* @return Divider. Divider = (PCR_LS_DIV_NUM + 1) * (PCR_CPU_LS_DIV_NUM + 1).
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_divider(void)
static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_ls_divider(void)
{
// TODO: IDF-5645
return 0;
return (PCR.sysclk_conf.ls_div_num + 1) * (PCR.cpu_freq_conf.cpu_ls_div_num + 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);
PCR.ahb_freq_conf.ahb_hs_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));
PCR.ahb_freq_conf.ahb_ls_div_num = divider - 1;
}
/**
* @brief Get AHB_CLK's high-speed divider
*
* @return Divider. Divider = (PCR_HS_DIV_NUM + 1) * (PCR_AHB_HS_DIV_NUM + 1).
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_ahb_get_hs_divider(void)
{
return (PCR.sysclk_conf.hs_div_num + 1) * (PCR.ahb_freq_conf.ahb_hs_div_num + 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)
{
return (PCR.sysclk_conf.ls_div_num + 1) * (PCR.ahb_freq_conf.ahb_ls_div_num + 1);
}
/**
* @brief Set APB_CLK divider. freq of APB_CLK = freq of AHB_CLK / divider
*
* @param divider Divider. PCR_APB_DIV_NUM = divider - 1.
*/
static inline __attribute__((always_inline)) void clk_ll_apb_set_divider(uint32_t divider)
{
// AHB ------> APB
// Divider option: 1, 2, 4 (PCR_APB_DIV_NUM=0, 1, 3)
HAL_ASSERT(divider == 1 || divider == 2 || divider == 4);
PCR.apb_freq_conf.apb_div_num = divider - 1;
}
/**
* @brief Get APB_CLK divider
*
* @return Divider. Divider = (PCR_APB_DIV_NUM + 1).
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_apb_get_divider(void)
{
return 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)
switch (divider) {
case 4:
PCR.mspi_clk_conf.mspi_fast_hs_div_num = 3;
break;
case 5:
PCR.mspi_clk_conf.mspi_fast_hs_div_num = 4;
break;
case 6:
PCR.mspi_clk_conf.mspi_fast_hs_div_num = 5;
break;
default:
// Unsupported HS MSPI_FAST divider
abort();
}
}
/**
* @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)
switch (divider) {
case 1:
PCR.mspi_clk_conf.mspi_fast_ls_div_num = 0;
break;
case 2:
PCR.mspi_clk_conf.mspi_fast_ls_div_num = 1;
break;
case 4:
PCR.mspi_clk_conf.mspi_fast_ls_div_num = 2;
break;
default:
// Unsupported LS MSPI_FAST divider
abort();
}
}
/**
* @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 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 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;
}
}
/**
@ -359,7 +598,23 @@ static inline __attribute__((always_inline)) uint32_t clk_ll_cpu_get_divider(voi
*/
static inline void clk_ll_rtc_slow_set_src(soc_rtc_slow_clk_src_t in_sel)
{
// TODO: IDF-5645
switch (in_sel) {
case SOC_RTC_SLOW_CLK_SRC_RC_SLOW:
LP_CLKRST.lp_clk_conf.slow_clk_sel = 0;
break;
case SOC_RTC_SLOW_CLK_SRC_XTAL32K:
LP_CLKRST.lp_clk_conf.slow_clk_sel = 1;
break;
case SOC_RTC_SLOW_CLK_SRC_RC32K:
LP_CLKRST.lp_clk_conf.slow_clk_sel = 2;
break;
case SOC_RTC_SLOW_CLK_SRC_OSC_SLOW:
LP_CLKRST.lp_clk_conf.slow_clk_sel = 3;
break;
default:
// Unsupported RTC_SLOW_CLK mux input sel
abort();
}
}
/**
@ -369,8 +624,19 @@ static inline void clk_ll_rtc_slow_set_src(soc_rtc_slow_clk_src_t in_sel)
*/
static inline soc_rtc_slow_clk_src_t clk_ll_rtc_slow_get_src(void)
{
// TODO: IDF-5645
return 0;
uint32_t clk_sel = LP_CLKRST.lp_clk_conf.slow_clk_sel;
switch (clk_sel) {
case 0:
return SOC_RTC_SLOW_CLK_SRC_RC_SLOW;
case 1:
return SOC_RTC_SLOW_CLK_SRC_XTAL32K;
case 2:
return SOC_RTC_SLOW_CLK_SRC_RC32K;
case 3:
return SOC_RTC_SLOW_CLK_SRC_OSC_SLOW;
default:
return SOC_RTC_SLOW_CLK_SRC_INVALID;
}
}
/**
@ -380,7 +646,17 @@ static inline soc_rtc_slow_clk_src_t clk_ll_rtc_slow_get_src(void)
*/
static inline void clk_ll_rtc_fast_set_src(soc_rtc_fast_clk_src_t in_sel)
{
// TODO: IDF-5645
switch (in_sel) {
case SOC_RTC_FAST_CLK_SRC_RC_FAST:
LP_CLKRST.lp_clk_conf.fast_clk_sel = 0;
break;
case SOC_RTC_FAST_CLK_SRC_XTAL_D2:
LP_CLKRST.lp_clk_conf.fast_clk_sel = 1;
break;
default:
// Unsupported RTC_FAST_CLK mux input sel
abort();
}
}
/**
@ -390,8 +666,15 @@ static inline void clk_ll_rtc_fast_set_src(soc_rtc_fast_clk_src_t in_sel)
*/
static inline soc_rtc_fast_clk_src_t clk_ll_rtc_fast_get_src(void)
{
// TODO: IDF-5645
return 0;
uint32_t clk_sel = LP_CLKRST.lp_clk_conf.fast_clk_sel;
switch (clk_sel) {
case 0:
return SOC_RTC_FAST_CLK_SRC_RC_FAST;
case 1:
return SOC_RTC_FAST_CLK_SRC_XTAL_D2;
default:
return SOC_RTC_FAST_CLK_SRC_INVALID;
}
}
/**
@ -401,7 +684,8 @@ static inline soc_rtc_fast_clk_src_t clk_ll_rtc_fast_get_src(void)
*/
static inline void clk_ll_rc_fast_set_divider(uint32_t divider)
{
// TODO: IDF-5645
// No divider on the target
HAL_ASSERT(divider == 1);
}
/**
@ -411,8 +695,8 @@ static inline void clk_ll_rc_fast_set_divider(uint32_t divider)
*/
static inline uint32_t clk_ll_rc_fast_get_divider(void)
{
// TODO: IDF-5645
return 0;
// No divider on the target, always return divider = 1
return 1;
}
/**
@ -422,7 +706,8 @@ static inline uint32_t clk_ll_rc_fast_get_divider(void)
*/
static inline void clk_ll_rc_slow_set_divider(uint32_t divider)
{
// TODO: IDF-5645
// No divider on the target
HAL_ASSERT(divider == 1);
}
/************************* RTC STORAGE REGISTER STORE/LOAD **************************/
@ -436,7 +721,7 @@ static inline void clk_ll_rc_slow_set_divider(uint32_t divider)
*/
static inline void clk_ll_xtal_store_freq_mhz(uint32_t xtal_freq_mhz)
{
// TODO: IDF-5645
WRITE_PERI_REG(RTC_XTAL_FREQ_REG, (xtal_freq_mhz & UINT16_MAX) | ((xtal_freq_mhz & UINT16_MAX) << 16));
}
/**
@ -449,34 +734,13 @@ static inline void clk_ll_xtal_store_freq_mhz(uint32_t xtal_freq_mhz)
*/
static inline __attribute__((always_inline)) uint32_t clk_ll_xtal_load_freq_mhz(void)
{
// TODO: IDF-5645
return 0;
}
/**
* @brief Store APB_CLK frequency in RTC storage register
*
* Value of RTC_APB_FREQ_REG is stored as two copies in lower and upper 16-bit
* halves. These are the routines to work with that representation.
*
* @param apb_freq_hz APB frequency, in Hz
*/
static inline __attribute__((always_inline)) void clk_ll_apb_store_freq_hz(uint32_t apb_freq_hz)
{
// TODO: IDF-5645
}
/**
* @brief Load APB_CLK frequency from RTC storage register
*
* Value of RTC_APB_FREQ_REG is stored as two copies in lower and upper 16-bit
* halves. These are the routines to work with that representation.
*
* @return The stored APB frequency, in Hz
*/
static inline uint32_t clk_ll_apb_load_freq_hz(void)
{
// TODO: IDF-5645
// 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 & UINT16_MAX;
}
// If the format in reg is invalid
return 0;
}
@ -490,7 +754,7 @@ static inline uint32_t clk_ll_apb_load_freq_hz(void)
*/
static inline void clk_ll_rtc_slow_store_cal(uint32_t cal_value)
{
// TODO: IDF-5645
REG_WRITE(RTC_SLOW_CLK_CAL_REG, cal_value);
}
/**
@ -502,8 +766,7 @@ static inline void clk_ll_rtc_slow_store_cal(uint32_t cal_value)
*/
static inline uint32_t clk_ll_rtc_slow_load_cal(void)
{
// TODO: IDF-5645
return 0;
return REG_READ(RTC_SLOW_CLK_CAL_REG);
}
#ifdef __cplusplus

View File

@ -33,6 +33,8 @@ extern "C" {
#define I2S_LL_MCLK_DIVIDER_BIT_WIDTH (9)
#define I2S_LL_MCLK_DIVIDER_MAX ((1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1)
#define I2S_LL_PLL_F160M_CLK_FREQ (160 * 1000000) // PLL_F160M_CLK: 160MHz
/* I2S clock configuration structure */
typedef struct {
uint16_t mclk_div; // I2S module clock divider, Fmclk = Fsclk /(mclk_div+b/a)

View File

@ -14,21 +14,21 @@
extern "C" {
#endif
/**
* @brief Reset (Disable) the I2C internal bus for all regi2c registers
*/
static inline void regi2c_ctrl_ll_i2c_reset(void)
{
SET_PERI_REG_BITS(ANA_CONFIG_REG, ANA_CONFIG_M, ANA_CONFIG_M, ANA_CONFIG_S);
}
// /**
// * @brief Reset (Disable) the I2C internal bus for all regi2c registers
// */
// static inline void regi2c_ctrl_ll_i2c_reset(void)
// {
// SET_PERI_REG_BITS(ANA_CONFIG_REG, ANA_CONFIG_M, ANA_CONFIG_M, ANA_CONFIG_S);
// }
/**
* @brief Enable the I2C internal bus to do I2C read/write operation to the BBPLL configuration register
*/
static inline void regi2c_ctrl_ll_i2c_bbpll_enable(void)
{
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, ANA_I2C_BBPLL_M);
}
// /**
// * @brief Enable the I2C internal bus to do I2C read/write operation to the BBPLL configuration register
// */
// static inline void regi2c_ctrl_ll_i2c_bbpll_enable(void)
// {
// CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, ANA_I2C_BBPLL_M);
// }
/**
* @brief Start BBPLL self-calibration
@ -39,6 +39,25 @@ static inline __attribute__((always_inline)) void regi2c_ctrl_ll_bbpll_calibrati
REG_SET_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_LOW);
}
/**
* @brief Stop BBPLL self-calibration
*/
static inline __attribute__((always_inline)) void regi2c_ctrl_ll_bbpll_calibration_stop(void)
{
REG_CLR_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_LOW);
REG_SET_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_HIGH);
}
/**
* @brief Check whether BBPLL calibration is done
*
* @return True if calibration is done; otherwise false
*/
static inline __attribute__((always_inline)) bool regi2c_ctrl_ll_bbpll_calibration_is_done(void)
{
return REG_GET_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_CAL_DONE);
}
/**
* @brief Enable the I2C internal bus to do I2C read/write operation to the SAR_ADC register
*/

View File

@ -550,6 +550,7 @@ static inline void spimem_flash_ll_set_cs_setup(spi_mem_dev_t *dev, uint32_t cs_
*/
static inline uint8_t spimem_flash_ll_get_source_freq_mhz(void)
{
// MAY CAN IMPROVE (ONLY rc_fast case is incorrect)!
// TODO: Default is PLL480M, this is hard-coded.
// In the future, we can get the CPU clock source by calling interface.
uint8_t clock_val = 0;
@ -584,8 +585,6 @@ static inline uint8_t spimem_flash_ll_get_source_freq_mhz(void)
HAL_ASSERT(false);
}
}
// Hard-coded line, will be removed when pll is enabled.
clock_val = 80;
return clock_val;
}

View File

@ -65,7 +65,7 @@ static inline void timer_ll_set_clock_source(timg_dev_t *hw, uint32_t timer_num,
case GPTIMER_CLK_SRC_XTAL:
clk_id = 0;
break;
case GPTIMER_CLK_SRC_APB:
case GPTIMER_CLK_SRC_PLL_F80M:
clk_id = 1;
break;
default:

View File

@ -33,6 +33,8 @@ extern "C" {
#define I2S_LL_MCLK_DIVIDER_BIT_WIDTH (9)
#define I2S_LL_MCLK_DIVIDER_MAX ((1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1)
#define I2S_LL_PLL_F96M_CLK_FREQ (96 * 1000000) // PLL_F96M_CLK: 96MHz
/* I2S clock configuration structure */
typedef struct {
uint16_t mclk_div; // I2S module clock divider, Fmclk = Fsclk /(mclk_div+b/a)

View File

@ -42,6 +42,8 @@ extern "C" {
#define I2S_LL_TX_EVENT_MASK I2S_LL_EVENT_TX_EOF
#define I2S_LL_RX_EVENT_MASK I2S_LL_EVENT_RX_EOF
#define I2S_LL_PLL_F160M_CLK_FREQ (160 * 1000000) // PLL_F160M_CLK: 160MHz
/* I2S clock configuration structure */
typedef struct {
uint16_t mclk_div; // I2S module clock divider, Fmclk = Fsclk /(mclk_div+b/a)

View File

@ -33,6 +33,8 @@ extern "C" {
#define I2S_LL_MCLK_DIVIDER_BIT_WIDTH (9)
#define I2S_LL_MCLK_DIVIDER_MAX ((1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1)
#define I2S_LL_PLL_F160M_CLK_FREQ (160 * 1000000) // PLL_F160M_CLK: 160MHz
/* I2S clock configuration structure */
typedef struct {
uint16_t mclk_div; // I2S module clock divider, Fmclk = Fsclk /(mclk_div+b/a)

View File

@ -299,6 +299,10 @@ config SOC_I2S_SUPPORTS_APLL
bool
default y
config SOC_I2S_SUPPORTS_PLL_F160M
bool
default y
config SOC_I2S_SUPPORTS_PDM
bool
default y

View File

@ -244,15 +244,15 @@ typedef enum {
/**
* @brief Array initializer for all supported clock sources of I2S
*/
#define SOC_I2S_CLKS {SOC_MOD_CLK_PLL_D2, SOC_MOD_CLK_APLL}
#define SOC_I2S_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_APLL}
/**
* @brief I2S clock source enum
*
*/
typedef enum {
I2S_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_D2, /*!< Select PLL_D2 as the default source clock */
I2S_CLK_SRC_PLL_160M = SOC_MOD_CLK_PLL_D2, /*!< Select PLL_D2 as the source clock */
I2S_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default source clock */
I2S_CLK_SRC_PLL_160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the source clock */
I2S_CLK_SRC_APLL = SOC_MOD_CLK_APLL, /*!< Select APLL as the source clock */
} soc_periph_i2s_clk_src_t;

View File

@ -185,6 +185,7 @@
#define SOC_I2S_NUM (2U)
#define SOC_I2S_HW_VERSION_1 (1)
#define SOC_I2S_SUPPORTS_APLL (1)
#define SOC_I2S_SUPPORTS_PLL_F160M (1)
#define SOC_I2S_SUPPORTS_PDM (1)
#define SOC_I2S_SUPPORTS_PDM_TX (1)
#define SOC_I2S_PDM_MAX_TX_LINES (1U)

View File

@ -154,7 +154,10 @@ typedef struct rtc_cpu_freq_config_s {
typedef enum {
RTC_CAL_RTC_MUX = 0, //!< Currently selected RTC SLOW_CLK
RTC_CAL_8MD256 = 1, //!< Internal 8 MHz RC oscillator, divided by 256
RTC_CAL_EXT_32K = 2 //!< External 32.768 KHz CLK
RTC_CAL_32K_OSC_SLOW = 2, //!< External 32.768 KHz CLK
// deprecated name
RTC_CAL_EXT_32K __attribute__((deprecated)) = RTC_CAL_32K_OSC_SLOW,
} rtc_cal_sel_t;
/**

View File

@ -375,6 +375,10 @@ config SOC_I2S_SUPPORTS_XTAL
bool
default y
config SOC_I2S_SUPPORTS_PLL_F160M
bool
default y
config SOC_I2S_SUPPORTS_PCM
bool
default y

View File

@ -184,6 +184,7 @@
#define SOC_I2S_NUM (1)
#define SOC_I2S_HW_VERSION_2 (1)
#define SOC_I2S_SUPPORTS_XTAL (1)
#define SOC_I2S_SUPPORTS_PLL_F160M (1)
#define SOC_I2S_SUPPORTS_PCM (1)
#define SOC_I2S_SUPPORTS_PDM (1)
#define SOC_I2S_SUPPORTS_PDM_TX (1)

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

View File

@ -1,12 +1,11 @@
/*
* SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "modem/reg_base.h"
#ifdef __cplusplus
extern "C" {
#endif
@ -228,7 +227,9 @@ typedef volatile struct {
uint32_t val;
} date;
} modem_lpcon_dev_t;
extern modem_lpcon_dev_t MODEM_LPCON;
#ifdef __cplusplus
}
#endif

View File

@ -367,6 +367,10 @@ config SOC_I2S_SUPPORTS_XTAL
bool
default y
config SOC_I2S_SUPPORTS_PLL_F160M
bool
default y
config SOC_I2S_SUPPORTS_PCM
bool
default y
@ -751,7 +755,7 @@ config SOC_TIMER_GROUP_SUPPORT_XTAL
bool
default y
config SOC_TIMER_GROUP_SUPPORT_APB
config SOC_TIMER_GROUP_SUPPORT_PLL_F80M
bool
default y

View File

@ -5,44 +5,50 @@
*/
#pragma once
#include "sdkconfig.h" // TODO: IDF-5973
#ifdef __cplusplus
extern "C" {
#endif
// TODO: IDF-5346 Copied from C3, need to update
/*
************************* ESP32C6 Root Clock Source ****************************
* 1) Internal 17.5MHz RC Oscillator: RC_FAST (usually referred as FOSC or CK8M/CLK8M in TRM and reg. description)
* 1) Internal 17.5MHz RC Oscillator: RC_FAST (may also referred as FOSC in TRM and reg. description)
*
* This RC oscillator generates a ~17.5MHz clock signal output as the RC_FAST_CLK.
* The ~17.5MHz signal output is also passed into a configurable divider, which by default divides the input clock
* frequency by 256, to generate a RC_FAST_D256_CLK (usually referred as 8md256 or simply d256 in reg. description).
*
* The exact frequency of RC_FAST_CLK can be computed in runtime through calibration on the RC_FAST_D256_CLK.
* The exact frequency of RC_FAST_CLK can be computed in runtime through calibration.
*
* 2) External 40MHz Crystal Clock: XTAL
*
* 3) Internal 136kHz RC Oscillator: RC_SLOW (usually referrred as RTC in TRM or reg. description)
* 3) Internal 136kHz RC Oscillator: RC_SLOW (may also referrred as SOSC in TRM or reg. description)
*
* This RC oscillator generates a ~136kHz clock signal output as the RC_SLOW_CLK. The exact frequency of this clock
* can be computed in runtime through calibration.
*
* 4) External 32kHz Crystal Clock (optional): XTAL32K
* 4) Internal 32kHz RC Oscillator: RC32K
*
* The clock source for this XTAL32K_CLK can be either a 32kHz crystal connecting to the XTAL_32K_P and XTAL_32K_N
* pins or a 32kHz clock signal generated by an external circuit. The external signal must be connected to the
* XTAL_32K_P pin.
* The exact frequency of this clock can be computed in runtime through calibration.
*
* 5) External 32kHz Crystal Clock (optional): XTAL32K
*
* The clock source for this XTAL32K_CLK should be a 32kHz crystal connecting to the XTAL_32K_P and XTAL_32K_N
* pins.
*
* XTAL32K_CLK can also be calibrated to get its exact frequency.
*
* 6) External Slow Clock (optional): OSC_SLOW
*
* A clock signal generated by an external circuit with frequency ~32kHz can be connected to GPIO0
* to be the clock source for the RTC_SLOW_CLK.
*
* OSC_SLOW_CLK can also be calibrated to get its exact frequency.
*/
/* With the default value of CK8M_DFREQ = 100, RC_FAST clock frequency is 17.5 MHz +/- 7% */
/* With the default value of FOSC_DFREQ = 100, RC_FAST clock frequency is 17.5 MHz +/- 7% */
#define SOC_CLK_RC_FAST_FREQ_APPROX 17500000 /*!< Approximate RC_FAST_CLK frequency in Hz */
#define SOC_CLK_RC_SLOW_FREQ_APPROX 136000 /*!< Approximate RC_SLOW_CLK frequency in Hz */
#define SOC_CLK_RC_FAST_D256_FREQ_APPROX (SOC_CLK_RC_FAST_FREQ_APPROX / 256) /*!< Approximate RC_FAST_D256_CLK frequency in Hz */
#define SOC_CLK_RC32K_FREQ_APPROX 32768 /*!< Approximate RC32K_CLK frequency in Hz */
#define SOC_CLK_XTAL32K_FREQ_APPROX 32768 /*!< Approximate XTAL32K_CLK frequency in Hz */
#define SOC_CLK_OSC_SLOW_FREQ_APPROX 32768 /*!< Approximate OSC_SLOW_CLK (external slow clock) frequency in Hz */
// Naming convention: SOC_ROOT_CLK_{loc}_{type}_[attr]
// {loc}: EXT, INT
@ -55,7 +61,9 @@ 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_XTAL32K, /*!< External 32kHz crystal/clock signal */
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, only support 32.768 kHz currently */
} soc_root_clk_t;
/**
@ -64,7 +72,7 @@ typedef enum {
*/
typedef enum {
SOC_CPU_CLK_SRC_XTAL = 0, /*!< Select XTAL_CLK as CPU_CLK source */
SOC_CPU_CLK_SRC_PLL = 1, /*!< Select PLL_CLK as CPU_CLK source (PLL_CLK is the output of 40MHz crystal oscillator frequency multiplier, can be 480MHz or 320MHz) */
SOC_CPU_CLK_SRC_PLL = 1, /*!< Select PLL_CLK as CPU_CLK source (PLL_CLK is the output of 40MHz crystal oscillator frequency multiplier, 480MHz) */
SOC_CPU_CLK_SRC_RC_FAST = 2, /*!< Select RC_FAST_CLK as CPU_CLK source */
SOC_CPU_CLK_SRC_INVALID, /*!< Invalid CPU_CLK source */
} soc_cpu_clk_src_t;
@ -74,10 +82,11 @@ typedef enum {
* @note Enum values are matched with the register field values on purpose
*/
typedef enum {
SOC_RTC_SLOW_CLK_SRC_RC_SLOW = 0, /*!< Select RC_SLOW_CLK as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_XTAL32K = 1, /*!< Select XTAL32K_CLK as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256 = 2, /*!< Select RC_FAST_D256_CLK (referred as FOSC_DIV or 8m_d256/8md256 in TRM and reg. description) as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_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 */
SOC_RTC_SLOW_CLK_SRC_OSC_SLOW = 3, /*!< Select OSC_SLOW_CLK (external slow clock) as RTC_SLOW_CLK source */
SOC_RTC_SLOW_CLK_SRC_INVALID, /*!< Invalid RTC_SLOW_CLK source */
} soc_rtc_slow_clk_src_t;
/**
@ -85,9 +94,9 @@ typedef enum {
* @note Enum values are matched with the register field values on purpose
*/
typedef enum {
SOC_RTC_FAST_CLK_SRC_XTAL_D2 = 0, /*!< Select XTAL_D2_CLK (may referred as XTAL_CLK_DIV_2) as RTC_FAST_CLK source */
SOC_RTC_FAST_CLK_SRC_RC_FAST = 0, /*!< Select RC_FAST_CLK as RTC_FAST_CLK source */
SOC_RTC_FAST_CLK_SRC_XTAL_D2 = 1, /*!< Select XTAL_D2_CLK (may referred as XTAL_CLK_DIV_2) as RTC_FAST_CLK source */
SOC_RTC_FAST_CLK_SRC_XTAL_DIV = SOC_RTC_FAST_CLK_SRC_XTAL_D2, /*!< Alias name for `SOC_RTC_FAST_CLK_SRC_XTAL_D2` */
SOC_RTC_FAST_CLK_SRC_RC_FAST = 1, /*!< Select RC_FAST_CLK as RTC_FAST_CLK source */
SOC_RTC_FAST_CLK_SRC_INVALID, /*!< Invalid RTC_FAST_CLK source */
} soc_rtc_fast_clk_src_t;
@ -106,13 +115,12 @@ typedef enum {
SOC_MOD_CLK_RTC_FAST, /*!< RTC_FAST_CLK can be sourced from XTAL_D2 or RC_FAST by configuring soc_rtc_fast_clk_src_t */
SOC_MOD_CLK_RTC_SLOW, /*!< RTC_SLOW_CLK can be sourced from RC_SLOW, XTAL32K, or RC_FAST_D256 by configuring soc_rtc_slow_clk_src_t */
// For digital domain: peripherals, WIFI, BLE
SOC_MOD_CLK_APB, /*!< APB_CLK is highly dependent on the CPU_CLK source */
SOC_MOD_CLK_APB, /*!< APB_CLK is highly dependent on the CPU_CLK source */ // TODO: IDF-6343 This should be removed on ESP32C6! Impacts on all following peripheral drivers!
SOC_MOD_CLK_PLL_F80M, /*!< PLL_F80M_CLK is derived from PLL, and has a fixed frequency of 80MHz */
SOC_MOD_CLK_PLL_F160M, /*!< PLL_F160M_CLK is derived from PLL, and has a fixed frequency of 160MHz */
SOC_MOD_CLK_PLL_D2, /*!< PLL_D2_CLK is derived from PLL, it has a fixed divider of 2 */
SOC_MOD_CLK_PLL_F240M, /*!< PLL_F240M_CLK is derived from PLL, and has a fixed frequency of 240MHz */
SOC_MOD_CLK_XTAL32K, /*!< XTAL32K_CLK comes from the external 32kHz crystal, passing a clock gating to the peripherals */
SOC_MOD_CLK_RC_FAST, /*!< RC_FAST_CLK comes from the internal 20MHz rc oscillator, passing a clock gating to the peripherals */
SOC_MOD_CLK_RC_FAST_D256, /*!< RC_FAST_D256_CLK comes from the internal 20MHz rc oscillator, divided by 256, and passing a clock gating to the peripherals */
SOC_MOD_CLK_XTAL, /*!< XTAL_CLK comes from the external 40MHz crystal */
} soc_module_clk_t;
@ -141,32 +149,24 @@ typedef enum {
* }
* @endcode
*/
#if CONFIG_IDF_ENV_FPGA
#define SOC_GPTIMER_CLKS {SOC_MOD_CLK_XTAL}
#else
#define SOC_GPTIMER_CLKS {SOC_MOD_CLK_APB, SOC_MOD_CLK_XTAL}
#endif
#define SOC_GPTIMER_CLKS {SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_XTAL}
/**
* @brief Type of GPTimer clock source
*/
typedef enum {
GPTIMER_CLK_SRC_APB = SOC_MOD_CLK_APB, /*!< Select APB as the source clock */
GPTIMER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
#if CONFIG_IDF_ENV_FPGA
GPTIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default choice */
#else
GPTIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default choice */
#endif
GPTIMER_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the source clock */
GPTIMER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
GPTIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the default choice */
} soc_periph_gptimer_clk_src_t;
/**
* @brief Type of Timer Group clock source, reserved for the legacy timer group driver
*/
typedef enum {
TIMER_SRC_CLK_APB = SOC_MOD_CLK_APB, /*!< Timer group clock source is APB */
TIMER_SRC_CLK_XTAL = SOC_MOD_CLK_XTAL, /*!< Timer group clock source is XTAL */
TIMER_SRC_CLK_DEFAULT = SOC_MOD_CLK_APB, /*!< Timer group clock source default choice is APB */
TIMER_SRC_CLK_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Timer group clock source is PLL_F80M */
TIMER_SRC_CLK_XTAL = SOC_MOD_CLK_XTAL, /*!< Timer group clock source is XTAL */
TIMER_SRC_CLK_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Timer group clock source default choice is PLL_F80M */
} soc_periph_tg_clk_src_legacy_t;
//////////////////////////////////////////////////RMT///////////////////////////////////////////////////////////////////
@ -174,11 +174,7 @@ typedef enum {
/**
* @brief Array initializer for all supported clock sources of RMT
*/
#if CONFIG_IDF_ENV_FPGA
#define SOC_RMT_CLKS {SOC_MOD_CLK_XTAL}
#else
#define SOC_RMT_CLKS {SOC_MOD_CLK_APB, SOC_MOD_CLK_XTAL}
#endif
/**
* @brief Type of RMT clock source
@ -186,11 +182,7 @@ typedef enum {
typedef enum {
RMT_CLK_SRC_APB = SOC_MOD_CLK_APB, /*!< Select APB as the source clock */
RMT_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
#if CONFIG_IDF_ENV_FPGA
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default choice */
#else
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default choice */
#endif
} soc_periph_rmt_clk_src_t;
/**
@ -227,11 +219,7 @@ typedef enum {
UART_SCLK_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< UART source clock is PLL_F80M */
UART_SCLK_RTC = SOC_MOD_CLK_RC_FAST, /*!< UART source clock is RC_FAST */
UART_SCLK_XTAL = SOC_MOD_CLK_XTAL, /*!< UART source clock is XTAL */
#if CONFIG_IDF_ENV_FPGA
UART_SCLK_DEFAULT = SOC_MOD_CLK_XTAL, /*!< UART source clock default choice is XTAL for FPGA environment */
#else
UART_SCLK_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< UART source clock default choice is PLL_F80M */
#endif
} soc_periph_uart_clk_src_legacy_t;
//////////////////////////////////////////////////MCPWM/////////////////////////////////////////////////////////////////
@ -247,11 +235,7 @@ typedef enum {
typedef enum {
MCPWM_TIMER_CLK_SRC_PLL160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the source clock */
MCPWM_TIMER_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
#if CONFIG_IDF_ENV_FPGA
MCPWM_TIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default clock choice */
#else
MCPWM_TIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default clock choice */
#endif
} soc_periph_mcpwm_timer_clk_src_t;
/**
@ -265,11 +249,7 @@ typedef enum {
typedef enum {
MCPWM_CAPTURE_CLK_SRC_PLL160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the source clock */
MCPWM_CAPTURE_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
#if CONFIG_IDF_ENV_FPGA
MCPWM_CAPTURE_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default clock choice */
#else
MCPWM_CAPTURE_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default clock choice */
#endif
} soc_periph_mcpwm_capture_clk_src_t;
///////////////////////////////////////////////////// I2S //////////////////////////////////////////////////////////////
@ -277,21 +257,13 @@ typedef enum {
/**
* @brief Array initializer for all supported clock sources of I2S
*/
#if CONFIG_IDF_ENV_FPGA
#define SOC_I2S_CLKS {SOC_MOD_CLK_XTAL}
#else
#define SOC_I2S_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_XTAL}
#endif
/**
* @brief I2S clock source enum
*/
typedef enum {
#if CONFIG_IDF_ENV_FPGA
I2S_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL,
#else
I2S_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default source clock */
#endif
I2S_CLK_SRC_PLL_160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the source clock */
I2S_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
} soc_periph_i2s_clk_src_t;

View File

@ -146,6 +146,8 @@
#define USB_DM_GPIO_NUM 12
#define USB_DP_GPIO_NUM 13
#define EXT_OSC_SLOW_GPIO_NUM 0
#define MAX_RTC_GPIO_NUM 8
#define MAX_PAD_GPIO_NUM 30
#define MAX_GPIO_NUM 34

View File

@ -11,7 +11,7 @@
* @brief Register definitions for bias
*
* This file lists register fields of BIAS. These definitions are used via macros defined in regi2c_ctrl.h, by
* bootloader_hardware_init function in bootloader_esp32c3.c.
* bootloader_hardware_init function in bootloader_esp32c6.c.
*/
#define I2C_BIAS 0X6A

View File

@ -9,11 +9,13 @@
#include "esp_bit_defs.h"
/* Analog function control register */
#define I2C_MST_ANA_CONF0_REG 0x6000E040
#define I2C_MST_ANA_CONF0_REG 0x600AF818
#define I2C_MST_BBPLL_STOP_FORCE_HIGH (BIT(2))
#define I2C_MST_BBPLL_STOP_FORCE_LOW (BIT(3))
#define I2C_MST_BBPLL_STOP_FORCE_LOW (BIT(3))
#define I2C_MST_BBPLL_CAL_DONE (BIT(24))
#define ANA_CONFIG_REG 0x6000E044
#define ANA_CONFIG_REG 0x600AF81C
#define ANA_CONFIG_S (8)
#define ANA_CONFIG_M (0x3FF)
@ -21,11 +23,12 @@
#define ANA_I2C_BBPLL_M BIT(17) /* Clear to enable BBPLL */
#define ANA_CONFIG2_REG 0x6000E048
#define ANA_CONFIG2_REG 0x600AF820
#define ANA_CONFIG2_M BIT(18)
#define ANA_I2C_SAR_FORCE_PU BIT(16)
/**
* Restore regi2c analog calibration related configuration registers.
* This is a workaround, and is fixed on later chips

View File

@ -0,0 +1,64 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
/**
* @file regi2c_dig_reg.h
* @brief Register definitions for digital to get rtc voltage & digital voltage
* by setting rtc_dbias_Wak & dig_dbias_wak or by analog self-calibration.
*/
#define I2C_DIG_REG 0x6D
#define I2C_DIG_REG_HOSTID 0
#define I2C_DIG_REG_EXT_RTC_DREG 4
#define I2C_DIG_REG_EXT_RTC_DREG_MSB 4
#define I2C_DIG_REG_EXT_RTC_DREG_LSB 0
#define I2C_DIG_REG_ENX_RTC_DREG 4
#define I2C_DIG_REG_ENX_RTC_DREG_MSB 7
#define I2C_DIG_REG_ENX_RTC_DREG_LSB 7
#define I2C_DIG_REG_EXT_RTC_DREG_SLEEP 5
#define I2C_DIG_REG_EXT_RTC_DREG_SLEEP_MSB 4
#define I2C_DIG_REG_EXT_RTC_DREG_SLEEP_LSB 0
#define I2C_DIG_REG_ENIF_RTC_DREG 5
#define I2C_DIG_REG_ENIF_RTC_DREG_MSB 7
#define I2C_DIG_REG_ENIF_RTC_DREG_LSB 7
#define I2C_DIG_REG_EXT_DIG_DREG 6
#define I2C_DIG_REG_EXT_DIG_DREG_MSB 4
#define I2C_DIG_REG_EXT_DIG_DREG_LSB 0
#define I2C_DIG_REG_ENX_DIG_DREG 6
#define I2C_DIG_REG_ENX_DIG_DREG_MSB 7
#define I2C_DIG_REG_ENX_DIG_DREG_LSB 7
#define I2C_DIG_REG_EXT_DIG_DREG_SLEEP 7
#define I2C_DIG_REG_EXT_DIG_DREG_SLEEP_MSB 4
#define I2C_DIG_REG_EXT_DIG_DREG_SLEEP_LSB 0
#define I2C_DIG_REG_ENIF_DIG_DREG 7
#define I2C_DIG_REG_ENIF_DIG_DREG_MSB 7
#define I2C_DIG_REG_ENIF_DIG_DREG_LSB 7
#define I2C_DIG_REG_OR_EN_CONT_CAL 9
#define I2C_DIG_REG_OR_EN_CONT_CAL_MSB 7
#define I2C_DIG_REG_OR_EN_CONT_CAL_LSB 7
#define I2C_DIG_REG_XPD_RTC_REG 13
#define I2C_DIG_REG_XPD_RTC_REG_MSB 2
#define I2C_DIG_REG_XPD_RTC_REG_LSB 2
#define I2C_DIG_REG_XPD_DIG_REG 13
#define I2C_DIG_REG_XPD_DIG_REG_MSB 3
#define I2C_DIG_REG_XPD_DIG_REG_LSB 3
#define I2C_DIG_REG_SCK_DCAP 14
#define I2C_DIG_REG_SCK_DCAP_MSB 7
#define I2C_DIG_REG_SCK_DCAP_LSB 0

View File

@ -46,13 +46,14 @@ extern "C" {
#define MHZ (1000000)
#define RTC_SLOW_CLK_X32K_CAL_TIMEOUT_THRES(cycles) (cycles << 12)
#define RTC_SLOW_CLK_8MD256_CAL_TIMEOUT_THRES(cycles) (cycles << 12)
#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
// TODO: IDF-5781
/* Approximate mapping of voltages to RTC_CNTL_DBIAS_WAK, RTC_CNTL_DBIAS_SLP,
* RTC_CNTL_DIG_DBIAS_WAK, RTC_CNTL_DIG_DBIAS_SLP values.
*/
@ -74,9 +75,10 @@ extern "C" {
#define SOC_DELAY_RTC_SLOW_CLK_SWITCH 300
#define SOC_DELAY_RC_FAST_ENABLE 50
#define SOC_DELAY_RC_FAST_DIGI_SWITCH 5
#define SOC_DELAY_RC32K_ENABLE 300
/* Core voltage:
* Currently, ESP32C3 never adjust its wake voltage in runtime
/* Core voltage: // TODO: IDF-5781
* Currently, ESP32C6 never adjust its wake voltage in runtime
* Only sets dig/rtc voltage dbias at startup time
*/
#define DIG_DBIAS_80M RTC_CNTL_DBIAS_1V20
@ -89,8 +91,9 @@ extern "C" {
#define RTC_CNTL_CK8M_WAIT_DEFAULT 20
#define RTC_CK8M_ENABLE_WAIT_DEFAULT 5
#define RTC_CNTL_CK8M_DFREQ_DEFAULT 100
#define RTC_CNTL_SCK_DCAP_DEFAULT 255
#define RTC_CNTL_CK8M_DFREQ_DEFAULT 100
#define RTC_CNTL_SCK_DCAP_DEFAULT 128
#define RTC_CNTL_RC32K_DFREQ_DEFAULT 700
/* Various delays to be programmed into power control state machines */
#define RTC_CNTL_XTL_BUF_WAIT_SLP_US (250)
@ -140,7 +143,7 @@ typedef enum {
typedef struct rtc_cpu_freq_config_s {
soc_cpu_clk_src_t source; //!< The clock from which CPU clock is derived
uint32_t source_freq_mhz; //!< Source clock frequency
uint32_t div; //!< Divider, freq_mhz = source_freq_mhz / div
uint32_t div; //!< Divider, freq_mhz = SOC_ROOT_CLK freq_mhz / div
uint32_t freq_mhz; //!< CPU clock frequency
} rtc_cpu_freq_config_t;
@ -151,12 +154,18 @@ typedef struct rtc_cpu_freq_config_s {
/**
* @brief Clock source to be calibrated using rtc_clk_cal function
*
* @note On previous targets, the enum values somehow reflects the register field values of TIMG_RTC_CALI_CLK_SEL
* However, this is not true on ESP32C6. The conversion to register field values is explicitly done in
* rtc_clk_cal_internal
*/
typedef enum {
RTC_CAL_RTC_MUX = 0, //!< Currently selected RTC SLOW_CLK
RTC_CAL_32K_XTAL = 2, //!< External 32 kHz XTAL
RTC_CAL_INTERNAL_OSC = 3, //!< Internal 150 kHz oscillator
RTC_CAL_RC_FAST, //!< Internal 20 MHz oscillator
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 32kHz clk signal input by lp_pad_gpio0, as one type of 32k clock
RTC_CAL_RC_FAST //!< Internal 20MHz RC oscillator
} rtc_cal_sel_t;
/**
@ -166,11 +175,12 @@ typedef struct {
rtc_xtal_freq_t xtal_freq : 8; //!< Main XTAL frequency
uint32_t cpu_freq_mhz : 10; //!< CPU frequency to set, in MHz
soc_rtc_fast_clk_src_t fast_clk_src : 2; //!< RTC_FAST_CLK clock source to choose
soc_rtc_slow_clk_src_t slow_clk_src : 2; //!< RTC_SLOW_CLK clock source to choose
soc_rtc_slow_clk_src_t slow_clk_src : 3; //!< RTC_SLOW_CLK clock source to choose
uint32_t clk_rtc_clk_div : 8;
uint32_t clk_8m_clk_div : 3; //!< RTC 8M clock divider (division is by clk_8m_div+1, i.e. 0 means 8MHz frequency)
uint32_t slow_clk_dcap : 8; //!< RTC 150k clock adjustment parameter (higher value leads to lower frequency)
uint32_t clk_8m_dfreq : 8; //!< RTC 8m clock adjustment parameter (higher value leads to higher frequency)
uint32_t clk_8m_clk_div : 3; //!< RC_FAST clock divider (division is by clk_8m_div+1, i.e. 0 means ~20MHz frequency)
uint32_t slow_clk_dcap : 8; //!< RC_SLOW clock adjustment parameter (higher value leads to lower frequency)
uint32_t clk_8m_dfreq : 8; //!< RC_FAST clock adjustment parameter (higher value leads to higher frequency)
uint32_t rc32k_dfreq : 10; //!< Internal RC32K clock adjustment parameter (higher value leads to higher frequency)
} rtc_clk_config_t;
/**
@ -185,6 +195,7 @@ typedef struct {
.clk_8m_clk_div = 0, \
.slow_clk_dcap = RTC_CNTL_SCK_DCAP_DEFAULT, \
.clk_8m_dfreq = RTC_CNTL_CK8M_DFREQ_DEFAULT, \
.rc32k_dfreq = RTC_CNTL_RC32K_DFREQ_DEFAULT, \
}
typedef struct {
@ -213,10 +224,6 @@ typedef struct {
.dg_peri_wait_cycles = OTHER_BLOCKS_WAIT, \
}
void rtc_clk_divider_set(uint32_t div);
void rtc_clk_8m_divider_set(uint32_t div);
/**
* Initialize clocks and set CPU frequency
*
@ -273,23 +280,18 @@ bool rtc_clk_32k_enabled(void);
*/
void rtc_clk_32k_bootstrap(uint32_t cycle);
/**
* @brief Enable or disable 32 kHz internal rc oscillator
* @param en true to enable, false to disable
*/
void rtc_clk_rc32k_enable(bool enable);
/**
* @brief Enable or disable 8 MHz internal oscillator
*
* Output from 8 MHz internal oscillator is passed into a configurable
* divider, which by default divides the input clock frequency by 256.
* Output of the divider may be used as RTC_SLOW_CLK source.
* Output of the divider is referred to in register descriptions and code as
* 8md256 or simply d256. Divider values other than 256 may be configured, but
* this facility is not currently needed, so is not exposed in the code.
*
* When 8MHz/256 divided output is not needed, the divider should be disabled
* to reduce power consumption.
*
* @param clk_8m_en true to enable 8MHz generator
* @param d256_en true to enable /256 divider
*/
void rtc_clk_8m_enable(bool clk_8m_en, bool d256_en);
void rtc_clk_8m_enable(bool clk_8m_en);
/**
* @brief Get the state of 8 MHz internal oscillator
@ -297,12 +299,6 @@ void rtc_clk_8m_enable(bool clk_8m_en, bool d256_en);
*/
bool rtc_clk_8m_enabled(void);
/**
* @brief Get the state of /256 divider which is applied to 8MHz clock
* @return true if the divided output is enabled
*/
bool rtc_clk_8md256_enabled(void);
/**
* @brief Select source for RTC_SLOW_CLK
* @param clk_src clock source (one of soc_rtc_slow_clk_src_t values)
@ -401,25 +397,29 @@ void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config);
void rtc_clk_cpu_freq_set_xtal(void);
/**
* @brief Store new APB frequency value into RTC_APB_FREQ_REG
*
* This function doesn't change any hardware clocks.
*
* Functions which perform frequency switching and change APB frequency call
* this function to update the value of APB frequency stored in RTC_APB_FREQ_REG
* (one of RTC general purpose retention registers). This should not normally
* be called from application code.
*
* @param apb_freq new APB frequency, in Hz
*/
void rtc_clk_apb_freq_update(uint32_t apb_freq);
/**
* @brief Get the current stored APB frequency.
* @return The APB frequency value as last set via rtc_clk_apb_freq_update(), in Hz.
* @brief Get the current APB frequency.
* @return The calculated APB frequency value, in Hz.
*/
uint32_t rtc_clk_apb_freq_get(void);
/**
* @brief Clock calibration function used by rtc_clk_cal
*
* Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0.
* This feature counts the number of XTAL clock cycles within a given number of
* RTC_SLOW_CLK cycles.
*
* Slow clock calibration feature has two modes of operation: one-off and cycling.
* In cycling mode (which is enabled by default on SoC reset), counting of XTAL
* cycles within RTC_SLOW_CLK cycle is done continuously. Cycling mode is enabled
* using TIMG_RTC_CALI_START_CYCLING bit. In one-off mode counting is performed
* once, and TIMG_RTC_CALI_RDY bit is set when counting is done. One-off mode is
* enabled using TIMG_RTC_CALI_START bit.
*
* @param cal_clk which clock to calibrate
* @param slowclk_cycles number of slow clock cycles to count
* @return number of XTAL clock cycles within the given number of slow clock cycles
*/
uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles);
/**
@ -430,6 +430,11 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles);
* 32k XTAL is being calibrated, but the oscillator has not started up (due to
* incorrect loading capacitance, board design issue, or lack of 32 XTAL on board).
*
* @note When 32k CLK is being calibrated, this function will check the accuracy
* of the clock. Since the xtal 32k or ext osc 32k is generally very stable, if
* the check fails, then consider this an invalid 32k clock and return 0. This
* check can filter some jamming signal.
*
* @param cal_clk clock to be measured
* @param slow_clk_cycles number of slow clock cycles to average
* @return average slow clock period in microseconds, Q13.19 fixed point format,
@ -437,15 +442,6 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles);
*/
uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slow_clk_cycles);
/**
* @brief Measure ratio between XTAL frequency and RTC slow clock frequency
* @param cal_clk slow clock to be measured
* @param slow_clk_cycles number of slow clock cycles to average
* @return average ratio between XTAL frequency and slow clock frequency,
* Q13.19 fixed point format, or 0 if calibration has timed out.
*/
uint32_t rtc_clk_cal_ratio(rtc_cal_sel_t cal_clk, uint32_t slow_clk_cycles);
/**
* @brief Convert time interval from microseconds to RTC_SLOW_CLK cycles
* @param time_in_us Time interval in microseconds

View File

@ -140,19 +140,10 @@
#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM
#define EFUSE_CLK_FREQ_ROM ( 20*1000000)
#define CPU_CLK_FREQ APB_CLK_FREQ
#if CONFIG_IDF_ENV_FPGA
#define APB_CLK_FREQ ( 40*1000000 )
#else
#define APB_CLK_FREQ ( 80*1000000 )
#endif
#define APB_CLK_FREQ ( 80*1000000 ) // TODO: IDF-6343 APB clock freq is 40MHz indeed
#define REF_CLK_FREQ ( 1000000 )
#define RTC_CLK_FREQ (20*1000000)
#define XTAL_CLK_FREQ (40*1000000)
#define UART_CLK_FREQ APB_CLK_FREQ
#define WDT_CLK_FREQ APB_CLK_FREQ
#define TIMER_CLK_FREQ (80000000>>4) //80MHz divided by 16
#define SPI_CLK_DIV 4
#define TICKS_PER_US_ROM 40 // CPU is 80MHz
#define GPIO_MATRIX_DELAY_NS 0
//}}

View File

@ -205,6 +205,7 @@
#define SOC_I2S_NUM (1)
#define SOC_I2S_HW_VERSION_2 (1)
#define SOC_I2S_SUPPORTS_XTAL (1)
#define SOC_I2S_SUPPORTS_PLL_F160M (1)
#define SOC_I2S_SUPPORTS_PCM (1)
#define SOC_I2S_SUPPORTS_PDM (1)
#define SOC_I2S_SUPPORTS_PDM_TX (1)
@ -362,7 +363,7 @@
#define SOC_TIMER_GROUP_TIMERS_PER_GROUP (1U)
#define SOC_TIMER_GROUP_COUNTER_BIT_WIDTH (54)
#define SOC_TIMER_GROUP_SUPPORT_XTAL (1)
#define SOC_TIMER_GROUP_SUPPORT_APB (1)
#define SOC_TIMER_GROUP_SUPPORT_PLL_F80M (1)
#define SOC_TIMER_GROUP_TOTAL_TIMERS (2)
#define SOC_TIMER_SUPPORT_ETM (1)

View File

@ -351,6 +351,10 @@ config SOC_I2S_SUPPORTS_XTAL
bool
default y
config SOC_I2S_SUPPORTS_PLL_F96M
bool
default y
config SOC_I2S_SUPPORTS_PCM
bool
default y

View File

@ -58,3 +58,7 @@
#define I2C_DIG_REG_XPD_DIG_REG 13
#define I2C_DIG_REG_XPD_DIG_REG_MSB 3
#define I2C_DIG_REG_XPD_DIG_REG_LSB 3
#define I2C_DIG_REG_SCK_DCAP 14
#define I2C_DIG_REG_SCK_DCAP_MSB 7
#define I2C_DIG_REG_SCK_DCAP_LSB 0

View File

@ -191,6 +191,7 @@
#define SOC_I2S_NUM (1)
#define SOC_I2S_HW_VERSION_2 (1)
#define SOC_I2S_SUPPORTS_XTAL (1)
#define SOC_I2S_SUPPORTS_PLL_F96M (1)
#define SOC_I2S_SUPPORTS_PCM (1)
#define SOC_I2S_SUPPORTS_PDM (1)
#define SOC_I2S_SUPPORTS_PDM_TX (1)

View File

@ -363,6 +363,10 @@ config SOC_I2S_SUPPORTS_APLL
bool
default y
config SOC_I2S_SUPPORTS_PLL_F160M
bool
default y
config SOC_I2S_SUPPORTS_DMA_EQUAL
bool
default y

View File

@ -181,6 +181,7 @@
#define SOC_I2S_NUM (1U)
#define SOC_I2S_HW_VERSION_1 (1)
#define SOC_I2S_SUPPORTS_APLL (1)
#define SOC_I2S_SUPPORTS_PLL_F160M (1)
#define SOC_I2S_SUPPORTS_DMA_EQUAL (1)
#define SOC_I2S_SUPPORTS_LCD_CAMERA (1)
#define SOC_I2S_APLL_MIN_FREQ (250000000)

View File

@ -419,6 +419,10 @@ config SOC_I2S_SUPPORTS_XTAL
bool
default y
config SOC_I2S_SUPPORTS_PLL_F160M
bool
default y
config SOC_I2S_SUPPORTS_PCM
bool
default y

View File

@ -185,6 +185,7 @@
#define SOC_I2S_NUM (2)
#define SOC_I2S_HW_VERSION_2 (1)
#define SOC_I2S_SUPPORTS_XTAL (1)
#define SOC_I2S_SUPPORTS_PLL_F160M (1)
#define SOC_I2S_SUPPORTS_PCM (1)
#define SOC_I2S_SUPPORTS_PDM (1)
#define SOC_I2S_SUPPORTS_PDM_TX (1)