Merge branch 'bugfix/fix_i2s_reconfig_slot_issue' into 'master'

fix(i2s): fixed incorrect logic in slot reconfig

Closes IDFGH-14486

See merge request espressif/esp-idf!36574
This commit is contained in:
Kevin (Lao Kaiyao)
2025-01-26 11:27:54 +08:00
5 changed files with 33 additions and 5 deletions

View File

@@ -126,6 +126,9 @@ static esp_err_t i2s_pdm_tx_set_slot(i2s_chan_handle_t handle, const i2s_pdm_tx_
/* Update the mode info: slot configuration */
i2s_pdm_tx_config_t *pdm_tx_cfg = (i2s_pdm_tx_config_t *)handle->mode_info;
memcpy(&(pdm_tx_cfg->slot_cfg), slot_cfg, sizeof(i2s_pdm_tx_slot_config_t));
/* Update the slot bit width to the actual slot bit width */
pdm_tx_cfg->slot_cfg.slot_bit_width = (int)pdm_tx_cfg->slot_cfg.slot_bit_width < (int)pdm_tx_cfg->slot_cfg.data_bit_width ?
pdm_tx_cfg->slot_cfg.data_bit_width : pdm_tx_cfg->slot_cfg.slot_bit_width;
portENTER_CRITICAL(&g_i2s.spinlock);
/* Configure the hardware to apply PDM format */
@@ -311,7 +314,7 @@ esp_err_t i2s_channel_reconfig_pdm_tx_slot(i2s_chan_handle_t handle, const i2s_p
/* 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 (pdm_tx_cfg->slot_cfg.slot_bit_width == slot_bits) {
if (pdm_tx_cfg->slot_cfg.slot_bit_width != slot_bits) {
ESP_GOTO_ON_ERROR(i2s_pdm_tx_set_clock(handle, &pdm_tx_cfg->clk_cfg), err, TAG, "update clock failed");
}
@@ -438,6 +441,9 @@ static esp_err_t i2s_pdm_rx_set_slot(i2s_chan_handle_t handle, const i2s_pdm_rx_
/* Update the mode info: slot configuration */
i2s_pdm_rx_config_t *pdm_rx_cfg = (i2s_pdm_rx_config_t *)handle->mode_info;
memcpy(&(pdm_rx_cfg->slot_cfg), slot_cfg, sizeof(i2s_pdm_rx_slot_config_t));
/* Update the slot bit width to the actual slot bit width */
pdm_rx_cfg->slot_cfg.slot_bit_width = (int)pdm_rx_cfg->slot_cfg.slot_bit_width < (int)pdm_rx_cfg->slot_cfg.data_bit_width ?
pdm_rx_cfg->slot_cfg.data_bit_width : pdm_rx_cfg->slot_cfg.slot_bit_width;
portENTER_CRITICAL(&g_i2s.spinlock);
/* Configure the hardware to apply PDM format */
@@ -624,7 +630,7 @@ esp_err_t i2s_channel_reconfig_pdm_rx_slot(i2s_chan_handle_t handle, const i2s_p
/* 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 (pdm_rx_cfg->slot_cfg.slot_bit_width == slot_bits) {
if (pdm_rx_cfg->slot_cfg.slot_bit_width != slot_bits) {
ESP_GOTO_ON_ERROR(i2s_pdm_rx_set_clock(handle, &pdm_rx_cfg->clk_cfg), err, TAG, "update clock failed");
}

View File

@@ -136,6 +136,9 @@ static esp_err_t i2s_std_set_slot(i2s_chan_handle_t handle, const i2s_std_slot_c
/* Update the mode info: slot configuration */
i2s_std_config_t *std_cfg = (i2s_std_config_t *)(handle->mode_info);
memcpy(&(std_cfg->slot_cfg), slot_cfg, sizeof(i2s_std_slot_config_t));
/* Update the slot bit width to the actual slot bit width */
std_cfg->slot_cfg.slot_bit_width = (int)std_cfg->slot_cfg.slot_bit_width < (int)std_cfg->slot_cfg.data_bit_width ?
std_cfg->slot_cfg.data_bit_width : std_cfg->slot_cfg.slot_bit_width;
return ESP_OK;
}
@@ -334,7 +337,7 @@ 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) {
if (std_cfg->slot_cfg.slot_bit_width != slot_bits) {
ESP_GOTO_ON_ERROR(i2s_std_set_clock(handle, &std_cfg->clk_cfg), err, TAG, "update clock failed");
}

View File

@@ -94,6 +94,9 @@ static esp_err_t i2s_tdm_set_clock(i2s_chan_handle_t handle, const i2s_tdm_clk_c
/* Update the mode info: clock configuration */
memcpy(&(tdm_cfg->clk_cfg), clk_cfg, sizeof(i2s_tdm_clk_config_t));
/* Update the slot bit width to the actual slot bit width */
tdm_cfg->slot_cfg.slot_bit_width = (int)tdm_cfg->slot_cfg.slot_bit_width < (int)tdm_cfg->slot_cfg.data_bit_width ?
tdm_cfg->slot_cfg.data_bit_width : tdm_cfg->slot_cfg.slot_bit_width;
return ret;
}
@@ -343,7 +346,7 @@ esp_err_t i2s_channel_reconfig_tdm_slot(i2s_chan_handle_t handle, const i2s_tdm_
/* 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 (tdm_cfg->slot_cfg.slot_bit_width == slot_bits) {
if (tdm_cfg->slot_cfg.slot_bit_width != slot_bits) {
ESP_GOTO_ON_ERROR(i2s_tdm_set_clock(handle, &tdm_cfg->clk_cfg), err, TAG, "update clock failed");
}

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -193,6 +193,7 @@ extern "C" {
I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) // Alias
/** @endcond */
#if SOC_I2S_HW_VERSION_1
/**
* @brief I2S default standard clock configuration
* @note Please set the mclk_multiple to I2S_MCLK_MULTIPLE_384 while using 24 bits data width
@@ -204,6 +205,20 @@ extern "C" {
.clk_src = I2S_CLK_SRC_DEFAULT, \
.mclk_multiple = I2S_MCLK_MULTIPLE_256, \
}
#else
/**
* @brief I2S default standard clock configuration
* @note Please set the mclk_multiple to I2S_MCLK_MULTIPLE_384 while using 24 bits data width
* Otherwise the sample rate might be imprecise since the BCLK division is not a integer
* @param rate sample rate
*/
#define I2S_STD_CLK_DEFAULT_CONFIG(rate) { \
.sample_rate_hz = rate, \
.clk_src = I2S_CLK_SRC_DEFAULT, \
.mclk_multiple = I2S_MCLK_MULTIPLE_256, \
.ext_clk_freq_hz = 0, \
}
#endif
/**
* @brief I2S slot configuration for standard mode

View File

@@ -122,6 +122,7 @@ extern "C" {
#define I2S_TDM_CLK_DEFAULT_CONFIG(rate) { \
.sample_rate_hz = rate, \
.clk_src = I2S_CLK_SRC_DEFAULT, \
.ext_clk_freq_hz = 0, \
.mclk_multiple = I2S_MCLK_MULTIPLE_256, \
.bclk_div = 8, \
}