Merge branch 'bugfix/fix_i2s_assign_and_check_sequence_v5.1' into 'release/v5.1'

fix(i2s): fixed i2s inappropriate check and assign sequence (v5.1)

See merge request espressif/esp-idf!38608
This commit is contained in:
morris
2025-04-28 11:19:07 +08:00
11 changed files with 47 additions and 31 deletions

View File

@@ -375,34 +375,39 @@ uint32_t i2s_get_buf_size(i2s_chan_handle_t handle, uint32_t data_bit_width, uin
esp_err_t i2s_free_dma_desc(i2s_chan_handle_t handle)
{
I2S_NULL_POINTER_CHECK(TAG, handle);
if (!handle->dma.desc) {
return ESP_OK;
}
for (int i = 0; i < handle->dma.desc_num; i++) {
if (handle->dma.bufs[i]) {
free(handle->dma.bufs[i]);
}
if (handle->dma.desc[i]) {
free(handle->dma.desc[i]);
}
}
if (handle->dma.bufs) {
free(handle->dma.bufs);
}
handle->dma.buf_size = 0;
if (handle->dma.desc) {
for (int i = 0; i < handle->dma.desc_num; i++) {
if (handle->dma.desc[i]) {
free(handle->dma.desc[i]);
handle->dma.desc[i] = NULL;
}
}
free(handle->dma.desc);
}
handle->dma.desc = NULL;
if (handle->dma.bufs) {
for (int i = 0; i < handle->dma.desc_num; i++) {
if (handle->dma.bufs[i]) {
free(handle->dma.bufs[i]);
handle->dma.bufs[i] = NULL;
}
}
free(handle->dma.bufs);
handle->dma.bufs = NULL;
}
return ESP_OK;
}
esp_err_t i2s_alloc_dma_desc(i2s_chan_handle_t handle, uint32_t num, uint32_t bufsize)
esp_err_t i2s_alloc_dma_desc(i2s_chan_handle_t handle, uint32_t bufsize)
{
I2S_NULL_POINTER_CHECK(TAG, handle);
esp_err_t ret = ESP_OK;
ESP_RETURN_ON_FALSE(bufsize <= I2S_DMA_BUFFER_MAX_SIZE, ESP_ERR_INVALID_ARG, TAG, "dma buffer can't be bigger than %d", I2S_DMA_BUFFER_MAX_SIZE);
handle->dma.desc_num = num;
uint32_t num = handle->dma.desc_num;
handle->dma.buf_size = bufsize;
/* Descriptors must be in the internal RAM */

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -44,7 +44,8 @@ static esp_err_t i2s_pdm_tx_calculate_clock(i2s_chan_handle_t handle, const i2s_
clk_info->mclk_div = clk_info->sclk / clk_info->mclk;
/* Check if the configuration is correct. Use float for check in case the mclk division might be carried up in the fine division calculation */
ESP_RETURN_ON_FALSE(clk_info->sclk / (float)clk_info->mclk > 1.99, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large");
ESP_RETURN_ON_FALSE((float)clk_info->sclk > clk_info->mclk * 1.99, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large");
ESP_RETURN_ON_FALSE(clk_info->mclk_div < 256, ESP_ERR_INVALID_ARG, TAG, "sample rate is too small");
/* 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);
@@ -89,9 +90,8 @@ static esp_err_t i2s_pdm_tx_set_slot(i2s_chan_handle_t handle, const i2s_pdm_tx_
uint32_t buf_size = i2s_get_buf_size(handle, slot_cfg->data_bit_width, handle->dma.frame_num);
/* The DMA buffer need to re-allocate if the buffer size changed */
if (handle->dma.buf_size != buf_size) {
handle->dma.buf_size = buf_size;
ESP_RETURN_ON_ERROR(i2s_free_dma_desc(handle), TAG, "failed to free the old dma descriptor");
ESP_RETURN_ON_ERROR(i2s_alloc_dma_desc(handle, handle->dma.desc_num, buf_size),
ESP_RETURN_ON_ERROR(i2s_alloc_dma_desc(handle, buf_size),
TAG, "allocate memory for dma descriptor failed");
}
/* Share bck and ws signal in full-duplex mode */
@@ -333,7 +333,8 @@ static esp_err_t i2s_pdm_rx_calculate_clock(i2s_chan_handle_t handle, const i2s_
clk_info->mclk_div = clk_info->sclk / clk_info->mclk;
/* Check if the configuration is correct. Use float for check in case the mclk division might be carried up in the fine division calculation */
ESP_RETURN_ON_FALSE(clk_info->sclk / (float)clk_info->mclk > 1.99, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large");
ESP_RETURN_ON_FALSE((float)clk_info->sclk > clk_info->mclk * 1.99, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large");
ESP_RETURN_ON_FALSE(clk_info->mclk_div < I2S_LL_CLK_FRAC_DIV_N_MAX, ESP_ERR_INVALID_ARG, TAG, "sample rate is too small");
/* Set down-sampling configuration */
i2s_ll_rx_set_pdm_dsr(handle->controller->hal.dev, pdm_rx_clk->dn_sample_mode);
return ESP_OK;
@@ -370,9 +371,8 @@ static esp_err_t i2s_pdm_rx_set_slot(i2s_chan_handle_t handle, const i2s_pdm_rx_
uint32_t buf_size = i2s_get_buf_size(handle, slot_cfg->data_bit_width, handle->dma.frame_num);
/* The DMA buffer need to re-allocate if the buffer size changed */
if (handle->dma.buf_size != buf_size) {
handle->dma.buf_size = buf_size;
ESP_RETURN_ON_ERROR(i2s_free_dma_desc(handle), TAG, "failed to free the old dma descriptor");
ESP_RETURN_ON_ERROR(i2s_alloc_dma_desc(handle, handle->dma.desc_num, buf_size),
ESP_RETURN_ON_ERROR(i2s_alloc_dma_desc(handle, buf_size),
TAG, "allocate memory for dma descriptor failed");
}
/* Share bck and ws signal in full-duplex mode */

View File

@@ -150,7 +150,6 @@ esp_err_t i2s_free_dma_desc(i2s_chan_handle_t handle);
* @brief Allocate memory for I2S DMA descriptor and DMA buffer
*
* @param handle I2S channel handle
* @param num Number of DMA descriptors
* @param bufsize The DMA buffer size
*
* @return
@@ -158,7 +157,7 @@ esp_err_t i2s_free_dma_desc(i2s_chan_handle_t handle);
* - ESP_ERR_INVALID_ARG NULL pointer or bufsize is too big
* - ESP_ERR_NO_MEM No memory for DMA descriptor and DMA buffer
*/
esp_err_t i2s_alloc_dma_desc(i2s_chan_handle_t handle, uint32_t num, uint32_t bufsize);
esp_err_t i2s_alloc_dma_desc(i2s_chan_handle_t handle, uint32_t bufsize);
/**
* @brief Get DMA buffer size

View File

@@ -49,7 +49,8 @@ static esp_err_t i2s_std_calculate_clock(i2s_chan_handle_t handle, const i2s_std
clk_info->mclk_div = clk_info->sclk / clk_info->mclk;
/* Check if the configuration is correct. Use float for check in case the mclk division might be carried up in the fine division calculation */
ESP_RETURN_ON_FALSE(clk_info->sclk / (float)clk_info->mclk > 1.99, ESP_ERR_INVALID_ARG, TAG, "sample rate or mclk_multiple is too large for the current clock source");
ESP_RETURN_ON_FALSE((float)clk_info->sclk > clk_info->mclk * 1.99, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large");
ESP_RETURN_ON_FALSE(clk_info->mclk_div < I2S_LL_CLK_FRAC_DIV_N_MAX, ESP_ERR_INVALID_ARG, TAG, "sample rate is too small");
return ESP_OK;
}
@@ -94,9 +95,8 @@ static esp_err_t i2s_std_set_slot(i2s_chan_handle_t handle, const i2s_std_slot_c
uint32_t buf_size = i2s_get_buf_size(handle, slot_cfg->data_bit_width, handle->dma.frame_num);
/* The DMA buffer need to re-allocate if the buffer size changed */
if (handle->dma.buf_size != buf_size) {
handle->dma.buf_size = buf_size;
ESP_RETURN_ON_ERROR(i2s_free_dma_desc(handle), TAG, "failed to free the old dma descriptor");
ESP_RETURN_ON_ERROR(i2s_alloc_dma_desc(handle, handle->dma.desc_num, buf_size),
ESP_RETURN_ON_ERROR(i2s_alloc_dma_desc(handle, buf_size),
TAG, "allocate memory for dma descriptor failed");
}
bool is_slave = handle->role == I2S_ROLE_SLAVE;

View File

@@ -60,7 +60,8 @@ static esp_err_t i2s_tdm_calculate_clock(i2s_chan_handle_t handle, const i2s_tdm
clk_info->mclk_div = clk_info->sclk / clk_info->mclk;
/* Check if the configuration is correct. Use float for check in case the mclk division might be carried up in the fine division calculation */
ESP_RETURN_ON_FALSE(clk_info->sclk / (float)clk_info->mclk > 1.99, ESP_ERR_INVALID_ARG, TAG, "sample rate or mclk_multiple is too large for the current clock source");
ESP_RETURN_ON_FALSE((float)clk_info->sclk > clk_info->mclk * 1.99, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large");
ESP_RETURN_ON_FALSE(clk_info->mclk_div < I2S_LL_CLK_FRAC_DIV_N_MAX, ESP_ERR_INVALID_ARG, TAG, "sample rate is too small");
return ESP_OK;
}
@@ -107,9 +108,8 @@ static esp_err_t i2s_tdm_set_slot(i2s_chan_handle_t handle, const i2s_tdm_slot_c
uint32_t buf_size = i2s_get_buf_size(handle, slot_cfg->data_bit_width, handle->dma.frame_num);
/* The DMA buffer need to re-allocate if the buffer size changed */
if (handle->dma.buf_size != buf_size) {
handle->dma.buf_size = buf_size;
ESP_RETURN_ON_ERROR(i2s_free_dma_desc(handle), TAG, "failed to free the old dma descriptor");
ESP_RETURN_ON_ERROR(i2s_alloc_dma_desc(handle, handle->dma.desc_num, buf_size),
ESP_RETURN_ON_ERROR(i2s_alloc_dma_desc(handle, buf_size),
TAG, "allocate memory for dma descriptor failed");
}
bool is_slave = handle->role == I2S_ROLE_SLAVE;

View File

@@ -30,6 +30,8 @@ extern "C" {
#define I2S_LL_AD_BCK_FACTOR (2)
#define I2S_LL_PDM_BCK_FACTOR (64)
#define I2S_LL_CLK_FRAC_DIV_N_MAX 256 // I2S_MCLK = I2S_SRC_CLK / (N + b/a), the N register is 8 bit-width
#define I2S_LL_MCLK_DIVIDER_BIT_WIDTH (6)
#define I2S_LL_MCLK_DIVIDER_MAX ((1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1)

View File

@@ -29,6 +29,8 @@ extern "C" {
#define I2S_LL_TDM_CH_MASK (0xffff)
#define I2S_LL_PDM_BCK_FACTOR (64)
#define I2S_LL_CLK_FRAC_DIV_N_MAX 256 // I2S_MCLK = I2S_SRC_CLK / (N + b/a), the N register is 8 bit-width
#define I2S_LL_MCLK_DIVIDER_BIT_WIDTH (9)
#define I2S_LL_MCLK_DIVIDER_MAX ((1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1)
#define I2S_LL_SLOT_FRAME_BIT_MAX 128 // Up-to 128 bits in one frame, determined by MAX(half_sample_bits) * 2

View File

@@ -30,6 +30,8 @@ extern "C" {
#define I2S_LL_TDM_CH_MASK (0xffff)
#define I2S_LL_PDM_BCK_FACTOR (64)
#define I2S_LL_CLK_FRAC_DIV_N_MAX 256 // I2S_MCLK = I2S_SRC_CLK / (N + b/a), the N register is 8 bit-width
#define I2S_LL_MCLK_DIVIDER_BIT_WIDTH (9)
#define I2S_LL_MCLK_DIVIDER_MAX ((1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1)
#define I2S_LL_SLOT_FRAME_BIT_MAX 128 // Up-to 128 bits in one frame, determined by MAX(half_sample_bits) * 2

View File

@@ -30,6 +30,8 @@ extern "C" {
#define I2S_LL_TDM_CH_MASK (0xffff)
#define I2S_LL_PDM_BCK_FACTOR (64)
#define I2S_LL_CLK_FRAC_DIV_N_MAX 256 // I2S_MCLK = I2S_SRC_CLK / (N + b/a), the N register is 8 bit-width
#define I2S_LL_MCLK_DIVIDER_BIT_WIDTH (9)
#define I2S_LL_MCLK_DIVIDER_MAX ((1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1)
#define I2S_LL_SLOT_FRAME_BIT_MAX 512 // Up-to 512 bits in one frame, determined by MAX(half_sample_bits) * 2

View File

@@ -30,6 +30,8 @@ extern "C" {
#define I2S_LL_BCK_MAX_PRESCALE (64)
#define I2S_LL_CLK_FRAC_DIV_N_MAX 256 // I2S_MCLK = I2S_SRC_CLK / (N + b/a), the N register is 8 bit-width
#define I2S_LL_MCLK_DIVIDER_BIT_WIDTH (6)
#define I2S_LL_MCLK_DIVIDER_MAX ((1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1)

View File

@@ -30,6 +30,8 @@ extern "C" {
#define I2S_LL_TDM_CH_MASK (0xffff)
#define I2S_LL_PDM_BCK_FACTOR (64)
#define I2S_LL_CLK_FRAC_DIV_N_MAX 256 // I2S_MCLK = I2S_SRC_CLK / (N + b/a), the N register is 8 bit-width
#define I2S_LL_MCLK_DIVIDER_BIT_WIDTH (9)
#define I2S_LL_MCLK_DIVIDER_MAX ((1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1)
#define I2S_LL_SLOT_FRAME_BIT_MAX 128 // Up-to 128 bits in one frame, determined by MAX(half_sample_bits) * 2