diff --git a/components/driver/i2s/i2s_pdm.c b/components/driver/i2s/i2s_pdm.c index 8e57e30389..f3e30556a5 100644 --- a/components/driver/i2s/i2s_pdm.c +++ b/components/driver/i2s/i2s_pdm.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -43,8 +43,8 @@ static esp_err_t i2s_pdm_tx_calculate_clock(i2s_chan_handle_t handle, const i2s_ clk_info->sclk = i2s_get_source_clk_freq(clk_cfg->clk_src, clk_info->mclk); clk_info->mclk_div = clk_info->sclk / clk_info->mclk; - /* Check if the configuration is correct */ - ESP_RETURN_ON_FALSE(clk_info->mclk_div, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large"); + /* 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"); /* 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); @@ -329,8 +329,8 @@ static esp_err_t i2s_pdm_rx_calculate_clock(i2s_chan_handle_t handle, const i2s_ clk_info->sclk = i2s_get_source_clk_freq(clk_cfg->clk_src, clk_info->mclk); clk_info->mclk_div = clk_info->sclk / clk_info->mclk; - /* Check if the configuration is correct */ - ESP_RETURN_ON_FALSE(clk_info->mclk_div, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large"); + /* 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"); /* Set down-sampling configuration */ i2s_ll_rx_set_pdm_dsr(handle->controller->hal.dev, pdm_rx_clk->dn_sample_mode); return ESP_OK; diff --git a/components/driver/i2s/i2s_std.c b/components/driver/i2s/i2s_std.c index 1a70e5852a..bfaf9140d4 100644 --- a/components/driver/i2s/i2s_std.c +++ b/components/driver/i2s/i2s_std.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -48,8 +48,8 @@ static esp_err_t i2s_std_calculate_clock(i2s_chan_handle_t handle, const i2s_std clk_info->sclk = i2s_get_source_clk_freq(clk_cfg->clk_src, clk_info->mclk); clk_info->mclk_div = clk_info->sclk / clk_info->mclk; - /* Check if the configuration is correct */ - ESP_RETURN_ON_FALSE(clk_info->mclk_div, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large"); + /* 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"); return ESP_OK; } diff --git a/components/driver/i2s/i2s_tdm.c b/components/driver/i2s/i2s_tdm.c index b1e89990eb..47315bf486 100644 --- a/components/driver/i2s/i2s_tdm.c +++ b/components/driver/i2s/i2s_tdm.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -59,8 +59,8 @@ static esp_err_t i2s_tdm_calculate_clock(i2s_chan_handle_t handle, const i2s_tdm clk_info->sclk = i2s_get_source_clk_freq(clk_cfg->clk_src, clk_info->mclk); clk_info->mclk_div = clk_info->sclk / clk_info->mclk; - /* Check if the configuration is correct */ - ESP_RETURN_ON_FALSE(clk_info->mclk_div, ESP_ERR_INVALID_ARG, TAG, "sample rate is too large"); + /* 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"); return ESP_OK; } diff --git a/components/driver/test_apps/i2s_test_apps/i2s_tdm/main/test_i2s_tdm_full_duplex.c b/components/driver/test_apps/i2s_test_apps/i2s_tdm/main/test_i2s_tdm_full_duplex.c index 28a8a7124b..10c228a263 100644 --- a/components/driver/test_apps/i2s_test_apps/i2s_tdm/main/test_i2s_tdm_full_duplex.c +++ b/components/driver/test_apps/i2s_test_apps/i2s_tdm/main/test_i2s_tdm_full_duplex.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -29,9 +29,11 @@ static const char *TAG = "i2s_tdm_full_duplex_test"; #if CONFIG_IDF_TARGET_ESP32H2 #define TEST_I2S_DO_IO (GPIO_NUM_2) #define TEST_I2S_DI_IO (GPIO_NUM_3) // DI and DO gpio will be reversed on slave runner +#define TEST_I2S_SAMPLE_RATE (16000) #else #define TEST_I2S_DO_IO (GPIO_NUM_6) #define TEST_I2S_DI_IO (GPIO_NUM_7) // DI and DO gpio will be reversed on slave runner +#define TEST_I2S_SAMPLE_RATE (48000) #endif // CONFIG_IDF_TARGET_ESP32H2 typedef struct { @@ -263,12 +265,12 @@ static void test_i2s_tdm_slave(uint32_t sample_rate, i2s_data_bit_width_t bit_wi static void test_i2s_tdm_master_48k_32bits_4slots(void) { - test_i2s_tdm_master(48000, I2S_DATA_BIT_WIDTH_32BIT, I2S_TDM_SLOT0 | I2S_TDM_SLOT1 | I2S_TDM_SLOT2 | I2S_TDM_SLOT3); + test_i2s_tdm_master(TEST_I2S_SAMPLE_RATE, I2S_DATA_BIT_WIDTH_32BIT, I2S_TDM_SLOT0 | I2S_TDM_SLOT1 | I2S_TDM_SLOT2 | I2S_TDM_SLOT3); } static void test_i2s_tdm_slave_48k_32bits_4slots(void) { - test_i2s_tdm_slave(48000, I2S_DATA_BIT_WIDTH_32BIT, I2S_TDM_SLOT0 | I2S_TDM_SLOT1 | I2S_TDM_SLOT2 | I2S_TDM_SLOT3); + test_i2s_tdm_slave(TEST_I2S_SAMPLE_RATE, I2S_DATA_BIT_WIDTH_32BIT, I2S_TDM_SLOT0 | I2S_TDM_SLOT1 | I2S_TDM_SLOT2 | I2S_TDM_SLOT3); } TEST_CASE_MULTIPLE_DEVICES("I2S_TDM_full_duplex_test_in_48k_32bits_4slots", "[I2S_TDM]", @@ -277,12 +279,12 @@ TEST_CASE_MULTIPLE_DEVICES("I2S_TDM_full_duplex_test_in_48k_32bits_4slots", "[I2 static void test_i2s_tdm_master_48k_16bits_4slots(void) { - test_i2s_tdm_master(48000, I2S_DATA_BIT_WIDTH_16BIT, I2S_TDM_SLOT0 | I2S_TDM_SLOT1 | I2S_TDM_SLOT2 | I2S_TDM_SLOT3); + test_i2s_tdm_master(TEST_I2S_SAMPLE_RATE, I2S_DATA_BIT_WIDTH_16BIT, I2S_TDM_SLOT0 | I2S_TDM_SLOT1 | I2S_TDM_SLOT2 | I2S_TDM_SLOT3); } static void test_i2s_tdm_slave_48k_16bits_4slots(void) { - test_i2s_tdm_slave(48000, I2S_DATA_BIT_WIDTH_16BIT, I2S_TDM_SLOT0 | I2S_TDM_SLOT1 | I2S_TDM_SLOT2 | I2S_TDM_SLOT3); + test_i2s_tdm_slave(TEST_I2S_SAMPLE_RATE, I2S_DATA_BIT_WIDTH_16BIT, I2S_TDM_SLOT0 | I2S_TDM_SLOT1 | I2S_TDM_SLOT2 | I2S_TDM_SLOT3); } TEST_CASE_MULTIPLE_DEVICES("I2S_TDM_full_duplex_test_in_48k_16bits_4slots", "[I2S_TDM]", @@ -291,12 +293,12 @@ TEST_CASE_MULTIPLE_DEVICES("I2S_TDM_full_duplex_test_in_48k_16bits_4slots", "[I2 static void test_i2s_tdm_master_48k_8bits_4slots(void) { - test_i2s_tdm_master(48000, I2S_DATA_BIT_WIDTH_8BIT, I2S_TDM_SLOT0 | I2S_TDM_SLOT1 | I2S_TDM_SLOT2 | I2S_TDM_SLOT3); + test_i2s_tdm_master(TEST_I2S_SAMPLE_RATE, I2S_DATA_BIT_WIDTH_8BIT, I2S_TDM_SLOT0 | I2S_TDM_SLOT1 | I2S_TDM_SLOT2 | I2S_TDM_SLOT3); } static void test_i2s_tdm_slave_48k_8bits_4slots(void) { - test_i2s_tdm_slave(48000, I2S_DATA_BIT_WIDTH_8BIT, I2S_TDM_SLOT0 | I2S_TDM_SLOT1 | I2S_TDM_SLOT2 | I2S_TDM_SLOT3); + test_i2s_tdm_slave(TEST_I2S_SAMPLE_RATE, I2S_DATA_BIT_WIDTH_8BIT, I2S_TDM_SLOT0 | I2S_TDM_SLOT1 | I2S_TDM_SLOT2 | I2S_TDM_SLOT3); } TEST_CASE_MULTIPLE_DEVICES("I2S_TDM_full_duplex_test_in_48k_8bits_4slots", "[I2S_TDM]", @@ -307,13 +309,13 @@ TEST_CASE_MULTIPLE_DEVICES("I2S_TDM_full_duplex_test_in_48k_8bits_4slots", "[I2S #if !CONFIG_IDF_TARGET_ESP32H2 static void test_i2s_tdm_master_48k_16bits_8slots(void) { - test_i2s_tdm_master(48000, I2S_DATA_BIT_WIDTH_16BIT, I2S_TDM_SLOT0 | I2S_TDM_SLOT1 | I2S_TDM_SLOT2 | I2S_TDM_SLOT3 | + test_i2s_tdm_master(TEST_I2S_SAMPLE_RATE, I2S_DATA_BIT_WIDTH_16BIT, I2S_TDM_SLOT0 | I2S_TDM_SLOT1 | I2S_TDM_SLOT2 | I2S_TDM_SLOT3 | I2S_TDM_SLOT4 | I2S_TDM_SLOT5 | I2S_TDM_SLOT6 | I2S_TDM_SLOT7); } static void test_i2s_tdm_slave_48k_16bits_8slots(void) { - test_i2s_tdm_slave(48000, I2S_DATA_BIT_WIDTH_16BIT, I2S_TDM_SLOT0 | I2S_TDM_SLOT1 | I2S_TDM_SLOT2 | I2S_TDM_SLOT3 | + test_i2s_tdm_slave(TEST_I2S_SAMPLE_RATE, I2S_DATA_BIT_WIDTH_16BIT, I2S_TDM_SLOT0 | I2S_TDM_SLOT1 | I2S_TDM_SLOT2 | I2S_TDM_SLOT3 | I2S_TDM_SLOT4 | I2S_TDM_SLOT5 | I2S_TDM_SLOT6 | I2S_TDM_SLOT7); }