Skip to content

Commit

Permalink
Merge branch 'feature/esp32c6_clock_basic_support' into 'master'
Browse files Browse the repository at this point in the history
clk: Add basic clock support for esp32c6

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

See merge request espressif/esp-idf!21149
  • Loading branch information
songruo committed Dec 13, 2022
2 parents c01f71c + 536d582 commit edd815a
Show file tree
Hide file tree
Showing 59 changed files with 1,206 additions and 658 deletions.
1 change: 0 additions & 1 deletion Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
21 changes: 17 additions & 4 deletions components/bootloader_support/src/bootloader_clock_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
5 changes: 5 additions & 0 deletions components/driver/deprecated/timer_legacy.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
12 changes: 12 additions & 0 deletions components/driver/gptimer/gptimer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
15 changes: 13 additions & 2 deletions components/driver/i2s/i2s_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}

Expand Down
2 changes: 0 additions & 2 deletions components/driver/test/test_ledc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
8 changes: 8 additions & 0 deletions components/driver/test_apps/gpio/main/test_gpio_filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
5 changes: 5 additions & 0 deletions components/esp_hw_support/esp_clk.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion components/esp_hw_support/port/esp32c2/rtc_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
10 changes: 5 additions & 5 deletions components/esp_hw_support/port/esp32c2/rtc_time.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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();
}

Expand Down Expand Up @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion components/esp_hw_support/port/esp32c3/rtc_clk.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion components/esp_hw_support/port/esp32c6/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
5 changes: 2 additions & 3 deletions components/esp_hw_support/port/esp32c6/Kconfig.rtc
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
choice RTC_CLK_SRC
# TODO: IDF-5346
prompt "RTC clock source"
default RTC_CLK_SRC_INT_RC
help
Expand All @@ -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
Expand Down
Loading

0 comments on commit edd815a

Please sign in to comment.