diff --git a/components/driver/deprecated/adc_dma_legacy.c b/components/driver/deprecated/adc_dma_legacy.c index 9c7800e0fc..5e135ca53d 100644 --- a/components/driver/deprecated/adc_dma_legacy.c +++ b/components/driver/deprecated/adc_dma_legacy.c @@ -480,7 +480,7 @@ esp_err_t adc_digi_start(void) adc_hal_digi_init(&s_adc_digi_ctx->hal); #if !CONFIG_IDF_TARGET_ESP32 - esp_clk_tree_enable_src((soc_module_clk_t)(s_adc_digi_ctx->hal_digi_ctrlr_cfg.clk_src), true); + ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)(s_adc_digi_ctx->hal_digi_ctrlr_cfg.clk_src), true)); #endif adc_hal_digi_controller_config(&s_adc_digi_ctx->hal, &s_adc_digi_ctx->hal_digi_ctrlr_cfg); @@ -524,6 +524,7 @@ esp_err_t adc_digi_stop(void) if (s_adc_digi_ctx->use_adc1) { adc_lock_release(ADC_UNIT_1); } + ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)(s_adc_digi_ctx->hal_digi_ctrlr_cfg.clk_src), false)); sar_periph_ctrl_adc_continuous_power_release(); return ESP_OK; diff --git a/components/driver/deprecated/adc_legacy.c b/components/driver/deprecated/adc_legacy.c index 2cbbcf083b..e331e0c30e 100644 --- a/components/driver/deprecated/adc_legacy.c +++ b/components/driver/deprecated/adc_legacy.c @@ -756,7 +756,7 @@ int adc1_get_raw(adc1_channel_t channel) adc_apb_periph_claim(); sar_periph_ctrl_adc_oneshot_power_acquire(); - esp_clk_tree_enable_src((soc_module_clk_t)ADC_DIGI_CLK_SRC_DEFAULT, true); + ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)ADC_DIGI_CLK_SRC_DEFAULT, true)); adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_DEFAULT); adc_atten_t atten = s_atten1_single[channel]; @@ -775,6 +775,7 @@ int adc1_get_raw(adc1_channel_t channel) adc_hal_convert(ADC_UNIT_1, channel, clk_src_freq_hz, &raw_out); ADC_REG_LOCK_EXIT(); + ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)ADC_DIGI_CLK_SRC_DEFAULT, false)); sar_periph_ctrl_adc_oneshot_power_release(); adc_apb_periph_free(); adc_lock_release(ADC_UNIT_1); @@ -820,7 +821,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int * adc_apb_periph_claim(); sar_periph_ctrl_adc_oneshot_power_acquire(); - esp_clk_tree_enable_src((soc_module_clk_t)ADC_DIGI_CLK_SRC_DEFAULT, true); + ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)ADC_DIGI_CLK_SRC_DEFAULT, true)); adc_ll_digi_clk_sel(ADC_DIGI_CLK_SRC_DEFAULT); #if SOC_ADC_ARBITER_SUPPORTED @@ -838,6 +839,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int * ret = adc_hal_convert(ADC_UNIT_2, channel, clk_src_freq_hz, raw_out); ADC_REG_LOCK_EXIT(); + ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)ADC_DIGI_CLK_SRC_DEFAULT, false)); sar_periph_ctrl_adc_oneshot_power_release(); adc_apb_periph_free(); adc_lock_release(ADC_UNIT_2); diff --git a/components/driver/deprecated/mcpwm_legacy.c b/components/driver/deprecated/mcpwm_legacy.c index 94723decdd..9be6b29518 100644 --- a/components/driver/deprecated/mcpwm_legacy.c +++ b/components/driver/deprecated/mcpwm_legacy.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -470,7 +470,7 @@ esp_err_t mcpwm_init(mcpwm_unit_t mcpwm_num, mcpwm_timer_t timer_num, const mcpw uint32_t group_pre_scale = clk_src_hz / group_resolution; uint32_t timer_pre_scale = group_resolution / timer_resolution; - esp_clk_tree_enable_src((soc_module_clk_t)MCPWM_CAPTURE_CLK_SRC_DEFAULT, true); + ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)MCPWM_CAPTURE_CLK_SRC_DEFAULT, true)); MCPWM_CLOCK_SRC_ATOMIC() { mcpwm_ll_group_set_clock_source(mcpwm_num, (soc_module_clk_t)MCPWM_CAPTURE_CLK_SRC_DEFAULT); mcpwm_ll_group_set_clock_prescale(mcpwm_num, group_pre_scale); @@ -868,7 +868,7 @@ esp_err_t mcpwm_capture_enable_channel(mcpwm_unit_t mcpwm_num, mcpwm_capture_cha uint32_t group_resolution = mcpwm_group_get_resolution(mcpwm_num); uint32_t group_pre_scale = clk_src_hz / group_resolution; - esp_clk_tree_enable_src((soc_module_clk_t)MCPWM_CAPTURE_CLK_SRC_DEFAULT, true); + ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)MCPWM_CAPTURE_CLK_SRC_DEFAULT, true)); MCPWM_CLOCK_SRC_ATOMIC() { mcpwm_ll_group_set_clock_source(mcpwm_num, (soc_module_clk_t)MCPWM_CAPTURE_CLK_SRC_DEFAULT); mcpwm_ll_group_set_clock_prescale(mcpwm_num, group_pre_scale); @@ -910,6 +910,7 @@ esp_err_t mcpwm_capture_disable_channel(mcpwm_unit_t mcpwm_num, mcpwm_capture_ch mcpwm_ll_capture_enable_channel(hal->dev, cap_channel, false); mcpwm_ll_intr_enable(hal->dev, MCPWM_LL_EVENT_CAPTURE(cap_channel), false); mcpwm_critical_exit(mcpwm_num); + ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)MCPWM_CAPTURE_CLK_SRC_DEFAULT, false)); mcpwm_mutex_lock(mcpwm_num); context[mcpwm_num].cap_isr_func[cap_channel].fn = NULL; diff --git a/components/driver/deprecated/rmt_legacy.c b/components/driver/deprecated/rmt_legacy.c index baff30aa46..254aa46c06 100644 --- a/components/driver/deprecated/rmt_legacy.c +++ b/components/driver/deprecated/rmt_legacy.c @@ -440,7 +440,7 @@ esp_err_t rmt_set_source_clk(rmt_channel_t channel, rmt_source_clk_t base_clk) { ESP_RETURN_ON_FALSE(channel < RMT_CHANNEL_MAX, ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR); RMT_ENTER_CRITICAL(); - esp_clk_tree_enable_src((soc_module_clk_t)base_clk, true); + ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)base_clk, true)); // `rmt_clock_source_t` and `rmt_source_clk_t` are binary compatible, as the underlying enum entries come from the same `soc_module_clk_t` RMT_CLOCK_SRC_ATOMIC() { rmt_ll_set_group_clock_src(rmt_contex.hal.regs, channel, (rmt_clock_source_t)base_clk, 1, 0, 0); @@ -606,7 +606,7 @@ static esp_err_t rmt_internal_config(rmt_dev_t *dev, const rmt_config_t *rmt_par #endif } esp_clk_tree_src_get_freq_hz((soc_module_clk_t)clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &rmt_source_clk_hz); - esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true); + ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true)); RMT_CLOCK_SRC_ATOMIC() { rmt_ll_set_group_clock_src(dev, channel, clk_src, 1, 0, 0); rmt_ll_enable_group_clock(dev, true); diff --git a/components/driver/deprecated/timer_legacy.c b/components/driver/deprecated/timer_legacy.c index 27c446836b..48c8aeb725 100644 --- a/components/driver/deprecated/timer_legacy.c +++ b/components/driver/deprecated/timer_legacy.c @@ -328,7 +328,7 @@ esp_err_t timer_init(timer_group_t group_num, timer_idx_t timer_num, const timer if (config->clk_src) { clk_src = config->clk_src; } - esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true); + ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true)); GPTIMER_CLOCK_SRC_ATOMIC() { // although `clk_src` is of `timer_src_clk_t` type, but it's binary compatible with `gptimer_clock_source_t`, // as the underlying enum entries come from the same `soc_module_clk_t` @@ -364,6 +364,7 @@ esp_err_t timer_deinit(timer_group_t group_num, timer_idx_t timer_num) GPTIMER_CLOCK_SRC_ATOMIC() { timer_ll_enable_clock(group_num, hal->timer_id, false); } + ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)p_timer_obj[group_num][timer_num]->clk_src, false)); TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); timer_ll_enable_intr(hal->dev, TIMER_LL_EVENT_ALARM(timer_num), false); timer_ll_clear_intr_status(hal->dev, TIMER_LL_EVENT_ALARM(timer_num)); diff --git a/components/esp_adc/adc_continuous.c b/components/esp_adc/adc_continuous.c index 8e609d73b6..fe7173e704 100644 --- a/components/esp_adc/adc_continuous.c +++ b/components/esp_adc/adc_continuous.c @@ -321,10 +321,10 @@ esp_err_t adc_continuous_start(adc_continuous_handle_t handle) adc_hal_set_controller(ADC_UNIT_2, ADC_HAL_CONTINUOUS_READ_MODE); } - adc_hal_digi_init(&handle->hal); #if !CONFIG_IDF_TARGET_ESP32 - esp_clk_tree_enable_src((soc_module_clk_t)(handle->hal_digi_ctrlr_cfg.clk_src), true); + ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)(handle->hal_digi_ctrlr_cfg.clk_src), true)); #endif + adc_hal_digi_init(&handle->hal); adc_hal_digi_controller_config(&handle->hal, &handle->hal_digi_ctrlr_cfg); adc_hal_digi_enable(false); @@ -362,7 +362,9 @@ esp_err_t adc_continuous_stop(adc_continuous_handle_t handle) #endif adc_hal_digi_deinit(); - +#if !CONFIG_IDF_TARGET_ESP32 + ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)(handle->hal_digi_ctrlr_cfg.clk_src), false)); +#endif if (handle->use_adc2) { adc_lock_release(ADC_UNIT_2); } @@ -377,7 +379,6 @@ esp_err_t adc_continuous_stop(adc_continuous_handle_t handle) ESP_RETURN_ON_ERROR(esp_pm_lock_release(handle->pm_lock), ADC_TAG, "release pm_lock failed"); } #endif - ANALOG_CLOCK_DISABLE(); return ESP_OK; diff --git a/components/esp_adc/adc_oneshot.c b/components/esp_adc/adc_oneshot.c index aba44c2748..cd85a76281 100644 --- a/components/esp_adc/adc_oneshot.c +++ b/components/esp_adc/adc_oneshot.c @@ -156,6 +156,9 @@ esp_err_t adc_oneshot_new_unit(const adc_oneshot_unit_init_cfg_t *init_config, a if (init_config->ulp_mode == ADC_ULP_MODE_DISABLE) { sar_periph_ctrl_adc_oneshot_power_acquire(); } else { +#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED + ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)(unit->hal.clk_src), true), err, TAG, "clock source enable failed"); +#endif #if SOC_LIGHT_SLEEP_SUPPORTED || SOC_DEEP_SLEEP_SUPPORTED esp_sleep_sub_mode_config(ESP_SLEEP_USE_ADC_TSEN_MONITOR_MODE, true); #endif @@ -189,9 +192,6 @@ esp_err_t adc_oneshot_config_channel(adc_oneshot_unit_handle_t handle, adc_chann portENTER_CRITICAL(&rtc_spinlock); adc_oneshot_hal_channel_config(hal, &cfg, channel); if (handle->ulp_mode) { -#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED - esp_clk_tree_enable_src((soc_module_clk_t)(hal->clk_src), true); -#endif adc_oneshot_hal_setup(hal, channel); } portEXIT_CRITICAL(&rtc_spinlock); @@ -210,7 +210,7 @@ esp_err_t adc_oneshot_read(adc_oneshot_unit_handle_t handle, adc_channel_t chan, portENTER_CRITICAL(&rtc_spinlock); #if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED - esp_clk_tree_enable_src((soc_module_clk_t)(handle->hal.clk_src), true); + ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)(handle->hal.clk_src), true)); #endif ANALOG_CLOCK_ENABLE(); adc_oneshot_hal_setup(&(handle->hal), chan); @@ -222,6 +222,9 @@ esp_err_t adc_oneshot_read(adc_oneshot_unit_handle_t handle, adc_channel_t chan, bool valid = false; valid = adc_oneshot_hal_convert(&(handle->hal), out_raw); ANALOG_CLOCK_DISABLE(); +#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED + ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)(handle->hal.clk_src), false)); +#endif portEXIT_CRITICAL(&rtc_spinlock); adc_lock_release(handle->unit_id); @@ -238,7 +241,7 @@ esp_err_t adc_oneshot_read_isr(adc_oneshot_unit_handle_t handle, adc_channel_t c portENTER_CRITICAL_SAFE(&rtc_spinlock); #if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED - esp_clk_tree_enable_src((soc_module_clk_t)(handle->hal.clk_src), true); + ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)(handle->hal.clk_src), true)); #endif ANALOG_CLOCK_ENABLE(); adc_oneshot_hal_setup(&(handle->hal), chan); @@ -249,6 +252,9 @@ esp_err_t adc_oneshot_read_isr(adc_oneshot_unit_handle_t handle, adc_channel_t c #endif adc_oneshot_hal_convert(&(handle->hal), out_raw); ANALOG_CLOCK_DISABLE(); +#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED + ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)(handle->hal.clk_src), false)); +#endif portEXIT_CRITICAL_SAFE(&rtc_spinlock); @@ -271,7 +277,6 @@ esp_err_t adc_oneshot_del_unit(adc_oneshot_unit_handle_t handle) _lock_release(&s_ctx.mutex); ESP_LOGD(TAG, "adc unit%"PRId32" is deleted", handle->unit_id); - free(handle); if (ulp_mode == ADC_ULP_MODE_DISABLE) { sar_periph_ctrl_adc_oneshot_power_release(); @@ -279,7 +284,9 @@ esp_err_t adc_oneshot_del_unit(adc_oneshot_unit_handle_t handle) #if SOC_LIGHT_SLEEP_SUPPORTED || SOC_DEEP_SLEEP_SUPPORTED esp_sleep_sub_mode_config(ESP_SLEEP_USE_ADC_TSEN_MONITOR_MODE, false); #endif + ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)(handle->hal.clk_src), false)); } + free(handle); #if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED //To free the APB_SARADC periph if needed diff --git a/components/esp_driver_cam/csi/src/esp_cam_ctlr_csi.c b/components/esp_driver_cam/csi/src/esp_cam_ctlr_csi.c index 0b759a86fe..5dbaf54ba6 100644 --- a/components/esp_driver_cam/csi/src/esp_cam_ctlr_csi.c +++ b/components/esp_driver_cam/csi/src/esp_cam_ctlr_csi.c @@ -119,7 +119,7 @@ esp_err_t esp_cam_new_csi_ctlr(const esp_cam_ctlr_csi_config_t *config, esp_cam_ #endif mipi_csi_phy_clock_source_t clk_src = !config->clk_src ? MIPI_CSI_PHY_CLK_SRC_DEFAULT : config->clk_src; - esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true); + ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true), err, TAG, "clock source enable failed"); PERIPH_RCC_ATOMIC() { // phy clock source setting mipi_csi_ll_set_phy_clock_source(ctlr->csi_id, clk_src); diff --git a/components/esp_driver_cam/dvp/src/esp_cam_ctlr_dvp_cam.c b/components/esp_driver_cam/dvp/src/esp_cam_ctlr_dvp_cam.c index 5e867279f5..5e53b9bab4 100644 --- a/components/esp_driver_cam/dvp/src/esp_cam_ctlr_dvp_cam.c +++ b/components/esp_driver_cam/dvp/src/esp_cam_ctlr_dvp_cam.c @@ -332,7 +332,7 @@ esp_err_t esp_cam_ctlr_dvp_init(int ctlr_id, cam_clock_source_t clk_src, const e } } - esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true); + ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true)); PERIPH_RCC_ATOMIC() { cam_ll_enable_clk(ctlr_id, true); cam_ll_select_clk_src(ctlr_id, clk_src); diff --git a/components/esp_driver_gptimer/src/gptimer.c b/components/esp_driver_gptimer/src/gptimer.c index 40cd65d4eb..88d6cea08d 100644 --- a/components/esp_driver_gptimer/src/gptimer.c +++ b/components/esp_driver_gptimer/src/gptimer.c @@ -108,6 +108,9 @@ static void gptimer_unregister_from_group(gptimer_t *timer) static esp_err_t gptimer_destroy(gptimer_t *timer) { + if (timer->clk_src) { + ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)(timer->clk_src), false), TAG, "clock source disable failed"); + } #if CONFIG_PM_ENABLE if (timer->pm_lock) { ESP_RETURN_ON_ERROR(esp_pm_lock_delete(timer->pm_lock), TAG, "delete pm_lock failed"); @@ -157,6 +160,7 @@ esp_err_t gptimer_new_timer(const gptimer_config_t *config, gptimer_handle_t *re // initialize HAL layer timer_hal_init(&timer->hal, group_id, timer_id); // select clock source, set clock resolution + ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)config->clk_src, true), err, TAG, "clock source enable failed"); ESP_GOTO_ON_ERROR(gptimer_select_periph_clock(timer, config->clk_src, config->resolution_hz), err, TAG, "set periph clock failed"); // initialize counter value to zero timer_hal_set_counter_value(&timer->hal, 0); diff --git a/components/esp_driver_gptimer/src/gptimer_common.c b/components/esp_driver_gptimer/src/gptimer_common.c index 3adae18d24..67d3a0cdab 100644 --- a/components/esp_driver_gptimer/src/gptimer_common.c +++ b/components/esp_driver_gptimer/src/gptimer_common.c @@ -99,6 +99,7 @@ esp_err_t gptimer_select_periph_clock(gptimer_t *timer, gptimer_clock_source_t s periph_rtc_dig_clk8m_enable(); } #endif // SOC_TIMER_GROUP_SUPPORT_RC_FAST + timer->clk_src = src_clk; // get clock source frequency ESP_RETURN_ON_ERROR(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)src_clk, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &counter_src_hz), @@ -139,7 +140,6 @@ esp_err_t gptimer_select_periph_clock(gptimer_t *timer, gptimer_clock_source_t s } #endif // CONFIG_PM_ENABLE - esp_clk_tree_enable_src((soc_module_clk_t)src_clk, true); // !!! HARDWARE SHARED RESOURCE !!! // on some ESP chip, different peripheral's clock source setting are mixed in the same register // so we need to make this done in an atomic way @@ -147,7 +147,6 @@ esp_err_t gptimer_select_periph_clock(gptimer_t *timer, gptimer_clock_source_t s timer_ll_set_clock_source(group_id, timer_id, src_clk); timer_ll_enable_clock(group_id, timer_id, true); } - timer->clk_src = src_clk; uint32_t prescale = counter_src_hz / resolution_hz; // potential resolution loss here timer_ll_set_clock_prescale(timer->hal.dev, timer_id, prescale); timer->resolution_hz = counter_src_hz / prescale; // this is the real resolution diff --git a/components/esp_driver_gptimer/src/gptimer_priv.h b/components/esp_driver_gptimer/src/gptimer_priv.h index e9b1030fdc..8abeae4941 100644 --- a/components/esp_driver_gptimer/src/gptimer_priv.h +++ b/components/esp_driver_gptimer/src/gptimer_priv.h @@ -28,6 +28,7 @@ #include "hal/timer_hal.h" #include "hal/timer_ll.h" #include "clk_ctrl_os.h" +#include "esp_private/esp_clk_tree_common.h" #include "esp_private/sleep_retention.h" #include "esp_private/periph_ctrl.h" diff --git a/components/esp_driver_isp/include/esp_private/isp_private.h b/components/esp_driver_isp/include/esp_private/isp_private.h index 9d0ec92e25..7bcb151c1d 100644 --- a/components/esp_driver_isp/include/esp_private/isp_private.h +++ b/components/esp_driver_isp/include/esp_private/isp_private.h @@ -53,6 +53,7 @@ typedef enum { ---------------------------------------------------------------*/ typedef struct isp_processor_t { int proc_id; + isp_clk_src_t clk_src; isp_hal_context_t hal; #if SOC_ISP_SHARE_CSI_BRG int csi_brg_id; diff --git a/components/esp_driver_isp/src/isp_core.c b/components/esp_driver_isp/src/isp_core.c index fd5aa59213..d6dd2bbeae 100644 --- a/components/esp_driver_isp/src/isp_core.c +++ b/components/esp_driver_isp/src/isp_core.c @@ -112,14 +112,13 @@ esp_err_t esp_isp_new_processor(const esp_isp_processor_cfg_t *proc_config, isp_ if (out_clk_freq_hz != proc_config->clk_hz) { ESP_LOGW(TAG, "precision loss, real output frequency: %"PRIu32"Hz", out_clk_freq_hz); } - ; isp_hal_init(&proc->hal, proc->proc_id); - esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true); + ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true), err, TAG, "clock source enable failed"); PERIPH_RCC_ATOMIC() { isp_ll_select_clk_source(proc->hal.hw, clk_src); isp_ll_set_clock_div(proc->hal.hw, &clk_div); } - + proc->clk_src = clk_src; proc->isp_fsm = ISP_FSM_INIT; proc->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; @@ -197,6 +196,7 @@ esp_err_t esp_isp_del_processor(isp_proc_handle_t proc) #if SOC_ISP_SHARE_CSI_BRG ESP_RETURN_ON_ERROR(mipi_csi_brg_declaim(proc->csi_brg_id), TAG, "declaim csi bridge fail"); #endif + ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)(proc->clk_src), false), TAG, "clock source disable failed"); free(proc); return ESP_OK; diff --git a/components/esp_driver_ledc/src/ledc.c b/components/esp_driver_ledc/src/ledc.c index d69a8434ed..9737e06cbf 100644 --- a/components/esp_driver_ledc/src/ledc.c +++ b/components/esp_driver_ledc/src/ledc.c @@ -698,7 +698,7 @@ static esp_err_t ledc_set_timer_div(ledc_mode_t speed_mode, ledc_timer_t timer_n if (p_ledc_obj[speed_mode]->glb_clk != glb_clk) { // TODO: release old glb_clk (if not UNINIT), and acquire new glb_clk [clk_tree] p_ledc_obj[speed_mode]->glb_clk = glb_clk; - esp_clk_tree_enable_src((soc_module_clk_t)glb_clk, true); + ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)glb_clk, true), LEDC_TAG, "clock source enable failed"); LEDC_FUNC_CLOCK_ATOMIC() { ledc_hal_set_slow_clk_sel(&(p_ledc_obj[speed_mode]->ledc_hal), glb_clk); } @@ -863,7 +863,7 @@ esp_err_t ledc_channel_config(const ledc_channel_config_t *ledc_conf) else if (new_speed_mode_ctx_created) { portENTER_CRITICAL(&ledc_spinlock); if (p_ledc_obj[speed_mode]->glb_clk == LEDC_SLOW_CLK_UNINIT) { - esp_clk_tree_enable_src((soc_module_clk_t)LEDC_LL_GLOBAL_CLK_DEFAULT, true); + ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)LEDC_LL_GLOBAL_CLK_DEFAULT, true)); ledc_hal_set_slow_clk_sel(&(p_ledc_obj[speed_mode]->ledc_hal), LEDC_LL_GLOBAL_CLK_DEFAULT); } portEXIT_CRITICAL(&ledc_spinlock); diff --git a/components/esp_driver_ledc/test_apps/ledc/main/test_ledc.c b/components/esp_driver_ledc/test_apps/ledc/main/test_ledc.c index 0c38ae8425..c6a3a7483e 100644 --- a/components/esp_driver_ledc/test_apps/ledc/main/test_ledc.c +++ b/components/esp_driver_ledc/test_apps/ledc/main/test_ledc.c @@ -465,7 +465,7 @@ static void timer_frequency_test(ledc_channel_t channel, ledc_timer_bit_t timer_ } else if (clk_src_freq == 60 * 1000 * 1000) { theoretical_freq = 8993; } - frequency_set_get(speed_mode, timer, 9000, theoretical_freq, 50); + frequency_set_get(speed_mode, timer, 9000, theoretical_freq, 60); #endif // Pause and de-configure the timer so that it won't affect the following test cases diff --git a/components/esp_driver_mcpwm/src/mcpwm_com.c b/components/esp_driver_mcpwm/src/mcpwm_com.c index e13334d9c4..21f7cfbbab 100644 --- a/components/esp_driver_mcpwm/src/mcpwm_com.c +++ b/components/esp_driver_mcpwm/src/mcpwm_com.c @@ -201,7 +201,7 @@ esp_err_t mcpwm_select_periph_clock(mcpwm_group_t *group, soc_module_clk_t clk_s ESP_RETURN_ON_ERROR(ret, TAG, "create pm lock failed"); #endif // CONFIG_PM_ENABLE - esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true); + ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true), TAG, "clock source enable failed"); MCPWM_CLOCK_SRC_ATOMIC() { mcpwm_ll_group_set_clock_source(group_id, clk_src); } diff --git a/components/esp_driver_parlio/src/parlio_rx.c b/components/esp_driver_parlio/src/parlio_rx.c index de86eb6f47..1ca177cdb2 100644 --- a/components/esp_driver_parlio/src/parlio_rx.c +++ b/components/esp_driver_parlio/src/parlio_rx.c @@ -466,6 +466,7 @@ static esp_err_t parlio_select_periph_clock(parlio_rx_unit_handle_t rx_unit, con { parlio_hal_context_t *hal = &rx_unit->base.group->hal; parlio_clock_source_t clk_src = config->clk_src; + rx_unit->clk_src = clk_src; uint32_t src_freq_hz = 0; uint32_t exp_freq_hz = 0; hal_utils_clk_div_t clk_div = { @@ -510,14 +511,12 @@ static esp_err_t parlio_select_periph_clock(parlio_rx_unit_handle_t rx_unit, con } #endif - esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true); /* Set clock configuration */ PARLIO_CLOCK_SRC_ATOMIC() { parlio_ll_rx_set_clock_source(hal->regs, clk_src); parlio_ll_rx_set_clock_div(hal->regs, &clk_div); } - rx_unit->clk_src = clk_src; /* warning if precision lost due to division */ if ((clk_src != PARLIO_CLK_SRC_EXTERNAL) && (config->exp_clk_freq_hz != rx_unit->cfg.exp_clk_freq_hz)) { @@ -571,6 +570,9 @@ static esp_err_t parlio_destroy_rx_unit(parlio_rx_unit_handle_t rx_unit) if (rx_unit->base.group) { parlio_unregister_unit_from_group(&rx_unit->base); } + if (rx_unit->clk_src) { + ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)rx_unit->clk_src, false), TAG, "clock source disable failed"); + } /* Free the RX unit */ free(rx_unit); return ESP_OK; @@ -637,6 +639,7 @@ esp_err_t parlio_new_rx_unit(const parlio_rx_unit_config_t *config, parlio_rx_un } parlio_ll_rx_start(hal->regs, false); /* parlio_ll_clock_source_t and parlio_clock_source_t are binary compatible if the clock source is from internal */ + ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)(config->clk_src), true), err, TAG, "clock source enable failed"); ESP_GOTO_ON_ERROR(parlio_select_periph_clock(unit, config), err, TAG, "set clock source failed"); /* Set the data width */ parlio_ll_rx_set_bus_width(hal->regs, config->data_width); diff --git a/components/esp_driver_parlio/src/parlio_tx.c b/components/esp_driver_parlio/src/parlio_tx.c index 5b3ff50272..f3c0d6b0d1 100644 --- a/components/esp_driver_parlio/src/parlio_tx.c +++ b/components/esp_driver_parlio/src/parlio_tx.c @@ -74,6 +74,9 @@ static esp_err_t parlio_destroy_tx_unit(parlio_tx_unit_t *tx_unit) ESP_RETURN_ON_ERROR(gdma_del_link_list(tx_unit->dma_link[i]), TAG, "delete dma link list failed"); } } + if (tx_unit->clk_src) { + ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)tx_unit->clk_src, false), TAG, "clock source disable failed"); + } free(tx_unit); return ESP_OK; } @@ -182,6 +185,7 @@ static esp_err_t parlio_select_periph_clock(parlio_tx_unit_t *tx_unit, const par { parlio_hal_context_t *hal = &tx_unit->base.group->hal; parlio_clock_source_t clk_src = config->clk_src; + tx_unit->clk_src = clk_src; if (config->clk_in_gpio_num >= 0 && clk_src != PARLIO_CLK_SRC_EXTERNAL) { ESP_LOGW(TAG, "input clock GPIO is set, use external clk src"); clk_src = PARLIO_CLK_SRC_EXTERNAL; @@ -223,7 +227,6 @@ static esp_err_t parlio_select_periph_clock(parlio_tx_unit_t *tx_unit, const par #else tx_unit->out_clk_freq_hz = hal_utils_calc_clk_div_integer(&clk_info, &clk_div.integer); #endif - esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true); PARLIO_CLOCK_SRC_ATOMIC() { // turn on the tx module clock to sync the clock divider configuration because of the CDC (Cross Domain Crossing) parlio_ll_tx_enable_clock(hal->regs, true); @@ -235,8 +238,6 @@ static esp_err_t parlio_select_periph_clock(parlio_tx_unit_t *tx_unit, const par if (tx_unit->out_clk_freq_hz != config->output_clk_freq_hz) { ESP_LOGW(TAG, "precision loss, real output frequency: %"PRIu32, tx_unit->out_clk_freq_hz); } - tx_unit->clk_src = clk_src; - return ESP_OK; } @@ -284,6 +285,7 @@ esp_err_t parlio_new_tx_unit(const parlio_tx_unit_config_t *config, parlio_tx_un parlio_group_t *group = unit->base.group; parlio_hal_context_t *hal = &group->hal; // select the clock source + ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)(config->clk_src), true), err, TAG, "clock source enable failed"); ESP_GOTO_ON_ERROR(parlio_select_periph_clock(unit, config), err, TAG, "set clock source failed"); // install interrupt service diff --git a/components/esp_driver_rmt/src/rmt_common.c b/components/esp_driver_rmt/src/rmt_common.c index 83d4b6eb3d..449b46a573 100644 --- a/components/esp_driver_rmt/src/rmt_common.c +++ b/components/esp_driver_rmt/src/rmt_common.c @@ -240,7 +240,7 @@ esp_err_t rmt_select_periph_clock(rmt_channel_handle_t chan, rmt_clock_source_t ESP_RETURN_ON_ERROR(ret, TAG, "create pm lock failed"); #endif // CONFIG_PM_ENABLE - esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true); + ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true), TAG, "clock source enable failed"); uint32_t real_div; #if SOC_RMT_CHANNEL_CLK_INDEPENDENT uint32_t periph_src_clk_hz = 0; diff --git a/components/esp_driver_sdmmc/src/sd_host_sdmmc.c b/components/esp_driver_sdmmc/src/sd_host_sdmmc.c index 9fa2eb95f3..2defb6e717 100644 --- a/components/esp_driver_sdmmc/src/sd_host_sdmmc.c +++ b/components/esp_driver_sdmmc/src/sd_host_sdmmc.c @@ -987,7 +987,7 @@ static esp_err_t sd_host_reset(sd_host_sdmmc_ctlr_t *ctlr) */ static void sd_host_set_clk_div(sd_host_sdmmc_ctlr_t *ctlr, soc_periph_sdmmc_clk_src_t src, int div) { - esp_clk_tree_enable_src((soc_module_clk_t)src, true); + ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)src, true)); SD_HOST_SDMMC_CLK_SRC_ATOMIC() { sdmmc_ll_set_clock_div(ctlr->hal.dev, div); sdmmc_ll_select_clk_source(ctlr->hal.dev, src); diff --git a/components/esp_driver_spi/src/gpspi/spi_master.c b/components/esp_driver_spi/src/gpspi/spi_master.c index daf953fb92..1a0519724f 100644 --- a/components/esp_driver_spi/src/gpspi/spi_master.c +++ b/components/esp_driver_spi/src/gpspi/spi_master.c @@ -424,7 +424,7 @@ esp_err_t spi_bus_add_device(spi_host_device_t host_id, const spi_device_interfa spi_clock_source_t clk_src = dev_config->clock_source ? dev_config->clock_source : SPI_CLK_SRC_DEFAULT; uint32_t clock_source_hz = 0; uint32_t clock_source_div = 1; - esp_clk_tree_enable_src(clk_src, true); + SPI_CHECK(esp_clk_tree_enable_src(clk_src, true) == ESP_OK, "clock source enable failed", ESP_ERR_INVALID_STATE); esp_clk_tree_src_get_freq_hz(clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clock_source_hz); #if SPI_LL_SUPPORT_CLK_SRC_PRE_DIV SPI_CHECK((dev_config->clock_speed_hz > 0) && (dev_config->clock_speed_hz <= MIN(clock_source_hz / 2, (80 * 1000000))), "invalid sclk speed", ESP_ERR_INVALID_ARG); @@ -601,7 +601,7 @@ esp_err_t spi_bus_remove_device(spi_device_handle_t handle) periph_rtc_dig_clk8m_disable(); } #endif - esp_clk_tree_enable_src(handle->hal_dev.timing_conf.clock_source, false); + SPI_CHECK(esp_clk_tree_enable_src(handle->hal_dev.timing_conf.clock_source, false) == ESP_OK, "clock source disable failed", ESP_ERR_INVALID_STATE); //return int spics_io_num = handle->cfg.spics_io_num; diff --git a/components/esp_driver_twai/esp_twai_onchip.c b/components/esp_driver_twai/esp_twai_onchip.c index 2fe116d8ef..7e7b97d0a1 100644 --- a/components/esp_driver_twai/esp_twai_onchip.c +++ b/components/esp_driver_twai/esp_twai_onchip.c @@ -376,6 +376,8 @@ static esp_err_t _node_set_bit_timing(twai_node_handle_t node, const twai_timing #endif if (new_clock_src != twai_ctx->curr_clk_src) { + // TODO: IDF-13144 + ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)(new_clock_src), true)); twai_ctx->curr_clk_src = new_clock_src; _twai_rcc_clock_sel(twai_ctx->ctrlr_id, new_clock_src); } diff --git a/components/esp_driver_uart/src/uart.c b/components/esp_driver_uart/src/uart.c index 12733ec167..8eb9caa1eb 100644 --- a/components/esp_driver_uart/src/uart.c +++ b/components/esp_driver_uart/src/uart.c @@ -109,6 +109,7 @@ static const char *UART_TAG = "uart"; #define UART_CONTEXT_INIT_DEF(uart_num) { \ .port_id = uart_num, \ .hal.dev = UART_LL_GET_HW(uart_num), \ + .sclk_sel = -1, \ INIT_CRIT_SECTION_LOCK_IN_STRUCT(spinlock) \ .hw_enabled = false, \ .tx_io_num = -1, \ @@ -175,6 +176,7 @@ typedef struct uart_context_t { _lock_t mutex; /*!< Protect uart_module_enable, uart_module_disable, retention, etc. */ uart_port_t port_id; uart_hal_context_t hal; /*!< UART hal context*/ + soc_module_clk_t sclk_sel; /*!< UART port clock source selection*/ DECLARE_CRIT_SECTION_LOCK_IN_STRUCT(spinlock) bool hw_enabled; int tx_io_num; @@ -973,6 +975,56 @@ esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_conf uart_module_enable(uart_num); + soc_module_clk_t uart_sclk_sel = 0; // initialize to an invalid module clock ID + if (uart_num < SOC_UART_HP_NUM) { + uart_sclk_sel = (soc_module_clk_t)((uart_config->source_clk) ? uart_config->source_clk : UART_SCLK_DEFAULT); // if no specifying the clock source (soc_module_clk_t starts from 1), then just use the default clock + } +#if (SOC_UART_LP_NUM >= 1) + else { + uart_sclk_sel = (soc_module_clk_t)((uart_config->lp_source_clk) ? uart_config->lp_source_clk : LP_UART_SCLK_DEFAULT); + } +#endif + uint32_t sclk_freq; + ESP_RETURN_ON_ERROR(esp_clk_tree_src_get_freq_hz(uart_sclk_sel, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &sclk_freq), UART_TAG, "invalid src_clk"); + + // Enable the newly selected clock source. + ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src(uart_sclk_sel, true), UART_TAG, "clock source enable failed"); +#if SOC_UART_SUPPORT_RTC_CLK + if (uart_sclk_sel == (soc_module_clk_t)UART_SCLK_RTC) { + periph_rtc_dig_clk8m_enable(); + } +#endif + + bool success = false; + UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); + soc_module_clk_t uart_old_sclk_sel = uart_context[uart_num].sclk_sel; + uart_context[uart_num].sclk_sel = uart_sclk_sel; + uart_hal_init(&(uart_context[uart_num].hal), uart_num); + if (uart_num < SOC_UART_HP_NUM) { + HP_UART_SRC_CLK_ATOMIC() { + uart_hal_set_sclk(&(uart_context[uart_num].hal), uart_sclk_sel); + success = uart_hal_set_baudrate(&(uart_context[uart_num].hal), uart_config->baud_rate, sclk_freq); + } + } +#if (SOC_UART_LP_NUM >= 1) + else { + LP_UART_SRC_CLK_ATOMIC() { + lp_uart_ll_set_source_clk(uart_context[uart_num].hal.dev, (soc_periph_lp_uart_clk_src_t)uart_sclk_sel); + } + success = lp_uart_ll_set_baudrate(uart_context[uart_num].hal.dev, uart_config->baud_rate, sclk_freq); + } +#endif + // Disable the previously selected clock source + uart_hal_set_parity(&(uart_context[uart_num].hal), uart_config->parity); + uart_hal_set_data_bit_num(&(uart_context[uart_num].hal), uart_config->data_bits); + uart_hal_set_stop_bits(&(uart_context[uart_num].hal), uart_config->stop_bits); + uart_hal_set_tx_idle_num(&(uart_context[uart_num].hal), UART_TX_IDLE_NUM_DEFAULT); + uart_hal_set_hw_flow_ctrl(&(uart_context[uart_num].hal), uart_config->flow_ctrl, uart_config->rx_flow_ctrl_thresh); + UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock)); + uart_hal_rxfifo_rst(&(uart_context[uart_num].hal)); + uart_hal_txfifo_rst(&(uart_context[uart_num].hal)); + ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src(uart_old_sclk_sel, false), UART_TAG, "clock source disable failed"); + ESP_RETURN_ON_FALSE(success, ESP_FAIL, UART_TAG, "baud rate unachievable"); #if SOC_UART_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP // Create sleep retention link if desired if (uart_num != CONFIG_ESP_CONSOLE_UART_NUM && uart_num < SOC_UART_HP_NUM) { @@ -994,52 +1046,6 @@ esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_conf _lock_release(&(uart_context[uart_num].mutex)); } #endif - - soc_module_clk_t uart_sclk_sel = 0; // initialize to an invalid module clock ID - if (uart_num < SOC_UART_HP_NUM) { - uart_sclk_sel = (soc_module_clk_t)((uart_config->source_clk) ? uart_config->source_clk : UART_SCLK_DEFAULT); // if no specifying the clock source (soc_module_clk_t starts from 1), then just use the default clock - } -#if (SOC_UART_LP_NUM >= 1) - else { - uart_sclk_sel = (soc_module_clk_t)((uart_config->lp_source_clk) ? uart_config->lp_source_clk : LP_UART_SCLK_DEFAULT); - } -#endif - -#if SOC_UART_SUPPORT_RTC_CLK - if (uart_sclk_sel == (soc_module_clk_t)UART_SCLK_RTC) { - periph_rtc_dig_clk8m_enable(); - } -#endif - uint32_t sclk_freq; - ESP_RETURN_ON_ERROR(esp_clk_tree_src_get_freq_hz(uart_sclk_sel, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &sclk_freq), UART_TAG, "invalid src_clk"); - - bool success = false; - UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); - uart_hal_init(&(uart_context[uart_num].hal), uart_num); - if (uart_num < SOC_UART_HP_NUM) { - esp_clk_tree_enable_src((soc_module_clk_t)uart_sclk_sel, true); - HP_UART_SRC_CLK_ATOMIC() { - uart_hal_set_sclk(&(uart_context[uart_num].hal), uart_sclk_sel); - success = uart_hal_set_baudrate(&(uart_context[uart_num].hal), uart_config->baud_rate, sclk_freq); - } - } -#if (SOC_UART_LP_NUM >= 1) - else { - LP_UART_SRC_CLK_ATOMIC() { - lp_uart_ll_set_source_clk(uart_context[uart_num].hal.dev, (soc_periph_lp_uart_clk_src_t)uart_sclk_sel); - } - success = lp_uart_ll_set_baudrate(uart_context[uart_num].hal.dev, uart_config->baud_rate, sclk_freq); - } -#endif - uart_hal_set_parity(&(uart_context[uart_num].hal), uart_config->parity); - uart_hal_set_data_bit_num(&(uart_context[uart_num].hal), uart_config->data_bits); - uart_hal_set_stop_bits(&(uart_context[uart_num].hal), uart_config->stop_bits); - uart_hal_set_tx_idle_num(&(uart_context[uart_num].hal), UART_TX_IDLE_NUM_DEFAULT); - uart_hal_set_hw_flow_ctrl(&(uart_context[uart_num].hal), uart_config->flow_ctrl, uart_config->rx_flow_ctrl_thresh); - UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock)); - uart_hal_rxfifo_rst(&(uart_context[uart_num].hal)); - uart_hal_txfifo_rst(&(uart_context[uart_num].hal)); - ESP_RETURN_ON_FALSE(success, ESP_FAIL, UART_TAG, "baud rate unachievable"); return ESP_OK; } @@ -1910,6 +1916,7 @@ esp_err_t uart_driver_delete(uart_port_t uart_num) uart_free_driver_obj(p_uart_obj[uart_num]); p_uart_obj[uart_num] = NULL; + ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src(uart_context[uart_num].sclk_sel, false), UART_TAG, "clock source disable failed"); #if SOC_UART_SUPPORT_RTC_CLK soc_module_clk_t sclk = 0; uart_hal_get_sclk(&(uart_context[uart_num].hal), &sclk); @@ -2118,7 +2125,7 @@ esp_err_t uart_detect_bitrate_start(uart_port_t uart_num, const uart_bitrate_det uart_sclk_sel = (soc_module_clk_t)((config->source_clk) ? config->source_clk : UART_SCLK_DEFAULT); // if no specifying the clock source (soc_module_clk_t starts from 1), then just use the default clock uint32_t sclk_freq = 0; ESP_GOTO_ON_ERROR(esp_clk_tree_src_get_freq_hz(uart_sclk_sel, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &sclk_freq), err, UART_TAG, "invalid source_clk"); - esp_clk_tree_enable_src(uart_sclk_sel, true); + ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src(uart_sclk_sel, true), err, UART_TAG, "clock source enable failed"); #if SOC_UART_SUPPORT_RTC_CLK if (uart_sclk_sel == (soc_module_clk_t)UART_SCLK_RTC) { periph_rtc_dig_clk8m_enable(); @@ -2180,6 +2187,7 @@ esp_err_t uart_detect_bitrate_stop(uart_port_t uart_num, bool deinit, uart_bitra if (deinit) { // release the port uart_release_pin(uart_num); + ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src(uart_context[uart_num].sclk_sel, false), UART_TAG, "clock source disable failed"); #if SOC_UART_SUPPORT_RTC_CLK if (src_clk == (soc_module_clk_t)UART_SCLK_RTC) { periph_rtc_dig_clk8m_disable(); diff --git a/components/esp_eth/src/mac/esp_eth_mac_esp.c b/components/esp_eth/src/mac/esp_eth_mac_esp.c index 0b7dc19268..c9f9084b8e 100644 --- a/components/esp_eth/src/mac/esp_eth_mac_esp.c +++ b/components/esp_eth/src/mac/esp_eth_mac_esp.c @@ -521,7 +521,7 @@ static esp_err_t emac_config_pll_clock(emac_esp32_t *emac) real_freq /= div; } // Enable 50MHz MPLL derived clock - esp_clk_tree_enable_src(SOC_MOD_CLK_PLL_F50M, true); + ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src(SOC_MOD_CLK_PLL_F50M, true), TAG, "clock source enable failed"); #endif // If the difference of real RMII CLK frequency is not within 50 ppm, i.e. 2500 Hz, the (A/M)PLL is unusable ESP_RETURN_ON_FALSE(abs((int)real_freq - (int)expt_freq) <= 2500, diff --git a/components/esp_hw_support/include/esp_private/esp_clk_tree_common.h b/components/esp_hw_support/include/esp_private/esp_clk_tree_common.h index 7b57285062..5755cd8232 100644 --- a/components/esp_hw_support/include/esp_private/esp_clk_tree_common.h +++ b/components/esp_hw_support/include/esp_private/esp_clk_tree_common.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -84,11 +84,6 @@ uint32_t esp_clk_tree_lp_fast_get_freq_hz(esp_clk_tree_src_freq_precision_t prec * @param[in] clk_src Clock source available to modules, in soc_module_clk_t * @param[in] enable Enable / Disable the clock gate * - * @note !!! WARNING !!! - * There's no reference counter to protect the clock source status, the caller should use the interface - * with CAUTION to disable the clock source to avoid damaging other peripherals that are dependent on - * the clock source. - * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error diff --git a/components/esp_hw_support/modem_clock.c b/components/esp_hw_support/modem_clock.c index 8e98b61f37..57a0f1baa9 100644 --- a/components/esp_hw_support/modem_clock.c +++ b/components/esp_hw_support/modem_clock.c @@ -171,7 +171,7 @@ modem_clock_context_t * __attribute__((weak)) IRAM_ATTR MODEM_CLOCK_instance(voi modem_clock_hal.syscon_dev = &MODEM_SYSCON; modem_clock_hal.lpcon_dev = &MODEM_LPCON; #if SOC_CLOCK_TREE_MANAGEMENT_SUPPORTED - esp_clk_tree_enable_src(SOC_MOD_CLK_MODEM_APB, true); + ESP_ERROR_CHECK(esp_clk_tree_enable_src(SOC_MOD_CLK_MODEM_APB, true)); #endif } return &modem_clock_context; diff --git a/components/esp_hw_support/port/esp32c5/io_mux.c b/components/esp_hw_support/port/esp32c5/io_mux.c index e6e53ee3ba..6e00bb0da5 100644 --- a/components/esp_hw_support/port/esp32c5/io_mux.c +++ b/components/esp_hw_support/port/esp32c5/io_mux.c @@ -41,7 +41,7 @@ esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) return ESP_ERR_INVALID_STATE; } - esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true); + ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true)); gpio_ll_iomux_set_clk_src(clk_src); return ESP_OK; diff --git a/components/esp_hw_support/port/esp32p4/esp_clk_tree.c b/components/esp_hw_support/port/esp32p4/esp_clk_tree.c index 9e46ca5877..102ea66476 100644 --- a/components/esp_hw_support/port/esp32p4/esp_clk_tree.c +++ b/components/esp_hw_support/port/esp32p4/esp_clk_tree.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -91,6 +91,11 @@ esp_err_t esp_clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, esp_clk_tree_sr esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable) { + if(!enable) { + // TODO: remove it after reference counter supported + return ESP_OK; + } + PERIPH_RCC_ATOMIC() { switch (clk_src) { case SOC_MOD_CLK_PLL_F20M: diff --git a/components/esp_hw_support/port/esp32p4/io_mux.c b/components/esp_hw_support/port/esp32p4/io_mux.c index e74205bf8d..89befcb95e 100644 --- a/components/esp_hw_support/port/esp32p4/io_mux.c +++ b/components/esp_hw_support/port/esp32p4/io_mux.c @@ -44,7 +44,7 @@ esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src) return ESP_ERR_INVALID_STATE; } - esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true); + ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true)); PERIPH_RCC_ATOMIC() { gpio_ll_iomux_set_clk_src(clk_src); } diff --git a/components/esp_lcd/dsi/esp_lcd_mipi_dsi_bus.c b/components/esp_lcd/dsi/esp_lcd_mipi_dsi_bus.c index 90af97617a..1c188b3ffb 100644 --- a/components/esp_lcd/dsi/esp_lcd_mipi_dsi_bus.c +++ b/components/esp_lcd/dsi/esp_lcd_mipi_dsi_bus.c @@ -48,7 +48,7 @@ esp_err_t esp_lcd_new_dsi_bus(const esp_lcd_dsi_bus_config_t *bus_config, esp_lc if (phy_clk_src == 0) { phy_clk_src = MIPI_DSI_PHY_CLK_SRC_DEFAULT; } - esp_clk_tree_enable_src((soc_module_clk_t)phy_clk_src, true); + ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)phy_clk_src, true), err, TAG, "clock source enable failed"); // enable the clock source for DSI PHY DSI_CLOCK_SRC_ATOMIC() { // set clock source for DSI PHY diff --git a/components/esp_lcd/dsi/esp_lcd_panel_dpi.c b/components/esp_lcd/dsi/esp_lcd_panel_dpi.c index f6d307a6a0..cb0cd9e77b 100644 --- a/components/esp_lcd/dsi/esp_lcd_panel_dpi.c +++ b/components/esp_lcd/dsi/esp_lcd_panel_dpi.c @@ -262,7 +262,7 @@ esp_err_t esp_lcd_new_panel_dpi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dpi_ &dpi_clk_src_freq_hz), err, TAG, "get clock source frequency failed"); // divide the source clock to get the final DPI clock uint32_t dpi_div = mipi_dsi_hal_host_dpi_calculate_divider(hal, dpi_clk_src_freq_hz / 1000 / 1000, panel_config->dpi_clock_freq_mhz); - esp_clk_tree_enable_src((soc_module_clk_t)dpi_clk_src, true); + ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)dpi_clk_src, true), err, TAG, "clock source enable failed"); // set the clock source, set the divider, and enable the dpi clock DSI_CLOCK_SRC_ATOMIC() { mipi_dsi_ll_set_dpi_clock_source(bus_id, dpi_clk_src); diff --git a/components/esp_lcd/i80/esp_lcd_panel_io_i80.c b/components/esp_lcd/i80/esp_lcd_panel_io_i80.c index 35a14a0ba5..a607e1e825 100644 --- a/components/esp_lcd/i80/esp_lcd_panel_io_i80.c +++ b/components/esp_lcd/i80/esp_lcd_panel_io_i80.c @@ -582,7 +582,7 @@ static esp_err_t lcd_i80_select_periph_clock(esp_lcd_i80_bus_handle_t bus, lcd_c ESP_RETURN_ON_ERROR(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &src_clk_hz), TAG, "get clock source frequency failed"); - esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true); + ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true), TAG, "clock source enable failed"); LCD_CLOCK_SRC_ATOMIC() { lcd_ll_select_clk_src(bus->hal.dev, clk_src); // force to use integer division, as fractional division might lead to clock jitter diff --git a/components/esp_lcd/rgb/esp_lcd_panel_rgb.c b/components/esp_lcd/rgb/esp_lcd_panel_rgb.c index dc5b5e52b0..87a334d772 100644 --- a/components/esp_lcd/rgb/esp_lcd_panel_rgb.c +++ b/components/esp_lcd/rgb/esp_lcd_panel_rgb.c @@ -786,7 +786,7 @@ static esp_err_t lcd_rgb_panel_select_clock_src(esp_rgb_panel_t *rgb_panel, lcd_ ESP_RETURN_ON_ERROR(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &src_clk_hz), TAG, "get clock source frequency failed"); rgb_panel->src_clk_hz = src_clk_hz; - esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true); + ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true), TAG, "clock source enable failed"); LCD_CLOCK_SRC_ATOMIC() { lcd_ll_select_clk_src(rgb_panel->hal.dev, clk_src); } diff --git a/components/esp_pm/pm_impl.c b/components/esp_pm/pm_impl.c index a576d0d1ac..9277d8b183 100644 --- a/components/esp_pm/pm_impl.c +++ b/components/esp_pm/pm_impl.c @@ -926,7 +926,7 @@ void esp_pm_impl_init(void) ; } - esp_clk_tree_enable_src((soc_module_clk_t)clk_source, true); + ESP_ERROR_CHECK(esp_clk_tree_enable_src((soc_module_clk_t)clk_source, true)); /* When DFS is enabled, override system setting and use REFTICK as UART clock source */ HP_UART_SRC_CLK_ATOMIC() { uart_ll_set_sclk(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), (soc_module_clk_t)clk_source);