Skip to content

Commit 84bfea4

Browse files
committed
Merge branch 'bugfix/check_i2s_minimum_sample_freq' into 'master'
fix(i2s): add check for the minimum sample rate Closes IDFGH-14952 See merge request espressif/esp-idf!38108
2 parents 2ee8c06 + 9d33cd4 commit 84bfea4

File tree

4 files changed

+16
-6
lines changed

4 files changed

+16
-6
lines changed

components/esp_driver_i2s/i2s_pdm.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ static esp_err_t i2s_pdm_tx_calculate_clock(i2s_chan_handle_t handle, const i2s_
5656
clk_info->mclk_div = clk_info->sclk / clk_info->mclk;
5757

5858
/* Check if the configuration is correct. Use float for check in case the mclk division might be carried up in the fine division calculation */
59-
ESP_RETURN_ON_FALSE(clk_info->sclk / (float)clk_info->mclk > 1.99, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large");
59+
ESP_RETURN_ON_FALSE((float)clk_info->sclk > clk_info->mclk * 1.99, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large");
6060
ESP_RETURN_ON_FALSE(clk_info->mclk_div < 256, ESP_ERR_INVALID_ARG, TAG, "sample rate is too small");
6161
#if SOC_I2S_SUPPORTS_PCM2PDM
6262
if (!handle->is_raw_pdm) {
@@ -385,7 +385,8 @@ static esp_err_t i2s_pdm_rx_calculate_clock(i2s_chan_handle_t handle, const i2s_
385385
clk_info->mclk_div = clk_info->sclk / clk_info->mclk;
386386

387387
/* Check if the configuration is correct. Use float for check in case the mclk division might be carried up in the fine division calculation */
388-
ESP_RETURN_ON_FALSE(clk_info->sclk / (float)clk_info->mclk > 1.99, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large");
388+
ESP_RETURN_ON_FALSE((float)clk_info->sclk > clk_info->mclk * 1.99, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large");
389+
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");
389390
#if SOC_I2S_SUPPORTS_PDM2PCM
390391
if (!handle->is_raw_pdm) {
391392
/* Set down-sampling configuration */

components/esp_driver_i2s/i2s_std.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,12 @@ static esp_err_t i2s_std_calculate_clock(i2s_chan_handle_t handle, const i2s_std
4343
ESP_LOGW(TAG, "the current mclk multiple cannot perform integer division (slot_num: %"PRIu32", slot_bits: %"PRIu32")", handle->total_slot, slot_bits);
4444
}
4545
} else {
46-
/* For slave mode, mclk >= bclk * 8, so fix bclk_div to 2 first */
47-
clk_info->bclk_div = 8;
46+
if (clk_cfg->bclk_div < 8) {
47+
ESP_LOGW(TAG, "the current bclk division is too small, adjust the bclk division to 8");
48+
clk_info->bclk_div = 8;
49+
} else {
50+
clk_info->bclk_div = clk_cfg->bclk_div;
51+
}
4852
clk_info->bclk = rate * handle->total_slot * slot_bits;
4953
clk_info->mclk = clk_info->bclk * clk_info->bclk_div;
5054
}
@@ -60,7 +64,8 @@ static esp_err_t i2s_std_calculate_clock(i2s_chan_handle_t handle, const i2s_std
6064
clk_info->mclk_div = clk_info->sclk / clk_info->mclk;
6165

6266
/* Check if the configuration is correct. Use float for check in case the mclk division might be carried up in the fine division calculation */
63-
ESP_RETURN_ON_FALSE(clk_info->sclk / (float)clk_info->mclk > min_mclk_div, ESP_ERR_INVALID_ARG, TAG, "sample rate or mclk_multiple is too large for the current clock source");
67+
ESP_RETURN_ON_FALSE((float)clk_info->sclk > clk_info->mclk * min_mclk_div, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large");
68+
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");
6469

6570
return ESP_OK;
6671
}

components/esp_driver_i2s/i2s_tdm.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ static esp_err_t i2s_tdm_calculate_clock(i2s_chan_handle_t handle, const i2s_tdm
6666
clk_info->mclk_div = clk_info->sclk / clk_info->mclk;
6767

6868
/* Check if the configuration is correct. Use float for check in case the mclk division might be carried up in the fine division calculation */
69-
ESP_RETURN_ON_FALSE(clk_info->sclk / (float)clk_info->mclk > min_mclk_div, ESP_ERR_INVALID_ARG, TAG, "sample rate or mclk_multiple is too large for the current clock source");
69+
ESP_RETURN_ON_FALSE((float)clk_info->sclk > clk_info->mclk * min_mclk_div, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large");
70+
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");
7071

7172
return ESP_OK;
7273
}

components/esp_driver_i2s/include/driver/i2s_std.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ extern "C" {
204204
.sample_rate_hz = rate, \
205205
.clk_src = I2S_CLK_SRC_DEFAULT, \
206206
.mclk_multiple = I2S_MCLK_MULTIPLE_256, \
207+
.bclk_div = 8, \
207208
}
208209
#else
209210
/**
@@ -217,6 +218,7 @@ extern "C" {
217218
.clk_src = I2S_CLK_SRC_DEFAULT, \
218219
.ext_clk_freq_hz = 0, \
219220
.mclk_multiple = I2S_MCLK_MULTIPLE_256, \
221+
.bclk_div = 8, \
220222
}
221223
#endif
222224

@@ -265,6 +267,7 @@ typedef struct {
265267
* but please set this field a multiple of `3` (like 384) when using 24-bit data width,
266268
* otherwise the sample rate might be inaccurate
267269
*/
270+
uint32_t bclk_div; /*!< The division from MCLK to BCLK, only take effect for slave role, it shouldn't be smaller than 8. Increase this field when data sent by slave lag behind */
268271
} i2s_std_clk_config_t;
269272

270273
/**

0 commit comments

Comments
 (0)