mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
refactor(clk_tree): use general api to enable the clk
This commit is contained in:
@@ -21,7 +21,6 @@
|
||||
#include "driver/i2s_std.h"
|
||||
#include "i2s_private.h"
|
||||
#include "esp_private/esp_clk_tree_common.h"
|
||||
#include "clk_ctrl_os.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "esp_check.h"
|
||||
|
||||
@@ -82,23 +81,18 @@ static esp_err_t i2s_std_set_clock(i2s_chan_handle_t handle, const i2s_std_clk_c
|
||||
(clk_cfg->mclk_multiple % 3 == 0), ESP_ERR_INVALID_ARG, TAG,
|
||||
"The 'mclk_multiple' should be the multiple of 3 while using 24-bit data width");
|
||||
|
||||
i2s_hal_clock_info_t clk_info;
|
||||
/* Calculate clock parameters */
|
||||
ESP_RETURN_ON_ERROR(i2s_std_calculate_clock(handle, clk_cfg, &clk_info), TAG, "clock calculate failed");
|
||||
|
||||
#if SOC_I2S_HW_VERSION_2
|
||||
i2s_clock_src_t old_clk_src = handle->clk_src;
|
||||
if (clk_cfg->clk_src != I2S_CLK_SRC_EXTERNAL)
|
||||
#endif
|
||||
{
|
||||
i2s_clock_src_t clk_src = clk_cfg->clk_src;
|
||||
i2s_clock_src_t clk_src = clk_cfg->clk_src;
|
||||
#ifdef I2S_LL_DEFAULT_CLK_SRC
|
||||
if (clk_src == I2S_CLK_SRC_DEFAULT) {
|
||||
clk_src = I2S_LL_DEFAULT_CLK_SRC;
|
||||
}
|
||||
#endif
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true);
|
||||
if (clk_src == I2S_CLK_SRC_DEFAULT) {
|
||||
clk_src = I2S_LL_DEFAULT_CLK_SRC;
|
||||
}
|
||||
#endif
|
||||
|
||||
i2s_hal_clock_info_t clk_info;
|
||||
// Calculate clock parameters before enabling clock source
|
||||
ESP_RETURN_ON_ERROR(i2s_std_calculate_clock(handle, clk_cfg, &clk_info), TAG, "clock calculate failed");
|
||||
ESP_RETURN_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)clk_src, true), TAG, "clock source enable failed");
|
||||
|
||||
hal_utils_clk_div_t ret_mclk_div = {};
|
||||
portENTER_CRITICAL(&g_i2s.spinlock);
|
||||
/* Set clock configurations in HAL*/
|
||||
@@ -111,7 +105,7 @@ static esp_err_t i2s_std_set_clock(i2s_chan_handle_t handle, const i2s_std_clk_c
|
||||
}
|
||||
portEXIT_CRITICAL(&g_i2s.spinlock);
|
||||
uint64_t tmp_div = (uint64_t)ret_mclk_div.integer * ret_mclk_div.denominator + ret_mclk_div.numerator;
|
||||
ESP_RETURN_ON_FALSE(tmp_div != 0 && ret_mclk_div.denominator != 0, ESP_ERR_INVALID_ARG, TAG, "invalid mclk division result");
|
||||
ESP_GOTO_ON_FALSE(tmp_div != 0 && ret_mclk_div.denominator != 0, ESP_ERR_INVALID_ARG, err, TAG, "invalid mclk division result");
|
||||
|
||||
/* Update the mode info: clock configuration */
|
||||
memcpy(&(std_cfg->clk_cfg), clk_cfg, sizeof(i2s_std_clk_config_t));
|
||||
@@ -121,16 +115,14 @@ static esp_err_t i2s_std_set_clock(i2s_chan_handle_t handle, const i2s_std_clk_c
|
||||
handle->curr_mclk_hz = handle->origin_mclk_hz;
|
||||
handle->bclk_hz = clk_info.bclk;
|
||||
|
||||
#if SOC_I2S_HW_VERSION_2
|
||||
if (old_clk_src != I2S_CLK_SRC_EXTERNAL) {
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)old_clk_src, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
ESP_LOGD(TAG, "Clock division info: [sclk] %"PRIu32" Hz [mdiv] %"PRIu32" %"PRIu32"/%"PRIu32" [mclk] %"PRIu32" Hz [bdiv] %d [bclk] %"PRIu32" Hz",
|
||||
clk_info.sclk, ret_mclk_div.integer, ret_mclk_div.numerator, ret_mclk_div.denominator, handle->origin_mclk_hz, clk_info.bclk_div, clk_info.bclk);
|
||||
|
||||
return ret;
|
||||
|
||||
err:
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)clk_src, false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static i2s_std_slot_config_t s_i2s_std_normalize_slot_config(const i2s_std_slot_config_t *slot_cfg)
|
||||
@@ -345,13 +337,6 @@ esp_err_t i2s_channel_init_std_mode(i2s_chan_handle_t handle, const i2s_std_conf
|
||||
#endif
|
||||
/* i2s_set_std_slot should be called before i2s_set_std_clock while initializing, because clock is relay on the slot */
|
||||
ESP_GOTO_ON_ERROR(i2s_std_set_slot(handle, &std_cfg->slot_cfg), err, TAG, "initialize channel failed while setting slot");
|
||||
#if SOC_I2S_SUPPORTS_APLL
|
||||
/* Enable APLL and acquire its lock when the clock source is APLL */
|
||||
if (std_cfg->clk_cfg.clk_src == I2S_CLK_SRC_APLL) {
|
||||
periph_rtc_apll_acquire();
|
||||
handle->apll_en = true;
|
||||
}
|
||||
#endif
|
||||
ESP_GOTO_ON_ERROR(i2s_std_set_clock(handle, &std_cfg->clk_cfg), err, TAG, "initialize channel failed while setting clock");
|
||||
/* i2s_std_set_gpio should be called after i2s_std_set_clock as mclk relies on the clock source */
|
||||
ESP_GOTO_ON_ERROR(i2s_std_set_gpio(handle, &std_cfg->gpio_cfg), err, TAG, "initialize channel failed while setting gpio pins");
|
||||
@@ -403,23 +388,21 @@ esp_err_t i2s_channel_reconfig_std_clock(i2s_chan_handle_t handle, const i2s_std
|
||||
i2s_std_config_t *std_cfg = (i2s_std_config_t *)handle->mode_info;
|
||||
ESP_GOTO_ON_FALSE(std_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete");
|
||||
|
||||
#if SOC_I2S_SUPPORTS_APLL
|
||||
/* Enable APLL and acquire its lock when the clock source is changed to APLL */
|
||||
if (clk_cfg->clk_src == I2S_CLK_SRC_APLL && std_cfg->clk_cfg.clk_src != I2S_CLK_SRC_APLL) {
|
||||
periph_rtc_apll_acquire();
|
||||
handle->apll_en = true;
|
||||
}
|
||||
/* Disable APLL and release its lock when clock source is changed to 160M_PLL */
|
||||
if (clk_cfg->clk_src != I2S_CLK_SRC_APLL && std_cfg->clk_cfg.clk_src == I2S_CLK_SRC_APLL) {
|
||||
periph_rtc_apll_release();
|
||||
handle->apll_en = false;
|
||||
i2s_clock_src_t old_clk_src = std_cfg->clk_cfg.clk_src;
|
||||
#ifdef I2S_LL_DEFAULT_CLK_SRC
|
||||
if (old_clk_src == I2S_CLK_SRC_DEFAULT) {
|
||||
old_clk_src = I2S_LL_DEFAULT_CLK_SRC;
|
||||
}
|
||||
#endif
|
||||
|
||||
ESP_GOTO_ON_ERROR(i2s_std_set_clock(handle, clk_cfg), err, TAG, "update clock failed");
|
||||
|
||||
// disable old clock source after new clock is successfully configured
|
||||
ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)old_clk_src, false), err, TAG, "clock source disable failed");
|
||||
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
// Create/Re-create power management lock
|
||||
if (std_cfg->clk_cfg.clk_src != clk_cfg->clk_src) {
|
||||
if (old_clk_src != clk_cfg->clk_src) {
|
||||
ESP_GOTO_ON_ERROR(esp_pm_lock_delete(handle->pm_lock), err, TAG, "I2S delete old pm lock failed");
|
||||
esp_pm_lock_type_t pm_type = ESP_PM_APB_FREQ_MAX;
|
||||
#if SOC_I2S_SUPPORTS_APLL && SOC_I2S_HW_VERSION_2
|
||||
@@ -460,7 +443,15 @@ esp_err_t i2s_channel_reconfig_std_slot(i2s_chan_handle_t handle, const i2s_std_
|
||||
/* If the slot bit width changed, then need to update the clock */
|
||||
uint32_t slot_bits = slot_cfg->slot_bit_width == I2S_SLOT_BIT_WIDTH_AUTO ? slot_cfg->data_bit_width : slot_cfg->slot_bit_width;
|
||||
if (std_cfg->slot_cfg.slot_bit_width != slot_bits) {
|
||||
i2s_clock_src_t old_clk_src = std_cfg->clk_cfg.clk_src;
|
||||
#ifdef I2S_LL_DEFAULT_CLK_SRC
|
||||
if (old_clk_src == I2S_CLK_SRC_DEFAULT) {
|
||||
old_clk_src = I2S_LL_DEFAULT_CLK_SRC;
|
||||
}
|
||||
#endif
|
||||
ESP_GOTO_ON_ERROR(i2s_std_set_clock(handle, &std_cfg->clk_cfg), err, TAG, "update clock failed");
|
||||
// disable old clock source after new clock is successfully configured
|
||||
ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)old_clk_src, false), err, TAG, "clock source disable failed");
|
||||
}
|
||||
|
||||
xSemaphoreGive(handle->mutex);
|
||||
|
||||
Reference in New Issue
Block a user