fix(i2s): reset the dma buf_size while allocation failed

Closes https://github.com/espressif/esp-idf/issues/15648
This commit is contained in:
laokaiyao
2025-03-26 15:24:29 +08:00
parent 635c4190f8
commit fdcf1dcecc
5 changed files with 26 additions and 29 deletions

View File

@@ -389,37 +389,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) esp_err_t i2s_free_dma_desc(i2s_chan_handle_t handle)
{ {
I2S_NULL_POINTER_CHECK(TAG, handle); I2S_NULL_POINTER_CHECK(TAG, handle);
if (!handle->dma.desc) { handle->dma.buf_size = 0;
return ESP_OK;
}
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;
}
if (handle->dma.desc[i]) {
free(handle->dma.desc[i]);
handle->dma.desc[i] = NULL;
}
}
if (handle->dma.bufs) {
free(handle->dma.bufs);
handle->dma.bufs = NULL;
}
if (handle->dma.desc) { 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); free(handle->dma.desc);
handle->dma.desc = NULL; 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; 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); I2S_NULL_POINTER_CHECK(TAG, handle);
esp_err_t ret = ESP_OK; 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); 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; handle->dma.buf_size = bufsize;
/* Descriptors must be in the internal RAM */ /* Descriptors must be in the internal RAM */

View File

@@ -95,9 +95,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); 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 */ /* The DMA buffer need to re-allocate if the buffer size changed */
if (handle->dma.buf_size != buf_size) { 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_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"); TAG, "allocate memory for dma descriptor failed");
} }
/* Share bck and ws signal in full-duplex mode */ /* Share bck and ws signal in full-duplex mode */
@@ -388,9 +387,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); 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 */ /* The DMA buffer need to re-allocate if the buffer size changed */
if (handle->dma.buf_size != buf_size) { 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_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"); TAG, "allocate memory for dma descriptor failed");
} }
/* Share bck and ws signal in full-duplex mode */ /* Share bck and ws signal in full-duplex mode */

View File

@@ -191,7 +191,6 @@ esp_err_t i2s_free_dma_desc(i2s_chan_handle_t handle);
* @brief Allocate memory for I2S DMA descriptor and DMA buffer * @brief Allocate memory for I2S DMA descriptor and DMA buffer
* *
* @param handle I2S channel handle * @param handle I2S channel handle
* @param num Number of DMA descriptors
* @param bufsize The DMA buffer size * @param bufsize The DMA buffer size
* *
* @return * @return
@@ -199,7 +198,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_INVALID_ARG NULL pointer or bufsize is too big
* - ESP_ERR_NO_MEM No memory for DMA descriptor and DMA buffer * - 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 * @brief Get DMA buffer size

View File

@@ -106,9 +106,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); 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 */ /* The DMA buffer need to re-allocate if the buffer size changed */
if (handle->dma.buf_size != buf_size) { 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_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"); TAG, "allocate memory for dma descriptor failed");
} }
bool is_slave = handle->role == I2S_ROLE_SLAVE; bool is_slave = handle->role == I2S_ROLE_SLAVE;

View File

@@ -114,9 +114,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); 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 */ /* The DMA buffer need to re-allocate if the buffer size changed */
if (handle->dma.buf_size != buf_size) { 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_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"); TAG, "allocate memory for dma descriptor failed");
} }
bool is_slave = handle->role == I2S_ROLE_SLAVE; bool is_slave = handle->role == I2S_ROLE_SLAVE;