Skip to content

Commit 1bd8fab

Browse files
committed
Merge branch 'feature/i2s_support_change_freq_in_runtime' into 'master'
feat(i2s): support tuning rate dynamically Closes IDF-11679 See merge request espressif/esp-idf!36537
2 parents 581cbca + d2c5724 commit 1bd8fab

File tree

37 files changed

+1193
-112
lines changed

37 files changed

+1193
-112
lines changed

components/driver/deprecated/i2s_legacy.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -1096,10 +1096,10 @@ static void i2s_set_clock_legacy(i2s_port_t i2s_num)
10961096
i2s_calculate_clock(i2s_num, &clk_info);
10971097
I2S_CLOCK_SRC_ATOMIC() {
10981098
if (p_i2s[i2s_num]->dir & I2S_DIR_TX) {
1099-
i2s_hal_set_tx_clock(&(p_i2s[i2s_num]->hal), &clk_info, clk_cfg->clk_src);
1099+
i2s_hal_set_tx_clock(&(p_i2s[i2s_num]->hal), &clk_info, clk_cfg->clk_src, NULL);
11001100
}
11011101
if (p_i2s[i2s_num]->dir & I2S_DIR_RX) {
1102-
i2s_hal_set_rx_clock(&(p_i2s[i2s_num]->hal), &clk_info, clk_cfg->clk_src);
1102+
i2s_hal_set_rx_clock(&(p_i2s[i2s_num]->hal), &clk_info, clk_cfg->clk_src, NULL);
11031103
}
11041104
}
11051105
}
@@ -1634,10 +1634,10 @@ esp_err_t i2s_driver_uninstall(i2s_port_t i2s_num)
16341634
I2S_CLOCK_SRC_ATOMIC() {
16351635
// switch back to PLL clock source
16361636
if (obj->dir & I2S_DIR_TX) {
1637-
i2s_hal_set_tx_clock(&obj->hal, NULL, I2S_CLK_SRC_DEFAULT);
1637+
i2s_hal_set_tx_clock(&obj->hal, NULL, I2S_CLK_SRC_DEFAULT, NULL);
16381638
}
16391639
if (obj->dir & I2S_DIR_RX) {
1640-
i2s_hal_set_rx_clock(&obj->hal, NULL, I2S_CLK_SRC_DEFAULT);
1640+
i2s_hal_set_rx_clock(&obj->hal, NULL, I2S_CLK_SRC_DEFAULT, NULL);
16411641
}
16421642
}
16431643
periph_rtc_apll_release();

components/esp_driver_i2s/i2s_common.c

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "soc/soc_caps.h"
2626
#include "hal/gpio_hal.h"
2727
#include "hal/i2s_hal.h"
28+
#include "hal/hal_utils.h"
2829
#include "hal/dma_types.h"
2930
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
3031
#include "hal/cache_hal.h"
@@ -1374,6 +1375,95 @@ esp_err_t i2s_channel_read(i2s_chan_handle_t handle, void *dest, size_t size, si
13741375
return ret;
13751376
}
13761377

1378+
esp_err_t i2s_channel_tune_rate(i2s_chan_handle_t handle, const i2s_tuning_config_t *tune_cfg, i2s_tuning_info_t *tune_info)
1379+
{
1380+
/** We tune the sample rate via the MCLK clock.
1381+
* Because the sample rate is decided by MCLK eventually,
1382+
* and MCLK has a higher resolution which can be tuned more precisely.
1383+
*/
1384+
1385+
ESP_RETURN_ON_FALSE(handle, ESP_ERR_INVALID_ARG, TAG, "NULL pointer");
1386+
ESP_RETURN_ON_FALSE(!handle->is_external, ESP_ERR_NOT_SUPPORTED, TAG, "Not support to tune rate for external mclk");
1387+
1388+
/* If no tuning configuration given, just return the current information */
1389+
if (tune_cfg == NULL) {
1390+
xSemaphoreTake(handle->mutex, portMAX_DELAY);
1391+
goto result;
1392+
}
1393+
ESP_RETURN_ON_FALSE(tune_cfg->max_delta_mclk >= tune_cfg->min_delta_mclk, ESP_ERR_INVALID_ARG, TAG, "invalid range");
1394+
1395+
uint32_t new_mclk = 0;
1396+
1397+
/* Get the new MCLK according to the tuning operation */
1398+
switch (tune_cfg->tune_mode) {
1399+
case I2S_TUNING_MODE_ADDSUB:
1400+
new_mclk = handle->curr_mclk_hz + tune_cfg->tune_mclk_val;
1401+
break;
1402+
case I2S_TUNING_MODE_SET:
1403+
new_mclk = tune_cfg->tune_mclk_val;
1404+
break;
1405+
case I2S_TUNING_MODE_RESET:
1406+
new_mclk = handle->origin_mclk_hz;
1407+
break;
1408+
default:
1409+
return ESP_ERR_INVALID_ARG;
1410+
}
1411+
/* Check if the tuned mclk is within the supposed range */
1412+
if ((int32_t)new_mclk - (int32_t)handle->origin_mclk_hz > tune_cfg->max_delta_mclk) {
1413+
new_mclk = handle->origin_mclk_hz + tune_cfg->max_delta_mclk;
1414+
} else if ((int32_t)new_mclk - (int32_t)handle->origin_mclk_hz < tune_cfg->min_delta_mclk) {
1415+
new_mclk = handle->origin_mclk_hz + tune_cfg->min_delta_mclk;
1416+
}
1417+
xSemaphoreTake(handle->mutex, portMAX_DELAY);
1418+
#if SOC_CLK_APLL_SUPPORTED
1419+
if (handle->clk_src == I2S_CLK_SRC_APLL) {
1420+
periph_rtc_apll_release();
1421+
handle->sclk_hz = i2s_set_get_apll_freq(new_mclk);
1422+
periph_rtc_apll_acquire();
1423+
}
1424+
#endif
1425+
/* Calculate the new divider */
1426+
hal_utils_clk_div_t mclk_div = {};
1427+
i2s_hal_calc_mclk_precise_division(handle->sclk_hz, new_mclk, &mclk_div);
1428+
/* mclk_div = sclk / mclk >= 2 */
1429+
if (mclk_div.integer < 2) {
1430+
return ESP_ERR_INVALID_ARG;
1431+
}
1432+
/* Set the new divider for MCLK */
1433+
I2S_CLOCK_SRC_ATOMIC() {
1434+
if (handle->dir == I2S_DIR_TX) {
1435+
i2s_ll_tx_set_mclk(handle->controller->hal.dev, &mclk_div);
1436+
#if SOC_I2S_HW_VERSION_2
1437+
i2s_ll_tx_update(handle->controller->hal.dev);
1438+
#endif
1439+
} else {
1440+
i2s_ll_rx_set_mclk(handle->controller->hal.dev, &mclk_div);
1441+
#if SOC_I2S_HW_VERSION_2
1442+
i2s_ll_rx_update(handle->controller->hal.dev);
1443+
#endif
1444+
}
1445+
}
1446+
/* Save the current mclk frequency */
1447+
handle->curr_mclk_hz = (uint32_t)(((uint64_t)handle->sclk_hz * mclk_div.denominator) /
1448+
(mclk_div.integer * mclk_div.denominator + mclk_div.numerator));
1449+
result:
1450+
/* Assign the information if needed */
1451+
if (tune_info) {
1452+
tune_info->curr_mclk_hz = handle->curr_mclk_hz;
1453+
tune_info->delta_mclk_hz = (int32_t)handle->curr_mclk_hz - (int32_t)handle->origin_mclk_hz;
1454+
uint32_t tot_size = handle->dma.buf_size * handle->dma.desc_num;
1455+
uint32_t used_size = 0;
1456+
if (handle->dir == I2S_DIR_TX) {
1457+
used_size = uxQueueSpacesAvailable(handle->msg_queue) * handle->dma.buf_size + handle->dma.rw_pos;
1458+
} else {
1459+
used_size = uxQueueMessagesWaiting(handle->msg_queue) * handle->dma.buf_size + handle->dma.buf_size - handle->dma.rw_pos;
1460+
}
1461+
tune_info->water_mark = used_size * 100 / tot_size;
1462+
}
1463+
xSemaphoreGive(handle->mutex);
1464+
return ESP_OK;
1465+
}
1466+
13771467
#if SOC_I2S_SUPPORTS_TX_SYNC_CNT
13781468
uint32_t i2s_sync_get_bclk_count(i2s_chan_handle_t tx_handle)
13791469
{

components/esp_driver_i2s/i2s_pdm.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,12 @@ static esp_err_t i2s_pdm_tx_set_clock(i2s_chan_handle_t handle, const i2s_pdm_tx
8181
i2s_hal_clock_info_t clk_info;
8282
/* Calculate clock parameters */
8383
ESP_RETURN_ON_ERROR(i2s_pdm_tx_calculate_clock(handle, clk_cfg, &clk_info), TAG, "clock calculate failed");
84-
ESP_LOGD(TAG, "Clock division info: [sclk] %"PRIu32" Hz [mdiv] %d [mclk] %"PRIu32" Hz [bdiv] %d [bclk] %"PRIu32" Hz",
85-
clk_info.sclk, clk_info.mclk_div, clk_info.mclk, clk_info.bclk_div, clk_info.bclk);
8684

85+
hal_utils_clk_div_t ret_mclk_div = {};
8786
portENTER_CRITICAL(&g_i2s.spinlock);
8887
/* Set clock configurations in HAL*/
8988
I2S_CLOCK_SRC_ATOMIC() {
90-
i2s_hal_set_tx_clock(&handle->controller->hal, &clk_info, clk_cfg->clk_src);
89+
i2s_hal_set_tx_clock(&handle->controller->hal, &clk_info, clk_cfg->clk_src, &ret_mclk_div);
9190
}
9291
#if SOC_I2S_HW_VERSION_2
9392
/* Work around for PDM TX clock, overwrite the raw division directly to reduce the noise
@@ -98,6 +97,13 @@ static esp_err_t i2s_pdm_tx_set_clock(i2s_chan_handle_t handle, const i2s_pdm_tx
9897

9998
/* Update the mode info: clock configuration */
10099
memcpy(&(pdm_tx_cfg->clk_cfg), clk_cfg, sizeof(i2s_pdm_tx_clk_config_t));
100+
handle->clk_src = clk_cfg->clk_src;
101+
handle->sclk_hz = clk_info.sclk;
102+
handle->origin_mclk_hz = ((uint64_t)clk_info.sclk * ret_mclk_div.denominator) / (ret_mclk_div.integer * ret_mclk_div.denominator + ret_mclk_div.numerator);
103+
handle->curr_mclk_hz = handle->origin_mclk_hz;
104+
105+
ESP_LOGD(TAG, "Clock division info: [sclk] %"PRIu32" Hz [mdiv] %"PRIu32" %"PRIu32"/%"PRIu32" [mclk] %"PRIu32" Hz [bdiv] %d [bclk] %"PRIu32" Hz",
106+
clk_info.sclk, ret_mclk_div.integer, ret_mclk_div.numerator, ret_mclk_div.denominator, handle->origin_mclk_hz, clk_info.bclk_div, clk_info.bclk);
101107

102108
return ret;
103109
}
@@ -401,18 +407,23 @@ static esp_err_t i2s_pdm_rx_set_clock(i2s_chan_handle_t handle, const i2s_pdm_rx
401407
i2s_hal_clock_info_t clk_info;
402408
/* Calculate clock parameters */
403409
ESP_RETURN_ON_ERROR(i2s_pdm_rx_calculate_clock(handle, clk_cfg, &clk_info), TAG, "clock calculate failed");
404-
ESP_LOGD(TAG, "Clock division info: [sclk] %"PRIu32" Hz [mdiv] %d [mclk] %"PRIu32" Hz [bdiv] %d [bclk] %"PRIu32" Hz",
405-
clk_info.sclk, clk_info.mclk_div, clk_info.mclk, clk_info.bclk_div, clk_info.bclk);
406410

411+
hal_utils_clk_div_t ret_mclk_div = {};
407412
portENTER_CRITICAL(&g_i2s.spinlock);
408413
/* Set clock configurations in HAL*/
409414
I2S_CLOCK_SRC_ATOMIC() {
410-
i2s_hal_set_rx_clock(&handle->controller->hal, &clk_info, clk_cfg->clk_src);
415+
i2s_hal_set_rx_clock(&handle->controller->hal, &clk_info, clk_cfg->clk_src, &ret_mclk_div);
411416
}
412417
portEXIT_CRITICAL(&g_i2s.spinlock);
413418

414419
/* Update the mode info: clock configuration */
415420
memcpy(&(pdm_rx_cfg->clk_cfg), clk_cfg, sizeof(i2s_pdm_rx_clk_config_t));
421+
handle->clk_src = clk_cfg->clk_src;
422+
handle->sclk_hz = clk_info.sclk;
423+
handle->origin_mclk_hz = ((uint64_t)clk_info.sclk * ret_mclk_div.denominator) / (ret_mclk_div.integer * ret_mclk_div.denominator + ret_mclk_div.numerator);
424+
handle->curr_mclk_hz = handle->origin_mclk_hz;
425+
ESP_LOGD(TAG, "Clock division info: [sclk] %"PRIu32" Hz [mdiv] %"PRIu32" %"PRIu32"/%"PRIu32" [mclk] %"PRIu32" Hz [bdiv] %d [bclk] %"PRIu32" Hz",
426+
clk_info.sclk, ret_mclk_div.integer, ret_mclk_div.numerator, ret_mclk_div.denominator, handle->origin_mclk_hz, clk_info.bclk_div, clk_info.bclk);
416427

417428
return ret;
418429
}

components/esp_driver_i2s/i2s_private.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -159,14 +159,21 @@ struct i2s_channel_obj_t {
159159
/* Stored configurations */
160160
int intr_prio_flags;/*!< i2s interrupt priority flags */
161161
void *mode_info; /*!< Slot, clock and gpio information of each mode */
162-
bool is_etm_start; /*!< Whether start by etm tasks */
163-
bool is_etm_stop; /*!< Whether stop by etm tasks */
162+
struct {
163+
bool is_etm_start: 1; /*!< Whether start by etm tasks */
164+
bool is_etm_stop: 1; /*!< Whether stop by etm tasks */
165+
bool is_raw_pdm: 1; /*!< Flag of whether send/receive PDM in raw data, i.e., no PCM2PDM/PDM2PCM filter enabled */
166+
bool is_external: 1; /*!< Whether use external clock */
164167
#if SOC_I2S_SUPPORTS_APLL
165-
bool apll_en; /*!< Flag of whether APLL enabled */
168+
bool apll_en: 1; /*!< Flag of whether APLL enabled */
166169
#endif
167-
bool is_raw_pdm; /*!< Flag of whether send/receive PDM in raw data, i.e., no PCM2PDM/PDM2PCM filter enabled */
170+
};
168171
uint32_t active_slot; /*!< Active slot number */
169172
uint32_t total_slot; /*!< Total slot number */
173+
i2s_clock_src_t clk_src; /*!< Clock source */
174+
uint32_t sclk_hz; /*!< Source clock frequency */
175+
uint32_t origin_mclk_hz; /*!< Original mclk frequency */
176+
uint32_t curr_mclk_hz; /*!< Current mclk frequency */
170177
/* Locks and queues */
171178
SemaphoreHandle_t mutex; /*!< Mutex semaphore for the channel operations */
172179
SemaphoreHandle_t binary; /*!< Binary semaphore for writing / reading / enabling / disabling */

components/esp_driver_i2s/i2s_std.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,10 @@ static esp_err_t i2s_std_calculate_clock(i2s_chan_handle_t handle, const i2s_std
4949
clk_info->mclk = clk_info->bclk * clk_info->bclk_div;
5050
}
5151
#if SOC_I2S_HW_VERSION_2
52-
clk_info->sclk = clk_cfg->clk_src == I2S_CLK_SRC_EXTERNAL ?
53-
clk_cfg->ext_clk_freq_hz : i2s_get_source_clk_freq(clk_cfg->clk_src, clk_info->mclk);
54-
float min_mclk_div = clk_cfg->clk_src == I2S_CLK_SRC_EXTERNAL ? 0.99 : 1.99;
52+
handle->is_external = clk_cfg->clk_src == I2S_CLK_SRC_EXTERNAL;
53+
clk_info->sclk = handle->is_external ? clk_cfg->ext_clk_freq_hz :
54+
i2s_get_source_clk_freq(clk_cfg->clk_src, clk_info->mclk);
55+
float min_mclk_div = handle->is_external ? 0.99 : 1.99;
5556
#else
5657
clk_info->sclk = i2s_get_source_clk_freq(clk_cfg->clk_src, clk_info->mclk);
5758
float min_mclk_div = 1.99;
@@ -77,22 +78,28 @@ static esp_err_t i2s_std_set_clock(i2s_chan_handle_t handle, const i2s_std_clk_c
7778
i2s_hal_clock_info_t clk_info;
7879
/* Calculate clock parameters */
7980
ESP_RETURN_ON_ERROR(i2s_std_calculate_clock(handle, clk_cfg, &clk_info), TAG, "clock calculate failed");
80-
ESP_LOGD(TAG, "Clock division info: [sclk] %"PRIu32" Hz [mdiv] %d [mclk] %"PRIu32" Hz [bdiv] %d [bclk] %"PRIu32" Hz",
81-
clk_info.sclk, clk_info.mclk_div, clk_info.mclk, clk_info.bclk_div, clk_info.bclk);
8281

82+
hal_utils_clk_div_t ret_mclk_div = {};
8383
portENTER_CRITICAL(&g_i2s.spinlock);
8484
/* Set clock configurations in HAL*/
8585
I2S_CLOCK_SRC_ATOMIC() {
8686
if (handle->dir == I2S_DIR_TX) {
87-
i2s_hal_set_tx_clock(&handle->controller->hal, &clk_info, clk_cfg->clk_src);
87+
i2s_hal_set_tx_clock(&handle->controller->hal, &clk_info, clk_cfg->clk_src, &ret_mclk_div);
8888
} else {
89-
i2s_hal_set_rx_clock(&handle->controller->hal, &clk_info, clk_cfg->clk_src);
89+
i2s_hal_set_rx_clock(&handle->controller->hal, &clk_info, clk_cfg->clk_src, &ret_mclk_div);
9090
}
9191
}
9292
portEXIT_CRITICAL(&g_i2s.spinlock);
9393

9494
/* Update the mode info: clock configuration */
9595
memcpy(&(std_cfg->clk_cfg), clk_cfg, sizeof(i2s_std_clk_config_t));
96+
handle->clk_src = clk_cfg->clk_src;
97+
handle->sclk_hz = clk_info.sclk;
98+
handle->origin_mclk_hz = ((uint64_t)clk_info.sclk * ret_mclk_div.denominator) / (ret_mclk_div.integer * ret_mclk_div.denominator + ret_mclk_div.numerator);
99+
handle->curr_mclk_hz = handle->origin_mclk_hz;
100+
101+
ESP_LOGD(TAG, "Clock division info: [sclk] %"PRIu32" Hz [mdiv] %"PRIu32" %"PRIu32"/%"PRIu32" [mclk] %"PRIu32" Hz [bdiv] %d [bclk] %"PRIu32" Hz",
102+
clk_info.sclk, ret_mclk_div.integer, ret_mclk_div.numerator, ret_mclk_div.denominator, handle->origin_mclk_hz, clk_info.bclk_div, clk_info.bclk);
96103

97104
return ret;
98105
}

components/esp_driver_i2s/i2s_tdm.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,10 @@ static esp_err_t i2s_tdm_calculate_clock(i2s_chan_handle_t handle, const i2s_tdm
5959
clk_info->bclk = rate * handle->total_slot * slot_bits;
6060
clk_info->mclk = clk_info->bclk * clk_info->bclk_div;
6161
}
62-
clk_info->sclk = clk_cfg->clk_src == I2S_CLK_SRC_EXTERNAL ?
63-
clk_cfg->ext_clk_freq_hz : i2s_get_source_clk_freq(clk_cfg->clk_src, clk_info->mclk);
64-
float min_mclk_div = clk_cfg->clk_src == I2S_CLK_SRC_EXTERNAL ? 0.99 : 1.99;
62+
handle->is_external = clk_cfg->clk_src == I2S_CLK_SRC_EXTERNAL;
63+
clk_info->sclk = handle->is_external ? clk_cfg->ext_clk_freq_hz :
64+
i2s_get_source_clk_freq(clk_cfg->clk_src, clk_info->mclk);
65+
float min_mclk_div = handle->is_external ? 0.99 : 1.99;
6566
clk_info->mclk_div = clk_info->sclk / clk_info->mclk;
6667

6768
/* Check if the configuration is correct. Use float for check in case the mclk division might be carried up in the fine division calculation */
@@ -78,25 +79,28 @@ static esp_err_t i2s_tdm_set_clock(i2s_chan_handle_t handle, const i2s_tdm_clk_c
7879
i2s_hal_clock_info_t clk_info;
7980
/* Calculate clock parameters */
8081
ESP_RETURN_ON_ERROR(i2s_tdm_calculate_clock(handle, clk_cfg, &clk_info), TAG, "clock calculate failed");
81-
ESP_LOGD(TAG, "Clock division info: [sclk] %"PRIu32" Hz [mdiv] %d [mclk] %"PRIu32" Hz [bdiv] %d [bclk] %"PRIu32" Hz",
82-
clk_info.sclk, clk_info.mclk_div, clk_info.mclk, clk_info.bclk_div, clk_info.bclk);
8382

83+
hal_utils_clk_div_t ret_mclk_div = {};
8484
portENTER_CRITICAL(&g_i2s.spinlock);
8585
/* Set clock configurations in HAL*/
8686
I2S_CLOCK_SRC_ATOMIC() {
8787
if (handle->dir == I2S_DIR_TX) {
88-
i2s_hal_set_tx_clock(&handle->controller->hal, &clk_info, clk_cfg->clk_src);
88+
i2s_hal_set_tx_clock(&handle->controller->hal, &clk_info, clk_cfg->clk_src, &ret_mclk_div);
8989
} else {
90-
i2s_hal_set_rx_clock(&handle->controller->hal, &clk_info, clk_cfg->clk_src);
90+
i2s_hal_set_rx_clock(&handle->controller->hal, &clk_info, clk_cfg->clk_src, &ret_mclk_div);
9191
}
9292
}
9393
portEXIT_CRITICAL(&g_i2s.spinlock);
9494

9595
/* Update the mode info: clock configuration */
9696
memcpy(&(tdm_cfg->clk_cfg), clk_cfg, sizeof(i2s_tdm_clk_config_t));
97-
/* Update the slot bit width to the actual slot bit width */
98-
tdm_cfg->slot_cfg.slot_bit_width = (int)tdm_cfg->slot_cfg.slot_bit_width < (int)tdm_cfg->slot_cfg.data_bit_width ?
99-
tdm_cfg->slot_cfg.data_bit_width : tdm_cfg->slot_cfg.slot_bit_width;
97+
handle->clk_src = clk_cfg->clk_src;
98+
handle->sclk_hz = clk_info.sclk;
99+
handle->origin_mclk_hz = ((uint64_t)clk_info.sclk * ret_mclk_div.denominator) / (ret_mclk_div.integer * ret_mclk_div.denominator + ret_mclk_div.numerator);
100+
handle->curr_mclk_hz = handle->origin_mclk_hz;
101+
102+
ESP_LOGD(TAG, "Clock division info: [sclk] %"PRIu32" Hz [mdiv] %"PRIu32" %"PRIu32"/%"PRIu32" [mclk] %"PRIu32" Hz [bdiv] %d [bclk] %"PRIu32" Hz",
103+
clk_info.sclk, ret_mclk_div.integer, ret_mclk_div.numerator, ret_mclk_div.denominator, handle->origin_mclk_hz, clk_info.bclk_div, clk_info.bclk);
100104

101105
return ret;
102106
}
@@ -147,6 +151,9 @@ static esp_err_t i2s_tdm_set_slot(i2s_chan_handle_t handle, const i2s_tdm_slot_c
147151
/* Update the mode info: slot configuration */
148152
i2s_tdm_config_t *tdm_cfg = (i2s_tdm_config_t *)(handle->mode_info);
149153
memcpy(&(tdm_cfg->slot_cfg), slot_cfg, sizeof(i2s_tdm_slot_config_t));
154+
/* Update the slot bit width to the actual slot bit width */
155+
tdm_cfg->slot_cfg.slot_bit_width = (int)tdm_cfg->slot_cfg.slot_bit_width < (int)tdm_cfg->slot_cfg.data_bit_width ?
156+
tdm_cfg->slot_cfg.data_bit_width : tdm_cfg->slot_cfg.slot_bit_width;
150157

151158
return ESP_OK;
152159
}

0 commit comments

Comments
 (0)