Skip to content

Commit 42509fa

Browse files
committed
Merge branch 'bugfix/i2s_pdm_dac_wrong_clock_freq' into 'master'
i2s_pdm: fix tx frequency limitation Closes IDFGH-9010 See merge request espressif/esp-idf!21764
2 parents c681c92 + 943dcd2 commit 42509fa

File tree

23 files changed

+120
-65
lines changed

23 files changed

+120
-65
lines changed

components/driver/deprecated/dac_common_legacy.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ esp_err_t dac_cw_generator_config(dac_cw_config_t *cw)
115115
{
116116
ESP_RETURN_ON_FALSE(cw, ESP_ERR_INVALID_ARG, TAG, "invalid clock configuration");
117117
portENTER_CRITICAL(&rtc_spinlock);
118-
/* Enable the rtc8m clock temporary to get the correct frequecy */
118+
/* Enable the rtc8m clock temporary to get the correct frequency */
119119
periph_rtc_dig_clk8m_enable();
120120
uint32_t rtc_freq = periph_rtc_dig_clk8m_get_freq();
121121
periph_rtc_dig_clk8m_disable();

components/driver/deprecated/i2s_legacy.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,6 +1201,7 @@ esp_err_t i2s_set_pdm_tx_up_sample(i2s_port_t i2s_num, const i2s_pdm_tx_upsample
12011201
p_i2s[i2s_num]->clk_cfg.up_sample_fp = upsample_cfg->fp;
12021202
p_i2s[i2s_num]->clk_cfg.up_sample_fs = upsample_cfg->fs;
12031203
i2s_ll_tx_set_pdm_fpfs(p_i2s[i2s_num]->hal.dev, upsample_cfg->fp, upsample_cfg->fs);
1204+
i2s_ll_tx_set_pdm_over_sample_ratio(p_i2s[i2s_num]->hal.dev, upsample_cfg->fp / upsample_cfg->fs);
12041205
i2s_start(i2s_num);
12051206
xSemaphoreGive(p_i2s[i2s_num]->tx->mux);
12061207
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);

components/driver/i2s/i2s_common.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ static uint32_t i2s_set_get_apll_freq(uint32_t mclk_freq_hz)
456456
mclk_div = mclk_div < 2 ? 2 : mclk_div;
457457
uint32_t expt_freq = mclk_freq_hz * mclk_div;
458458
if (expt_freq > SOC_APLL_MAX_HZ) {
459-
ESP_LOGE(TAG, "The required APLL frequecy exceed its maximum value");
459+
ESP_LOGE(TAG, "The required APLL frequency exceed its maximum value");
460460
return 0;
461461
}
462462
uint32_t real_freq = 0;

components/driver/i2s/i2s_pdm.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,19 @@ static esp_err_t i2s_pdm_tx_calculate_clock(i2s_chan_handle_t handle, const i2s_
3535
uint32_t rate = clk_cfg->sample_rate_hz;
3636
i2s_pdm_tx_clk_config_t *pdm_tx_clk = (i2s_pdm_tx_clk_config_t *)clk_cfg;
3737

38-
clk_info->bclk = rate * I2S_LL_PDM_BCK_FACTOR * pdm_tx_clk->up_sample_fp / pdm_tx_clk->up_sample_fs;
38+
// Over sampling ratio (integer, mostly should be 1 or 2)
39+
uint32_t over_sample_ratio = pdm_tx_clk->up_sample_fp / pdm_tx_clk->up_sample_fs;
40+
clk_info->bclk = rate * I2S_LL_PDM_BCK_FACTOR * over_sample_ratio;
3941
clk_info->bclk_div = 8;
4042
clk_info->mclk = clk_info->bclk * clk_info->bclk_div;
4143
clk_info->sclk = i2s_get_source_clk_freq(clk_cfg->clk_src, clk_info->mclk);
4244
clk_info->mclk_div = clk_info->sclk / clk_info->mclk;
4345

4446
/* Check if the configuration is correct */
4547
ESP_RETURN_ON_FALSE(clk_info->mclk_div, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large");
46-
/* Set upsampling configuration */
48+
/* Set up sampling configuration */
4749
i2s_ll_tx_set_pdm_fpfs(handle->controller->hal.dev, pdm_tx_clk->up_sample_fp, pdm_tx_clk->up_sample_fs);
50+
i2s_ll_tx_set_pdm_over_sample_ratio(handle->controller->hal.dev, over_sample_ratio);
4851

4952
return ESP_OK;
5053
}
@@ -53,6 +56,7 @@ static esp_err_t i2s_pdm_tx_set_clock(i2s_chan_handle_t handle, const i2s_pdm_tx
5356
{
5457
esp_err_t ret = ESP_OK;
5558
i2s_pdm_tx_config_t *pdm_tx_cfg = (i2s_pdm_tx_config_t *)(handle->mode_info);
59+
ESP_RETURN_ON_FALSE(clk_cfg->up_sample_fs <= 480, ESP_ERR_INVALID_ARG, TAG, "up_sample_fs should be within 480");
5660

5761
i2s_hal_clock_info_t clk_info;
5862
/* Calculate clock parameters */
@@ -64,7 +68,7 @@ static esp_err_t i2s_pdm_tx_set_clock(i2s_chan_handle_t handle, const i2s_pdm_tx
6468
/* Set clock configurations in HAL*/
6569
i2s_hal_set_tx_clock(&handle->controller->hal, &clk_info, clk_cfg->clk_src);
6670
#if SOC_I2S_HW_VERSION_2
67-
/* Work aroud for PDM TX clock, overwrite the raw division directly to reduce the noise
71+
/* Work around for PDM TX clock, overwrite the raw division directly to reduce the noise
6872
* This set of coefficients is a special division to reduce the background noise in PDM TX mode */
6973
i2s_ll_tx_set_raw_clk_div(handle->controller->hal.dev, 1, 1, 0, 0);
7074
#endif
@@ -213,7 +217,7 @@ esp_err_t i2s_channel_reconfig_pdm_tx_clock(i2s_chan_handle_t handle, const i2s_
213217
esp_err_t ret = ESP_OK;
214218

215219
xSemaphoreTake(handle->mutex, portMAX_DELAY);
216-
ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded");
220+
ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard mode");
217221
ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be disabled before reconfiguring the clock");
218222
i2s_pdm_tx_config_t *pdm_tx_cfg = (i2s_pdm_tx_config_t *)handle->mode_info;
219223
ESP_GOTO_ON_FALSE(pdm_tx_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete");
@@ -263,7 +267,7 @@ esp_err_t i2s_channel_reconfig_pdm_tx_slot(i2s_chan_handle_t handle, const i2s_p
263267
esp_err_t ret = ESP_OK;
264268

265269
xSemaphoreTake(handle->mutex, portMAX_DELAY);
266-
ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded");
270+
ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard mode");
267271
ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be disabled before reconfiguring the slot");
268272

269273
i2s_pdm_tx_config_t *pdm_tx_cfg = (i2s_pdm_tx_config_t *)handle->mode_info;
@@ -294,7 +298,7 @@ esp_err_t i2s_channel_reconfig_pdm_tx_gpio(i2s_chan_handle_t handle, const i2s_p
294298
esp_err_t ret = ESP_OK;
295299

296300
xSemaphoreTake(handle->mutex, portMAX_DELAY);
297-
ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "This handle is not working in standard moded");
301+
ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "This handle is not working in standard mode");
298302
ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "Invalid state, I2S should be disabled before reconfiguring the gpio");
299303

300304
ESP_GOTO_ON_ERROR(i2s_pdm_tx_set_gpio(handle, gpio_cfg), err, TAG, "set i2s standard slot failed");
@@ -489,7 +493,7 @@ esp_err_t i2s_channel_reconfig_pdm_rx_clock(i2s_chan_handle_t handle, const i2s_
489493
esp_err_t ret = ESP_OK;
490494

491495
xSemaphoreTake(handle->mutex, portMAX_DELAY);
492-
ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded");
496+
ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard mode");
493497
ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be disabled before reconfiguring the clock");
494498
i2s_pdm_rx_config_t *pdm_rx_cfg = (i2s_pdm_rx_config_t *)handle->mode_info;
495499
ESP_GOTO_ON_FALSE(pdm_rx_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete");
@@ -539,7 +543,7 @@ esp_err_t i2s_channel_reconfig_pdm_rx_slot(i2s_chan_handle_t handle, const i2s_p
539543
esp_err_t ret = ESP_OK;
540544

541545
xSemaphoreTake(handle->mutex, portMAX_DELAY);
542-
ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded");
546+
ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard mode");
543547
ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be disabled before reconfiguring the slot");
544548

545549
i2s_pdm_rx_config_t *pdm_rx_cfg = (i2s_pdm_rx_config_t *)handle->mode_info;
@@ -569,7 +573,7 @@ esp_err_t i2s_channel_reconfig_pdm_rx_gpio(i2s_chan_handle_t handle, const i2s_p
569573
esp_err_t ret = ESP_OK;
570574

571575
xSemaphoreTake(handle->mutex, portMAX_DELAY);
572-
ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "This handle is not working in standard moded");
576+
ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "This handle is not working in standard mode");
573577
ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "Invalid state, I2S should be disabled before reconfiguring the gpio");
574578

575579
ESP_GOTO_ON_ERROR(i2s_pdm_rx_set_gpio(handle, gpio_cfg), err, TAG, "set i2s standard slot failed");

components/driver/i2s/i2s_private.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ esp_err_t i2s_free_dma_desc(i2s_chan_handle_t handle);
145145
* @return
146146
* - ESP_OK Allocate memory success
147147
* - ESP_ERR_INVALID_ARG NULL pointer or bufsize is too big
148-
* - ESP_ERR_NO_MEM No memmory for DMA descriptor and DMA buffer
148+
* - ESP_ERR_NO_MEM No memory for DMA descriptor and DMA buffer
149149
*/
150150
esp_err_t i2s_alloc_dma_desc(i2s_chan_handle_t handle, uint32_t num, uint32_t bufsize);
151151

@@ -165,7 +165,7 @@ uint32_t i2s_get_buf_size(i2s_chan_handle_t handle, uint32_t data_bit_width, uin
165165
* @brief Get the frequency of the source clock
166166
*
167167
* @param clk_src clock source
168-
* @param mclk_freq_hz Expected mclk frequenct in Hz
168+
* @param mclk_freq_hz Expected mclk frequency in Hz
169169
* @return
170170
* - Actual source clock frequency
171171
*/

components/driver/i2s/i2s_std.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ esp_err_t i2s_channel_reconfig_std_clock(i2s_chan_handle_t handle, const i2s_std
259259
esp_err_t ret = ESP_OK;
260260

261261
xSemaphoreTake(handle->mutex, portMAX_DELAY);
262-
ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_STD, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded");
262+
ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_STD, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard mode");
263263
ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be disabled before reconfiguring the clock");
264264

265265
i2s_std_config_t *std_cfg = (i2s_std_config_t *)handle->mode_info;
@@ -309,7 +309,7 @@ esp_err_t i2s_channel_reconfig_std_slot(i2s_chan_handle_t handle, const i2s_std_
309309
esp_err_t ret = ESP_OK;
310310

311311
xSemaphoreTake(handle->mutex, portMAX_DELAY);
312-
ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_STD, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded");
312+
ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_STD, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard mode");
313313
ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be disabled before reconfiguring the slot");
314314

315315
i2s_std_config_t *std_cfg = (i2s_std_config_t *)handle->mode_info;
@@ -339,7 +339,7 @@ esp_err_t i2s_channel_reconfig_std_gpio(i2s_chan_handle_t handle, const i2s_std_
339339
esp_err_t ret = ESP_OK;
340340

341341
xSemaphoreTake(handle->mutex, portMAX_DELAY);
342-
ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_STD, ESP_ERR_INVALID_ARG, err, TAG, "This handle is not working in standard moded");
342+
ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_STD, ESP_ERR_INVALID_ARG, err, TAG, "This handle is not working in standard mode");
343343
ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "Invalid state, I2S should be disabled before reconfiguring the gpio");
344344

345345
ESP_GOTO_ON_ERROR(i2s_std_set_gpio(handle, gpio_cfg), err, TAG, "set i2s standard slot failed");

components/driver/i2s/i2s_tdm.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ esp_err_t i2s_channel_reconfig_tdm_clock(i2s_chan_handle_t handle, const i2s_tdm
264264
esp_err_t ret = ESP_OK;
265265

266266
xSemaphoreTake(handle->mutex, portMAX_DELAY);
267-
ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_TDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded");
267+
ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_TDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard mode");
268268
ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be disabled before reconfiguring the clock");
269269
i2s_tdm_config_t *tdm_cfg = (i2s_tdm_config_t *)handle->mode_info;
270270
ESP_GOTO_ON_FALSE(tdm_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete");
@@ -314,7 +314,7 @@ esp_err_t i2s_channel_reconfig_tdm_slot(i2s_chan_handle_t handle, const i2s_tdm_
314314
esp_err_t ret = ESP_OK;
315315

316316
xSemaphoreTake(handle->mutex, portMAX_DELAY);
317-
ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_TDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded");
317+
ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_TDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard mode");
318318
ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be disabled before reconfiguring the slot");
319319

320320
i2s_tdm_config_t *tdm_cfg = (i2s_tdm_config_t *)handle->mode_info;
@@ -347,7 +347,7 @@ esp_err_t i2s_channel_reconfig_tdm_gpio(i2s_chan_handle_t handle, const i2s_tdm_
347347
esp_err_t ret = ESP_OK;
348348

349349
xSemaphoreTake(handle->mutex, portMAX_DELAY);
350-
ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_TDM, ESP_ERR_INVALID_ARG, err, TAG, "This handle is not working in standard moded");
350+
ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_TDM, ESP_ERR_INVALID_ARG, err, TAG, "This handle is not working in standard mode");
351351
ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "Invalid state, I2S should be disabled before reconfiguring the gpio");
352352

353353
ESP_GOTO_ON_ERROR(i2s_tdm_set_gpio(handle, gpio_cfg), err, TAG, "set i2s standard slot failed");

components/driver/include/driver/i2s_common.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ typedef struct {
4545
i2s_isr_callback_t on_sent; /**< Callback of data sent event, only for tx channel
4646
* The event data includes DMA buffer address and size that just finished sending data
4747
*/
48-
i2s_isr_callback_t on_send_q_ovf; /**< Callback of sending queue overflowed evnet, only for tx channel
48+
i2s_isr_callback_t on_send_q_ovf; /**< Callback of sending queue overflowed event, only for tx channel
4949
* The event data includes buffer size that has been overwritten
5050
*/
5151
} i2s_event_callbacks_t;
@@ -130,7 +130,7 @@ esp_err_t i2s_channel_get_info(i2s_chan_handle_t handle, i2s_chan_info_t *chan_i
130130
* @brief Enable the i2s channel
131131
* @note Only allowed to be called when the channel state is READY, (i.e., channel has been initialized, but not started)
132132
* the channel will enter RUNNING state once it is enabled successfully.
133-
* @note Enbale the channel can start the I2S communication on hardware. It will start outputting bclk and ws signal.
133+
* @note Enable the channel can start the I2S communication on hardware. It will start outputting bclk and ws signal.
134134
* For mclk signal, it will start to output when initialization is finished
135135
*
136136
* @param[in] handle I2S channel handler

0 commit comments

Comments
 (0)