diff --git a/components/driver/dac/esp32/dac_dma.c b/components/driver/dac/esp32/dac_dma.c index b5bd20e9b9..f1e648f16d 100644 --- a/components/driver/dac/esp32/dac_dma.c +++ b/components/driver/dac/esp32/dac_dma.c @@ -47,7 +47,7 @@ static const char *TAG = "DAC_DMA"; static uint32_t s_dac_set_apll_freq(uint32_t mclk) { /* Calculate the expected APLL */ - int div = (int)((SOC_APLL_MIN_HZ / mclk) + 1); + int div = (int)((CLK_LL_APLL_MIN_HZ / mclk) + 1); /* apll_freq = mclk * div * when div = 1, hardware will still divide 2 * when div = 0, hardware will divide 255 diff --git a/components/driver/dac/esp32s2/dac_dma.c b/components/driver/dac/esp32s2/dac_dma.c index af9dfb11c6..d13c63f39b 100644 --- a/components/driver/dac/esp32s2/dac_dma.c +++ b/components/driver/dac/esp32s2/dac_dma.c @@ -19,6 +19,7 @@ #include "hal/dac_ll.h" #include "hal/adc_ll.h" #include "hal/hal_utils.h" +#include "hal/clk_tree_ll.h" #include "soc/lldesc.h" #include "soc/soc.h" #include "soc/soc_caps.h" @@ -75,9 +76,9 @@ static esp_err_t s_dac_dma_periph_set_clock(uint32_t freq_hz, bool is_apll){ uint32_t digi_ctrl_freq; // Digital controller clock if (is_apll) { /* Theoretical frequency range (due to the limitation of DAC, the maximum frequency may not reach): - * SOC_APLL_MAX_HZ: 119.24 Hz ~ 67.5 MHz - * SOC_APLL_MIN_HZ: 5.06 Hz ~ 2.65 MHz */ - digi_ctrl_freq = s_dac_set_apll_freq(freq_hz < 120 ? SOC_APLL_MIN_HZ :SOC_APLL_MAX_HZ); + * CLK_LL_APLL_MAX_HZ: 119.24 Hz ~ 67.5 MHz + * CLK_LL_APLL_MIN_HZ: 5.06 Hz ~ 2.65 MHz */ + digi_ctrl_freq = s_dac_set_apll_freq(freq_hz < 120 ? CLK_LL_APLL_MIN_HZ :CLK_LL_APLL_MAX_HZ); ESP_RETURN_ON_FALSE(digi_ctrl_freq, ESP_ERR_INVALID_ARG, TAG, "set APLL coefficients failed"); } else { digi_ctrl_freq = APB_CLK_FREQ; diff --git a/components/driver/deprecated/i2s_legacy.c b/components/driver/deprecated/i2s_legacy.c index 9397275979..9b2ec2a349 100644 --- a/components/driver/deprecated/i2s_legacy.c +++ b/components/driver/deprecated/i2s_legacy.c @@ -25,6 +25,10 @@ #include "hal/gpio_hal.h" #include "driver/i2s_types_legacy.h" #include "hal/i2s_hal.h" +#if SOC_I2S_SUPPORTS_APLL +#include "hal/clk_tree_ll.h" +#endif + #if SOC_I2S_SUPPORTS_DAC #include "hal/dac_ll.h" #include "hal/dac_types.h" @@ -58,12 +62,16 @@ static const char *TAG = "i2s(legacy)"; #define I2S_ENTER_CRITICAL(i2s_num) portENTER_CRITICAL(&i2s_spinlock[i2s_num]) #define I2S_EXIT_CRITICAL(i2s_num) portEXIT_CRITICAL(&i2s_spinlock[i2s_num]) +#if SOC_SYS_DIGI_CLKRST_REG_SHARED +#define I2S_CLOCK_SRC_ATOMIC() PERIPH_RCC_ATOMIC() +#else +#define I2S_CLOCK_SRC_ATOMIC() +#endif + #if !SOC_RCC_IS_INDEPENDENT -#define I2S_RCC_ATOMIC() PERIPH_RCC_ATOMIC() -#define I2S_RCC_ENV_DECLARE (void)__DECLARE_RCC_ATOMIC_ENV +#define I2S_RCC_ATOMIC() PERIPH_RCC_ATOMIC() #else #define I2S_RCC_ATOMIC() -#define I2S_RCC_ENV_DECLARE #endif #define I2S_DMA_BUFFER_MAX_SIZE 4092 @@ -641,7 +649,7 @@ static uint32_t i2s_config_source_clock(i2s_port_t i2s_num, bool use_apll, uint3 #if SOC_I2S_SUPPORTS_APLL if (use_apll) { /* Calculate the expected APLL */ - int div = (int)((SOC_APLL_MIN_HZ / mclk) + 1); + int div = (int)((CLK_LL_APLL_MIN_HZ / mclk) + 1); /* apll_freq = mclk * div * when div = 1, hardware will still divide 2 * when div = 0, the final mclk will be unpredictable @@ -1029,8 +1037,7 @@ static void i2s_set_clock_legacy(i2s_port_t i2s_num) i2s_clk_config_t *clk_cfg = &p_i2s[i2s_num]->clk_cfg; i2s_hal_clock_info_t clk_info; i2s_calculate_clock(i2s_num, &clk_info); - I2S_RCC_ATOMIC() { - I2S_RCC_ENV_DECLARE; + I2S_CLOCK_SRC_ATOMIC() { if (p_i2s[i2s_num]->dir & I2S_DIR_TX) { i2s_hal_set_tx_clock(&(p_i2s[i2s_num]->hal), &clk_info, clk_cfg->clk_src); } @@ -1538,14 +1545,13 @@ esp_err_t i2s_driver_uninstall(i2s_port_t i2s_num) #if SOC_I2S_SUPPORTS_APLL if (obj->use_apll) { - I2S_RCC_ATOMIC() { - I2S_RCC_ENV_DECLARE; + I2S_CLOCK_SRC_ATOMIC() { // switch back to PLL clock source if (obj->dir & I2S_DIR_TX) { - i2s_ll_tx_clk_set_src(obj->hal.dev, I2S_CLK_SRC_DEFAULT); + i2s_hal_set_tx_clock(&obj->hal, NULL, I2S_CLK_SRC_DEFAULT); } if (obj->dir & I2S_DIR_RX) { - i2s_ll_rx_clk_set_src(obj->hal.dev, I2S_CLK_SRC_DEFAULT); + i2s_hal_set_rx_clock(&obj->hal, NULL, I2S_CLK_SRC_DEFAULT); } } periph_rtc_apll_release(); @@ -1559,7 +1565,7 @@ esp_err_t i2s_driver_uninstall(i2s_port_t i2s_num) } #endif #if SOC_I2S_HW_VERSION_2 - I2S_RCC_ATOMIC() { + I2S_CLOCK_SRC_ATOMIC() { if (obj->dir & I2S_DIR_TX) { i2s_ll_tx_disable_clock(obj->hal.dev); } @@ -1910,7 +1916,9 @@ esp_err_t i2s_platform_acquire_occupation(int id, const char *comp_name) ret = ESP_OK; comp_using_i2s[id] = comp_name; I2S_RCC_ATOMIC() { - i2s_ll_enable_clock(I2S_LL_GET_HW(id)); + i2s_ll_enable_bus_clock(id, true); + i2s_ll_reset_register(id); + i2s_ll_enable_core_clock(I2S_LL_GET_HW(id), true); } } portEXIT_CRITICAL(&i2s_spinlock[id]); @@ -1927,7 +1935,8 @@ esp_err_t i2s_platform_release_occupation(int id) comp_using_i2s[id] = NULL; /* Disable module clock */ I2S_RCC_ATOMIC() { - i2s_ll_disable_clock(I2S_LL_GET_HW(id)); + i2s_ll_enable_bus_clock(id, false); + i2s_ll_enable_core_clock(I2S_LL_GET_HW(id), false); } } portEXIT_CRITICAL(&i2s_spinlock[id]); diff --git a/components/driver/i2s/i2s_common.c b/components/driver/i2s/i2s_common.c index 41dde28b77..269fe52b5d 100644 --- a/components/driver/i2s/i2s_common.c +++ b/components/driver/i2s/i2s_common.c @@ -36,6 +36,7 @@ #include "driver/adc_i2s_legacy.h" #endif #if SOC_I2S_SUPPORTS_APLL +#include "hal/clk_tree_ll.h" #include "clk_ctrl_os.h" #endif @@ -401,7 +402,7 @@ esp_err_t i2s_alloc_dma_desc(i2s_chan_handle_t handle, uint32_t num, uint32_t bu handle->dma.buf_size = bufsize; #if SOC_GDMA_TRIG_PERIPH_I2S0_BUS == SOC_GDMA_BUS_AHB - uint32_t alignment = 32; + uint32_t alignment = 64; uint32_t desc_size = alignment; #else uint32_t alignment = 4; @@ -448,14 +449,14 @@ err: static uint32_t i2s_set_get_apll_freq(uint32_t mclk_freq_hz) { /* Calculate the expected APLL */ - int mclk_div = (int)((SOC_APLL_MIN_HZ / mclk_freq_hz) + 1); + int mclk_div = (int)((CLK_LL_APLL_MIN_HZ / mclk_freq_hz) + 1); /* apll_freq = mclk * div * when div = 1, hardware will still divide 2 * when div = 0, the final mclk will be unpredictable * So the div here should be at least 2 */ mclk_div = mclk_div < 2 ? 2 : mclk_div; uint32_t expt_freq = mclk_freq_hz * mclk_div; - if (expt_freq > SOC_APLL_MAX_HZ) { + if (expt_freq > CLK_LL_APLL_MAX_HZ) { ESP_LOGE(TAG, "The required APLL frequency exceed its maximum value"); return 0; } @@ -867,7 +868,7 @@ esp_err_t i2s_del_channel(i2s_chan_handle_t handle) bool is_bound = true; #if SOC_I2S_HW_VERSION_2 - I2S_RCC_ATOMIC() { + I2S_CLOCK_SRC_ATOMIC() { if (dir == I2S_DIR_TX) { i2s_ll_tx_disable_clock(handle->controller->hal.dev); } else { @@ -1202,7 +1203,9 @@ esp_err_t i2s_platform_acquire_occupation(int id, const char *comp_name) g_i2s.comp_name[id] = comp_name; /* Enable module clock */ I2S_RCC_ATOMIC() { - i2s_ll_enable_clock(I2S_LL_GET_HW(id)); + i2s_ll_enable_bus_clock(id, true); + i2s_ll_reset_register(id); + i2s_ll_enable_core_clock(I2S_LL_GET_HW(id), true); } } else { occupied_comp = g_i2s.comp_name[id]; @@ -1224,7 +1227,8 @@ esp_err_t i2s_platform_release_occupation(int id) g_i2s.comp_name[id] = NULL; /* Disable module clock */ I2S_RCC_ATOMIC() { - i2s_ll_disable_clock(I2S_LL_GET_HW(id)); + i2s_ll_enable_bus_clock(id, false); + i2s_ll_enable_core_clock(I2S_LL_GET_HW(id), false); } } else { ret = ESP_ERR_INVALID_STATE; diff --git a/components/driver/i2s/i2s_pdm.c b/components/driver/i2s/i2s_pdm.c index 2426e896fe..574247c0c8 100644 --- a/components/driver/i2s/i2s_pdm.c +++ b/components/driver/i2s/i2s_pdm.c @@ -70,8 +70,7 @@ static esp_err_t i2s_pdm_tx_set_clock(i2s_chan_handle_t handle, const i2s_pdm_tx portENTER_CRITICAL(&g_i2s.spinlock); /* Set clock configurations in HAL*/ - I2S_RCC_ATOMIC() { - I2S_RCC_ENV_DECLARE; + I2S_CLOCK_SRC_ATOMIC() { i2s_hal_set_tx_clock(&handle->controller->hal, &clk_info, clk_cfg->clk_src); } #if SOC_I2S_HW_VERSION_2 @@ -357,8 +356,7 @@ static esp_err_t i2s_pdm_rx_set_clock(i2s_chan_handle_t handle, const i2s_pdm_rx portENTER_CRITICAL(&g_i2s.spinlock); /* Set clock configurations in HAL*/ - I2S_RCC_ATOMIC() { - I2S_RCC_ENV_DECLARE; + I2S_CLOCK_SRC_ATOMIC() { i2s_hal_set_rx_clock(&handle->controller->hal, &clk_info, clk_cfg->clk_src); } portEXIT_CRITICAL(&g_i2s.spinlock); diff --git a/components/driver/i2s/i2s_private.h b/components/driver/i2s/i2s_private.h index 802eb32fbb..90858a04b4 100644 --- a/components/driver/i2s/i2s_private.h +++ b/components/driver/i2s/i2s_private.h @@ -36,12 +36,16 @@ extern "C" { #endif //CONFIG_I2S_ISR_IRAM_SAFE #define I2S_DMA_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA) +#if SOC_SYS_DIGI_CLKRST_REG_SHARED +#define I2S_CLOCK_SRC_ATOMIC() PERIPH_RCC_ATOMIC() +#else +#define I2S_CLOCK_SRC_ATOMIC() +#endif + #if !SOC_RCC_IS_INDEPENDENT -#define I2S_RCC_ATOMIC() PERIPH_RCC_ATOMIC() -#define I2S_RCC_ENV_DECLARE (void)__DECLARE_RCC_ATOMIC_ENV +#define I2S_RCC_ATOMIC() PERIPH_RCC_ATOMIC() #else #define I2S_RCC_ATOMIC() -#define I2S_RCC_ENV_DECLARE #endif #define I2S_NULL_POINTER_CHECK(tag, p) ESP_RETURN_ON_FALSE((p), ESP_ERR_INVALID_ARG, tag, "input parameter '"#p"' is NULL") diff --git a/components/driver/i2s/i2s_std.c b/components/driver/i2s/i2s_std.c index 0b32139c21..715ca04399 100644 --- a/components/driver/i2s/i2s_std.c +++ b/components/driver/i2s/i2s_std.c @@ -77,8 +77,7 @@ static esp_err_t i2s_std_set_clock(i2s_chan_handle_t handle, const i2s_std_clk_c portENTER_CRITICAL(&g_i2s.spinlock); /* Set clock configurations in HAL*/ - I2S_RCC_ATOMIC() { - I2S_RCC_ENV_DECLARE; + I2S_CLOCK_SRC_ATOMIC() { if (handle->dir == I2S_DIR_TX) { i2s_hal_set_tx_clock(&handle->controller->hal, &clk_info, clk_cfg->clk_src); } else { diff --git a/components/driver/i2s/i2s_tdm.c b/components/driver/i2s/i2s_tdm.c index b4353f8c83..caed5c51a4 100644 --- a/components/driver/i2s/i2s_tdm.c +++ b/components/driver/i2s/i2s_tdm.c @@ -79,8 +79,7 @@ static esp_err_t i2s_tdm_set_clock(i2s_chan_handle_t handle, const i2s_tdm_clk_c portENTER_CRITICAL(&g_i2s.spinlock); /* Set clock configurations in HAL*/ - I2S_RCC_ATOMIC() { - I2S_RCC_ENV_DECLARE; + I2S_CLOCK_SRC_ATOMIC() { if (handle->dir == I2S_DIR_TX) { i2s_hal_set_tx_clock(&handle->controller->hal, &clk_info, clk_cfg->clk_src); } else { diff --git a/components/driver/i2s/include/driver/i2s_pdm.h b/components/driver/i2s/include/driver/i2s_pdm.h index 11601166aa..f697c2371b 100644 --- a/components/driver/i2s/include/driver/i2s_pdm.h +++ b/components/driver/i2s/include/driver/i2s_pdm.h @@ -35,8 +35,8 @@ extern "C" { .slot_mode = mono_or_stereo, \ .slot_mask = (mono_or_stereo == I2S_SLOT_MODE_MONO) ? \ I2S_PDM_SLOT_LEFT : I2S_PDM_SLOT_BOTH, \ - .hpf_en = true, \ - .hpf_cut_off_freq_hz = 35.5, \ + .hp_en = true, \ + .hp_cut_off_freq_hz = 35.5, \ .amplify_num = 1, \ } #else @@ -81,7 +81,10 @@ typedef struct { #if SOC_I2S_SUPPORTS_PDM_RX_HP_FILTER bool hp_en; /*!< High pass filter enable */ float hp_cut_off_freq_hz; /*!< High pass filter cut-off frequency, range 23.3Hz ~ 185Hz, see cut-off frequency sheet above */ - uint32_t amplify_num; /*!< The amplification number of the final conversion result, range 1~15, default 1 */ + uint32_t amplify_num; /*!< The amplification number of the final conversion result. + * The data that have converted from PDM to PCM module, will time 'amplify_num' additionally to amplify the final result. + * Note that it's only a multiplier of the digital PCM data, not the gain of the analog signal + * range 1~15, default 1 */ #endif // SOC_I2S_SUPPORTS_PDM_RX_HP_FILTER } i2s_pdm_rx_slot_config_t; @@ -331,8 +334,8 @@ typedef struct { i2s_pdm_sig_scale_t sinc_scale; /*!< Sinc filter scaling value */ #if SOC_I2S_HW_VERSION_2 i2s_pdm_tx_line_mode_t line_mode; /*!< PDM TX line mode, one-line codec, one-line dac, two-line dac mode can be selected */ - bool hpf_en; /*!< High pass filter enable */ - float hpf_cut_off_freq_hz; /*!< High pass filter cut-off frequency, range 23.3Hz ~ 185Hz, see cut-off frequency sheet above */ + bool hp_en; /*!< High pass filter enable */ + float hp_cut_off_freq_hz; /*!< High pass filter cut-off frequency, range 23.3Hz ~ 185Hz, see cut-off frequency sheet above */ uint32_t sd_dither; /*!< Sigma-delta filter dither */ uint32_t sd_dither2; /*!< Sigma-delta filter dither2 */ #endif // SOC_I2S_HW_VERSION_2 diff --git a/components/esp_hw_support/include/clk_ctrl_os.h b/components/esp_hw_support/include/clk_ctrl_os.h index 519fddee40..99366497fe 100644 --- a/components/esp_hw_support/include/clk_ctrl_os.h +++ b/components/esp_hw_support/include/clk_ctrl_os.h @@ -54,7 +54,7 @@ void periph_rtc_apll_release(void); * @brief Calculate and set APLL coefficients by given frequency * @note Have to call 'periph_rtc_apll_acquire' to enable APLL power before setting frequency * @note This calculation is based on the inequality: - * xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) >= SOC_APLL_MULTIPLIER_OUT_MIN_HZ(350 MHz) + * xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) >= CLK_LL_APLL_MULTIPLIER_MIN_HZ(350 MHz) * It will always calculate the minimum coefficients that can satisfy the inequality above, instead of loop them one by one. * which means more appropriate coefficients are likely to exist. * But this algorithm can meet almost all the cases and the accuracy can be guaranteed as well. diff --git a/components/esp_hw_support/port/esp32/rtc_clk.c b/components/esp_hw_support/port/esp32/rtc_clk.c index 384964e3d3..1856425f2e 100644 --- a/components/esp_hw_support/port/esp32/rtc_clk.c +++ b/components/esp_hw_support/port/esp32/rtc_clk.c @@ -217,7 +217,7 @@ uint32_t rtc_clk_apll_coeff_calc(uint32_t freq, uint32_t *_o_div, uint32_t *_sdm * i.e. xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) >= 350 MHz, '+1' in the following code is to get the ceil value. * With this condition, as we know the 'o_div' can't be greater than 31, then we can calculate the APLL minimum support frequency is * 350 MHz / ((31 + 2) * 2) = 5303031 Hz (for ceil) */ - o_div = (int)(SOC_APLL_MULTIPLIER_OUT_MIN_HZ / (float)(freq * 2) + 1) - 2; + o_div = (int)(CLK_LL_APLL_MULTIPLIER_MIN_HZ / (float)(freq * 2) + 1) - 2; if (o_div > 31) { ESP_HW_LOGE(TAG, "Expected frequency is too small"); return 0; @@ -227,7 +227,7 @@ uint32_t rtc_clk_apll_coeff_calc(uint32_t freq, uint32_t *_o_div, uint32_t *_sdm * i.e. xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) <= 500 MHz, we need to get the floor value in the following code. * With this condition, as we know the 'o_div' can't be smaller than 0, then we can calculate the APLL maximum support frequency is * 500 MHz / ((0 + 2) * 2) = 125000000 Hz */ - o_div = (int)(SOC_APLL_MULTIPLIER_OUT_MAX_HZ / (float)(freq * 2)) - 2; + o_div = (int)(CLK_LL_APLL_MULTIPLIER_MAX_HZ / (float)(freq * 2)) - 2; if (o_div < 0) { ESP_HW_LOGE(TAG, "Expected frequency is too big"); return 0; diff --git a/components/esp_hw_support/port/esp32s2/rtc_clk.c b/components/esp_hw_support/port/esp32s2/rtc_clk.c index 8c77c4cd88..75558b8f50 100644 --- a/components/esp_hw_support/port/esp32s2/rtc_clk.c +++ b/components/esp_hw_support/port/esp32s2/rtc_clk.c @@ -119,7 +119,7 @@ uint32_t rtc_clk_apll_coeff_calc(uint32_t freq, uint32_t *_o_div, uint32_t *_sdm * i.e. xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) >= 350 MHz, '+1' in the following code is to get the ceil value. * With this condition, as we know the 'o_div' can't be greater than 31, then we can calculate the APLL minimum support frequency is * 350 MHz / ((31 + 2) * 2) = 5303031 Hz (for ceil) */ - o_div = (int)(SOC_APLL_MULTIPLIER_OUT_MIN_HZ / (float)(freq * 2) + 1) - 2; + o_div = (int)(CLK_LL_APLL_MULTIPLIER_MIN_HZ / (float)(freq * 2) + 1) - 2; if (o_div > 31) { ESP_HW_LOGE(TAG, "Expected frequency is too small"); return 0; @@ -129,7 +129,7 @@ uint32_t rtc_clk_apll_coeff_calc(uint32_t freq, uint32_t *_o_div, uint32_t *_sdm * i.e. xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) <= 500 MHz, we need to get the floor value in the following code. * With this condition, as we know the 'o_div' can't be smaller than 0, then we can calculate the APLL maximum support frequency is * 500 MHz / ((0 + 2) * 2) = 125000000 Hz */ - o_div = (int)(SOC_APLL_MULTIPLIER_OUT_MAX_HZ / (float)(freq * 2)) - 2; + o_div = (int)(CLK_LL_APLL_MULTIPLIER_MAX_HZ / (float)(freq * 2)) - 2; if (o_div < 0) { ESP_HW_LOGE(TAG, "Expected frequency is too big"); return 0; diff --git a/components/hal/esp32/include/hal/clk_tree_ll.h b/components/hal/esp32/include/hal/clk_tree_ll.h index 79ea9fc003..67ae94a51a 100644 --- a/components/hal/esp32/include/hal/clk_tree_ll.h +++ b/components/hal/esp32/include/hal/clk_tree_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -73,6 +73,15 @@ extern "C" { #define CLK_LL_XTAL_32K_BOOTSTRAP_DRES_VAL 3 #define CLK_LL_XTAL_32K_BOOTSTRAP_DBIAS_VAL 0 +/* APLL multiplier output frequency range */ +// apll_multiplier_out = xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) +#define CLK_LL_APLL_MULTIPLIER_MIN_HZ (350000000) // 350 MHz +#define CLK_LL_APLL_MULTIPLIER_MAX_HZ (500000000) // 500 MHz + +/* APLL output frequency range */ +#define CLK_LL_APLL_MIN_HZ (5303031) // 5.303031 MHz, refer to 'periph_rtc_apll_freq_set' for the calculation +#define CLK_LL_APLL_MAX_HZ (125000000) // 125MHz, refer to 'periph_rtc_apll_freq_set' for the calculation + /** * @brief XTAL32K_CLK enable modes */ diff --git a/components/hal/esp32/include/hal/i2s_ll.h b/components/hal/esp32/include/hal/i2s_ll.h index d718d17a34..a6a7a1b15f 100644 --- a/components/hal/esp32/include/hal/i2s_ll.h +++ b/components/hal/esp32/include/hal/i2s_ll.h @@ -84,52 +84,73 @@ static inline void i2s_ll_dma_enable_eof_on_fifo_empty(i2s_dev_t *hw, bool en) hw->lc_conf.out_eof_mode = en; } +/** + * @brief Enable the bus clock for I2S module + * + * @param i2s_id The port id of I2S + * @param enable Set true to enable the buf clock + */ +static inline void i2s_ll_enable_bus_clock(int i2s_id, bool enable) +{ + if (enable) { + if (i2s_id == 0) { + DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN); + } else { + DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S1_CLK_EN); + } + } else if (i2s_id == 1) { + if (i2s_id == 0) { + DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN); + } else { + DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S1_CLK_EN); + } + } +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance +#define i2s_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_enable_bus_clock(__VA_ARGS__) + + +/** + * @brief Reset the I2S module + * + * @param i2s_id The port id of I2S + */ +static inline void i2s_ll_reset_register(int i2s_id) +{ + if (i2s_id == 0) { + DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST); + DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST); + } else if (i2s_id == 1) { + DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S1_RST); + DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S1_RST); + } +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance +#define i2s_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_reset_register(__VA_ARGS__) + /** * @brief I2S module general init, enable I2S clock. * * @param hw Peripheral I2S hardware instance address. + * @param enable set true to enable the core clock */ -static inline void i2s_ll_enable_clock(i2s_dev_t *hw) +static inline void i2s_ll_enable_core_clock(i2s_dev_t *hw, bool enable) { - if (hw == &I2S0) { - DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN); - DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST); - } else { - DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S1_CLK_EN); - DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S1_RST); - } - if (hw->clkm_conf.clk_en == 0) { + if (enable && !hw->clkm_conf.clk_en) { hw->clkm_conf.clk_en = 1; hw->conf2.val = 0; - } -} - -/// use a macro to wrap the function, force the caller to use it in a critical section -/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance -#define i2s_ll_enable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_enable_clock(__VA_ARGS__) - -/** - * @brief I2S module disable clock. - * - * @param hw Peripheral I2S hardware instance address. - */ -static inline void i2s_ll_disable_clock(i2s_dev_t *hw) -{ - if (hw->clkm_conf.clk_en == 1) { + } else if (!enable && hw->clkm_conf.clk_en) { hw->clkm_conf.clk_en = 0; } - if (hw == &I2S0) { - DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN); - DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST); - } else { - DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S1_CLK_EN); - DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S1_RST); - } } /// use a macro to wrap the function, force the caller to use it in a critical section /// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance -#define i2s_ll_disable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_disable_clock(__VA_ARGS__) +#define i2s_ll_enable_core_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_enable_core_clock(__VA_ARGS__) /** * @brief I2S tx msb right enable diff --git a/components/hal/esp32c3/include/hal/i2s_ll.h b/components/hal/esp32c3/include/hal/i2s_ll.h index e79f5ec9c5..1b7e9de0da 100644 --- a/components/hal/esp32c3/include/hal/i2s_ll.h +++ b/components/hal/esp32c3/include/hal/i2s_ll.h @@ -37,37 +37,54 @@ extern "C" { #define I2S_LL_PLL_F160M_CLK_FREQ (160 * 1000000) // PLL_F160M_CLK: 160MHz #define I2S_LL_DEFAULT_CLK_FREQ I2S_LL_PLL_F160M_CLK_FREQ // The default PLL clock frequency while using I2S_CLK_SRC_DEFAULT + +/** + * @brief Enable the bus clock for I2S module + * + * @param i2s_id The port id of I2S + * @param enable Set true to enable the buf clock + */ +static inline void i2s_ll_enable_bus_clock(int i2s_id, bool enable) +{ + (void)i2s_id; + SYSTEM.perip_clk_en0.reg_i2s1_clk_en = enable; +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance +#define i2s_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_enable_bus_clock(__VA_ARGS__) + + +/** + * @brief Reset the I2S module + * + * @param i2s_id The port id of I2S + */ +static inline void i2s_ll_reset_register(int i2s_id) +{ + (void)i2s_id; + SYSTEM.perip_rst_en0.reg_i2s1_rst = 1; + SYSTEM.perip_rst_en0.reg_i2s1_rst = 0; +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance +#define i2s_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_reset_register(__VA_ARGS__) + /** * @brief I2S module general init, enable I2S clock. * * @param hw Peripheral I2S hardware instance address. + * @param enable set true to enable the core clock */ -static inline void i2s_ll_enable_clock(i2s_dev_t *hw) +static inline void i2s_ll_enable_core_clock(i2s_dev_t *hw, bool enable) { - SYSTEM.perip_clk_en0.reg_i2s1_clk_en = 1; - SYSTEM.perip_rst_en0.reg_i2s1_rst = 0; - hw->tx_clkm_conf.clk_en = 1; + hw->tx_clkm_conf.clk_en = enable; } /// use a macro to wrap the function, force the caller to use it in a critical section /// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance -#define i2s_ll_enable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_enable_clock(__VA_ARGS__) - -/** - * @brief I2S module disable I2S clock. - * - * @param hw Peripheral I2S hardware instance address. - */ -static inline void i2s_ll_disable_clock(i2s_dev_t *hw) -{ - hw->tx_clkm_conf.clk_en = 0; - SYSTEM.perip_clk_en0.reg_i2s1_clk_en = 0; - SYSTEM.perip_rst_en0.reg_i2s1_rst = 1; -} - -/// use a macro to wrap the function, force the caller to use it in a critical section -/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance -#define i2s_ll_disable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_disable_clock(__VA_ARGS__) +#define i2s_ll_enable_core_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_enable_core_clock(__VA_ARGS__) /** * @brief Enable I2S tx module clock @@ -99,11 +116,6 @@ static inline void i2s_ll_tx_disable_clock(i2s_dev_t *hw) hw->tx_clkm_conf.tx_clk_active = 0; } -/// use a macro to wrap the function, force the caller to use it in a critical section -/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance -// i2s_ll_tx_disable_clock don't need RCC ENV actually, but still defined here for compatiblity -#define i2s_ll_tx_disable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_tx_disable_clock(__VA_ARGS__) - /** * @brief Disable I2S rx module clock * @@ -114,11 +126,6 @@ static inline void i2s_ll_rx_disable_clock(i2s_dev_t *hw) hw->rx_clkm_conf.rx_clk_active = 0; } -/// use a macro to wrap the function, force the caller to use it in a critical section -/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance -// i2s_ll_rx_disable_clock don't need RCC ENV actually, but still defined here for compatiblity -#define i2s_ll_rx_disable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_rx_disable_clock(__VA_ARGS__) - /** * @brief I2S mclk use tx module clock * diff --git a/components/hal/esp32c6/include/hal/i2s_ll.h b/components/hal/esp32c6/include/hal/i2s_ll.h index 86c5788fbf..52c15d43f0 100644 --- a/components/hal/esp32c6/include/hal/i2s_ll.h +++ b/components/hal/esp32c6/include/hal/i2s_ll.h @@ -38,25 +38,39 @@ extern "C" { #define I2S_LL_DEFAULT_CLK_FREQ I2S_LL_PLL_F160M_CLK_FREQ // The default PLL clock frequency while using I2S_CLK_SRC_DEFAULT /** - * @brief I2S module general init, enable I2S clock. * - * @param hw Peripheral I2S hardware instance address. + * @param i2s_id The port id of I2S + * @param enable Set true to enable the buf clock */ -static inline void i2s_ll_enable_clock(i2s_dev_t *hw) +static inline void i2s_ll_enable_bus_clock(int i2s_id, bool enable) { - PCR.i2s_conf.i2s_clk_en = 1; + (void)i2s_id; + PCR.i2s_conf.i2s_clk_en = enable; +} + +/** + * @brief Reset the I2S module + * + * @param i2s_id The port id of I2S + */ +static inline void i2s_ll_reset_register(int i2s_id) +{ + (void)i2s_id; + PCR.i2s_conf.i2s_rst_en = 1; PCR.i2s_conf.i2s_rst_en = 0; } /** - * @brief I2S module disable I2S clock. + * @brief I2S module general init, enable I2S clock. * * @param hw Peripheral I2S hardware instance address. + * @param enable set true to enable the core clock */ -static inline void i2s_ll_disable_clock(i2s_dev_t *hw) +static inline void i2s_ll_enable_core_clock(i2s_dev_t *hw, bool enable) { - PCR.i2s_conf.i2s_clk_en = 0; - PCR.i2s_conf.i2s_rst_en = 1; + (void)hw; + (void)enable; + // No need to do anything } /** diff --git a/components/hal/esp32h2/include/hal/i2s_ll.h b/components/hal/esp32h2/include/hal/i2s_ll.h index 9f9e648ce8..0baf7101e5 100644 --- a/components/hal/esp32h2/include/hal/i2s_ll.h +++ b/components/hal/esp32h2/include/hal/i2s_ll.h @@ -39,25 +39,39 @@ extern "C" { #define I2S_LL_DEFAULT_CLK_FREQ I2S_LL_PLL_F96M_CLK_FREQ // The default PLL clock frequency while using I2S_CLK_SRC_DEFAULT /** - * @brief I2S module general init, enable I2S clock. * - * @param hw Peripheral I2S hardware instance address. + * @param i2s_id The port id of I2S + * @param enable Set true to enable the buf clock */ -static inline void i2s_ll_enable_clock(i2s_dev_t *hw) +static inline void i2s_ll_enable_bus_clock(int i2s_id, bool enable) { - PCR.i2s_conf.i2s_clk_en = 1; + (void)i2s_id; + PCR.i2s_conf.i2s_clk_en = enable; +} + +/** + * @brief Reset the I2S module + * + * @param i2s_id The port id of I2S + */ +static inline void i2s_ll_reset_register(int i2s_id) +{ + (void)i2s_id; + PCR.i2s_conf.i2s_rst_en = 1; PCR.i2s_conf.i2s_rst_en = 0; } /** - * @brief I2S module disable I2S clock. + * @brief I2S module general init, enable I2S clock. * * @param hw Peripheral I2S hardware instance address. + * @param enable set true to enable the core clock */ -static inline void i2s_ll_disable_clock(i2s_dev_t *hw) +static inline void i2s_ll_enable_core_clock(i2s_dev_t *hw, bool enable) { - PCR.i2s_conf.i2s_clk_en = 0; - PCR.i2s_conf.i2s_rst_en = 1; + (void)hw; + (void)enable; + // No need to do anything } /** diff --git a/components/hal/esp32p4/include/hal/clk_tree_ll.h b/components/hal/esp32p4/include/hal/clk_tree_ll.h index c3fee0041a..29a38bdfc5 100644 --- a/components/hal/esp32p4/include/hal/clk_tree_ll.h +++ b/components/hal/esp32p4/include/hal/clk_tree_ll.h @@ -30,6 +30,16 @@ extern "C" { #define CLK_LL_PLL_480M_FREQ_MHZ (480) +/* APLL multiplier output frequency range */ +// TODO: IDF-7526 check if the APLL frequency range is same as before +// apll_multiplier_out = xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) +#define CLK_LL_APLL_MULTIPLIER_MIN_HZ (350000000) // 350 MHz +#define CLK_LL_APLL_MULTIPLIER_MAX_HZ (500000000) // 500 MHz + +/* APLL output frequency range */ +#define CLK_LL_APLL_MIN_HZ (5303031) // 5.303031 MHz, refer to 'periph_rtc_apll_freq_set' for the calculation +#define CLK_LL_APLL_MAX_HZ (125000000) // 125MHz, refer to 'periph_rtc_apll_freq_set' for the calculation + #define CLK_LL_XTAL32K_CONFIG_DEFAULT() { \ .dac = 3, \ .dres = 3, \ diff --git a/components/hal/esp32p4/include/hal/i2s_ll.h b/components/hal/esp32p4/include/hal/i2s_ll.h index 3d7027ede3..0fd64cad6f 100644 --- a/components/hal/esp32p4/include/hal/i2s_ll.h +++ b/components/hal/esp32p4/include/hal/i2s_ll.h @@ -47,67 +47,74 @@ typedef struct { uint16_t numer; // Numerator part of I2S module clock divider } i2s_ll_mclk_div_t; +/** + * @brief Enable the bus clock for I2S module + * + * @param i2s_id The port id of I2S + * @param enable Set true to enable the buf clock + */ +static inline void i2s_ll_enable_bus_clock(int i2s_id, bool enable) +{ + switch (i2s_id) { + case 0: + HP_SYS_CLKRST.soc_clk_ctrl2.reg_i2s0_apb_clk_en = enable; + return; + case 1: + HP_SYS_CLKRST.soc_clk_ctrl2.reg_i2s1_apb_clk_en = enable; + return; + case 2: + HP_SYS_CLKRST.soc_clk_ctrl2.reg_i2s2_apb_clk_en = enable; + return; + } +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance +#define i2s_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset the I2S module + * + * @param i2s_id The port id of I2S + */ +static inline void i2s_ll_reset_register(int i2s_id) +{ + switch (i2s_id) { + case 0: + HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_i2s0_apb = 1; + HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_i2s0_apb = 0; + return; + case 1: + HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_i2s1_apb = 1; + HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_i2s1_apb = 0; + return; + case 2: + HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_i2s2_apb = 1; + HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_i2s2_apb = 0; + return; + } +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance +#define i2s_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_reset_register(__VA_ARGS__) + /** * @brief I2S module general init, enable I2S clock. * * @param hw Peripheral I2S hardware instance address. + * @param enable set true to enable the core clock */ -static inline void i2s_ll_enable_clock(i2s_dev_t *hw) +static inline void i2s_ll_enable_core_clock(i2s_dev_t *hw, bool enable) { - // Note: this function involves HP_SYS_CLKRST register which is shared with other peripherals, need lock in upper layer - switch (I2S_LL_GET_ID(hw)) { - case 0: - HP_SYS_CLKRST.soc_clk_ctrl2.reg_i2s0_apb_clk_en = 1; - HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_i2s0_apb = 0; - break; - case 1: - HP_SYS_CLKRST.soc_clk_ctrl2.reg_i2s1_apb_clk_en = 1; - HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_i2s1_apb = 0; - break; - case 2: - HP_SYS_CLKRST.soc_clk_ctrl2.reg_i2s2_apb_clk_en = 1; - HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_i2s2_apb = 0; - break; - default: - // Never reach - HAL_ASSERT(false); - } + (void)hw; + (void)enable; + // No need to do anything } /// use a macro to wrap the function, force the caller to use it in a critical section /// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance -#define i2s_ll_enable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_enable_clock(__VA_ARGS__) - -/** - * @brief I2S module disable I2S clock. - * - * @param hw Peripheral I2S hardware instance address. - */ -static inline void i2s_ll_disable_clock(i2s_dev_t *hw) -{ - // Note: this function involves HP_SYS_CLKRST register which is shared with other peripherals, need lock in upper layer - switch (I2S_LL_GET_ID(hw)) { - case 0: - HP_SYS_CLKRST.soc_clk_ctrl2.reg_i2s0_apb_clk_en = 0; - HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_i2s0_apb = 1; - break; - case 1: - HP_SYS_CLKRST.soc_clk_ctrl2.reg_i2s1_apb_clk_en = 0; - HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_i2s1_apb = 1; - break; - case 2: - HP_SYS_CLKRST.soc_clk_ctrl2.reg_i2s2_apb_clk_en = 0; - HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_i2s2_apb = 1; - break; - default: - // Never reach - HAL_ASSERT(false); - } -} - -/// use a macro to wrap the function, force the caller to use it in a critical section -/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance -#define i2s_ll_disable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_disable_clock(__VA_ARGS__) +#define i2s_ll_enable_core_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_enable_core_clock(__VA_ARGS__) /** * @brief Enable I2S tx module clock diff --git a/components/hal/esp32s2/include/hal/clk_tree_ll.h b/components/hal/esp32s2/include/hal/clk_tree_ll.h index f7d67937ee..b0505b1ce2 100644 --- a/components/hal/esp32s2/include/hal/clk_tree_ll.h +++ b/components/hal/esp32s2/include/hal/clk_tree_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -47,6 +47,15 @@ extern "C" { #define CLK_LL_APLL_CAL_DELAY_2 0x3f #define CLK_LL_APLL_CAL_DELAY_3 0x1f +/* APLL multiplier output frequency range */ +// apll_multiplier_out = xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) +#define CLK_LL_APLL_MULTIPLIER_MIN_HZ (350000000) // 350 MHz +#define CLK_LL_APLL_MULTIPLIER_MAX_HZ (500000000) // 500 MHz + +/* APLL output frequency range */ +#define CLK_LL_APLL_MIN_HZ (5303031) // 5.303031 MHz, refer to 'periph_rtc_apll_freq_set' for the calculation +#define CLK_LL_APLL_MAX_HZ (125000000) // 125MHz, refer to 'periph_rtc_apll_freq_set' for the calculation + #define CLK_LL_XTAL32K_CONFIG_DEFAULT() { \ .dac = 3, \ .dres = 3, \ diff --git a/components/hal/esp32s2/include/hal/i2s_ll.h b/components/hal/esp32s2/include/hal/i2s_ll.h index f8791f1d19..2c97bf157a 100644 --- a/components/hal/esp32s2/include/hal/i2s_ll.h +++ b/components/hal/esp32s2/include/hal/i2s_ll.h @@ -82,53 +82,73 @@ static inline void i2s_ll_dma_enable_eof_on_fifo_empty(i2s_dev_t *hw, bool en) hw->lc_conf.out_eof_mode = en; } +/** + * @brief Enable the bus clock for I2S module + * + * @param i2s_id The port id of I2S + * @param enable Set true to enable the buf clock + */ +static inline void i2s_ll_enable_bus_clock(int i2s_id, bool enable) +{ + if (enable) { + if (i2s_id == 0) { + DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN); + } else { + DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S1_CLK_EN); + } + } else { + if (i2s_id == 0) { + DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN); + } else { + DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S1_CLK_EN); + } + } +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance +#define i2s_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset the I2S module + * + * @param i2s_id The port id of I2S + */ +static inline void i2s_ll_reset_register(int i2s_id) +{ + if (i2s_id == 0) { + DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST); + DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST); + } else { + DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S1_RST); + DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S1_RST); + } +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance +#define i2s_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_reset_register(__VA_ARGS__) + /** * @brief I2S module general init, enable I2S clock. * * @param hw Peripheral I2S hardware instance address. + * @param enable set true to enable the core clock */ -static inline void i2s_ll_enable_clock(i2s_dev_t *hw) +static inline void i2s_ll_enable_core_clock(i2s_dev_t *hw, bool enable) { - if (hw == &I2S0) { - DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN); - DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST); - } else { - DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S1_CLK_EN); - DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S1_RST); - } - if (hw->clkm_conf.clk_en == 0) { + if (enable && !hw->clkm_conf.clk_en) { hw->clkm_conf.clk_sel = 2; hw->clkm_conf.clk_en = 1; hw->conf2.val = 0; - } -} - -/// use a macro to wrap the function, force the caller to use it in a critical section -/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance -#define i2s_ll_enable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_enable_clock(__VA_ARGS__) - -/** - * @brief I2S module disable clock. - * - * @param hw Peripheral I2S hardware instance address. - */ -static inline void i2s_ll_disable_clock(i2s_dev_t *hw) -{ - if (hw->clkm_conf.clk_en == 1) { + } else if (!enable && hw->clkm_conf.clk_en) { hw->clkm_conf.clk_en = 0; } - if (hw == &I2S0) { - DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN); - DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST); - } else { - DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S1_CLK_EN); - DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S1_RST); - } } /// use a macro to wrap the function, force the caller to use it in a critical section /// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance -#define i2s_ll_disable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_disable_clock(__VA_ARGS__) +#define i2s_ll_enable_core_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_enable_core_clock(__VA_ARGS__) /** * @brief I2S tx msb right enable diff --git a/components/hal/esp32s3/include/hal/i2s_ll.h b/components/hal/esp32s3/include/hal/i2s_ll.h index ac4d99f859..89b53f8c24 100644 --- a/components/hal/esp32s3/include/hal/i2s_ll.h +++ b/components/hal/esp32s3/include/hal/i2s_ll.h @@ -38,47 +38,60 @@ extern "C" { #define I2S_LL_PLL_F160M_CLK_FREQ (160 * 1000000) // PLL_F160M_CLK: 160MHz #define I2S_LL_DEFAULT_CLK_FREQ I2S_LL_PLL_F160M_CLK_FREQ // The default PLL clock frequency while using I2S_CLK_SRC_DEFAULT + +/** + * @brief Enable the bus clock for I2S module + * + * @param i2s_id The port id of I2S + * @param enable Set true to enable the buf clock + */ +static inline void i2s_ll_enable_bus_clock(int i2s_id, bool enable) +{ + if (i2s_id == 0) { + SYSTEM.perip_clk_en0.i2s0_clk_en = enable; + } else if (i2s_id == 1) { + SYSTEM.perip_clk_en0.i2s1_clk_en = enable; + } +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance +#define i2s_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset the I2S module + * + * @param i2s_id The port id of I2S + */ +static inline void i2s_ll_reset_register(int i2s_id) +{ + if (i2s_id == 0) { + SYSTEM.perip_rst_en0.i2s0_rst = 1; + SYSTEM.perip_rst_en0.i2s0_rst = 0; + } else if (i2s_id == 1) { + SYSTEM.perip_rst_en0.i2s1_rst = 1; + SYSTEM.perip_rst_en0.i2s1_rst = 0; + } +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance +#define i2s_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_reset_register(__VA_ARGS__) + /** * @brief I2S module general init, enable I2S clock. * * @param hw Peripheral I2S hardware instance address. + * @param enable set true to enable the core clock */ -static inline void i2s_ll_enable_clock(i2s_dev_t *hw) +static inline void i2s_ll_enable_core_clock(i2s_dev_t *hw, bool enable) { - if (hw == &I2S0) { - SYSTEM.perip_clk_en0.i2s0_clk_en = 1; - SYSTEM.perip_rst_en0.i2s0_rst = 0; - } else { - SYSTEM.perip_clk_en0.i2s1_clk_en = 1; - SYSTEM.perip_rst_en0.i2s1_rst = 0; - } - hw->tx_clkm_conf.clk_en = 1; + hw->tx_clkm_conf.clk_en = enable; } /// use a macro to wrap the function, force the caller to use it in a critical section /// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance -#define i2s_ll_enable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_enable_clock(__VA_ARGS__) - -/** - * @brief I2S module disable I2S clock. - * - * @param hw Peripheral I2S hardware instance address. - */ -static inline void i2s_ll_disable_clock(i2s_dev_t *hw) -{ - hw->tx_clkm_conf.clk_en = 0; - if (hw == &I2S0) { - SYSTEM.perip_clk_en0.i2s0_clk_en = 0; - SYSTEM.perip_rst_en0.i2s0_rst = 1; - } else { - SYSTEM.perip_clk_en0.i2s1_clk_en = 0; - SYSTEM.perip_rst_en0.i2s1_rst = 1; - } -} - -/// use a macro to wrap the function, force the caller to use it in a critical section -/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance -#define i2s_ll_disable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_disable_clock(__VA_ARGS__) +#define i2s_ll_enable_core_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_enable_core_clock(__VA_ARGS__) /** * @brief Enable I2S tx module clock @@ -110,11 +123,6 @@ static inline void i2s_ll_tx_disable_clock(i2s_dev_t *hw) hw->tx_clkm_conf.tx_clk_active = 0; } -/// use a macro to wrap the function, force the caller to use it in a critical section -/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance -// i2s_ll_tx_disable_clock don't need RCC ENV actually, but still defined here for compatiblity -#define i2s_ll_tx_disable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_tx_disable_clock(__VA_ARGS__) - /** * @brief Disable I2S rx module clock * @@ -125,11 +133,6 @@ static inline void i2s_ll_rx_disable_clock(i2s_dev_t *hw) hw->rx_clkm_conf.rx_clk_active = 0; } -/// use a macro to wrap the function, force the caller to use it in a critical section -/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance -// i2s_ll_rx_disable_clock don't need RCC ENV actually, but still defined here for compatiblity -#define i2s_ll_rx_disable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; i2s_ll_rx_disable_clock(__VA_ARGS__) - /** * @brief I2S mclk use tx module clock * diff --git a/components/hal/i2s_hal.c b/components/hal/i2s_hal.c index 15653cce84..5ea3de62d6 100644 --- a/components/hal/i2s_hal.c +++ b/components/hal/i2s_hal.c @@ -65,30 +65,38 @@ void i2s_hal_init(i2s_hal_context_t *hal, int port_id) hal->dev = I2S_LL_GET_HW(port_id); } -void i2s_hal_set_tx_clock(i2s_hal_context_t *hal, const i2s_hal_clock_info_t *clk_info, i2s_clock_src_t clk_src) +void _i2s_hal_set_tx_clock(i2s_hal_context_t *hal, const i2s_hal_clock_info_t *clk_info, i2s_clock_src_t clk_src) { - hal_utils_clk_div_t mclk_div = {}; + if (clk_info) { + hal_utils_clk_div_t mclk_div = {}; #if SOC_I2S_HW_VERSION_2 - i2s_ll_tx_enable_clock(hal->dev); - i2s_ll_mclk_bind_to_tx_clk(hal->dev); + i2s_ll_tx_enable_clock(hal->dev); + i2s_ll_mclk_bind_to_tx_clk(hal->dev); #endif - i2s_ll_tx_clk_set_src(hal->dev, clk_src); - i2s_hal_calc_mclk_precise_division(clk_info->sclk, clk_info->mclk, &mclk_div); - i2s_ll_tx_set_mclk(hal->dev, &mclk_div); - i2s_ll_tx_set_bck_div_num(hal->dev, clk_info->bclk_div); + i2s_ll_tx_clk_set_src(hal->dev, clk_src); + i2s_hal_calc_mclk_precise_division(clk_info->sclk, clk_info->mclk, &mclk_div); + i2s_ll_tx_set_mclk(hal->dev, &mclk_div); + i2s_ll_tx_set_bck_div_num(hal->dev, clk_info->bclk_div); + } else { + i2s_ll_tx_clk_set_src(hal->dev, clk_src); + } } -void i2s_hal_set_rx_clock(i2s_hal_context_t *hal, const i2s_hal_clock_info_t *clk_info, i2s_clock_src_t clk_src) +void _i2s_hal_set_rx_clock(i2s_hal_context_t *hal, const i2s_hal_clock_info_t *clk_info, i2s_clock_src_t clk_src) { - hal_utils_clk_div_t mclk_div = {}; + if (clk_info) { + hal_utils_clk_div_t mclk_div = {}; #if SOC_I2S_HW_VERSION_2 - i2s_ll_rx_enable_clock(hal->dev); - i2s_ll_mclk_bind_to_rx_clk(hal->dev); + i2s_ll_rx_enable_clock(hal->dev); + i2s_ll_mclk_bind_to_rx_clk(hal->dev); #endif - i2s_ll_rx_clk_set_src(hal->dev, clk_src); - i2s_hal_calc_mclk_precise_division(clk_info->sclk, clk_info->mclk, &mclk_div); - i2s_ll_rx_set_mclk(hal->dev, &mclk_div); - i2s_ll_rx_set_bck_div_num(hal->dev, clk_info->bclk_div); + i2s_ll_rx_clk_set_src(hal->dev, clk_src); + i2s_hal_calc_mclk_precise_division(clk_info->sclk, clk_info->mclk, &mclk_div); + i2s_ll_rx_set_mclk(hal->dev, &mclk_div); + i2s_ll_rx_set_bck_div_num(hal->dev, clk_info->bclk_div); + } else { + i2s_ll_rx_clk_set_src(hal->dev, clk_src); + } } /*------------------------------------------------------------------------- diff --git a/components/hal/include/hal/i2s_hal.h b/components/hal/include/hal/i2s_hal.h index e2957e5cc4..6e8af9bf84 100644 --- a/components/hal/include/hal/i2s_hal.h +++ b/components/hal/include/hal/i2s_hal.h @@ -142,20 +142,35 @@ void i2s_hal_calc_mclk_precise_division(uint32_t sclk, uint32_t mclk, hal_utils_ * @brief Set tx channel clock * * @param hal Context of the HAL layer - * @param clk_info clock information + * @param clk_info clock information, if it is NULL, only set the clock source * @param clk_src clock source */ -void i2s_hal_set_tx_clock(i2s_hal_context_t *hal, const i2s_hal_clock_info_t *clk_info, i2s_clock_src_t clk_src); +void _i2s_hal_set_tx_clock(i2s_hal_context_t *hal, const i2s_hal_clock_info_t *clk_info, i2s_clock_src_t clk_src); + +#if SOC_SYS_DIGI_CLKRST_REG_SHARED +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance +#define i2s_hal_set_tx_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _i2s_hal_set_tx_clock(__VA_ARGS__) +#else +#define i2s_hal_set_tx_clock(...) _i2s_hal_set_tx_clock(__VA_ARGS__) +#endif /** * @brief Set rx channel clock * * @param hal Context of the HAL layer - * @param clk_info clock information + * @param clk_info clock information, if it is NULL, only set the clock source * @param clk_src clock source */ -void i2s_hal_set_rx_clock(i2s_hal_context_t *hal, const i2s_hal_clock_info_t *clk_info, i2s_clock_src_t clk_src); +void _i2s_hal_set_rx_clock(i2s_hal_context_t *hal, const i2s_hal_clock_info_t *clk_info, i2s_clock_src_t clk_src); +#if SOC_SYS_DIGI_CLKRST_REG_SHARED +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance +#define i2s_hal_set_rx_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _i2s_hal_set_rx_clock(__VA_ARGS__) +#else +#define i2s_hal_set_rx_clock(...) _i2s_hal_set_rx_clock(__VA_ARGS__) +#endif /*------------------------------------------------------------------------- | STD configuration | diff --git a/components/soc/esp32/include/soc/Kconfig.soc_caps.in b/components/soc/esp32/include/soc/Kconfig.soc_caps.in index a3348e6022..0945f539af 100644 --- a/components/soc/esp32/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32/include/soc/Kconfig.soc_caps.in @@ -811,22 +811,6 @@ config SOC_CLK_APLL_SUPPORTED bool default y -config SOC_APLL_MULTIPLIER_OUT_MIN_HZ - int - default 350000000 - -config SOC_APLL_MULTIPLIER_OUT_MAX_HZ - int - default 500000000 - -config SOC_APLL_MIN_HZ - int - default 5303031 - -config SOC_APLL_MAX_HZ - int - default 125000000 - config SOC_CLK_RC_FAST_D256_SUPPORTED bool default y diff --git a/components/soc/esp32/include/soc/soc_caps.h b/components/soc/esp32/include/soc/soc_caps.h index ab27817b34..a3ebb1c9b5 100644 --- a/components/soc/esp32/include/soc/soc_caps.h +++ b/components/soc/esp32/include/soc/soc_caps.h @@ -1,6 +1,6 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -399,11 +399,6 @@ /*-------------------------- CLOCK SUBSYSTEM CAPS ----------------------------------------*/ #define SOC_CLK_APLL_SUPPORTED (1) -// apll_multiplier_out = xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) -#define SOC_APLL_MULTIPLIER_OUT_MIN_HZ (350000000) // 350 MHz -#define SOC_APLL_MULTIPLIER_OUT_MAX_HZ (500000000) // 500 MHz -#define SOC_APLL_MIN_HZ (5303031) // 5.303031 MHz, refer to 'periph_rtc_apll_freq_set' for the calculation -#define SOC_APLL_MAX_HZ (125000000) // 125MHz, refer to 'periph_rtc_apll_freq_set' for the calculation #define SOC_CLK_RC_FAST_D256_SUPPORTED (1) #define SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256 (1) diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index fbc3963a49..76a4587ddd 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -1123,6 +1123,10 @@ config SOC_PM_PAU_LINK_NUM int default 4 +config SOC_SYS_DIGI_CLKRST_REG_SHARED + bool + default y + config SOC_CLK_RC_FAST_SUPPORT_CALIBRATION bool default n diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index 984d1526f9..d3a1b23870 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -154,6 +154,7 @@ #define SOC_CPU_HAS_PMA 1 #define SOC_CPU_IDRAM_SPLIT_USING_PMP 1 +// TODO: IDF-5360 (Copy from esp32c3, need check) /*-------------------------- DIGITAL SIGNATURE CAPS ----------------------------------------*/ /** The maximum length of a Digital Signature in bits. */ #define SOC_DS_SIGNATURE_MAX_BIT_LEN (4096) @@ -513,6 +514,7 @@ #define SOC_PM_PAU_LINK_NUM (4) /*-------------------------- CLOCK SUBSYSTEM CAPS ----------------------------------------*/ +#define SOC_SYS_DIGI_CLKRST_REG_SHARED (1) #define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION (0) #define SOC_MODEM_CLOCK_IS_INDEPENDENT (0) diff --git a/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in index 8643908f4f..f548a06b79 100644 --- a/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in @@ -1035,22 +1035,6 @@ config SOC_CLK_APLL_SUPPORTED bool default y -config SOC_APLL_MULTIPLIER_OUT_MIN_HZ - int - default 350000000 - -config SOC_APLL_MULTIPLIER_OUT_MAX_HZ - int - default 500000000 - -config SOC_APLL_MIN_HZ - int - default 5303031 - -config SOC_APLL_MAX_HZ - int - default 125000000 - config SOC_CLK_RC_FAST_D256_SUPPORTED bool default y diff --git a/components/soc/esp32s2/include/soc/soc_caps.h b/components/soc/esp32s2/include/soc/soc_caps.h index 6a3dff526e..809fb5ffc5 100644 --- a/components/soc/esp32s2/include/soc/soc_caps.h +++ b/components/soc/esp32s2/include/soc/soc_caps.h @@ -446,11 +446,6 @@ /*-------------------------- CLOCK SUBSYSTEM CAPS ----------------------------------------*/ #define SOC_CLK_APLL_SUPPORTED (1) -// apll_multiplier_out = xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536) -#define SOC_APLL_MULTIPLIER_OUT_MIN_HZ (350000000) // 350 MHz -#define SOC_APLL_MULTIPLIER_OUT_MAX_HZ (500000000) // 500 MHz -#define SOC_APLL_MIN_HZ (5303031) // 5.303031 MHz, refer to 'periph_rtc_apll_freq_set' for the calculation -#define SOC_APLL_MAX_HZ (125000000) // 125MHz, refer to 'periph_rtc_apll_freq_set' for the calculation #define SOC_CLK_RC_FAST_D256_SUPPORTED (1) #define SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256 (1)