From 7197e987cb1e4ec1ebb245495ae017e089a7342d Mon Sep 17 00:00:00 2001 From: laokaiyao Date: Thu, 15 Sep 2022 17:27:57 +0800 Subject: [PATCH] i2s: add XTAL clock source --- components/driver/deprecated/i2s_legacy.c | 5 +-- components/driver/i2s/i2s_common.c | 21 ++++++++++- components/driver/i2s/i2s_pdm.c | 12 ++----- components/driver/i2s/i2s_private.h | 9 +++-- components/driver/i2s/i2s_std.c | 6 +--- components/driver/i2s/i2s_tdm.c | 7 +--- .../i2s_test_apps/i2s/main/test_i2s.c | 13 ++++++- components/hal/esp32/include/hal/i2s_ll.h | 1 - components/hal/esp32c3/include/hal/i2s_ll.h | 32 ++++++++++++++--- components/hal/esp32h2/include/hal/i2s_ll.h | 33 +++++++++++++---- components/hal/esp32s2/include/hal/i2s_ll.h | 2 -- components/hal/esp32s3/include/hal/i2s_ll.h | 35 ++++++++++++++----- .../esp32c3/include/soc/Kconfig.soc_caps.in | 4 +++ .../soc/esp32c3/include/soc/clk_tree_defs.h | 3 +- .../soc/esp32c3/include/soc/i2s_struct.h | 4 +-- components/soc/esp32c3/include/soc/soc_caps.h | 1 + .../esp32c6/include/soc/Kconfig.soc_caps.in | 4 +++ components/soc/esp32c6/include/soc/soc_caps.h | 1 + .../esp32h2/include/soc/Kconfig.soc_caps.in | 4 +++ .../soc/esp32h2/include/soc/clk_tree_defs.h | 3 +- .../soc/esp32h2/include/soc/i2s_struct.h | 4 +-- components/soc/esp32h2/include/soc/soc_caps.h | 1 + .../esp32s3/include/soc/Kconfig.soc_caps.in | 4 +++ .../soc/esp32s3/include/soc/clk_tree_defs.h | 3 +- .../soc/esp32s3/include/soc/i2s_struct.h | 4 +-- components/soc/esp32s3/include/soc/soc_caps.h | 1 + 26 files changed, 156 insertions(+), 61 deletions(-) diff --git a/components/driver/deprecated/i2s_legacy.c b/components/driver/deprecated/i2s_legacy.c index 2e36ab2608..dc09444210 100644 --- a/components/driver/deprecated/i2s_legacy.c +++ b/components/driver/deprecated/i2s_legacy.c @@ -47,6 +47,7 @@ #include "esp_efuse.h" #include "esp_rom_gpio.h" #include "esp_private/periph_ctrl.h" +#include "esp_private/esp_clk.h" static const char *TAG = "i2s(legacy)"; @@ -650,12 +651,12 @@ static uint32_t i2s_config_source_clock(i2s_port_t i2s_num, bool use_apll, uint3 /* In APLL mode, there is no sclk but only mclk, so return 0 here to indicate APLL mode */ return real_freq; } - return I2S_LL_BASE_CLK; + return esp_clk_apb_freq() * 2; // [clk_tree] TODO: replace the following switch table by clk_tree API #else if (use_apll) { ESP_LOGW(TAG, "APLL not supported on current chip, use I2S_CLK_SRC_DEFAULT as default clock source"); } - return I2S_LL_BASE_CLK; + return esp_clk_apb_freq() * 2; // [clk_tree] TODO: replace the following switch table by clk_tree API #endif } diff --git a/components/driver/i2s/i2s_common.c b/components/driver/i2s/i2s_common.c index 3bd24a1ec7..c7f9f2d059 100644 --- a/components/driver/i2s/i2s_common.c +++ b/components/driver/i2s/i2s_common.c @@ -35,6 +35,7 @@ #include "esp_private/i2s_platform.h" #include "esp_private/periph_ctrl.h" +#include "esp_private/esp_clk.h" #include "driver/gpio.h" #include "driver/i2s_common.h" @@ -444,7 +445,7 @@ err: } #if SOC_I2S_SUPPORTS_APLL -uint32_t i2s_set_get_apll_freq(uint32_t mclk_freq_hz) +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); @@ -473,6 +474,24 @@ uint32_t i2s_set_get_apll_freq(uint32_t mclk_freq_hz) } #endif +uint32_t i2s_get_source_clk_freq(i2s_clock_src_t clk_src, uint32_t mclk_freq_hz) +{ + switch (clk_src) + { +#if SOC_I2S_SUPPORTS_APLL + case I2S_CLK_SRC_APLL: + return i2s_set_get_apll_freq(mclk_freq_hz); +#endif +#if SOC_I2S_SUPPORTS_XTAL + case I2S_CLK_SRC_XTAL: + (void)mclk_freq_hz; + return esp_clk_xtal_freq(); +#endif + default: // I2S_CLK_SRC_PLL_160M + return esp_clk_apb_freq() * 2; // [clk_tree] TODO: replace the following switch table by clk_tree API + } +} + #if SOC_GDMA_SUPPORTED static bool IRAM_ATTR i2s_dma_rx_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data) { diff --git a/components/driver/i2s/i2s_pdm.c b/components/driver/i2s/i2s_pdm.c index cb3b2e8c36..6863453d23 100644 --- a/components/driver/i2s/i2s_pdm.c +++ b/components/driver/i2s/i2s_pdm.c @@ -38,11 +38,7 @@ static esp_err_t i2s_pdm_tx_calculate_clock(i2s_chan_handle_t handle, const i2s_ clk_info->bclk = rate * I2S_LL_PDM_BCK_FACTOR * pdm_tx_clk->up_sample_fp / pdm_tx_clk->up_sample_fs; clk_info->bclk_div = 8; clk_info->mclk = clk_info->bclk * clk_info->bclk_div; -#if SOC_I2S_SUPPORTS_APLL - clk_info->sclk = (clk_cfg->clk_src == I2S_CLK_SRC_APLL) ? i2s_set_get_apll_freq(clk_info->mclk) : I2S_LL_BASE_CLK; -#else - clk_info->sclk = I2S_LL_BASE_CLK; -#endif + clk_info->sclk = i2s_get_source_clk_freq(clk_cfg->clk_src, clk_info->mclk); clk_info->mclk_div = clk_info->sclk / clk_info->mclk; /* Check if the configuration is correct */ @@ -326,11 +322,7 @@ static esp_err_t i2s_pdm_rx_calculate_clock(i2s_chan_handle_t handle, const i2s_ clk_info->bclk = rate * I2S_LL_PDM_BCK_FACTOR * (pdm_rx_clk->dn_sample_mode == I2S_PDM_DSR_16S ? 2 : 1); clk_info->bclk_div = 8; clk_info->mclk = clk_info->bclk * clk_info->bclk_div; -#if SOC_I2S_SUPPORTS_APLL - clk_info->sclk = (clk_cfg->clk_src == I2S_CLK_SRC_APLL) ? i2s_set_get_apll_freq(clk_info->mclk) : I2S_LL_BASE_CLK; -#else - clk_info->sclk = I2S_LL_BASE_CLK; -#endif + clk_info->sclk = i2s_get_source_clk_freq(clk_cfg->clk_src, clk_info->mclk); clk_info->mclk_div = clk_info->sclk / clk_info->mclk; /* Check if the configuration is correct */ diff --git a/components/driver/i2s/i2s_private.h b/components/driver/i2s/i2s_private.h index e58b55e24f..5c2369cdf0 100644 --- a/components/driver/i2s/i2s_private.h +++ b/components/driver/i2s/i2s_private.h @@ -161,16 +161,15 @@ esp_err_t i2s_alloc_dma_desc(i2s_chan_handle_t handle, uint32_t num, uint32_t bu */ uint32_t i2s_get_buf_size(i2s_chan_handle_t handle, uint32_t data_bit_width, uint32_t dma_frame_num); -#if SOC_I2S_SUPPORTS_APLL /** - * @brief Set mclk frequency and get the actuall APLL frequency + * @brief Get the frequency of the source clock * + * @param clk_src clock source * @param mclk_freq_hz Expected mclk frequenct in Hz * @return - * - Actuall APLL frequency + * - Actual source clock frequency */ -uint32_t i2s_set_get_apll_freq(uint32_t mclk_freq_hz); -#endif +uint32_t i2s_get_source_clk_freq(i2s_clock_src_t clk_src, uint32_t mclk_freq_hz); /** * @brief Check gpio validity and attach to corresponding signal diff --git a/components/driver/i2s/i2s_std.c b/components/driver/i2s/i2s_std.c index ba1097e908..cdfb85b51f 100644 --- a/components/driver/i2s/i2s_std.c +++ b/components/driver/i2s/i2s_std.c @@ -45,11 +45,7 @@ static esp_err_t i2s_std_calculate_clock(i2s_chan_handle_t handle, const i2s_std clk_info->bclk = rate * handle->total_slot * slot_bits; clk_info->mclk = clk_info->bclk * clk_info->bclk_div; } -#if SOC_I2S_SUPPORTS_APLL - clk_info->sclk = (clk_cfg->clk_src == I2S_CLK_SRC_APLL) ? i2s_set_get_apll_freq(clk_info->mclk) : I2S_LL_BASE_CLK; -#else - clk_info->sclk = I2S_LL_BASE_CLK; -#endif + clk_info->sclk = i2s_get_source_clk_freq(clk_cfg->clk_src, clk_info->mclk); clk_info->mclk_div = clk_info->sclk / clk_info->mclk; /* Check if the configuration is correct */ diff --git a/components/driver/i2s/i2s_tdm.c b/components/driver/i2s/i2s_tdm.c index fdbb9b0174..65a4cdb757 100644 --- a/components/driver/i2s/i2s_tdm.c +++ b/components/driver/i2s/i2s_tdm.c @@ -54,12 +54,7 @@ static esp_err_t i2s_tdm_calculate_clock(i2s_chan_handle_t handle, const i2s_tdm clk_info->bclk = rate * handle->total_slot * slot_bits; clk_info->mclk = clk_info->bclk * clk_info->bclk_div; } - -#if SOC_I2S_SUPPORTS_APLL - clk_info->sclk = clk_cfg->clk_src == I2S_CLK_SRC_APLL ? i2s_set_get_apll_freq(clk_info->mclk) : I2S_LL_BASE_CLK; -#else - clk_info->sclk = I2S_LL_BASE_CLK; -#endif + clk_info->sclk = i2s_get_source_clk_freq(clk_cfg->clk_src, clk_info->mclk); clk_info->mclk_div = clk_info->sclk / clk_info->mclk; /* Check if the configuration is correct */ diff --git a/components/driver/test_apps/i2s_test_apps/i2s/main/test_i2s.c b/components/driver/test_apps/i2s_test_apps/i2s/main/test_i2s.c index c787c0f79a..20d753fb64 100644 --- a/components/driver/test_apps/i2s_test_apps/i2s/main/test_i2s.c +++ b/components/driver/test_apps/i2s_test_apps/i2s/main/test_i2s.c @@ -751,7 +751,14 @@ static void i2s_test_common_sample_rate(i2s_chan_handle_t rx_chan, i2s_std_clk_c 32000, 44100, 48000, 64000, 88200, 96000, 128000, 144000, 196000}; int real_pulse = 0; - for (int i = 0; i < 15; i++) { + int case_cnt = 15; +#if SOC_I2S_HW_VERSION_2 + // Can't support a very high sample rate while using XTAL as clock source + if (clk_cfg->clk_src == I2S_CLK_SRC_XTAL) { + case_cnt = 9; + } +#endif + for (int i = 0; i < case_cnt; i++) { int expt_pulse = (int)((float)test_freq[i] * (TEST_I2S_PERIOD_MS / 1000.0)); clk_cfg->sample_rate_hz = test_freq[i]; TEST_ESP_OK(i2s_channel_reconfig_std_clock(rx_chan, clk_cfg)); @@ -789,6 +796,10 @@ TEST_CASE("I2S_default_PLL_clock_test", "[i2s]") TEST_ESP_OK(i2s_channel_init_std_mode(rx_handle, &std_cfg)); i2s_test_common_sample_rate(rx_handle, &std_cfg.clk_cfg); +#if SOC_I2S_HW_VERSION_2 + std_cfg.clk_cfg.clk_src = I2S_CLK_SRC_XTAL; + i2s_test_common_sample_rate(rx_handle, &std_cfg.clk_cfg); +#endif TEST_ESP_OK(i2s_del_channel(rx_handle)); } diff --git a/components/hal/esp32/include/hal/i2s_ll.h b/components/hal/esp32/include/hal/i2s_ll.h index 37b15698b2..b54bf1eac0 100644 --- a/components/hal/esp32/include/hal/i2s_ll.h +++ b/components/hal/esp32/include/hal/i2s_ll.h @@ -29,7 +29,6 @@ extern "C" { #define I2S_LL_AD_BCK_FACTOR (2) #define I2S_LL_PDM_BCK_FACTOR (64) -#define I2S_LL_BASE_CLK (2 * APB_CLK_FREQ) #define I2S_LL_MCLK_DIVIDER_BIT_WIDTH (6) #define I2S_LL_MCLK_DIVIDER_MAX ((1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1) diff --git a/components/hal/esp32c3/include/hal/i2s_ll.h b/components/hal/esp32c3/include/hal/i2s_ll.h index 579f356768..3ebe214372 100644 --- a/components/hal/esp32c3/include/hal/i2s_ll.h +++ b/components/hal/esp32c3/include/hal/i2s_ll.h @@ -14,6 +14,7 @@ #pragma once #include #include "hal/misc.h" +#include "hal/assert.h" #include "soc/i2s_periph.h" #include "soc/i2s_struct.h" #include "hal/i2s_types.h" @@ -23,11 +24,10 @@ extern "C" { #endif -#define I2S_LL_GET_HW(num) (&I2S0) +#define I2S_LL_GET_HW(num) (((num) == 0)? (&I2S0) : NULL) #define I2S_LL_TDM_CH_MASK (0xffff) #define I2S_LL_PDM_BCK_FACTOR (64) -#define I2S_LL_BASE_CLK (2*APB_CLK_FREQ) #define I2S_LL_MCLK_DIVIDER_BIT_WIDTH (9) #define I2S_LL_MCLK_DIVIDER_MAX ((1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1) @@ -193,18 +193,40 @@ static inline void i2s_ll_rx_reset_fifo(i2s_dev_t *hw) */ static inline void i2s_ll_tx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) { - hw->tx_clkm_conf.tx_clk_sel = 2; + switch (src) + { + case I2S_CLK_SRC_XTAL: + hw->tx_clkm_conf.tx_clk_sel = 0; + break; + case I2S_CLK_SRC_PLL_160M: + hw->tx_clkm_conf.tx_clk_sel = 2; + break; + default: + HAL_ASSERT(false && "unsupported clock source"); + break; + } } /** * @brief Set RX source clock * * @param hw Peripheral I2S hardware instance address. - * @param src I2S source clock, ESP32-C3 only support `I2S_CLK_SRC_PLL_160M` + * @param src I2S source clock */ static inline void i2s_ll_rx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) { - hw->rx_clkm_conf.rx_clk_sel = 2; + switch (src) + { + case I2S_CLK_SRC_XTAL: + hw->rx_clkm_conf.rx_clk_sel = 0; + break; + case I2S_CLK_SRC_PLL_160M: + hw->rx_clkm_conf.rx_clk_sel = 2; + break; + default: + hw->rx_clkm_conf.rx_clk_sel = 2; + break; + } } /** diff --git a/components/hal/esp32h2/include/hal/i2s_ll.h b/components/hal/esp32h2/include/hal/i2s_ll.h index edbafcc252..515f6e266d 100644 --- a/components/hal/esp32h2/include/hal/i2s_ll.h +++ b/components/hal/esp32h2/include/hal/i2s_ll.h @@ -15,6 +15,7 @@ #pragma once #include #include "hal/misc.h" +#include "hal/assert.h" #include "soc/i2s_periph.h" #include "soc/i2s_struct.h" #include "hal/i2s_types.h" @@ -24,12 +25,10 @@ extern "C" { #endif -#define I2S_LL_GET_HW(num) (&I2S0) +#define I2S_LL_GET_HW(num) (((num) == 0)? (&I2S0) : NULL) #define I2S_LL_TDM_CH_MASK (0xffff) #define I2S_LL_PDM_BCK_FACTOR (64) -// [clk_tree] TODO: replace the following switch table by clk_tree API -#define I2S_LL_BASE_CLK (96*1000000) #define I2S_LL_MCLK_DIVIDER_BIT_WIDTH (9) #define I2S_LL_MCLK_DIVIDER_MAX ((1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1) @@ -195,18 +194,40 @@ static inline void i2s_ll_rx_reset_fifo(i2s_dev_t *hw) */ static inline void i2s_ll_tx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) { - hw->tx_clkm_conf.tx_clk_sel = 2; + switch (src) + { + case I2S_CLK_SRC_XTAL: + hw->tx_clkm_conf.tx_clk_sel = 0; + break; + case I2S_CLK_SRC_PLL_96M: + hw->tx_clkm_conf.tx_clk_sel = 2; + break; + default: + HAL_ASSERT(false && "unsupported clock source"); + break; + } } /** * @brief Set RX source clock * * @param hw Peripheral I2S hardware instance address. - * @param src I2S source clock, ESP32-H2 only support `I2S_CLK_SRC_PLL_96M` for now + * @param src I2S source clock */ static inline void i2s_ll_rx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) { - hw->rx_clkm_conf.rx_clk_sel = 2; + switch (src) + { + case I2S_CLK_SRC_XTAL: + hw->rx_clkm_conf.rx_clk_sel = 0; + break; + case I2S_CLK_SRC_PLL_96M: + hw->rx_clkm_conf.rx_clk_sel = 2; + break; + default: + hw->rx_clkm_conf.rx_clk_sel = 2; + break; + } } /** diff --git a/components/hal/esp32s2/include/hal/i2s_ll.h b/components/hal/esp32s2/include/hal/i2s_ll.h index 9483235b46..1b64000b10 100644 --- a/components/hal/esp32s2/include/hal/i2s_ll.h +++ b/components/hal/esp32s2/include/hal/i2s_ll.h @@ -28,8 +28,6 @@ extern "C" { // Get I2S hardware instance with giving i2s num #define I2S_LL_GET_HW(num) (((num) == 0) ? (&I2S0) : NULL) -#define I2S_LL_BASE_CLK (2 * APB_CLK_FREQ) - #define I2S_LL_BCK_MAX_PRESCALE (64) #define I2S_LL_MCLK_DIVIDER_BIT_WIDTH (6) diff --git a/components/hal/esp32s3/include/hal/i2s_ll.h b/components/hal/esp32s3/include/hal/i2s_ll.h index 14b4e6d4e7..5a592e33d9 100644 --- a/components/hal/esp32s3/include/hal/i2s_ll.h +++ b/components/hal/esp32s3/include/hal/i2s_ll.h @@ -14,6 +14,7 @@ #pragma once #include #include "hal/misc.h" +#include "hal/assert.h" #include "soc/i2s_periph.h" #include "soc/i2s_struct.h" #include "hal/i2s_types.h" @@ -28,7 +29,6 @@ extern "C" { #define I2S_LL_TDM_CH_MASK (0xffff) #define I2S_LL_PDM_BCK_FACTOR (64) -#define I2S_LL_BASE_CLK (2*APB_CLK_FREQ) #define I2S_LL_MCLK_DIVIDER_BIT_WIDTH (9) #define I2S_LL_MCLK_DIVIDER_MAX ((1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1) @@ -190,26 +190,45 @@ static inline void i2s_ll_rx_reset_fifo(i2s_dev_t *hw) * @brief Set TX source clock * * @param hw Peripheral I2S hardware instance address. - * @param src I2S source clock, ESP32-S3 only support `I2S_CLK_SRC_PLL_160M` - * TX and RX share the same clock setting + * @param src I2S source clock. */ static inline void i2s_ll_tx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) { - hw->tx_clkm_conf.tx_clk_sel = 2; + switch (src) + { + case I2S_CLK_SRC_XTAL: + hw->tx_clkm_conf.tx_clk_sel = 0; + break; + case I2S_CLK_SRC_PLL_160M: + hw->tx_clkm_conf.tx_clk_sel = 2; + break; + default: + HAL_ASSERT(false && "unsupported clock source"); + break; + } } /** * @brief Set RX source clock * * @param hw Peripheral I2S hardware instance address. - * @param src I2S source clock, ESP32-S3 only support `I2S_CLK_SRC_PLL_160M` - * TX and RX share the same clock setting + * @param src I2S source clock */ static inline void i2s_ll_rx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) { - hw->rx_clkm_conf.rx_clk_sel = 2; + switch (src) + { + case I2S_CLK_SRC_XTAL: + hw->rx_clkm_conf.rx_clk_sel = 0; + break; + case I2S_CLK_SRC_PLL_160M: + hw->rx_clkm_conf.rx_clk_sel = 2; + break; + default: + hw->rx_clkm_conf.rx_clk_sel = 2; + break; + } } - /** * @brief Set I2S tx bck div num * diff --git a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in index 9396c57eeb..80f2d191a9 100644 --- a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in @@ -363,6 +363,10 @@ config SOC_I2S_HW_VERSION_2 bool default y +config SOC_I2S_SUPPORTS_XTAL + bool + default y + config SOC_I2S_SUPPORTS_PCM bool default y diff --git a/components/soc/esp32c3/include/soc/clk_tree_defs.h b/components/soc/esp32c3/include/soc/clk_tree_defs.h index b6c88ee00f..c9203c587a 100644 --- a/components/soc/esp32c3/include/soc/clk_tree_defs.h +++ b/components/soc/esp32c3/include/soc/clk_tree_defs.h @@ -206,7 +206,7 @@ typedef enum { /** * @brief Array initializer for all supported clock sources of I2S */ -#define SOC_I2S_CLKS {SOC_MOD_CLK_PLL_F160M} +#define SOC_I2S_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_XTAL} /** * @brief I2S clock source enum @@ -214,6 +214,7 @@ typedef enum { typedef enum { I2S_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default source clock */ I2S_CLK_SRC_PLL_160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the source clock */ + I2S_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ } soc_periph_i2s_clk_src_t; /////////////////////////////////////////////////I2C//////////////////////////////////////////////////////////////////// diff --git a/components/soc/esp32c3/include/soc/i2s_struct.h b/components/soc/esp32c3/include/soc/i2s_struct.h index de550a6c58..8e27e2b702 100644 --- a/components/soc/esp32c3/include/soc/i2s_struct.h +++ b/components/soc/esp32c3/include/soc/i2s_struct.h @@ -140,7 +140,7 @@ typedef volatile struct i2s_dev_s { uint32_t rx_clkm_div_num: 8; /*Integral I2S clock divider value*/ uint32_t reserved8: 18; /*Reserved*/ uint32_t rx_clk_active: 1; /*I2S Rx module clock enable signal.*/ - uint32_t rx_clk_sel: 2; /*Select I2S Rx module source clock. 0: no clock. 1: APLL. 2: CLK160. 3: I2S_MCLK_in.*/ + uint32_t rx_clk_sel: 2; /*Select I2S Rx module source clock. 0: XTAL clock. 1: PLL240M. 2: PLL160M. 3: I2S_MCLK_in.*/ uint32_t mclk_sel: 1; /*0: UseI2S Tx module clock as I2S_MCLK_OUT. 1: UseI2S Rx module clock as I2S_MCLK_OUT.*/ uint32_t reserved30: 2; /*Reserved*/ }; @@ -151,7 +151,7 @@ typedef volatile struct i2s_dev_s { uint32_t tx_clkm_div_num: 8; /*Integral I2S TX clock divider value. f_I2S_CLK = f_I2S_CLK_S/(N+b/a). There will be (a-b) * n-div and b * (n+1)-div. So the average combination will be: for b <= a/2 z * [x * n-div + (n+1)-div] + y * n-div. For b > a/2 z * [n-div + x * (n+1)-div] + y * (n+1)-div.*/ uint32_t reserved8: 18; /*Reserved*/ uint32_t tx_clk_active: 1; /*I2S Tx module clock enable signal.*/ - uint32_t tx_clk_sel: 2; /*Select I2S Tx module source clock. 0: XTAL clock. 1: APLL. 2: CLK160. 3: I2S_MCLK_in.*/ + uint32_t tx_clk_sel: 2; /*Select I2S Tx module source clock. 0: XTAL clock. 1: PLL240M. 2: PLL160M. 3: I2S_MCLK_in.*/ uint32_t clk_en: 1; /*Set this bit to enable clk gate*/ uint32_t reserved30: 2; /*Reserved*/ }; diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index 1f0da5868f..815c4cf75f 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -179,6 +179,7 @@ /*-------------------------- I2S CAPS ----------------------------------------*/ #define SOC_I2S_NUM (1) #define SOC_I2S_HW_VERSION_2 (1) +#define SOC_I2S_SUPPORTS_XTAL (1) #define SOC_I2S_SUPPORTS_PCM (1) #define SOC_I2S_SUPPORTS_PDM (1) #define SOC_I2S_SUPPORTS_PDM_TX (1) diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index e0f924e5ba..0d3d313211 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -287,6 +287,10 @@ config SOC_I2S_HW_VERSION_2 bool default y +config SOC_I2S_SUPPORTS_XTAL + bool + default y + config SOC_I2S_SUPPORTS_PCM bool default y diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index a68587ac8c..fc88f9c9e7 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -185,6 +185,7 @@ /*-------------------------- I2S CAPS ----------------------------------------*/ #define SOC_I2S_NUM (1) #define SOC_I2S_HW_VERSION_2 (1) +#define SOC_I2S_SUPPORTS_XTAL (1) #define SOC_I2S_SUPPORTS_PCM (1) #define SOC_I2S_SUPPORTS_PDM (1) #define SOC_I2S_SUPPORTS_PDM_TX (1) diff --git a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index f1c61bf610..07bc6db086 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -339,6 +339,10 @@ config SOC_I2S_HW_VERSION_2 bool default y +config SOC_I2S_SUPPORTS_XTAL + bool + default y + config SOC_I2S_SUPPORTS_PCM bool default y diff --git a/components/soc/esp32h2/include/soc/clk_tree_defs.h b/components/soc/esp32h2/include/soc/clk_tree_defs.h index 9b8afbcb92..db53424894 100644 --- a/components/soc/esp32h2/include/soc/clk_tree_defs.h +++ b/components/soc/esp32h2/include/soc/clk_tree_defs.h @@ -211,7 +211,7 @@ typedef enum { /** * @brief Array initializer for all supported clock sources of */ -#define SOC_I2S_CLKS {SOC_MOD_CLK_PLL} +#define SOC_I2S_CLKS {SOC_MOD_CLK_PLL, SOC_MOD_CLK_XTAL} /** * @brief I2S clock source enum @@ -219,6 +219,7 @@ typedef enum { typedef enum { I2S_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL, /*!< Select SOC_MOD_CLK_PLL as the default source clock */ I2S_CLK_SRC_PLL_96M = SOC_MOD_CLK_PLL, /*!< Select PLL as the source clock */ + I2S_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ } soc_periph_i2s_clk_src_t; /////////////////////////////////////////////////I2C//////////////////////////////////////////////////////////////////// diff --git a/components/soc/esp32h2/include/soc/i2s_struct.h b/components/soc/esp32h2/include/soc/i2s_struct.h index f58a924987..fac2c8af11 100644 --- a/components/soc/esp32h2/include/soc/i2s_struct.h +++ b/components/soc/esp32h2/include/soc/i2s_struct.h @@ -141,7 +141,7 @@ typedef volatile struct i2s_dev_s { uint32_t rx_clkm_div_num: 8; /*Integral I2S clock divider value*/ uint32_t reserved8: 18; /*Reserved*/ uint32_t rx_clk_active: 1; /*I2S Rx module clock enable signal.*/ - uint32_t rx_clk_sel: 2; /*Select I2S Rx module source clock. 0: no clock. 1: APLL. 2: CLK160. 3: I2S_MCLK_in.*/ + uint32_t rx_clk_sel: 2; /*Select I2S Rx module source clock. 0: XTAL clock. 1: PLL240M. 2: PLL160M. 3: I2S_MCLK_in.*/ uint32_t mclk_sel: 1; /*0: UseI2S Tx module clock as I2S_MCLK_OUT. 1: UseI2S Rx module clock as I2S_MCLK_OUT.*/ uint32_t reserved30: 2; /*Reserved*/ }; @@ -152,7 +152,7 @@ typedef volatile struct i2s_dev_s { uint32_t tx_clkm_div_num: 8; /*Integral I2S TX clock divider value. f_I2S_CLK = f_I2S_CLK_S/(N+b/a). There will be (a-b) * n-div and b * (n+1)-div. So the average combination will be: for b <= a/2 z * [x * n-div + (n+1)-div] + y * n-div. For b > a/2 z * [n-div + x * (n+1)-div] + y * (n+1)-div.*/ uint32_t reserved8: 18; /*Reserved*/ uint32_t tx_clk_active: 1; /*I2S Tx module clock enable signal.*/ - uint32_t tx_clk_sel: 2; /*Select I2S Tx module source clock. 0: XTAL clock. 1: APLL. 2: CLK160. 3: I2S_MCLK_in.*/ + uint32_t tx_clk_sel: 2; /*Select I2S Tx module source clock. 0: XTAL clock. 1: PLL240M. 2: PLL160M. 3: I2S_MCLK_in.*/ uint32_t clk_en: 1; /*Set this bit to enable clk gate*/ uint32_t reserved30: 2; /*Reserved*/ }; diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index 6980f32fcb..3422839a4e 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -184,6 +184,7 @@ /*-------------------------- I2S CAPS ----------------------------------------*/ #define SOC_I2S_NUM (1) #define SOC_I2S_HW_VERSION_2 (1) +#define SOC_I2S_SUPPORTS_XTAL (1) #define SOC_I2S_SUPPORTS_PCM (1) #define SOC_I2S_SUPPORTS_PDM (1) #define SOC_I2S_SUPPORTS_PDM_TX (1) diff --git a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in index 8c81c1f9ea..30046b2cef 100644 --- a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in @@ -431,6 +431,10 @@ config SOC_I2S_HW_VERSION_2 bool default y +config SOC_I2S_SUPPORTS_XTAL + bool + default y + config SOC_I2S_SUPPORTS_PCM bool default y diff --git a/components/soc/esp32s3/include/soc/clk_tree_defs.h b/components/soc/esp32s3/include/soc/clk_tree_defs.h index 4a55c25b75..7b96225a53 100644 --- a/components/soc/esp32s3/include/soc/clk_tree_defs.h +++ b/components/soc/esp32s3/include/soc/clk_tree_defs.h @@ -252,7 +252,7 @@ typedef enum { /** * @brief Array initializer for all supported clock sources of I2S */ -#define SOC_I2S_CLKS {SOC_MOD_CLK_PLL_F160M} +#define SOC_I2S_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_XTAL} /** * @brief I2S clock source enum @@ -260,6 +260,7 @@ typedef enum { typedef enum { I2S_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default source clock */ I2S_CLK_SRC_PLL_160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the source clock */ + I2S_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ } soc_periph_i2s_clk_src_t; /////////////////////////////////////////////////I2C//////////////////////////////////////////////////////////////////// diff --git a/components/soc/esp32s3/include/soc/i2s_struct.h b/components/soc/esp32s3/include/soc/i2s_struct.h index 587011c4b6..b048961085 100644 --- a/components/soc/esp32s3/include/soc/i2s_struct.h +++ b/components/soc/esp32s3/include/soc/i2s_struct.h @@ -142,7 +142,7 @@ typedef volatile struct i2s_dev_s { uint32_t rx_clkm_div_num : 8; /*Integral I2S clock divider value*/ uint32_t reserved8 : 18; /* Reserved*/ uint32_t rx_clk_active : 1; /*I2S Rx module clock enable signal.*/ - uint32_t rx_clk_sel : 2; /*Select I2S Rx module source clock. 0: no clock. 1: APLL. 2: CLK160. 3: I2S_MCLK_in.*/ + uint32_t rx_clk_sel : 2; /*Select I2S Rx module source clock. 0: XTAL clock. 1: PLL240M. 2: PLL160M. 3: I2S_MCLK_in.*/ uint32_t mclk_sel : 1; /* 0: UseI2S Tx module clock as I2S_MCLK_OUT. 1: UseI2S Rx module clock as I2S_MCLK_OUT. */ uint32_t reserved30 : 2; /* Reserved*/ }; @@ -153,7 +153,7 @@ typedef volatile struct i2s_dev_s { uint32_t tx_clkm_div_num : 8; /*Integral I2S TX clock divider value. f_I2S_CLK = f_I2S_CLK_S/(N+b/a). There will be (a-b) * n-div and b * (n+1)-div. So the average combination will be: for b <= a/2, z * [x * n-div + (n+1)-div] + y * n-div. For b > a/2, z * [n-div + x * (n+1)-div] + y * (n+1)-div. */ uint32_t reserved8 : 18; /* Reserved*/ uint32_t tx_clk_active : 1; /*I2S Tx module clock enable signal.*/ - uint32_t tx_clk_sel : 2; /*Select I2S Tx module source clock. 0: XTAL clock. 1: APLL. 2: CLK160. 3: I2S_MCLK_in.*/ + uint32_t tx_clk_sel : 2; /*Select I2S Tx module source clock. 0: XTAL clock. 1: PLL240M. 2: PLL160M. 3: I2S_MCLK_in.*/ uint32_t clk_en : 1; /*Set this bit to enable clk gate*/ uint32_t reserved30 : 2; /* Reserved*/ }; diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index ebbb1e1e7d..a0858494bc 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -182,6 +182,7 @@ /*-------------------------- I2S CAPS ----------------------------------------*/ #define SOC_I2S_NUM (2) #define SOC_I2S_HW_VERSION_2 (1) +#define SOC_I2S_SUPPORTS_XTAL (1) #define SOC_I2S_SUPPORTS_PCM (1) #define SOC_I2S_SUPPORTS_PDM (1) #define SOC_I2S_SUPPORTS_PDM_TX (1)