From 182e937c5aad06f2aa3e0799f0f60888a9a7560f Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Fri, 18 Nov 2022 17:59:05 +0800 Subject: [PATCH 1/4] clk_tree: Add basic clock support for esp32c6 - Support SOC ROOT clock source switch - Support CPU frequency change - Support RTC SLOW clock source switch - Support RTC SLOW clock + RC FAST calibration Remove FPGA build for esp32c6 --- Kconfig | 1 - .../src/bootloader_clock_init.c | 21 +- .../src/esp32c6/bootloader_esp32c6.c | 2 +- components/driver/test/test_ledc.c | 2 - components/esp_hw_support/esp_clk.c | 5 + .../esp_hw_support/port/esp32c2/rtc_init.c | 2 +- .../esp_hw_support/port/esp32c2/rtc_time.c | 10 +- .../esp_hw_support/port/esp32c3/rtc_clk.c | 2 +- .../port/esp32c6/CMakeLists.txt | 2 +- .../esp_hw_support/port/esp32c6/Kconfig.rtc | 5 +- .../esp_hw_support/port/esp32c6/rtc_clk.c | 318 ++++++++--- .../port/esp32c6/rtc_clk_init.c | 46 +- .../esp_hw_support/port/esp32c6/rtc_init.c | 19 +- .../esp_hw_support/port/esp32c6/rtc_time.c | 207 +++++-- components/esp_hw_support/rtc_module.c | 4 +- .../test_apps/rtc_clk/main/test_rtc_clk.c | 6 +- .../esp_rom/esp32c6/ld/esp32c6.rom.eco3.ld | 138 ----- components/esp_system/port/soc/esp32c2/clk.c | 2 +- .../esp_system/port/soc/esp32c6/Kconfig.cpu | 3 + components/esp_system/port/soc/esp32c6/clk.c | 66 +-- components/esptool_py/Kconfig.projbuild | 8 +- .../hal/esp32c6/include/hal/clk_tree_ll.h | 527 +++++++++++++----- .../hal/esp32c6/include/hal/regi2c_ctrl_ll.h | 39 +- .../hal/esp32c6/include/hal/spimem_flash_ll.h | 3 +- components/soc/esp32c2/include/soc/rtc.h | 5 +- .../esp32c6/include/modem/modem_lpcon_reg.h | 2 +- .../include/modem/modem_lpcon_struct.h | 5 +- .../soc/esp32c6/include/soc/clk_tree_defs.h | 94 ++-- .../soc/esp32c6/include/soc/io_mux_reg.h | 2 + .../soc/esp32c6/include/soc/regi2c_bias.h | 2 +- .../soc/esp32c6/include/soc/regi2c_defs.h | 11 +- .../soc/esp32c6/include/soc/regi2c_dig_reg.h | 64 +++ components/soc/esp32c6/include/soc/rtc.h | 118 ++-- components/soc/esp32c6/include/soc/soc.h | 11 +- .../soc/esp32h4/include/soc/regi2c_dig_reg.h | 4 + 35 files changed, 1113 insertions(+), 643 deletions(-) delete mode 100644 components/esp_rom/esp32c6/ld/esp32c6.rom.eco3.ld create mode 100644 components/soc/esp32c6/include/soc/regi2c_dig_reg.h diff --git a/Kconfig b/Kconfig index c80b0e848e7f..5d5baffd29c8 100644 --- a/Kconfig +++ b/Kconfig @@ -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 diff --git a/components/bootloader_support/src/bootloader_clock_init.c b/components/bootloader_support/src/bootloader_clock_init.c index ee1d6c31178e..73c844109a66 100644 --- a/components/bootloader_support/src/bootloader_clock_init.c +++ b/components/bootloader_support/src/bootloader_clock_init.c @@ -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); diff --git a/components/bootloader_support/src/esp32c6/bootloader_esp32c6.c b/components/bootloader_support/src/esp32c6/bootloader_esp32c6.c index 2208aed44fe9..f250b4b8c34a 100644 --- a/components/bootloader_support/src/esp32c6/bootloader_esp32c6.c +++ b/components/bootloader_support/src/esp32c6/bootloader_esp32c6.c @@ -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); } diff --git a/components/driver/test/test_ledc.c b/components/driver/test/test_ledc.c index 6b61530f01ba..781e7fafb804 100644 --- a/components/driver/test/test_ledc.c +++ b/components/driver/test/test_ledc.c @@ -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); diff --git a/components/esp_hw_support/esp_clk.c b/components/esp_hw_support/esp_clk.c index 4bd2544e5043..a5c472b92bca 100644 --- a/components/esp_hw_support/esp_clk.c +++ b/components/esp_hw_support/esp_clk.c @@ -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) diff --git a/components/esp_hw_support/port/esp32c2/rtc_init.c b/components/esp_hw_support/port/esp32c2/rtc_init.c index b55769a5d68a..277b2a0acdb9 100644 --- a/components/esp_hw_support/port/esp32c2/rtc_init.c +++ b/components/esp_hw_support/port/esp32c2/rtc_init.c @@ -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; } diff --git a/components/esp_hw_support/port/esp32c2/rtc_time.c b/components/esp_hw_support/port/esp32c2/rtc_time.c index e634eaaf2d1b..0333f05aec76 100644 --- a/components/esp_hw_support/port/esp32c2/rtc_time.c +++ b/components/esp_hw_support/port/esp32c2/rtc_time.c @@ -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; } diff --git a/components/esp_hw_support/port/esp32c3/rtc_clk.c b/components/esp_hw_support/port/esp32c3/rtc_clk.c index ff3930a46009..7e307aaa171f 100644 --- a/components/esp_hw_support/port/esp32c3/rtc_clk.c +++ b/components/esp_hw_support/port/esp32c3/rtc_clk.c @@ -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(); diff --git a/components/esp_hw_support/port/esp32c6/CMakeLists.txt b/components/esp_hw_support/port/esp32c6/CMakeLists.txt index 5a783cd05f89..ebcd4b15c2f2 100644 --- a/components/esp_hw_support/port/esp32c6/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32c6/CMakeLists.txt @@ -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" diff --git a/components/esp_hw_support/port/esp32c6/Kconfig.rtc b/components/esp_hw_support/port/esp32c6/Kconfig.rtc index 4dcb82924986..f50eef47040b 100644 --- a/components/esp_hw_support/port/esp32c6/Kconfig.rtc +++ b/components/esp_hw_support/port/esp32c6/Kconfig.rtc @@ -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 diff --git a/components/esp_hw_support/port/esp32c6/rtc_clk.c b/components/esp_hw_support/port/esp32c6/rtc_clk.c index fe7aa35b8406..7e73d999e413 100644 --- a/components/esp_hw_support/port/esp32c6/rtc_clk.c +++ b/components/esp_hw_support/port/esp32c6/rtc_clk.c @@ -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(); + } } -bool rtc_clk_8m_enabled(void) +void rtc_clk_8m_enable(bool clk_8m_en) { - // TODO: IDF-5645 - return 0; + 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_8md256_enabled(void) +bool rtc_clk_8m_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,109 +165,202 @@ 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 -} - -#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 -} + int freq_mhz = (int)rtc_clk_xtal_freq_get(); -static void rtc_clk_cpu_freq_to_8m(void) -{ - // TODO: IDF-5645 + rtc_clk_cpu_freq_to_xtal(freq_mhz, 1); + rtc_clk_bbpll_disable(); } -#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 -} - -void rtc_clk_apb_freq_update(uint32_t apb_freq) -{ - // TODO: IDF-5645 + clk_ll_xtal_store_freq_mhz(xtal_freq); +} + +static uint32_t rtc_clk_ahb_freq_get(void) +{ + soc_cpu_clk_src_t source = clk_ll_cpu_get_src(); + uint32_t soc_root_freq_mhz; + uint32_t divider; + 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; -} - -#if 0 -static bool rtc_clk_set_bbpll_always_on(void) -{ - // TODO: IDF-5645 - return 0; + return clk_ll_rc_fast_digi_is_enabled(); } -#endif /* Name used in libphy.a:phy_chip_v7.o * TODO: update the library to use rtc_clk_xtal_freq_get diff --git a/components/esp_hw_support/port/esp32c6/rtc_clk_init.c b/components/esp_hw_support/port/esp32c6/rtc_clk_init.c index 807cf9fd399a..78bb356bcb29 100644 --- a/components/esp_hw_support/port/esp32c6/rtc_clk_init.c +++ b/components/esp_hw_support/port/esp32c6/rtc_clk_init.c @@ -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 } diff --git a/components/esp_hw_support/port/esp32c6/rtc_init.c b/components/esp_hw_support/port/esp32c6/rtc_init.c index 8a5daa45174f..60a77df39a15 100644 --- a/components/esp_hw_support/port/esp32c6/rtc_init.c +++ b/components/esp_hw_support/port/esp32c6/rtc_init.c @@ -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); +} diff --git a/components/esp_hw_support/port/esp32c6/rtc_time.c b/components/esp_hw_support/port/esp32c6/rtc_time.c index b5bfa6e7d2df..bf4aad5fca81 100644 --- a/components/esp_hw_support/port/esp32c6/rtc_time.c +++ b/components/esp_hw_support/port/esp32c6/rtc_time.c @@ -7,10 +7,13 @@ #include #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; } diff --git a/components/esp_hw_support/rtc_module.c b/components/esp_hw_support/rtc_module.c index 8a8637c9e31b..1e443da4f2e3 100644 --- a/components/esp_hw_support/rtc_module.c +++ b/components/esp_hw_support/rtc_module.c @@ -101,7 +101,7 @@ static esp_err_t rtc_isr_ensure_installed(void) 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; diff --git a/components/esp_hw_support/test_apps/rtc_clk/main/test_rtc_clk.c b/components/esp_hw_support/test_apps/rtc_clk/main/test_rtc_clk.c index 01aa7bc7431d..3d5c69932e66 100644 --- a/components/esp_hw_support/test_apps/rtc_clk/main/test_rtc_clk.c +++ b/components/esp_hw_support/test_apps/rtc_clk/main/test_rtc_clk.c @@ -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 diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.eco3.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.eco3.ld deleted file mode 100644 index c7f10134f2f7..000000000000 --- a/components/esp_rom/esp32c6/ld/esp32c6.rom.eco3.ld +++ /dev/null @@ -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 ); diff --git a/components/esp_system/port/soc/esp32c2/clk.c b/components/esp_system/port/soc/esp32c2/clk.c index ebc800e57688..b0f8f6d1105b 100644 --- a/components/esp_system/port/soc/esp32c2/clk.c +++ b/components/esp_system/port/soc/esp32c2/clk.c @@ -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; diff --git a/components/esp_system/port/soc/esp32c6/Kconfig.cpu b/components/esp_system/port/soc/esp32c6/Kconfig.cpu index 414e4377f35e..2b5a7e45b803 100644 --- a/components/esp_system/port/soc/esp32c6/Kconfig.cpu +++ b/components/esp_system/port/soc/esp32c6/Kconfig.cpu @@ -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 diff --git a/components/esp_system/port/soc/esp32c6/clk.c b/components/esp_system/port/soc/esp32c6/clk.c index f27a26561f26..ba9be14df357 100644 --- a/components/esp_system/port/soc/esp32c6/clk.c +++ b/components/esp_system/port/soc/esp32c6/clk.c @@ -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. diff --git a/components/esptool_py/Kconfig.projbuild b/components/esptool_py/Kconfig.projbuild index 49a865667984..3b741360938d 100644 --- a/components/esptool_py/Kconfig.projbuild +++ b/components/esptool_py/Kconfig.projbuild @@ -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. diff --git a/components/hal/esp32c6/include/hal/clk_tree_ll.h b/components/hal/esp32c6/include/hal/clk_tree_ll.h index f7fd22513c43..c5fb811055d8 100644 --- a/components/hal/esp32c6/include/hal/clk_tree_ll.h +++ b/components/hal/esp32c6/include/hal/clk_tree_ll.h @@ -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,70 +113,61 @@ 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 RC_FAST_CLK + * @brief Enable the internal oscillator output for RC32K_CLK */ -static inline __attribute__((always_inline)) void clk_ll_rc_fast_enable(void) +static inline void clk_ll_rc32k_enable(void) { - // TODO: IDF-5645 + // 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 RC_FAST_CLK + * @brief Disable the internal oscillator output for RC32K_CLK */ -static inline __attribute__((always_inline)) void clk_ll_rc_fast_disable(void) +static inline void clk_ll_rc32k_disable(void) { - // TODO: IDF-5645 + // 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 RC_FAST_CLK + * @brief Get the state of the internal oscillator for RC32K_CLK * * @return True if the oscillator is enabled */ -static inline bool clk_ll_rc_fast_is_enabled(void) +static inline bool clk_ll_rc32k_is_enabled(void) { - // TODO: IDF-5645 - return 1; + return REG_GET_FIELD(PMU_HP_SLEEP_LP_CK_POWER_REG, PMU_HP_SLEEP_XPD_RC32K) == 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. + * @brief Enable the internal oscillator output for RC_FAST_CLK */ -static inline void clk_ll_rc_fast_d256_enable(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); } /** - * @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. + * @brief Disable the internal oscillator output for RC_FAST_CLK */ -static inline void clk_ll_rc_fast_d256_disable(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); } /** - * @brief Get the state of the divider which is applied to the output from the internal oscillator (RC_FAST_CLK) + * @brief Get the state of the internal oscillator for RC_FAST_CLK * - * @return True if the divided output is enabled + * @return True if the oscillator is enabled */ -static inline bool clk_ll_rc_fast_d256_is_enabled(void) +static inline bool clk_ll_rc_fast_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,51 +193,59 @@ 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; + return LP_CLKRST.clk_to_hp.icg_hp_fosc; } /** - * @brief Enable the digital RC_FAST_D256_CLK, which is used to support peripherals. + * @brief Enable the digital XTAL32K_CLK, which is used to support peripherals. */ -static inline void clk_ll_rc_fast_d256_digi_enable(void) +static inline void clk_ll_xtal32k_digi_enable(void) { - // TODO: IDF-5645 + LP_CLKRST.clk_to_hp.icg_hp_xtal32k = 1; } /** - * @brief Disable the digital RC_FAST_D256_CLK, which is used to support peripherals. + * @brief Disable the digital XTAL32K_CLK, which is used to support peripherals. */ -static inline void clk_ll_rc_fast_d256_digi_disable(void) +static inline void clk_ll_xtal32k_digi_disable(void) { - // TODO: IDF-5645 + LP_CLKRST.clk_to_hp.icg_hp_xtal32k = 0; } /** - * @brief Enable the digital XTAL32K_CLK, which is used to support peripherals. + * @brief Get the state of the digital XTAL32K_CLK + * + * @return True if the digital XTAL32K_CLK is enabled */ -static inline void clk_ll_xtal32k_digi_enable(void) +static inline bool clk_ll_xtal32k_digi_is_enabled(void) { - // TODO: IDF-5645 + return LP_CLKRST.clk_to_hp.icg_hp_xtal32k; } /** - * @brief Disable the digital XTAL32K_CLK, which is used to support peripherals. + * @brief Enable the digital RC32K_CLK, which is used to support peripherals. */ -static inline void clk_ll_xtal32k_digi_disable(void) +static inline void clk_ll_rc32k_digi_enable(void) { - // TODO: IDF-5645 + LP_CLKRST.clk_to_hp.icg_hp_osc32k = 1; } /** - * @brief Get the state of the digital XTAL32K_CLK + * @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 XTAL32K_CLK is enabled + * @return True if the digital RC32K_CLK is enabled */ -static inline bool clk_ll_xtal32k_digi_is_enabled(void) +static inline bool clk_ll_rc32k_digi_is_enabled(void) { - // TODO: IDF-5645 - return 0; + 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 diff --git a/components/hal/esp32c6/include/hal/regi2c_ctrl_ll.h b/components/hal/esp32c6/include/hal/regi2c_ctrl_ll.h index 627f9745e822..a452160d218e 100644 --- a/components/hal/esp32c6/include/hal/regi2c_ctrl_ll.h +++ b/components/hal/esp32c6/include/hal/regi2c_ctrl_ll.h @@ -14,29 +14,48 @@ 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 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 Reset (Disable) the I2C internal bus for all regi2c registers + * @brief Start BBPLL self-calibration */ -static inline void regi2c_ctrl_ll_i2c_reset(void) +static inline __attribute__((always_inline)) void regi2c_ctrl_ll_bbpll_calibration_start(void) { - SET_PERI_REG_BITS(ANA_CONFIG_REG, ANA_CONFIG_M, ANA_CONFIG_M, ANA_CONFIG_S); + REG_CLR_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_HIGH); + REG_SET_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_LOW); } /** - * @brief Enable the I2C internal bus to do I2C read/write operation to the BBPLL configuration register + * @brief Stop BBPLL self-calibration */ -static inline void regi2c_ctrl_ll_i2c_bbpll_enable(void) +static inline __attribute__((always_inline)) void regi2c_ctrl_ll_bbpll_calibration_stop(void) { - CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, ANA_I2C_BBPLL_M); + 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 Start BBPLL self-calibration + * @brief Check whether BBPLL calibration is done + * + * @return True if calibration is done; otherwise false */ -static inline __attribute__((always_inline)) void regi2c_ctrl_ll_bbpll_calibration_start(void) +static inline __attribute__((always_inline)) bool regi2c_ctrl_ll_bbpll_calibration_is_done(void) { - REG_CLR_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_HIGH); - REG_SET_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_LOW); + return REG_GET_BIT(I2C_MST_ANA_CONF0_REG, I2C_MST_BBPLL_CAL_DONE); } /** diff --git a/components/hal/esp32c6/include/hal/spimem_flash_ll.h b/components/hal/esp32c6/include/hal/spimem_flash_ll.h index 3a45e448a6ac..27106133fd48 100644 --- a/components/hal/esp32c6/include/hal/spimem_flash_ll.h +++ b/components/hal/esp32c6/include/hal/spimem_flash_ll.h @@ -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; } diff --git a/components/soc/esp32c2/include/soc/rtc.h b/components/soc/esp32c2/include/soc/rtc.h index 1725ac3dcb81..2331a29758ec 100644 --- a/components/soc/esp32c2/include/soc/rtc.h +++ b/components/soc/esp32c2/include/soc/rtc.h @@ -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; /** diff --git a/components/soc/esp32c6/include/modem/modem_lpcon_reg.h b/components/soc/esp32c6/include/modem/modem_lpcon_reg.h index 53d4d73a71d8..edbb585f93f8 100644 --- a/components/soc/esp32c6/include/modem/modem_lpcon_reg.h +++ b/components/soc/esp32c6/include/modem/modem_lpcon_reg.h @@ -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 */ diff --git a/components/soc/esp32c6/include/modem/modem_lpcon_struct.h b/components/soc/esp32c6/include/modem/modem_lpcon_struct.h index cee63ef3a192..d7fc2ed28d30 100644 --- a/components/soc/esp32c6/include/modem/modem_lpcon_struct.h +++ b/components/soc/esp32c6/include/modem/modem_lpcon_struct.h @@ -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 -#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 diff --git a/components/soc/esp32c6/include/soc/clk_tree_defs.h b/components/soc/esp32c6/include/soc/clk_tree_defs.h index ccd0d25f4158..ab40d7b1db68 100644 --- a/components/soc/esp32c6/include/soc/clk_tree_defs.h +++ b/components/soc/esp32c6/include/soc/clk_tree_defs.h @@ -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 exact frequency of this clock can be computed in runtime through calibration. * - * 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. + * 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,11 +149,7 @@ 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 /** * @brief Type of GPTimer clock source @@ -153,11 +157,7 @@ typedef enum { 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 } soc_periph_gptimer_clk_src_t; /** @@ -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; diff --git a/components/soc/esp32c6/include/soc/io_mux_reg.h b/components/soc/esp32c6/include/soc/io_mux_reg.h index 0e255ac519ce..304ed1c383bd 100644 --- a/components/soc/esp32c6/include/soc/io_mux_reg.h +++ b/components/soc/esp32c6/include/soc/io_mux_reg.h @@ -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 diff --git a/components/soc/esp32c6/include/soc/regi2c_bias.h b/components/soc/esp32c6/include/soc/regi2c_bias.h index 512cb54989b7..9a85b28fb580 100644 --- a/components/soc/esp32c6/include/soc/regi2c_bias.h +++ b/components/soc/esp32c6/include/soc/regi2c_bias.h @@ -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 diff --git a/components/soc/esp32c6/include/soc/regi2c_defs.h b/components/soc/esp32c6/include/soc/regi2c_defs.h index 9ff42a0da668..397a42c2a38f 100644 --- a/components/soc/esp32c6/include/soc/regi2c_defs.h +++ b/components/soc/esp32c6/include/soc/regi2c_defs.h @@ -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 diff --git a/components/soc/esp32c6/include/soc/regi2c_dig_reg.h b/components/soc/esp32c6/include/soc/regi2c_dig_reg.h new file mode 100644 index 000000000000..b71845476ed0 --- /dev/null +++ b/components/soc/esp32c6/include/soc/regi2c_dig_reg.h @@ -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 diff --git a/components/soc/esp32c6/include/soc/rtc.h b/components/soc/esp32c6/include/soc/rtc.h index 090088b36418..497cf8ccbb00 100644 --- a/components/soc/esp32c6/include/soc/rtc.h +++ b/components/soc/esp32c6/include/soc/rtc.h @@ -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 + * @brief Get the current APB frequency. + * @return The calculated APB frequency value, in Hz. */ -void rtc_clk_apb_freq_update(uint32_t apb_freq); +uint32_t rtc_clk_apb_freq_get(void); /** - * @brief Get the current stored APB frequency. - * @return The APB frequency value as last set via rtc_clk_apb_freq_update(), in Hz. + * @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_apb_freq_get(void); - 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 diff --git a/components/soc/esp32c6/include/soc/soc.h b/components/soc/esp32c6/include/soc/soc.h index 6ef720bfae7a..f35d791da1d7 100644 --- a/components/soc/esp32c6/include/soc/soc.h +++ b/components/soc/esp32c6/include/soc/soc.h @@ -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 //}} diff --git a/components/soc/esp32h4/include/soc/regi2c_dig_reg.h b/components/soc/esp32h4/include/soc/regi2c_dig_reg.h index 9d2032b60ef3..4fd99f7df03d 100644 --- a/components/soc/esp32h4/include/soc/regi2c_dig_reg.h +++ b/components/soc/esp32h4/include/soc/regi2c_dig_reg.h @@ -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 From 244d3caa97d75c86e66973f6d6ee9dabd9d3d4d7 Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Thu, 1 Dec 2022 12:56:36 +0800 Subject: [PATCH 2/4] i2s: Fix esp32c6 get I2S_CLK_SRC_PLL_160M clock frequency value wrong issue --- components/driver/i2s/i2s_common.c | 15 +++++++++++++-- components/hal/esp32/include/hal/i2s_ll.h | 2 ++ components/hal/esp32c3/include/hal/i2s_ll.h | 2 ++ components/hal/esp32c6/include/hal/i2s_ll.h | 2 ++ components/hal/esp32h4/include/hal/i2s_ll.h | 2 ++ components/hal/esp32s2/include/hal/i2s_ll.h | 2 ++ components/hal/esp32s3/include/hal/i2s_ll.h | 2 ++ .../soc/esp32/include/soc/Kconfig.soc_caps.in | 4 ++++ components/soc/esp32/include/soc/clk_tree_defs.h | 6 +++--- components/soc/esp32/include/soc/soc_caps.h | 1 + .../soc/esp32c3/include/soc/Kconfig.soc_caps.in | 4 ++++ components/soc/esp32c3/include/soc/soc_caps.h | 1 + .../soc/esp32c6/include/soc/Kconfig.soc_caps.in | 4 ++++ components/soc/esp32c6/include/soc/soc_caps.h | 1 + .../soc/esp32h4/include/soc/Kconfig.soc_caps.in | 4 ++++ components/soc/esp32h4/include/soc/soc_caps.h | 1 + .../soc/esp32s2/include/soc/Kconfig.soc_caps.in | 4 ++++ components/soc/esp32s2/include/soc/soc_caps.h | 1 + .../soc/esp32s3/include/soc/Kconfig.soc_caps.in | 4 ++++ components/soc/esp32s3/include/soc/soc_caps.h | 1 + 20 files changed, 58 insertions(+), 5 deletions(-) diff --git a/components/driver/i2s/i2s_common.c b/components/driver/i2s/i2s_common.c index 552368c1b3fd..324735351710 100644 --- a/components/driver/i2s/i2s_common.c +++ b/components/driver/i2s/i2s_common.c @@ -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; } } diff --git a/components/hal/esp32/include/hal/i2s_ll.h b/components/hal/esp32/include/hal/i2s_ll.h index e4b5e34d43e4..9fc492b08716 100644 --- a/components/hal/esp32/include/hal/i2s_ll.h +++ b/components/hal/esp32/include/hal/i2s_ll.h @@ -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) diff --git a/components/hal/esp32c3/include/hal/i2s_ll.h b/components/hal/esp32c3/include/hal/i2s_ll.h index 4448f0ef95b2..555a878aa8d4 100644 --- a/components/hal/esp32c3/include/hal/i2s_ll.h +++ b/components/hal/esp32c3/include/hal/i2s_ll.h @@ -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) diff --git a/components/hal/esp32c6/include/hal/i2s_ll.h b/components/hal/esp32c6/include/hal/i2s_ll.h index aac0bcbddd4c..3d36a0af899f 100644 --- a/components/hal/esp32c6/include/hal/i2s_ll.h +++ b/components/hal/esp32c6/include/hal/i2s_ll.h @@ -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) diff --git a/components/hal/esp32h4/include/hal/i2s_ll.h b/components/hal/esp32h4/include/hal/i2s_ll.h index a15fe826b3a7..b19165ad77e2 100644 --- a/components/hal/esp32h4/include/hal/i2s_ll.h +++ b/components/hal/esp32h4/include/hal/i2s_ll.h @@ -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) diff --git a/components/hal/esp32s2/include/hal/i2s_ll.h b/components/hal/esp32s2/include/hal/i2s_ll.h index 7ec9e948415d..6ab224a6c7d5 100644 --- a/components/hal/esp32s2/include/hal/i2s_ll.h +++ b/components/hal/esp32s2/include/hal/i2s_ll.h @@ -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) diff --git a/components/hal/esp32s3/include/hal/i2s_ll.h b/components/hal/esp32s3/include/hal/i2s_ll.h index 0f35ff0be372..d9c0cf26f28e 100644 --- a/components/hal/esp32s3/include/hal/i2s_ll.h +++ b/components/hal/esp32s3/include/hal/i2s_ll.h @@ -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) diff --git a/components/soc/esp32/include/soc/Kconfig.soc_caps.in b/components/soc/esp32/include/soc/Kconfig.soc_caps.in index 70d1efe7d226..30e5a3df62e2 100644 --- a/components/soc/esp32/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32/include/soc/Kconfig.soc_caps.in @@ -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 diff --git a/components/soc/esp32/include/soc/clk_tree_defs.h b/components/soc/esp32/include/soc/clk_tree_defs.h index 1a599c62ff8a..3069114b1249 100644 --- a/components/soc/esp32/include/soc/clk_tree_defs.h +++ b/components/soc/esp32/include/soc/clk_tree_defs.h @@ -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; diff --git a/components/soc/esp32/include/soc/soc_caps.h b/components/soc/esp32/include/soc/soc_caps.h index f5958086c4bb..7b72bf6dd8da 100644 --- a/components/soc/esp32/include/soc/soc_caps.h +++ b/components/soc/esp32/include/soc/soc_caps.h @@ -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) diff --git a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in index d328f4a92cdc..cfb7b79d4214 100644 --- a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in @@ -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 diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index 9c79e1895d28..604ced866c79 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -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) diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index 244bd789a64c..6e587ae4d4a1 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -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 diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index 0f9d99c411b4..71acc054366b 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -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) diff --git a/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in index 3edca105edce..bd2e0674cce1 100644 --- a/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in @@ -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 diff --git a/components/soc/esp32h4/include/soc/soc_caps.h b/components/soc/esp32h4/include/soc/soc_caps.h index d7772eeed4dd..c209d12f588d 100644 --- a/components/soc/esp32h4/include/soc/soc_caps.h +++ b/components/soc/esp32h4/include/soc/soc_caps.h @@ -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) diff --git a/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in index 35e159f3b31d..469453abce5a 100644 --- a/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in @@ -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 diff --git a/components/soc/esp32s2/include/soc/soc_caps.h b/components/soc/esp32s2/include/soc/soc_caps.h index 9c1c3ee2933e..683e6f681eea 100644 --- a/components/soc/esp32s2/include/soc/soc_caps.h +++ b/components/soc/esp32s2/include/soc/soc_caps.h @@ -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) diff --git a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in index b2bdf24ccf1c..181410cdbb87 100644 --- a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in @@ -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 diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index de2b9abf0268..d7864fa6e23c 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -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) From 19ee95e509f8aaa91e984e3b7bad17012d773cb1 Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Thu, 1 Dec 2022 14:38:23 +0800 Subject: [PATCH 3/4] gptimer: Fix esp32c6 gptimer clock source, no APB, instead, is PLL_F80M_CLK --- components/driver/deprecated/timer_legacy.c | 5 +++++ components/driver/gptimer/gptimer.c | 12 ++++++++++++ components/hal/esp32c6/include/hal/timer_ll.h | 2 +- .../soc/esp32c6/include/soc/Kconfig.soc_caps.in | 2 +- components/soc/esp32c6/include/soc/clk_tree_defs.h | 14 +++++++------- components/soc/esp32c6/include/soc/soc_caps.h | 2 +- 6 files changed, 27 insertions(+), 10 deletions(-) diff --git a/components/driver/deprecated/timer_legacy.c b/components/driver/deprecated/timer_legacy.c index 405d337f73a6..603841c40c55 100644 --- a/components/driver/deprecated/timer_legacy.c +++ b/components/driver/deprecated/timer_legacy.c @@ -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"); diff --git a/components/driver/gptimer/gptimer.c b/components/driver/gptimer/gptimer.c index 9477d0e4f420..b70f6bc96e51 100644 --- a/components/driver/gptimer/gptimer.c +++ b/components/driver/gptimer/gptimer.c @@ -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 diff --git a/components/hal/esp32c6/include/hal/timer_ll.h b/components/hal/esp32c6/include/hal/timer_ll.h index d76e95e2e27a..37eadf5ed205 100644 --- a/components/hal/esp32c6/include/hal/timer_ll.h +++ b/components/hal/esp32c6/include/hal/timer_ll.h @@ -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: diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index 6e587ae4d4a1..fe7ac2e40b63 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -755,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 diff --git a/components/soc/esp32c6/include/soc/clk_tree_defs.h b/components/soc/esp32c6/include/soc/clk_tree_defs.h index ab40d7b1db68..8fa92582e9af 100644 --- a/components/soc/esp32c6/include/soc/clk_tree_defs.h +++ b/components/soc/esp32c6/include/soc/clk_tree_defs.h @@ -149,24 +149,24 @@ typedef enum { * } * @endcode */ -#define SOC_GPTIMER_CLKS {SOC_MOD_CLK_APB, SOC_MOD_CLK_XTAL} +#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 */ - GPTIMER_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default choice */ + 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/////////////////////////////////////////////////////////////////// diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index 71acc054366b..7a5d4894a64f 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -363,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) From 536d5827c0d6a68a981c94076ef5a65e4524aed5 Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Tue, 13 Dec 2022 15:38:38 +0800 Subject: [PATCH 4/4] gpio_filter: Fix test case fail on esp32c6 due to slow io_mux clock compare to 160MHz cpu clock. --- components/driver/test_apps/gpio/main/test_gpio_filter.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/components/driver/test_apps/gpio/main/test_gpio_filter.c b/components/driver/test_apps/gpio/main/test_gpio_filter.c index 345ef6600b4d..a385cfc807ea 100644 --- a/components/driver/test_apps/gpio/main/test_gpio_filter.c +++ b/components/driver/test_apps/gpio/main/test_gpio_filter.c @@ -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