diff --git a/components/driver/deprecated/i2s_legacy.c b/components/driver/deprecated/i2s_legacy.c index 31e23cb6ee..165683e22b 100644 --- a/components/driver/deprecated/i2s_legacy.c +++ b/components/driver/deprecated/i2s_legacy.c @@ -1196,6 +1196,7 @@ esp_err_t i2s_set_pdm_tx_up_sample(i2s_port_t i2s_num, const i2s_pdm_tx_upsample p_i2s[i2s_num]->clk_cfg.up_sample_fp = upsample_cfg->fp; p_i2s[i2s_num]->clk_cfg.up_sample_fs = upsample_cfg->fs; i2s_ll_tx_set_pdm_fpfs(p_i2s[i2s_num]->hal.dev, upsample_cfg->fp, upsample_cfg->fs); + i2s_ll_tx_set_pdm_over_sample_ratio(p_i2s[i2s_num]->hal.dev, upsample_cfg->fp / upsample_cfg->fs); i2s_start(i2s_num); xSemaphoreGive(p_i2s[i2s_num]->tx->mux); return i2s_set_clk(i2s_num, p_i2s[i2s_num]->clk_cfg.sample_rate_hz, p_i2s[i2s_num]->slot_cfg.data_bit_width, p_i2s[i2s_num]->slot_cfg.slot_mode); diff --git a/components/driver/i2s/i2s_pdm.c b/components/driver/i2s/i2s_pdm.c index 8468d283f9..bf9ab352ac 100644 --- a/components/driver/i2s/i2s_pdm.c +++ b/components/driver/i2s/i2s_pdm.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -35,7 +35,9 @@ static esp_err_t i2s_pdm_tx_calculate_clock(i2s_chan_handle_t handle, const i2s_ uint32_t rate = clk_cfg->sample_rate_hz; i2s_pdm_tx_clk_config_t *pdm_tx_clk = (i2s_pdm_tx_clk_config_t *)clk_cfg; - clk_info->bclk = rate * I2S_LL_PDM_BCK_FACTOR * pdm_tx_clk->up_sample_fp / pdm_tx_clk->up_sample_fs; + // Over sampling ratio (integer, mostly should be 1 or 2) + uint32_t over_sample_ratio = pdm_tx_clk->up_sample_fp / pdm_tx_clk->up_sample_fs; + clk_info->bclk = rate * I2S_LL_PDM_BCK_FACTOR * over_sample_ratio; clk_info->bclk_div = 8; clk_info->mclk = clk_info->bclk * clk_info->bclk_div; #if SOC_I2S_SUPPORTS_APLL @@ -47,8 +49,9 @@ static esp_err_t i2s_pdm_tx_calculate_clock(i2s_chan_handle_t handle, const i2s_ /* Check if the configuration is correct */ ESP_RETURN_ON_FALSE(clk_info->mclk_div, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large"); - /* Set upsampling configuration */ + /* Set up sampling configuration */ i2s_ll_tx_set_pdm_fpfs(handle->controller->hal.dev, pdm_tx_clk->up_sample_fp, pdm_tx_clk->up_sample_fs); + i2s_ll_tx_set_pdm_over_sample_ratio(handle->controller->hal.dev, over_sample_ratio); return ESP_OK; } @@ -57,6 +60,7 @@ static esp_err_t i2s_pdm_tx_set_clock(i2s_chan_handle_t handle, const i2s_pdm_tx { esp_err_t ret = ESP_OK; i2s_pdm_tx_config_t *pdm_tx_cfg = (i2s_pdm_tx_config_t *)(handle->mode_info); + ESP_RETURN_ON_FALSE(clk_cfg->up_sample_fs <= 480, ESP_ERR_INVALID_ARG, TAG, "up_sample_fs should be within 480"); i2s_hal_clock_info_t clk_info; /* Calculate clock parameters */ diff --git a/components/driver/i2s/i2s_private.h b/components/driver/i2s/i2s_private.h index 3e7296dce4..3665542cdb 100644 --- a/components/driver/i2s/i2s_private.h +++ b/components/driver/i2s/i2s_private.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/driver/i2s/i2s_std.c b/components/driver/i2s/i2s_std.c index d006239735..905132d4b5 100644 --- a/components/driver/i2s/i2s_std.c +++ b/components/driver/i2s/i2s_std.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/driver/i2s/i2s_tdm.c b/components/driver/i2s/i2s_tdm.c index dbfb9c9ef9..c8bb0ca5ea 100644 --- a/components/driver/i2s/i2s_tdm.c +++ b/components/driver/i2s/i2s_tdm.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/driver/include/driver/i2s_pdm.h b/components/driver/include/driver/i2s_pdm.h index f16b967cb3..75283913b3 100644 --- a/components/driver/include/driver/i2s_pdm.h +++ b/components/driver/include/driver/i2s_pdm.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -207,7 +207,7 @@ esp_err_t i2s_channel_reconfig_pdm_rx_gpio(i2s_chan_handle_t handle, const i2s_p * 2: fp = 960, fs = 480, in this case, Fpdm = 128*Fpcm = 128*sample_rate_hz * If the pdm receiver do not care the pdm serial clock, it's recommended set Fpdm = 128*48000. * Otherwise, the second configuration should be adopted. - * @param rate sample rate + * @param rate sample rate (not suggest to exceed 48000 Hz, otherwise more glitches and noise may appear) */ #define I2S_PDM_TX_CLK_DEFAULT_CONFIG(rate) { \ .sample_rate_hz = rate, \ @@ -253,7 +253,7 @@ typedef struct { i2s_pdm_sig_scale_t lp_scale; /*!< Low pass filter scaling value */ 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, on-line codec, one-line dac, two-line dac mode can be selected */ + 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 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 */ @@ -266,12 +266,12 @@ typedef struct { */ typedef struct { /* General fields */ - uint32_t sample_rate_hz; /*!< I2S sample rate */ + uint32_t sample_rate_hz; /*!< I2S sample rate, not suggest to exceed 48000 Hz, otherwise more glitches and noise may appear */ i2s_clock_src_t clk_src; /*!< Choose clock source */ i2s_mclk_multiple_t mclk_multiple; /*!< The multiple of mclk to the sample rate */ /* Particular fields */ uint32_t up_sample_fp; /*!< Up-sampling param fp */ - uint32_t up_sample_fs; /*!< Up-sampling param fs */ + uint32_t up_sample_fs; /*!< Up-sampling param fs, not allowed to be greater than 480 */ } i2s_pdm_tx_clk_config_t; /** diff --git a/components/driver/include/driver/i2s_std.h b/components/driver/include/driver/i2s_std.h index 300691db4d..1080019e96 100644 --- a/components/driver/include/driver/i2s_std.h +++ b/components/driver/include/driver/i2s_std.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/driver/include/driver/i2s_tdm.h b/components/driver/include/driver/i2s_tdm.h index 883768d0a3..a2345a854b 100644 --- a/components/driver/include/driver/i2s_tdm.h +++ b/components/driver/include/driver/i2s_tdm.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/hal/esp32/include/hal/i2s_ll.h b/components/hal/esp32/include/hal/i2s_ll.h index 37b15698b2..d9c0f87cb1 100644 --- a/components/hal/esp32/include/hal/i2s_ll.h +++ b/components/hal/esp32/include/hal/i2s_ll.h @@ -1042,6 +1042,17 @@ static inline void i2s_ll_tx_set_pdm_sd_scale(i2s_dev_t *hw, i2s_pdm_sig_scale_t hw->pdm_conf.tx_sigmadelta_in_shift = sig_scale; } +/** + * @brief Set the PDM TX over sampling ratio + * + * @param hw Peripheral I2S hardware instance address. + * @param ovr Over sampling ratio + */ +static inline void i2s_ll_tx_set_pdm_over_sample_ratio(i2s_dev_t *hw, uint32_t ovr) +{ + hw->pdm_conf.tx_sinc_osr2 = ovr; +} + /** * @brief Configure I2S TX PDM sample rate * Fpdm = 64*Fpcm*fp/fs @@ -1054,7 +1065,6 @@ static inline void i2s_ll_tx_set_pdm_fpfs(i2s_dev_t *hw, uint32_t fp, uint32_t f { hw->pdm_freq_conf.tx_pdm_fp = fp; hw->pdm_freq_conf.tx_pdm_fs = fs; - hw->pdm_conf.tx_sinc_osr2 = fp / fs; } /** diff --git a/components/hal/esp32c3/include/hal/i2s_ll.h b/components/hal/esp32c3/include/hal/i2s_ll.h index 438dc054ca..97852788e9 100644 --- a/components/hal/esp32c3/include/hal/i2s_ll.h +++ b/components/hal/esp32c3/include/hal/i2s_ll.h @@ -851,6 +851,17 @@ static inline void i2s_ll_tx_set_pdm_sd_dither2(i2s_dev_t *hw, uint32_t dither2) hw->tx_pcm2pdm_conf.tx_pdm_sigmadelta_dither2 = dither2; } +/** + * @brief Set the PDM TX over sampling ratio + * + * @param hw Peripheral I2S hardware instance address. + * @param ovr Over sampling ratio + */ +static inline void i2s_ll_tx_set_pdm_over_sample_ratio(i2s_dev_t *hw, uint32_t ovr) +{ + hw->tx_pcm2pdm_conf.tx_pdm_sinc_osr2 = ovr; +} + /** * @brief Configure I2S TX PDM sample rate * Fpdm = 64*Fpcm*fp/fs @@ -863,7 +874,6 @@ static inline void i2s_ll_tx_set_pdm_fpfs(i2s_dev_t *hw, uint32_t fp, uint32_t f { hw->tx_pcm2pdm_conf1.tx_pdm_fp = fp; hw->tx_pcm2pdm_conf1.tx_pdm_fs = fs; - hw->tx_pcm2pdm_conf.tx_pdm_sinc_osr2 = fp / fs; } /** diff --git a/components/hal/esp32h2/include/hal/i2s_ll.h b/components/hal/esp32h2/include/hal/i2s_ll.h index 3d509ace99..fa5aaab182 100644 --- a/components/hal/esp32h2/include/hal/i2s_ll.h +++ b/components/hal/esp32h2/include/hal/i2s_ll.h @@ -853,6 +853,17 @@ static inline void i2s_ll_tx_set_pdm_sd_dither2(i2s_dev_t *hw, uint32_t dither2) hw->tx_pcm2pdm_conf.tx_pdm_sigmadelta_dither2 = dither2; } +/** + * @brief Set the PDM TX over sampling ratio + * + * @param hw Peripheral I2S hardware instance address. + * @param ovr Over sampling ratio + */ +static inline void i2s_ll_tx_set_pdm_over_sample_ratio(i2s_dev_t *hw, uint32_t ovr) +{ + hw->tx_pcm2pdm_conf.tx_pdm_sinc_osr2 = ovr; +} + /** * @brief Configure I2S TX PDM sample rate * Fpdm = 64*Fpcm*fp/fs @@ -865,7 +876,6 @@ static inline void i2s_ll_tx_set_pdm_fpfs(i2s_dev_t *hw, uint32_t fp, uint32_t f { hw->tx_pcm2pdm_conf1.tx_pdm_fp = fp; hw->tx_pcm2pdm_conf1.tx_pdm_fs = fs; - hw->tx_pcm2pdm_conf.tx_pdm_sinc_osr2 = fp / fs; } /** diff --git a/components/hal/esp32s3/include/hal/i2s_ll.h b/components/hal/esp32s3/include/hal/i2s_ll.h index eddeecb9e5..8bf96702fa 100644 --- a/components/hal/esp32s3/include/hal/i2s_ll.h +++ b/components/hal/esp32s3/include/hal/i2s_ll.h @@ -757,6 +757,17 @@ static inline void i2s_ll_rx_enable_pdm(i2s_dev_t *hw) hw->rx_conf.rx_pdm2pcm_en = true; } +/** + * @brief Set the PDM TX over sampling ratio + * + * @param hw Peripheral I2S hardware instance address. + * @param ovr Over sampling ratio + */ +static inline void i2s_ll_tx_set_pdm_over_sample_ratio(i2s_dev_t *hw, uint32_t ovr) +{ + hw->tx_pcm2pdm_conf.tx_sinc_osr2 = ovr; +} + /** * @brief Configure I2S TX PDM sample rate * Fpdm = 64*Fpcm*fp/fs @@ -769,7 +780,6 @@ static inline void i2s_ll_tx_set_pdm_fpfs(i2s_dev_t *hw, uint32_t fp, uint32_t f { hw->tx_pcm2pdm_conf1.tx_pdm_fp = fp; hw->tx_pcm2pdm_conf1.tx_pdm_fs = fs; - hw->tx_pcm2pdm_conf.tx_sinc_osr2 = fp / fs; } /**