From 621d0aa942f8ccfaac6166f53abbc64913eca563 Mon Sep 17 00:00:00 2001 From: laokaiyao Date: Wed, 18 Aug 2021 19:45:51 +0800 Subject: [PATCH] i2s: Introduced a brand new driver --- components/driver/CMakeLists.txt | 10 +- components/driver/Kconfig | 18 +- components/driver/adc.c | 5 +- .../{include => deprecated}/driver/i2s.h | 144 +-- .../deprecated/driver/i2s_types_legacy.h | 232 +++++ components/driver/i2s/i2s_common.c | 963 ++++++++++++++++++ components/driver/{i2s.c => i2s/i2s_legacy.c} | 317 +++--- components/driver/i2s/i2s_pdm.c | 533 ++++++++++ components/driver/i2s/i2s_private.h | 131 +++ components/driver/i2s/i2s_std.c | 315 ++++++ components/driver/i2s/i2s_tdm.c | 317 ++++++ components/driver/include/driver/i2s_common.h | 266 +++++ .../hal => driver/include/driver}/i2s_pdm.h | 42 +- .../hal => driver/include/driver}/i2s_std.h | 47 +- .../hal => driver/include/driver}/i2s_tdm.h | 37 +- .../driver/include/esp_private/i2s_platform.h | 17 +- .../driver/test/adc_dma_test/test_esp32.c | 159 --- .../driver/test/dac_dma_test/test_esp32.c | 161 --- components/driver/test/test_adc2_with_wifi.c | 74 +- components/driver/test/test_dac.c | 3 +- .../driver/test_apps/i2s/CMakeLists.txt | 5 + components/driver/test_apps/i2s/app_test.py | 30 + .../driver/test_apps/i2s/main/CMakeLists.txt | 16 + .../driver/test_apps/i2s/main/test_app_main.c | 53 + .../test_apps/i2s/main/test_i2s_controller.c | 512 ++++++++++ .../i2s/main/test_i2s_legacy.c} | 37 +- .../driver/test_apps/i2s/sdkconfig.defaults | 3 + components/esp_hw_support/clk_ctrl_os.c | 2 +- .../esp_hw_support/include/clk_ctrl_os.h | 1 + components/esp_lcd/src/esp_lcd_panel_io_i2s.c | 10 +- .../i80_lcd/main/test_i80_lcd_panel.c | 66 +- components/hal/adc_hal.c | 2 +- components/hal/esp32/include/hal/i2s_ll.h | 1 - components/hal/esp32c3/include/hal/i2s_ll.h | 2 +- components/hal/esp32h2/include/hal/i2s_ll.h | 2 +- components/hal/esp32s3/include/hal/i2s_ll.h | 4 +- components/hal/i2s_hal.c | 123 +-- components/hal/include/hal/i2s_hal.h | 84 +- components/hal/include/hal/i2s_types.h | 259 ++--- components/hal/include/hal/i2s_types_priv.h | 116 --- .../diagrams/i2s/i2s_file_structure.png | Bin 0 -> 64258 bytes .../diagrams/i2s/i2s_state_machine.png | Bin 0 -> 55870 bytes docs/_static/diagrams/i2s/pdm.png | Bin 0 -> 81899 bytes docs/_static/diagrams/i2s/std_msb.png | Bin 0 -> 23008 bytes docs/_static/diagrams/i2s/std_pcm.png | Bin 0 -> 20415 bytes docs/_static/diagrams/i2s/std_philip.png | Bin 0 -> 19028 bytes docs/_static/diagrams/i2s/tdm_msb.png | Bin 0 -> 73090 bytes docs/_static/diagrams/i2s/tdm_pcm_long.png | Bin 0 -> 63728 bytes docs/_static/diagrams/i2s/tdm_pcm_short.png | Bin 0 -> 71424 bytes docs/_static/diagrams/i2s/tdm_philip.png | Bin 0 -> 80203 bytes docs/doxygen/Doxyfile | 4 + docs/en/api-reference/peripherals/i2s.rst | 812 ++++++++++----- docs/en/migration-guides/peripherals.rst | 62 +- .../classic_bt/a2dp_sink/main/bt_app_av.c | 45 +- .../classic_bt/a2dp_sink/main/bt_app_core.c | 12 + .../classic_bt/a2dp_sink/main/main.c | 1 - .../classic_bt/a2dp_sink/sdkconfig.defaults | 1 + .../a2dp_sink/tutorial/Example_A2DP_Sink.md | 53 +- .../coex/a2dp_gatts_coex/main/bt_app_av.c | 13 + .../coex/a2dp_gatts_coex/main/bt_app_core.c | 16 +- .../coex/a2dp_gatts_coex/main/main.c | 54 +- .../coex/a2dp_gatts_coex/sdkconfig.defaults | 1 + .../i2s/i2s_adc_dac/main/app_main.c | 11 +- .../i2s/i2s_adc_dac/main/audio_example_file.h | 5 + .../i2s/i2s_adc_dac/sdkconfig.defaults | 5 + .../i2s_adc_dac/tools/generate_audio_file.py | 2 + .../main/i2s_recorder_main.c | 65 +- .../i2s/i2s_basic/main/i2s_example_main.c | 123 +-- examples/peripherals/i2s/i2s_es8311/README.md | 2 +- .../i2s/i2s_es8311/main/i2s_es8311_example.c | 72 +- tools/ci/check_copyright_ignore.txt | 5 - 71 files changed, 4934 insertions(+), 1549 deletions(-) rename components/driver/{include => deprecated}/driver/i2s.h (66%) create mode 100644 components/driver/deprecated/driver/i2s_types_legacy.h create mode 100644 components/driver/i2s/i2s_common.c rename components/driver/{i2s.c => i2s/i2s_legacy.c} (86%) create mode 100644 components/driver/i2s/i2s_pdm.c create mode 100644 components/driver/i2s/i2s_private.h create mode 100644 components/driver/i2s/i2s_std.c create mode 100644 components/driver/i2s/i2s_tdm.c create mode 100644 components/driver/include/driver/i2s_common.h rename components/{hal/include/hal => driver/include/driver}/i2s_pdm.h (88%) rename components/{hal/include/hal => driver/include/driver}/i2s_std.h (80%) rename components/{hal/include/hal => driver/include/driver}/i2s_tdm.h (81%) delete mode 100644 components/driver/test/adc_dma_test/test_esp32.c delete mode 100644 components/driver/test/dac_dma_test/test_esp32.c create mode 100644 components/driver/test_apps/i2s/CMakeLists.txt create mode 100644 components/driver/test_apps/i2s/app_test.py create mode 100644 components/driver/test_apps/i2s/main/CMakeLists.txt create mode 100644 components/driver/test_apps/i2s/main/test_app_main.c create mode 100644 components/driver/test_apps/i2s/main/test_i2s_controller.c rename components/driver/{test/test_i2s.c => test_apps/i2s/main/test_i2s_legacy.c} (97%) create mode 100644 components/driver/test_apps/i2s/sdkconfig.defaults delete mode 100644 components/hal/include/hal/i2s_types_priv.h create mode 100644 docs/_static/diagrams/i2s/i2s_file_structure.png create mode 100644 docs/_static/diagrams/i2s/i2s_state_machine.png create mode 100644 docs/_static/diagrams/i2s/pdm.png create mode 100644 docs/_static/diagrams/i2s/std_msb.png create mode 100644 docs/_static/diagrams/i2s/std_pcm.png create mode 100644 docs/_static/diagrams/i2s/std_philip.png create mode 100644 docs/_static/diagrams/i2s/tdm_msb.png create mode 100644 docs/_static/diagrams/i2s/tdm_pcm_long.png create mode 100644 docs/_static/diagrams/i2s/tdm_pcm_short.png create mode 100644 docs/_static/diagrams/i2s/tdm_philip.png create mode 100644 examples/peripherals/i2s/i2s_adc_dac/sdkconfig.defaults diff --git a/components/driver/CMakeLists.txt b/components/driver/CMakeLists.txt index 168619a024..001e650415 100644 --- a/components/driver/CMakeLists.txt +++ b/components/driver/CMakeLists.txt @@ -58,7 +58,15 @@ if(CONFIG_SOC_SDMMC_HOST_SUPPORTED) endif() if(CONFIG_SOC_I2S_SUPPORTED) - list(APPEND srcs "i2s.c") + list(APPEND srcs "i2s/i2s_common.c" + "i2s/i2s_std.c" + "i2s/i2s_legacy.c") + if(CONFIG_SOC_I2S_SUPPORTS_PDM) + list(APPEND srcs "i2s/i2s_pdm.c") + endif() + if(CONFIG_SOC_I2S_SUPPORTS_TDM) + list(APPEND srcs "i2s/i2s_tdm.c") + endif() endif() if(CONFIG_SOC_TEMP_SENSOR_SUPPORTED) diff --git a/components/driver/Kconfig b/components/driver/Kconfig index 93c0c97c1d..97125ebe23 100644 --- a/components/driver/Kconfig +++ b/components/driver/Kconfig @@ -305,4 +305,20 @@ menu "Driver Configurations" endmenu # MCPWM Configuration -endmenu # Driver Configurations + menu "I2S Configuration" + depends on SOC_I2S_SUPPORTED + config I2S_ISR_IRAM_SAFE + bool "I2S ISR IRAM-Safe" + default n + help + Ensure the I2S interrupt is IRAM-Safe by allowing the interrupt handler to be + executable when the cache is disabled (e.g. SPI Flash write). + + config I2S_SUPPRESS_DEPRECATE_WARN + bool "Suppress leagcy driver deprecated warning" + default n + help + Enable this option will suppress the deprecation warnings of using APIs in deprecated I2S driver. + endmenu # I2S Configuration + +endmenu # Driver configurations diff --git a/components/driver/adc.c b/components/driver/adc.c index 850089dc2f..fc88e89ce4 100644 --- a/components/driver/adc.c +++ b/components/driver/adc.c @@ -37,7 +37,6 @@ #include "hal/spi_types.h" #include "driver/spi_common_internal.h" #elif CONFIG_IDF_TARGET_ESP32 -#include "driver/i2s.h" #include "hal/i2s_types.h" #include "soc/i2s_periph.h" #include "esp_private/i2s_platform.h" @@ -259,7 +258,7 @@ esp_err_t adc_digi_initialize(const adc_digi_init_config_t *init_config) #elif CONFIG_IDF_TARGET_ESP32 //ADC utilises I2S0 DMA on ESP32 uint32_t dma_chan = 0; - ret = i2s_priv_register_object(&s_adc_digi_ctx, I2S_NUM_0); + ret = i2s_platform_acquire_occupation(I2S_NUM_0, "adc"); if (ret != ESP_OK) { goto cleanup; } @@ -541,7 +540,7 @@ esp_err_t adc_digi_deinitialize(void) spicommon_periph_free(s_adc_digi_ctx->spi_host); #elif CONFIG_IDF_TARGET_ESP32 esp_intr_free(s_adc_digi_ctx->intr_hdl); - i2s_priv_deregister_object(s_adc_digi_ctx->i2s_host); + i2s_platform_release_occupation(s_adc_digi_ctx->i2s_host); #endif free(s_adc_digi_ctx); s_adc_digi_ctx = NULL; diff --git a/components/driver/include/driver/i2s.h b/components/driver/deprecated/driver/i2s.h similarity index 66% rename from components/driver/include/driver/i2s.h rename to components/driver/deprecated/driver/i2s.h index 81ac4f2aea..94011c61e9 100644 --- a/components/driver/include/driver/i2s.h +++ b/components/driver/deprecated/driver/i2s.h @@ -4,147 +4,37 @@ * SPDX-License-Identifier: Apache-2.0 */ +/** + * This file is for the backward compatible to the deprecated I2S APIs, + * The deprecated APIs will no longer supported in the future + * Please refer to "driver/i2s_controller.h" for the latest I2S driver + * Note that only one set of I2S APIs is allowed to be used at the same time + */ + #pragma once #include "esp_types.h" #include "esp_err.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" -#include "soc/soc_caps.h" -#include "hal/i2s_types.h" -#include "esp_intr_alloc.h" +#include "soc/i2s_periph.h" +#include "driver/i2s_types_legacy.h" #if SOC_I2S_SUPPORTS_ADC #include "driver/adc.h" #endif +#if !CONFIG_I2S_SUPPRESS_DEPRECATE_WARN +#warning "This set of I2S APIs has been deprecated, \ +please include 'driver/i2s_std.h', 'driver/i2s_pdm' or 'driver/i2s_tdm' instead. \ +if you want to keep using the old APIs and ignore this warning, \ +you can enable 'Suppress leagcy driver deprecated warning' option under 'I2S Configuration' menu in Kconfig" +#endif + #ifdef __cplusplus extern "C" { #endif -#define I2S_PIN_NO_CHANGE (-1) /*!< Use in i2s_pin_config_t for pins which should not be changed */ - -/** - * @brief I2S port number, the max port number is (I2S_NUM_MAX -1). - */ -typedef enum { - I2S_NUM_0 = 0, /*!< I2S port 0 */ -#if SOC_I2S_NUM > 1 - I2S_NUM_1 = 1, /*!< I2S port 1 */ -#endif - I2S_NUM_MAX, /*!< I2S port max */ -} i2s_port_t; - -#if SOC_I2S_SUPPORTS_PCM -/** - * @brief I2S PCM configuration - * - */ -typedef struct { - i2s_pcm_compress_t pcm_type; /*!< I2S PCM a/u-law decompress or compress type */ -} i2s_pcm_cfg_t; -#endif - -#if SOC_I2S_SUPPORTS_PDM_TX -/** - * @brief Default I2S PDM Up-Sampling Rate configuration - */ -#define I2S_PDM_DEFAULT_UPSAMPLE_CONFIG(rate) { \ - .sample_rate = rate, \ - .fp = 960, \ - .fs = (rate) / 100, \ - } - -/** - * @brief I2S PDM up-sample rate configuration - * @note TX PDM can only be set to the following two upsampling rate configurations: - * 1: fp = 960, fs = sample_rate / 100, in this case, Fpdm = 128*48000 - * 2: fp = 960, fs = 480, in this case, Fpdm = 128*Fpcm = 128*sample_rate - * If the pdm receiver do not care the pdm serial clock, it's recommended set Fpdm = 128*48000. - * Otherwise, the second configuration should be applied. - */ -typedef struct { - int sample_rate; /*!< I2S PDM sample rate */ - int fp; /*!< I2S PDM TX upsampling paramater. Normally it should be set to 960 */ - int fs; /*!< I2S PDM TX upsampling paramater. When it is set to 480, the pdm clock frequency Fpdm = 128 * sample_rate, when it is set to sample_rate / 100, Fpdm will be fixed to 128*48000 */ -} i2s_pdm_tx_upsample_cfg_t; -#endif - -/** - * @brief I2S pin number for i2s_set_pin - * - */ -typedef struct { - int mck_io_num; /*!< MCK in out pin. Note that ESP32 supports setting MCK on GPIO0/GPIO1/GPIO3 only*/ - int bck_io_num; /*!< BCK in out pin*/ - int ws_io_num; /*!< WS in out pin*/ - int data_out_num; /*!< DATA out pin*/ - int data_in_num; /*!< DATA in pin*/ -} i2s_pin_config_t; - -/** - * @brief I2S driver configuration parameters - * - */ -typedef struct { - - i2s_mode_t mode; /*!< I2S work mode */ - uint32_t sample_rate; /*!< I2S sample rate */ - i2s_bits_per_sample_t bits_per_sample; /*!< I2S sample bits in one channel */ - i2s_channel_fmt_t channel_format; /*!< I2S channel format.*/ - i2s_comm_format_t communication_format; /*!< I2S communication format */ - int intr_alloc_flags; /*!< Flags used to allocate the interrupt. One or multiple (ORred) ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info */ - union { - int dma_desc_num; /*!< The total number of descriptors used by I2S DMA to receive/transmit data */ - int dma_buf_count __attribute__((deprecated)); /*!< This is an alias to 'dma_desc_num' for backward compatibility */ - }; - union { - int dma_frame_num; /*!< Number of frames for one-time sampling. The frame here means the total data from all the channels in a WS cycle */ - int dma_buf_len __attribute__((deprecated)); /*!< This is an alias to 'dma_frame_num' for backward compatibility */ - }; - - bool use_apll; /*!< I2S using APLL as main I2S clock, enable it to get accurate clock */ - bool tx_desc_auto_clear; /*!< I2S auto clear tx descriptor if there is underflow condition (helps in avoiding noise in case of data unavailability) */ - int fixed_mclk; /*!< I2S using fixed MCLK output. If use_apll = true and fixed_mclk > 0, then the clock output for i2s is fixed and equal to the fixed_mclk value. If fixed_mclk set, mclk_multiple won't take effect */ - i2s_mclk_multiple_t mclk_multiple; /*!< The multiple of I2S master clock(MCLK) to sample rate */ - i2s_bits_per_chan_t bits_per_chan; /*!< I2S total bits in one channel, only take effect when larger than 'bits_per_sample', default '0' means equal to 'bits_per_sample' */ - -#if SOC_I2S_SUPPORTS_TDM - i2s_channel_t chan_mask; /*!< I2S active channel bit mask, set value in `i2s_channel_t` to enable specific channel, the bit map of active channel can not exceed (0x1< 0, then the clock output for i2s is fixed and equal to the fixed_mclk value. If fixed_mclk set, mclk_multiple won't take effect */ + i2s_mclk_multiple_t mclk_multiple; /*!< The multiple of I2S master clock(MCLK) to sample rate */ + i2s_bits_per_chan_t bits_per_chan; /*!< I2S total bits in one channel, only take effect when larger than 'bits_per_sample', default '0' means equal to 'bits_per_sample' */ + +#if SOC_I2S_SUPPORTS_TDM + i2s_channel_t chan_mask; /*!< I2S active channel bit mask, set value in `i2s_channel_t` to enable specific channel, the bit map of active channel can not exceed (0x1< +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/queue.h" +#include "freertos/task.h" +#include "soc/i2s_periph.h" +#include "soc/soc_caps.h" +#include "soc/soc.h" +#include "hal/gpio_hal.h" +#include "hal/i2s_hal.h" + +#if SOC_I2S_SUPPORTS_ADC_DAC +#include "hal/adc_ll.h" +#endif +#if SOC_I2S_SUPPORTS_APLL +#include "clk_ctrl_os.h" +#endif + +#include "esp_private/i2s_platform.h" +#include "esp_private/periph_ctrl.h" + +#include "driver/gpio.h" +#include "driver/i2s_common.h" +#include "i2s_private.h" + +#include "clk_ctrl_os.h" +#include "esp_intr_alloc.h" +#include "esp_check.h" +#include "esp_attr.h" + +// // #include "esp_efuse.h" +#include "esp_rom_gpio.h" + +#include "sdkconfig.h" + +#define I2S_DMA_BUFFER_MAX_SIZE (4092) + +// If ISR handler is allowed to run whilst cache is disabled, +// Make sure all the code and related variables used by the handler are in the SRAM +#if CONFIG_I2S_ISR_IRAM_SAFE +#define I2S_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_SHARED) +#define I2S_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT) +#else +#define I2S_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_INTRDISABLED | ESP_INTR_FLAG_SHARED) +#define I2S_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT +#endif //CONFIG_I2S_ISR_IRAM_SAFE + +/** + * @brief Static i2s platform object + * @note For saving all the I2S related information + */ +i2s_platform_t s_i2s = { + .spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED, + .controller[0 ... (I2S_NUM_MAX - 1)] = NULL, // groups will be lazy installed + .comp_name[0 ... (I2S_NUM_MAX - 1)] = NULL, +}; + +static const char *TAG = "I2S_COMMON"; + +/*--------------------------------------------------------------------------- + I2S Static APIs + ---------------------------------------------------------------------------- + Scope: This file only + ----------------------------------------------------------------------------*/ + +static void i2s_tx_start(i2s_chan_handle_t handle) +{ + /* No lock here beacuse semaphore has been taken while calling this function */ + i2s_hal_tx_reset(&(handle->parent->hal)); + i2s_hal_tx_reset_fifo(&(handle->parent->hal)); +#if SOC_GDMA_SUPPORTED + gdma_reset(handle->dma.dma_chan); + gdma_start(handle->dma.dma_chan, (uint32_t) handle->dma.desc[0]); +#else + i2s_hal_tx_reset_dma(&(handle->parent->hal)); + i2s_hal_tx_enable_intr(&(handle->parent->hal)); + i2s_hal_tx_start_link(&(handle->parent->hal), (uint32_t) handle->dma.desc[0]); +#endif + i2s_hal_tx_start(&(handle->parent->hal)); +} + +static void i2s_rx_start(i2s_chan_handle_t handle) +{ + /* No lock here beacuse semaphore has been taken while calling this function */ + i2s_hal_rx_reset(&(handle->parent->hal)); + i2s_hal_rx_reset_fifo(&(handle->parent->hal)); +#if SOC_GDMA_SUPPORTED + gdma_reset(handle->dma.dma_chan); + gdma_start(handle->dma.dma_chan, (uint32_t) handle->dma.desc[0]); +#else + i2s_hal_rx_reset_dma(&(handle->parent->hal)); + i2s_hal_rx_enable_intr(&(handle->parent->hal)); + i2s_hal_rx_start_link(&(handle->parent->hal), (uint32_t) handle->dma.desc[0]); +#endif + i2s_hal_rx_start(&(handle->parent->hal)); +} + +static void i2s_tx_stop(i2s_chan_handle_t handle) +{ + /* No lock here beacuse semaphore has been taken while calling this function */ +#if SOC_GDMA_SUPPORTED + i2s_hal_tx_stop(&(handle->parent->hal)); + gdma_stop(handle->dma.dma_chan); +#else + i2s_hal_tx_stop(&(handle->parent->hal)); + i2s_hal_tx_stop_link(&(handle->parent->hal)); + i2s_hal_tx_disable_intr(&(handle->parent->hal)); +#endif +} + +static void i2s_rx_stop(i2s_chan_handle_t handle) +{ + /* No lock here beacuse semaphore has been taken while calling this function */ +#if SOC_GDMA_SUPPORTED + i2s_hal_rx_stop(&(handle->parent->hal)); + gdma_stop(handle->dma.dma_chan); +#else + i2s_hal_rx_stop(&(handle->parent->hal)); + i2s_hal_rx_stop_link(&(handle->parent->hal)); + i2s_hal_rx_disable_intr(&(handle->parent->hal)); +#endif +} + +static esp_err_t i2s_destroy_controller_obj(i2s_controller_t **i2s_obj) +{ + I2S_NULL_POINTER_CHECK(TAG, i2s_obj); + I2S_NULL_POINTER_CHECK(TAG, *i2s_obj); + ESP_RETURN_ON_FALSE(!(*i2s_obj)->rx_chan && !(*i2s_obj)->tx_chan, + ESP_ERR_INVALID_STATE, TAG, + "there still have channels under this i2s controller"); + int id = (*i2s_obj)->id; +#if SOC_I2S_HW_VERSION_1 + i2s_ll_enable_dma((*i2s_obj)->hal.dev, false); + esp_intr_disable((*i2s_obj)->i2s_isr_handle); + esp_intr_free((*i2s_obj)->i2s_isr_handle); +#endif + free(*i2s_obj); + *i2s_obj = NULL; + return i2s_platform_release_occupation(id); +} + +/** + * @brief Acquire i2s controller object + * + * @param id i2s port id + * @param search_reverse reverse the sequence of port acquirement + * set false to acquire from I2S_NUM_0 first + * set true to acquire from I2S_NUM_MAX - 1 first + * @return + * - pointer of acquired i2s controller object + */ +static i2s_controller_t *i2s_acquire_controller_obj(int id) +{ + if (id < 0 || id >= I2S_NUM_MAX) { + return NULL; + } + /* pre-alloc controller object */ + i2s_controller_t *pre_alloc = (i2s_controller_t *)heap_caps_calloc(1, sizeof(i2s_controller_t), I2S_MEM_ALLOC_CAPS); + if (pre_alloc == NULL) { + return NULL; + } + pre_alloc->id = id; + i2s_hal_init(&pre_alloc->hal, id); +#if !SOC_GDMA_SUPPORTED + pre_alloc->i2s_isr_handle = NULL; +#endif + pre_alloc->full_duplex = false; + pre_alloc->tx_chan = NULL; + pre_alloc->rx_chan = NULL; + pre_alloc->mclk = I2S_GPIO_UNUSED; + + i2s_controller_t *i2s_obj = NULL; + if (!s_i2s.controller[id]) { + /* Try to occupy this i2s controller + if failed, this controller could be occupied by other components */ + if (i2s_platform_acquire_occupation(id, "i2s_controller") == ESP_OK) { + i2s_obj = pre_alloc; + portENTER_CRITICAL(&s_i2s.spinlock); + s_i2s.controller[id] = i2s_obj; + portEXIT_CRITICAL(&s_i2s.spinlock); + #if SOC_I2S_SUPPORTS_ADC_DAC + if (id == I2S_NUM_0) { + adc_ll_digi_set_data_source(ADC_I2S_DATA_SRC_IO_SIG); + } + #endif + } else { + free(pre_alloc); + ESP_LOGE(TAG, "i2s%d might be occupied by other component", id); + } + } else { + i2s_obj = s_i2s.controller[id]; + free(pre_alloc); + } + + return i2s_obj; +} + +static inline bool i2s_take_available_channel(i2s_controller_t *i2s_obj, uint8_t chan_search_mask) +{ + bool is_available = false; + +#if SOC_I2S_HW_VERSION_1 + /* In ESP32 and ESP32-S2, tx channel and rx channel are not totally separated + * Take both two channels in case one channel can affect another + */ + chan_search_mask = I2S_DIR_RX | I2S_DIR_TX; +#endif + portENTER_CRITICAL(&s_i2s.spinlock); + if (!(chan_search_mask & i2s_obj->chan_occupancy)) { + i2s_obj->chan_occupancy |= chan_search_mask; + is_available = true; + } + portEXIT_CRITICAL(&s_i2s.spinlock); + return is_available; +} + +static esp_err_t i2s_register_channel(i2s_controller_t *i2s_obj, i2s_dir_t dir) +{ + I2S_NULL_POINTER_CHECK(TAG, i2s_obj); + + i2s_chan_handle_t new_chan = (i2s_chan_handle_t)heap_caps_calloc(1, sizeof(struct i2s_channel_t), I2S_MEM_ALLOC_CAPS); + ESP_RETURN_ON_FALSE(new_chan, ESP_ERR_NO_MEM, TAG, "No memory for new channel"); + new_chan->mode = I2S_COMM_MODE_NONE; + new_chan->role = I2S_ROLE_MASTER; // Set default role to master + new_chan->dir = dir; + new_chan->state = I2S_CHAN_STATE_REGISTER; +#if SOC_I2S_SUPPORTS_APLL + new_chan->apll_en = false; +#endif + new_chan->mode_info = NULL; + new_chan->parent = i2s_obj; + new_chan->event_queue = NULL; + new_chan->pm_lock = NULL; // Init in i2s_set_clock according to clock source + new_chan->msg_queue = NULL; + new_chan->mutex = xSemaphoreCreateMutex(); + new_chan->start = NULL; + new_chan->stop = NULL; + + if (!new_chan->mutex) { + ESP_LOGE(TAG, "mutex create failed"); + free(new_chan); + return ESP_ERR_NO_MEM; + } + if (dir == I2S_DIR_TX) { + if (i2s_obj->tx_chan) { + i2s_del_channel(i2s_obj->tx_chan); + } + i2s_obj->tx_chan = new_chan; + + } else { + if (i2s_obj->rx_chan) { + i2s_del_channel(i2s_obj->rx_chan); + } + i2s_obj->rx_chan = new_chan; + } + return ESP_OK; +} + +uint32_t i2s_get_buf_size(i2s_chan_handle_t handle, uint32_t data_bit_width, uint32_t dma_frame_num) +{ + uint32_t active_chan = handle->active_slot; + uint32_t bytes_per_sample = ((data_bit_width + 15) / 16) * 2; + uint32_t bytes_per_frame = bytes_per_sample * active_chan; + uint32_t bufsize = dma_frame_num * bytes_per_frame; + /* Limit DMA buffer size if it is out of range (DMA buffer limitation is 4092 bytes) */ + if (bufsize > I2S_DMA_BUFFER_MAX_SIZE) { + uint32_t frame_num = I2S_DMA_BUFFER_MAX_SIZE / bytes_per_frame; + bufsize = frame_num * bytes_per_frame; + ESP_LOGW(TAG, "dma frame num is out of dma buffer size, limited to %d", frame_num); + } + return bufsize; +} + +esp_err_t i2s_free_dma_desc(i2s_chan_handle_t handle) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + if (!handle->dma.desc) { + return ESP_OK; + } + for (int i = 0; i < handle->dma.desc_num; i++) { + if (handle->dma.bufs[i]) { + free(handle->dma.bufs[i]); + } + if (handle->dma.desc[i]) { + free(handle->dma.desc[i]); + } + } + free(handle->dma.bufs); + free(handle->dma.desc); + handle->dma.desc = NULL; + + return ESP_OK; +} + +esp_err_t i2s_alloc_dma_desc(i2s_chan_handle_t handle, uint32_t num, uint32_t bufsize) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + 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); + handle->dma.desc_num = num; + handle->dma.buf_size = bufsize; + + handle->msg_queue = xQueueCreate(num, sizeof(uint8_t *)); + ESP_GOTO_ON_FALSE(handle->msg_queue, ESP_ERR_NO_MEM, err, TAG, "message queue create failed"); + + handle->dma.desc = (lldesc_t **)heap_caps_calloc(num, sizeof(lldesc_t *), I2S_MEM_ALLOC_CAPS); + ESP_GOTO_ON_FALSE(handle->dma.desc, ESP_ERR_NO_MEM, err, TAG, "create I2S DMA decriptor array failed"); + handle->dma.bufs = (uint8_t **)heap_caps_calloc(num, sizeof(uint8_t *), I2S_MEM_ALLOC_CAPS); + for (int i = 0; i < num; i++) { + /* Allocate DMA descriptor */ + handle->dma.desc[i] = (lldesc_t *) heap_caps_calloc(1, sizeof(lldesc_t), MALLOC_CAP_DMA); + ESP_GOTO_ON_FALSE(handle->dma.desc[i], ESP_ERR_NO_MEM, err, TAG, "allocate DMA description failed"); + handle->dma.desc[i]->owner = 1; + handle->dma.desc[i]->eof = 1; + handle->dma.desc[i]->sosf = 0; + handle->dma.desc[i]->length = bufsize; + handle->dma.desc[i]->size = bufsize; + handle->dma.desc[i]->offset = 0; + handle->dma.bufs[i] = (uint8_t *) heap_caps_calloc(1, bufsize * sizeof(uint8_t), MALLOC_CAP_DMA); + handle->dma.desc[i]->buf = handle->dma.bufs[i]; + ESP_GOTO_ON_FALSE(handle->dma.desc[i]->buf, ESP_ERR_NO_MEM, err, TAG, "allocate DMA buffer failed"); + } + /* Connect DMA descriptor as a circle */ + for (int i = 0; i < num; i++) { + /* Link to the next descriptor */ + handle->dma.desc[i]->empty = (uint32_t)((i < (num - 1)) ? (handle->dma.desc[i + 1]) : handle->dma.desc[0]); + } + if (handle->dir == I2S_DIR_RX) { + i2s_ll_rx_set_eof_num(handle->parent->hal.dev, bufsize); + } + ESP_LOGD(TAG, "DMA malloc info: dma_desc_num = %d, dma_desc_buf_size = dma_frame_num * slot_num * data_bit_width = %d, ", bufsize, num); + return ESP_OK; +err: + i2s_free_dma_desc(handle); + return ret; +} + +#if SOC_I2S_SUPPORTS_APLL +uint32_t i2s_set_get_apll_freq(uint32_t mclk_freq) +{ + /* Calculate the expected APLL */ + int mclk_div = (int)((SOC_APLL_MIN_HZ / mclk_freq) + 1); + /* apll_freq = mclk * div + * when div = 1, hardware will still divide 2 + * when div = 0, the final mclk will be unpredictable + * So the div here should be at least 2 */ + mclk_div = mclk_div < 2 ? 2 : mclk_div; + uint32_t expt_freq = mclk_freq * mclk_div; + uint32_t real_freq = 0; + esp_err_t ret = periph_rtc_apll_freq_set(expt_freq, &real_freq); + if (ret == ESP_ERR_INVALID_ARG) { + ESP_LOGE(TAG, "set APLL freq failed due to invalid argument"); + return 0; + } + if (ret == ESP_ERR_INVALID_STATE) { + ESP_LOGW(TAG, "APLL is occupied already, it is working at %d Hz while the expected frequency is %d Hz", real_freq, expt_freq); + ESP_LOGW(TAG, "Trying to work at %d Hz...", real_freq); + } + ESP_LOGI(TAG, "APLL expected frequency is %d Hz, real frequency is %d Hz", expt_freq, real_freq); + return real_freq; +} +#endif + +static inline void i2s_isr_send_event_queue(QueueHandle_t event_queue, i2s_event_type_t type, portBASE_TYPE *need_yield) +{ + if (event_queue) { + i2s_event_t i2s_event; + portBASE_TYPE _need_yield; + i2s_event.type = type; + xQueueSendFromISR(event_queue, (void * )&i2s_event, &_need_yield); + *need_yield |= _need_yield; + } +} + +#if SOC_GDMA_SUPPORTED +static bool IRAM_ATTR i2s_dma_rx_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data) +{ + i2s_chan_handle_t handle = (i2s_chan_handle_t)user_data; + portBASE_TYPE need_yield = 0; + BaseType_t ret = 0; + lldesc_t *finish_desc; + + if (handle) { + finish_desc = (lldesc_t *)event_data->rx_eof_desc_addr; + ret = xQueueSendFromISR(handle->msg_queue, &(finish_desc->buf), &need_yield); + i2s_event_type_t type = (ret == pdTRUE) ? I2S_EVENT_RX_DONE : I2S_EVENT_RX_Q_OVF; + i2s_isr_send_event_queue(handle->event_queue, type, &need_yield); + } + return need_yield; +} + +static bool IRAM_ATTR i2s_dma_tx_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data) +{ + i2s_chan_handle_t handle = (i2s_chan_handle_t)user_data; + portBASE_TYPE need_yield = 0; + BaseType_t ret; + lldesc_t *finish_desc; + if (handle) { + finish_desc = (lldesc_t *)(event_data->tx_eof_desc_addr); + if (handle->dma.auto_clear) { + uint8_t *sent_buf = (uint8_t *)finish_desc->buf; + memset(sent_buf, 0, handle->dma.buf_size); + } + ret = xQueueSendFromISR(handle->msg_queue, &(finish_desc->buf), &need_yield); + i2s_event_type_t type = (ret == pdTRUE) ? I2S_EVENT_TX_DONE : I2S_EVENT_TX_Q_OVF; + i2s_isr_send_event_queue(handle->event_queue, type, &need_yield); + } + return need_yield; +} + +#else +static void IRAM_ATTR i2s_default_intr_handler(void *arg) +{ + portBASE_TYPE tx_need_yield = 0; + portBASE_TYPE rx_need_yield = 0; + lldesc_t *finish_desc = NULL; + BaseType_t ret; + i2s_controller_t *obj = (i2s_controller_t *)arg; + uint32_t status = i2s_hal_get_intr_status(&(obj->hal)); + i2s_hal_clear_intr_status(&(obj->hal), status); + if (!obj || !status) { + return; + } + + if (obj->tx_chan && (status & I2S_LL_EVENT_TX_EOF)) { + i2s_hal_get_out_eof_des_addr(&(obj->hal), (uint32_t *)&finish_desc); + // Auto clear the dma buffer after data sent + if (obj->tx_chan->dma.auto_clear) { + uint8_t *buff = (uint8_t *)finish_desc->buf; + memset(buff, 0, obj->tx_chan->dma.buf_size); + } + ret = xQueueSendFromISR(obj->tx_chan->msg_queue, &(finish_desc->buf), &tx_need_yield); + i2s_event_type_t type = (ret == pdTRUE) ? I2S_EVENT_TX_DONE : I2S_EVENT_TX_Q_OVF; + i2s_isr_send_event_queue(obj->tx_chan->event_queue, type, &tx_need_yield); + } + + if (obj->rx_chan && (status & I2S_LL_EVENT_RX_EOF)) { + i2s_hal_get_in_eof_des_addr(&(obj->hal), (uint32_t *)&finish_desc); + ret = xQueueSendFromISR(obj->rx_chan->msg_queue, &(finish_desc->buf), &rx_need_yield); + i2s_event_type_t type = (ret == pdTRUE) ? I2S_EVENT_RX_DONE : I2S_EVENT_RX_Q_OVF; + i2s_isr_send_event_queue(obj->rx_chan->event_queue, type, &rx_need_yield); + } + + if (tx_need_yield || rx_need_yield) { + portYIELD_FROM_ISR(); + } +} +#endif + +/** + * @brief I2S DMA interrupt initialization + * @note I2S will use GDMA if chip supports, and the interrupt is triggered by GDMA. + * + * @param handle I2S channel handle + * @param intr_flag Interrupt allocation flag + * @return + * - ESP_OK I2S DMA interrupt initialize success + * - ESP_ERR_NOT_FOUND GDMA channel not found + * - ESP_ERR_INVALID_ARG Invalid arguments + * - ESP_ERR_INVALID_STATE GDMA state error + */ +esp_err_t i2s_init_dma_intr(i2s_chan_handle_t handle, int intr_flag) +{ + i2s_port_t port_id = handle->parent->id; + ESP_RETURN_ON_FALSE((port_id >= 0) && (port_id < I2S_NUM_MAX), ESP_ERR_INVALID_ARG, TAG, "invalid handle"); +#if SOC_GDMA_SUPPORTED + /* Set GDMA trigger module */ + gdma_trigger_t trig = {.periph = GDMA_TRIG_PERIPH_I2S}; + + switch (port_id) { +#if SOC_I2S_NUM > 1 + case I2S_NUM_1: + trig.instance_id = SOC_GDMA_TRIG_PERIPH_I2S1; + break; +#endif + default: + trig.instance_id = SOC_GDMA_TRIG_PERIPH_I2S0; + break; + } + + /* Set GDMA config */ + gdma_channel_alloc_config_t dma_cfg = {}; + if (handle->dir & I2S_DIR_TX) { + dma_cfg.direction = GDMA_CHANNEL_DIRECTION_TX; + /* Register a new GDMA tx channel */ + ESP_RETURN_ON_ERROR(gdma_new_channel(&dma_cfg, &handle->dma.dma_chan), TAG, "Register tx dma channel error"); + ESP_RETURN_ON_ERROR(gdma_connect(handle->dma.dma_chan, trig), TAG, "Connect tx dma channel error"); + gdma_tx_event_callbacks_t cb = {.on_trans_eof = i2s_dma_tx_callback}; + /* Set callback function for GDMA, the interrupt is triggered by GDMA, then the GDMA ISR will call the callback function */ + gdma_register_tx_event_callbacks(handle->dma.dma_chan, &cb, handle); + } + if (handle->dir & I2S_DIR_RX) { + dma_cfg.direction = GDMA_CHANNEL_DIRECTION_RX; + /* Register a new GDMA rx channel */ + ESP_RETURN_ON_ERROR(gdma_new_channel(&dma_cfg, &handle->dma.dma_chan), TAG, "Register rx dma channel error"); + ESP_RETURN_ON_ERROR(gdma_connect(handle->dma.dma_chan, trig), TAG, "Connect rx dma channel error"); + gdma_rx_event_callbacks_t cb = {.on_recv_eof = i2s_dma_rx_callback}; + /* Set callback function for GDMA, the interrupt is triggered by GDMA, then the GDMA ISR will call the callback function */ + gdma_register_rx_event_callbacks(handle->dma.dma_chan, &cb, handle); + } +#else + /* Initial I2S module interrupt */ + if (!handle->parent->i2s_isr_handle) { + ESP_RETURN_ON_ERROR(esp_intr_alloc(i2s_periph_signal[port_id].irq, intr_flag, i2s_default_intr_handler, handle->parent, &(handle->parent->i2s_isr_handle)), TAG, "Register I2S Interrupt error"); + esp_intr_enable(handle->parent->i2s_isr_handle); + } + /* Start DMA */ + i2s_ll_enable_dma(handle->parent->hal.dev, true); +#endif // SOC_GDMA_SUPPORTED + return ESP_OK; +} + +void i2s_gpio_check_and_set(gpio_num_t gpio, uint32_t signal_idx, bool is_input) +{ + /* Ignore the pin if pin = -1 */ + if (gpio != I2S_GPIO_UNUSED) { + if (is_input) { + gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio], PIN_FUNC_GPIO); + /* Set direction, for some GPIOs, the input function are not enabled as default */ + gpio_set_direction(gpio, GPIO_MODE_INPUT); + esp_rom_gpio_connect_in_signal(gpio, signal_idx, 0); + } else { + gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio], PIN_FUNC_GPIO); + gpio_set_direction(gpio, GPIO_MODE_OUTPUT); + esp_rom_gpio_connect_out_signal(gpio, signal_idx, 0, 0); + } + } +} + +esp_err_t i2s_check_set_mclk(i2s_port_t id, gpio_num_t gpio_num) +{ + if (gpio_num == -1) { + return ESP_OK; + } +#if CONFIG_IDF_TARGET_ESP32 + ESP_RETURN_ON_FALSE((gpio_num == GPIO_NUM_0 || gpio_num == GPIO_NUM_1 || gpio_num == GPIO_NUM_3), + ESP_ERR_INVALID_ARG, TAG, + "ESP32 only support to set GPIO0/GPIO1/GPIO3 as mclk signal, error GPIO number:%d", gpio_num); + bool is_i2s0 = id == I2S_NUM_0; + if (gpio_num == GPIO_NUM_0) { + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0_CLK_OUT1); + WRITE_PERI_REG(PIN_CTRL, is_i2s0 ? 0xFFF0 : 0xFFFF); + } else if (gpio_num == GPIO_NUM_1) { + PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_CLK_OUT3); + WRITE_PERI_REG(PIN_CTRL, is_i2s0 ? 0xF0F0 : 0xF0FF); + } else { + PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_CLK_OUT2); + WRITE_PERI_REG(PIN_CTRL, is_i2s0 ? 0xFF00 : 0xFF0F); + } +#else + ESP_RETURN_ON_FALSE(GPIO_IS_VALID_GPIO(gpio_num), ESP_ERR_INVALID_ARG, TAG, "mck_io_num invalid"); + gpio_matrix_out_check_and_set(gpio_num, i2s_periph_signal[id].mck_out_sig, 0, 0); +#endif + ESP_LOGI(TAG, "MCLK is pinned to GPIO%d on I2S%d", id, gpio_num); + return ESP_OK; +} + +/*--------------------------------------------------------------------------- + I2S bus Public APIs + ---------------------------------------------------------------------------- + Scope: Public + ----------------------------------------------------------------------------*/ +esp_err_t i2s_new_channel(const i2s_chan_config_t *chan_cfg, i2s_chan_handle_t *tx_handle, i2s_chan_handle_t *rx_handle) +{ + /* Parameter validity check */ + I2S_NULL_POINTER_CHECK(TAG, chan_cfg); + I2S_NULL_POINTER_CHECK(TAG, tx_handle || rx_handle); + ESP_RETURN_ON_FALSE(chan_cfg->id < SOC_I2S_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid I2S port id"); + ESP_RETURN_ON_FALSE(chan_cfg->dma_desc_num >= 2, ESP_ERR_INVALID_ARG, TAG, "there should be at least 2 DMA buffers"); + + esp_err_t ret = ESP_OK; + i2s_controller_t *i2s_obj = NULL; + i2s_port_t id = chan_cfg->id; + bool channel_found = false; + uint8_t chan_search_mask = 0; + chan_search_mask |= tx_handle ? I2S_DIR_TX : 0; + chan_search_mask |= rx_handle ? I2S_DIR_RX : 0; + + /* Channel will be registered to one i2s port automatically if id is I2S_NUM_AUTO + * Otherwise, the channel will be registered to the specific port. */ + if (id == I2S_NUM_AUTO) { + for (int i = 0; i < I2S_NUM_MAX && !channel_found; i++) { + i2s_obj = i2s_acquire_controller_obj(i); + if (!i2s_obj) { + continue; + } + channel_found = i2s_take_available_channel(i2s_obj, chan_search_mask); + } + ESP_RETURN_ON_FALSE(i2s_obj, ESP_ERR_NOT_FOUND, TAG, "get i2s object failed"); + } else { + i2s_obj = i2s_acquire_controller_obj(id); + ESP_RETURN_ON_FALSE(i2s_obj, ESP_ERR_NOT_FOUND, TAG, "get i2s object failed"); + channel_found = i2s_take_available_channel(i2s_obj, chan_search_mask); + } + ESP_GOTO_ON_FALSE(channel_found, ESP_ERR_NOT_FOUND, err, TAG, "no available channel found"); + /* Register and specify the tx handle */ + if (tx_handle) { + ESP_GOTO_ON_ERROR(i2s_register_channel(i2s_obj, I2S_DIR_TX), err, TAG, "register I2S tx channel failed"); + i2s_obj->tx_chan->role = chan_cfg->role; + i2s_obj->tx_chan->dma.auto_clear = chan_cfg->auto_clear; + i2s_obj->tx_chan->dma.desc_num = chan_cfg->dma_desc_num; + i2s_obj->tx_chan->dma.frame_num = chan_cfg->dma_frame_num; + i2s_obj->tx_chan->start = i2s_tx_start; + i2s_obj->tx_chan->stop = i2s_tx_stop; + *tx_handle = i2s_obj->tx_chan; + ESP_LOGI(TAG, "tx channel is registered on I2S%d successfully", i2s_obj->id); + } + /* Register and specify the rx handle */ + if (rx_handle) { + ESP_GOTO_ON_ERROR(i2s_register_channel(i2s_obj, I2S_DIR_RX), err, TAG, "register I2S rx channel failed"); + i2s_obj->rx_chan->role = chan_cfg->role; + i2s_obj->rx_chan->dma.desc_num = chan_cfg->dma_desc_num; + i2s_obj->rx_chan->dma.frame_num = chan_cfg->dma_frame_num; + i2s_obj->rx_chan->start = i2s_rx_start; + i2s_obj->rx_chan->stop = i2s_rx_stop; + *rx_handle = i2s_obj->rx_chan; + ESP_LOGI(TAG, "rx channel is registered on I2S%d successfully", i2s_obj->id); + } + + if ((tx_handle != NULL) && (rx_handle != NULL)) { + i2s_obj->full_duplex = true; + } + + return ESP_OK; +/* i2s_obj allocated but register channel failed */ +err: + /* if the controller object has no channel, find the corresponding global object and destroy it */ + if (i2s_obj != NULL && i2s_obj->rx_chan == NULL && i2s_obj->tx_chan == NULL) { + for (int i = 0; i < I2S_NUM_MAX; i++) { + if (i2s_obj == s_i2s.controller[i]) { + i2s_destroy_controller_obj(&s_i2s.controller[i]); + break; + } + } + } + return ret; +} + +// TODO: finish delete channel +esp_err_t i2s_del_channel(i2s_chan_handle_t handle) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + /* Static mutex to avoid double delete */ + static SemaphoreHandle_t del_mut = NULL; + if (del_mut == NULL) { + del_mut = xSemaphoreCreateMutex(); + } + i2s_controller_t *i2s_obj = handle->parent; + int id = i2s_obj->id; + i2s_dir_t dir = handle->dir; + bool is_bound = true; + + xSemaphoreTake(del_mut, portMAX_DELAY); + /* Stop the channel first */ + if (handle->state > I2S_CHAN_STATE_READY) { + i2s_abort_reading_writing(handle); + i2s_stop_channel(handle); + } +#if SOC_I2S_HW_VERSION_2 + if (dir == I2S_DIR_TX) { + i2s_ll_tx_disable_clock(handle->parent->hal.dev); + } else { + i2s_ll_rx_disable_clock(handle->parent->hal.dev); + } +#endif +#if SOC_I2S_SUPPORTS_APLL + if (handle->apll_en) { + /* Must switch back to D2CLK on ESP32-S2, + * because the clock of some registers are bound to APLL, + * otherwise, once APLL is disabled, the registers can't be updated anymore */ + if (handle->dir == I2S_DIR_TX) { + i2s_ll_tx_clk_set_src(handle->parent->hal.dev, I2S_CLK_160M_PLL); + } else { + i2s_ll_rx_clk_set_src(handle->parent->hal.dev, I2S_CLK_160M_PLL); + } + periph_rtc_apll_release(); + } +#endif + if (handle->mode_info) { + free(handle->mode_info); + } + if (handle->dma.desc) { + i2s_free_dma_desc(handle); + } + if (handle->msg_queue) { + vQueueDelete(handle->msg_queue); + } + if (handle->event_queue) { + vQueueDelete(handle->event_queue); + } + if (handle->mutex) { + vSemaphoreDelete(handle->mutex); + } +#if SOC_I2S_HW_VERSION_1 + i2s_obj->chan_occupancy = 0; +#else + i2s_obj->chan_occupancy &= ~(uint32_t)dir; +#endif +#if SOC_GDMA_SUPPORTED + if (handle->dma.dma_chan) { + gdma_del_channel(handle->dma.dma_chan); + } +#endif + if (handle == i2s_obj->tx_chan) { + free(i2s_obj->tx_chan); + i2s_obj->tx_chan = NULL; + i2s_obj->full_duplex = false; + } else if (handle == i2s_obj->rx_chan) { + free(i2s_obj->rx_chan); + i2s_obj->rx_chan = NULL; + i2s_obj->full_duplex = false; + } else { + /* Indicate the delete channel is an unbound free channel */ + is_bound = false; + free(handle); + } + + /* If the delete channel was bound to a controller before, + we need to destroy this controller object if there is no channel any more */ + if (is_bound) { + if (!(i2s_obj->tx_chan) && !(i2s_obj->rx_chan)) { + i2s_destroy_controller_obj(&s_i2s.controller[i2s_obj->id]); + } + ESP_LOGI(TAG, "%s channel on I2S%d deleted", dir == I2S_DIR_TX ? "tx" : "rx", id); + } + xSemaphoreGive(del_mut); + return ESP_OK; +} + +QueueHandle_t i2s_get_event_queue(i2s_chan_handle_t handle, uint32_t que_len) +{ + QueueHandle_t que; + if (!handle) { + return NULL; + } + xSemaphoreTake(handle->mutex, portMAX_DELAY); + if (handle->event_queue) { + que = handle->event_queue; + } else { + handle->event_queue = xQueueCreate(que_len, sizeof(int *)); + que = handle->event_queue; + } + xSemaphoreGive(handle->mutex); + return que; +} + + +esp_err_t i2s_start_channel(i2s_chan_handle_t handle) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "the channel has already started or not initialized"); + + handle->dma.curr_ptr = NULL; + handle->dma.rw_pos = 0; + handle->start(handle); + handle->state = I2S_CHAN_STATE_IDLE; + xSemaphoreGive(handle->mutex); + + ESP_LOGI(TAG, "i2s %s channel started", handle->dir == I2S_DIR_TX ? "tx" : "rx"); + return ret; + +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +esp_err_t i2s_stop_channel(i2s_chan_handle_t handle) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->state > I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "the channel has not started yet"); + handle->stop(handle); + handle->state = I2S_CHAN_STATE_READY; + xSemaphoreGive(handle->mutex); + ESP_LOGI(TAG, "i2s %s channel stopped", handle->dir == I2S_DIR_TX ? "tx" : "rx"); + return ret; + +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +esp_err_t i2s_write_channel(i2s_chan_handle_t handle, const void *src, size_t size, size_t *bytes_written, TickType_t ticks_to_wait) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + ESP_RETURN_ON_FALSE(handle->dir == I2S_DIR_TX, ESP_ERR_INVALID_ARG, TAG, "this channel is not tx channel"); + + esp_err_t ret = ESP_OK; + char *data_ptr, *src_byte; + size_t bytes_can_write; + *bytes_written = 0; + + /* Take the semaphore brefore changing state to ensure only one writing thread running at the same time */ + xSemaphoreTake(handle->mutex, ticks_to_wait); +#ifdef CONFIG_PM_ENABLE + esp_pm_lock_acquire(handle->pm_lock); +#endif + ESP_GOTO_ON_FALSE(handle->state > I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "this channel has not started yet"); + handle->state = I2S_CHAN_STATE_WRITING; + src_byte = (char *)src; + while (size > 0 && handle->state == I2S_CHAN_STATE_WRITING) { + if (handle->dma.rw_pos == handle->dma.buf_size || handle->dma.curr_ptr == NULL) { + if (xQueueReceive(handle->msg_queue, &(handle->dma.curr_ptr), ticks_to_wait) == pdFALSE) { + ret = ESP_ERR_TIMEOUT; + break; + } + handle->dma.rw_pos = 0; + } + ESP_LOGD(TAG, "size: %d, rw_pos: %d, buf_size: %d, curr_ptr: %d", size, handle->dma.rw_pos, handle->dma.buf_size, (int)handle->dma.curr_ptr); + data_ptr = (char *)handle->dma.curr_ptr; + data_ptr += handle->dma.rw_pos; + bytes_can_write = handle->dma.buf_size - handle->dma.rw_pos; + if (bytes_can_write > size) { + bytes_can_write = size; + } + memcpy(data_ptr, src_byte, bytes_can_write); + size -= bytes_can_write; + src_byte += bytes_can_write; + handle->dma.rw_pos += bytes_can_write; + (*bytes_written) += bytes_can_write; + } + /* Need to judge the state before switch back to idle, in case the state has been changed by 'stop' or 'abort' */ + if (handle->state == I2S_CHAN_STATE_WRITING) { + handle->state = I2S_CHAN_STATE_IDLE; + } +err: +#ifdef CONFIG_PM_ENABLE + esp_pm_lock_release(handle->pm_lock); +#endif + xSemaphoreGive(handle->mutex); + + return ret; +} + +esp_err_t i2s_read_channel(i2s_chan_handle_t handle, void *dest, size_t size, size_t *bytes_read, TickType_t ticks_to_wait) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + ESP_RETURN_ON_FALSE(handle->dir == I2S_DIR_RX, ESP_ERR_INVALID_ARG, TAG, "this channel is not rx channel"); + + esp_err_t ret = ESP_OK; + uint8_t *data_ptr, *dest_byte; + int bytes_can_read; + *bytes_read = 0; + dest_byte = (uint8_t *)dest; + /* Take the semaphore brefore changing state to ensure only one reading thread running at the same time */ + xSemaphoreTake(handle->mutex, ticks_to_wait); +#ifdef CONFIG_PM_ENABLE + esp_pm_lock_acquire(handle->pm_lock); +#endif + ESP_GOTO_ON_FALSE(handle->state > I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "this channel has not started yet"); + handle->state = I2S_CHAN_STATE_READING; + while (size > 0 && handle->state == I2S_CHAN_STATE_READING) { + if (handle->dma.rw_pos == handle->dma.buf_size || handle->dma.curr_ptr == NULL) { + if (xQueueReceive(handle->msg_queue, &(handle->dma.curr_ptr), ticks_to_wait) == pdFALSE) { + ret = ESP_ERR_TIMEOUT; + break; + } + handle->dma.rw_pos = 0; + } + data_ptr = (uint8_t *)handle->dma.curr_ptr; + data_ptr += handle->dma.rw_pos; + bytes_can_read = handle->dma.buf_size - handle->dma.rw_pos; + if (bytes_can_read > (int)size) { + bytes_can_read = size; + } + memcpy(dest_byte, data_ptr, bytes_can_read); + size -= bytes_can_read; + dest_byte += bytes_can_read; + handle->dma.rw_pos += bytes_can_read; + (*bytes_read) += bytes_can_read; + } + /* Need to judge the state before switch back to idle, in case the state has been changed by 'stop' or 'abort' */ + if (handle->state == I2S_CHAN_STATE_READING) { + handle->state = I2S_CHAN_STATE_IDLE; + } +err: +#ifdef CONFIG_PM_ENABLE + esp_pm_lock_release(handle->pm_lock); +#endif + xSemaphoreGive(handle->mutex); + + return ret; +} + +esp_err_t i2s_clear_dma_buffer(i2s_chan_handle_t handle) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + ESP_RETURN_ON_FALSE(handle->state > I2S_CHAN_STATE_INIT, ESP_ERR_INVALID_STATE, TAG, "this channel has not initialized yet"); + /* Clear all the DMA buffer */ + for (int desc_num = handle->dma.desc_num; desc_num > 0; desc_num--) { + memset(handle->dma.bufs[desc_num-1], 0, handle->dma.buf_size); + } + return ESP_OK; +} + +esp_err_t i2s_abort_reading_writing(i2s_chan_handle_t handle) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + ESP_RETURN_ON_FALSE(handle->state > I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, TAG, "this channel has not started yet"); + /* No lock here. Force change state to idle when writing or reading */ + handle->state = I2S_CHAN_STATE_IDLE; + + return ESP_OK; +} + + +/*--------------------------------------------------------------------------- + I2S Platform APIs + ---------------------------------------------------------------------------- + Scope: This file and ADC/DAC/LCD driver + ----------------------------------------------------------------------------*/ + +esp_err_t i2s_platform_acquire_occupation(int id, const char *comp_name) +{ + esp_err_t ret = ESP_OK; + const char *occupied_comp = NULL; + ESP_RETURN_ON_FALSE(id < I2S_NUM_MAX, ESP_ERR_INVALID_ARG, TAG, "invalid i2s port id"); + portENTER_CRITICAL(&s_i2s.spinlock); + if ((!s_i2s.controller[id]) && (s_i2s.comp_name[id] == NULL)) { + s_i2s.comp_name[id] = comp_name; + /* Enable module clock */ + periph_module_enable(i2s_periph_signal[id].module); + i2s_ll_enable_clock(I2S_LL_GET_HW(id)); + } else { + occupied_comp = s_i2s.comp_name[id]; + ret = ESP_ERR_NOT_FOUND; + } + portEXIT_CRITICAL(&s_i2s.spinlock); + if (occupied_comp != NULL) { + ESP_LOGE(TAG, "i2s controller %d has been occupied by %s", id, occupied_comp); + } + return ret; +} + +esp_err_t i2s_platform_release_occupation(int id) +{ + esp_err_t ret = ESP_OK; + ESP_RETURN_ON_FALSE(id < I2S_NUM_MAX, ESP_ERR_INVALID_ARG, TAG, "invalid i2s port id"); + portENTER_CRITICAL(&s_i2s.spinlock); + if ((!s_i2s.controller[id])) { + s_i2s.comp_name[id] = NULL; + /* Disable module clock */ + periph_module_disable(i2s_periph_signal[id].module); + i2s_ll_disable_clock(I2S_LL_GET_HW(id)); + } else { + ret = ESP_ERR_INVALID_STATE; + } + portEXIT_CRITICAL(&s_i2s.spinlock); + return ret; +} diff --git a/components/driver/i2s.c b/components/driver/i2s/i2s_legacy.c similarity index 86% rename from components/driver/i2s.c rename to components/driver/i2s/i2s_legacy.c index e5d441b32c..fc834be793 100644 --- a/components/driver/i2s.c +++ b/components/driver/i2s/i2s_legacy.c @@ -16,14 +16,11 @@ #include "driver/gpio.h" #include "hal/gpio_hal.h" #include "hal/i2s_hal.h" -#include "hal/i2s_std.h" -#include "hal/i2s_pdm.h" -#include "hal/i2s_tdm.h" #include "driver/i2s.h" #if SOC_I2S_SUPPORTS_DAC #include "driver/dac.h" #include "driver/adc.h" -#include "adc1_private.h" +#include "../adc1_private.h" #endif // SOC_I2S_SUPPORTS_ADC #if SOC_GDMA_SUPPORTED @@ -57,6 +54,23 @@ static const char *TAG = "I2S"; #define I2S_COMM_MODE_ADC_DAC -1 #endif +/** + * @brief General clock configuration information + * @note It is a general purpose struct, not supposed to be used directly by user + */ +typedef struct { + uint32_t sample_rate_hz; /*!< I2S sample rate */ + i2s_clock_src_t clk_src; /*!< Choose clock source */ + i2s_mclk_multiple_t mclk_multiple; /*!< The multiple of mclk to the sample rate */ +#if SOC_I2S_SUPPORTS_PDM_TX + uint32_t up_sample_fp; /*!< Up-sampling param fp */ + uint32_t up_sample_fs; /*!< Up-sampling param fs */ +#endif +#if SOC_I2S_SUPPORTS_PDM_RX + i2s_pdm_dsr_t dn_sample_mode; /*!< Down-sampling rate mode */ +#endif +} i2s_clk_config_t; + /** * @brief DMA buffer object * @@ -104,8 +118,8 @@ typedef struct { i2s_dir_t dir; i2s_role_t role; i2s_comm_mode_t mode; - void *slot_cfg; - void *clk_cfg; + i2s_hal_slot_config_t slot_cfg; + i2s_clk_config_t clk_cfg; uint32_t active_slot; /*!< Active slot number */ uint32_t total_slot; /*!< Total slot number */ } i2s_obj_t; @@ -113,7 +127,6 @@ typedef struct { static i2s_obj_t *p_i2s[SOC_I2S_NUM] = { [0 ... SOC_I2S_NUM - 1] = NULL, }; -static portMUX_TYPE i2s_platform_spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; static portMUX_TYPE i2s_spinlock[SOC_I2S_NUM] = { [0 ... SOC_I2S_NUM - 1] = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED, }; @@ -443,7 +456,7 @@ esp_err_t i2s_stop(i2s_port_t i2s_num) -------------------------------------------------------------*/ static inline uint32_t i2s_get_buf_size(i2s_port_t i2s_num) { - i2s_slot_config_t *slot_cfg = (i2s_slot_config_t *)p_i2s[i2s_num]->slot_cfg; + i2s_hal_slot_config_t *slot_cfg = &p_i2s[i2s_num]->slot_cfg; /* Calculate bytes per sample, align to 16 bit */ uint32_t bytes_per_sample = ((slot_cfg->data_bit_width + 15) / 16) * 2; /* The DMA buffer limitation is 4092 bytes */ @@ -623,20 +636,20 @@ static uint32_t i2s_config_source_clock(i2s_port_t i2s_num, bool use_apll, uint3 return I2S_LL_BASE_CLK; #else if (use_apll) { - ESP_LOGW(TAG, "APLL not supported on current chip, use I2S_CLK_D2CLK as default clock source"); + ESP_LOGW(TAG, "APLL not supported on current chip, use I2S_CLK_160M_PLL as default clock source"); } return I2S_LL_BASE_CLK; #endif } #if SOC_I2S_SUPPORTS_ADC || SOC_I2S_SUPPORTS_DAC -static esp_err_t i2s_calculate_adc_dac_clock(int i2s_num, i2s_clock_info_t *clk_info) +static esp_err_t i2s_calculate_adc_dac_clock(int i2s_num, i2s_hal_clock_info_t *clk_info) { /* For ADC/DAC mode, the built-in ADC/DAC is driven by 'mclk' instead of 'bclk' * 'bclk' should be fixed to the double of sample rate * 'bclk_div' is the real coefficient that affects the slot bit */ - i2s_clk_config_t *clk_cfg = (i2s_clk_config_t *)p_i2s[i2s_num]->clk_cfg; - i2s_slot_config_t *slot_cfg = (i2s_slot_config_t *)p_i2s[i2s_num]->slot_cfg; + i2s_clk_config_t *clk_cfg = &p_i2s[i2s_num]->clk_cfg; + i2s_hal_slot_config_t *slot_cfg = &p_i2s[i2s_num]->slot_cfg; uint32_t slot_bits = slot_cfg->slot_bit_width; /* Set I2S bit clock */ clk_info->bclk = clk_cfg->sample_rate_hz * I2S_LL_AD_BCK_FACTOR; @@ -661,9 +674,9 @@ static esp_err_t i2s_calculate_adc_dac_clock(int i2s_num, i2s_clock_info_t *clk_ #endif // SOC_I2S_SUPPORTS_ADC || SOC_I2S_SUPPORTS_DAC #if SOC_I2S_SUPPORTS_PDM_TX -static esp_err_t i2s_calculate_pdm_tx_clock(int i2s_num, i2s_clock_info_t *clk_info) +static esp_err_t i2s_calculate_pdm_tx_clock(int i2s_num, i2s_hal_clock_info_t *clk_info) { - i2s_pdm_tx_clk_config_t *clk_cfg = (i2s_pdm_tx_clk_config_t *)p_i2s[i2s_num]->clk_cfg; + i2s_clk_config_t *clk_cfg = &p_i2s[i2s_num]->clk_cfg; int fp = clk_cfg->up_sample_fp; int fs = clk_cfg->up_sample_fs; @@ -690,9 +703,9 @@ static esp_err_t i2s_calculate_pdm_tx_clock(int i2s_num, i2s_clock_info_t *clk_i #endif // SOC_I2S_SUPPORTS_PDM_TX #if SOC_I2S_SUPPORTS_PDM_RX -static esp_err_t i2s_calculate_pdm_rx_clock(int i2s_num, i2s_clock_info_t *clk_info) +static esp_err_t i2s_calculate_pdm_rx_clock(int i2s_num, i2s_hal_clock_info_t *clk_info) { - i2s_pdm_rx_clk_config_t *clk_cfg = (i2s_pdm_rx_clk_config_t *)p_i2s[i2s_num]->clk_cfg; + i2s_clk_config_t *clk_cfg = &p_i2s[i2s_num]->clk_cfg; i2s_pdm_dsr_t dsr = clk_cfg->dn_sample_mode; /* Set I2S bit clock */ clk_info->bclk = clk_cfg->sample_rate_hz * I2S_LL_PDM_BCK_FACTOR * (dsr == I2S_PDM_DSR_16S ? 2 : 1); @@ -715,10 +728,10 @@ static esp_err_t i2s_calculate_pdm_rx_clock(int i2s_num, i2s_clock_info_t *clk_i return ESP_OK; } #endif // SOC_I2S_SUPPORTS_PDM_RX -static esp_err_t i2s_calculate_common_clock(int i2s_num, i2s_clock_info_t *clk_info) +static esp_err_t i2s_calculate_common_clock(int i2s_num, i2s_hal_clock_info_t *clk_info) { - i2s_clk_config_t *clk_cfg = (i2s_clk_config_t *)p_i2s[i2s_num]->clk_cfg; - i2s_slot_config_t *slot_cfg = (i2s_slot_config_t *)p_i2s[i2s_num]->slot_cfg; + i2s_clk_config_t *clk_cfg = &p_i2s[i2s_num]->clk_cfg; + i2s_hal_slot_config_t *slot_cfg = &p_i2s[i2s_num]->slot_cfg; uint32_t rate = clk_cfg->sample_rate_hz; uint32_t slot_num = p_i2s[i2s_num]->total_slot < 2 ? 2 : p_i2s[i2s_num]->total_slot; uint32_t slot_bits = slot_cfg->slot_bit_width; @@ -745,7 +758,7 @@ static esp_err_t i2s_calculate_common_clock(int i2s_num, i2s_clock_info_t *clk_i } -static esp_err_t i2s_calculate_clock(i2s_port_t i2s_num, i2s_clock_info_t *clk_info) +static esp_err_t i2s_calculate_clock(i2s_port_t i2s_num, i2s_hal_clock_info_t *clk_info) { /* Calculate clock for ADC/DAC mode */ #if SOC_I2S_SUPPORTS_ADC_DAC @@ -782,14 +795,6 @@ static esp_err_t i2s_calculate_clock(i2s_port_t i2s_num, i2s_clock_info_t *clk_i -------------------------------------------------------------*/ #if SOC_I2S_SUPPORTS_TDM -static uint32_t i2s_get_max_channel_num(uint32_t chan_mask) -{ - int max_chan; - for (max_chan = 0; chan_mask; max_chan++, chan_mask >>= 1); - /* Can't be smaller than 2 */ - return max_chan < 2 ? 2 : max_chan; -} - static uint32_t i2s_get_active_channel_num(uint32_t chan_mask) { uint32_t num = 0; @@ -806,7 +811,7 @@ static uint32_t i2s_get_active_channel_num(uint32_t chan_mask) static void i2s_dac_set_slot_legacy(void) { i2s_dev_t *dev = p_i2s[0]->hal.dev; - i2s_slot_config_t *slot_cfg = p_i2s[0]->slot_cfg; + i2s_hal_slot_config_t *slot_cfg = &p_i2s[0]->slot_cfg; i2s_ll_tx_reset(dev); i2s_ll_tx_set_slave_mod(dev, false); @@ -845,7 +850,7 @@ esp_err_t i2s_set_dac_mode(i2s_dac_mode_t dac_mode) static void i2s_adc_set_slot_legacy(void) { i2s_dev_t *dev = p_i2s[0]->hal.dev; - i2s_slot_config_t *slot_cfg = p_i2s[0]->slot_cfg; + i2s_hal_slot_config_t *slot_cfg = &p_i2s[0]->slot_cfg; // When ADC/DAC are installed as duplex mode, ADC will share the WS and BCLK clock by working in slave mode i2s_ll_rx_set_slave_mod(dev, false); i2s_ll_rx_set_sample_bit(dev, slot_cfg->slot_bit_width, slot_cfg->data_bit_width); @@ -958,22 +963,22 @@ static void i2s_set_slot_legacy(i2s_port_t i2s_num) } if (p_i2s[i2s_num]->mode == I2S_COMM_MODE_STD) { if (p_i2s[i2s_num]->dir & I2S_DIR_TX) { - i2s_hal_std_set_tx_slot(&(p_i2s[i2s_num]->hal), is_tx_slave, p_i2s[i2s_num]->slot_cfg ); + i2s_hal_std_set_tx_slot(&(p_i2s[i2s_num]->hal), is_tx_slave, (i2s_hal_slot_config_t *)(&p_i2s[i2s_num]->slot_cfg) ); } if (p_i2s[i2s_num]->dir & I2S_DIR_RX) { - i2s_hal_std_set_rx_slot(&(p_i2s[i2s_num]->hal), is_rx_slave, p_i2s[i2s_num]->slot_cfg ); + i2s_hal_std_set_rx_slot(&(p_i2s[i2s_num]->hal), is_rx_slave, (i2s_hal_slot_config_t *)(&p_i2s[i2s_num]->slot_cfg) ); } } #if SOC_I2S_SUPPORTS_PDM else if (p_i2s[i2s_num]->mode == I2S_COMM_MODE_PDM) { #if SOC_I2S_SUPPORTS_PDM_TX if (p_i2s[i2s_num]->dir & I2S_DIR_TX) { - i2s_hal_pdm_set_tx_slot(&(p_i2s[i2s_num]->hal), is_tx_slave, p_i2s[i2s_num]->slot_cfg ); + i2s_hal_pdm_set_tx_slot(&(p_i2s[i2s_num]->hal), is_tx_slave, (i2s_hal_slot_config_t *)(&p_i2s[i2s_num]->slot_cfg) ); } #endif #if SOC_I2S_SUPPORTS_PDM_RX if (p_i2s[i2s_num]->dir & I2S_DIR_RX) { - i2s_hal_pdm_set_rx_slot(&(p_i2s[i2s_num]->hal), is_rx_slave, p_i2s[i2s_num]->slot_cfg ); + i2s_hal_pdm_set_rx_slot(&(p_i2s[i2s_num]->hal), is_rx_slave, (i2s_hal_slot_config_t *)(&p_i2s[i2s_num]->slot_cfg) ); } #endif } @@ -981,10 +986,10 @@ static void i2s_set_slot_legacy(i2s_port_t i2s_num) #if SOC_I2S_SUPPORTS_TDM else if (p_i2s[i2s_num]->mode == I2S_COMM_MODE_TDM) { if (p_i2s[i2s_num]->dir & I2S_DIR_TX) { - i2s_hal_tdm_set_tx_slot(&(p_i2s[i2s_num]->hal), is_tx_slave, p_i2s[i2s_num]->slot_cfg ); + i2s_hal_tdm_set_tx_slot(&(p_i2s[i2s_num]->hal), is_tx_slave, (i2s_hal_slot_config_t *)(&p_i2s[i2s_num]->slot_cfg) ); } if (p_i2s[i2s_num]->dir & I2S_DIR_RX) { - i2s_hal_tdm_set_rx_slot(&(p_i2s[i2s_num]->hal), is_rx_slave, p_i2s[i2s_num]->slot_cfg ); + i2s_hal_tdm_set_rx_slot(&(p_i2s[i2s_num]->hal), is_rx_slave, (i2s_hal_slot_config_t *)(&p_i2s[i2s_num]->slot_cfg) ); } } #endif @@ -1002,8 +1007,8 @@ static void i2s_set_slot_legacy(i2s_port_t i2s_num) static void i2s_set_clock_legacy(i2s_port_t i2s_num) { - i2s_clk_config_t *clk_cfg = (i2s_clk_config_t *)p_i2s[i2s_num]->clk_cfg; - i2s_clock_info_t clk_info; + i2s_clk_config_t *clk_cfg = &p_i2s[i2s_num]->clk_cfg; + i2s_hal_clock_info_t clk_info; i2s_calculate_clock(i2s_num, &clk_info); if (p_i2s[i2s_num]->dir & I2S_DIR_TX) { i2s_hal_set_tx_clock(&(p_i2s[i2s_num]->hal), &clk_info, clk_cfg->clk_src); @@ -1016,7 +1021,7 @@ static void i2s_set_clock_legacy(i2s_port_t i2s_num) float i2s_get_clk(i2s_port_t i2s_num) { ESP_RETURN_ON_FALSE((i2s_num < I2S_NUM_MAX), ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); - i2s_clk_config_t *clk_cfg = (i2s_clk_config_t *)p_i2s[i2s_num]->clk_cfg; + i2s_clk_config_t *clk_cfg = &p_i2s[i2s_num]->clk_cfg; return (float)clk_cfg->sample_rate_hz; } @@ -1036,8 +1041,8 @@ esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, uint32_t bits_cfg, i2s_ /* Stop I2S */ i2s_stop(i2s_num); - i2s_clk_config_t *clk_cfg = (i2s_clk_config_t *)p_i2s[i2s_num]->clk_cfg; - i2s_slot_config_t *slot_cfg = (i2s_slot_config_t *)p_i2s[i2s_num]->slot_cfg; + i2s_clk_config_t *clk_cfg = &p_i2s[i2s_num]->clk_cfg; + i2s_hal_slot_config_t *slot_cfg = &p_i2s[i2s_num]->slot_cfg; clk_cfg->sample_rate_hz = rate; slot_cfg->data_bit_width = bits_cfg & 0xFFFF; @@ -1053,9 +1058,9 @@ esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, uint32_t bits_cfg, i2s_ if (slot_mask == 0) { slot_mask = (slot_cfg->slot_mode == I2S_SLOT_MODE_MONO) ? 1 : 2; } - ESP_RETURN_ON_FALSE(p_i2s[i2s_num]->total_slot >= i2s_get_max_channel_num(slot_mask), ESP_ERR_INVALID_ARG, TAG, + ESP_RETURN_ON_FALSE(p_i2s[i2s_num]->total_slot >= (32 - __builtin_clz(slot_mask)), ESP_ERR_INVALID_ARG, TAG, "The max channel number can't be greater than CH%d\n", p_i2s[i2s_num]->total_slot); - p_i2s[i2s_num]->active_slot = i2s_get_active_channel_num(slot_mask); + p_i2s[i2s_num]->active_slot = __builtin_popcount(slot_mask); } else #endif { @@ -1102,7 +1107,7 @@ esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, uint32_t bits_cfg, i2s_ esp_err_t i2s_set_sample_rates(i2s_port_t i2s_num, uint32_t rate) { ESP_RETURN_ON_FALSE((i2s_num < I2S_NUM_MAX), ESP_ERR_INVALID_ARG, TAG, "i2s_num error"); - i2s_slot_config_t *slot_cfg = (i2s_slot_config_t *)p_i2s[i2s_num]->slot_cfg; + i2s_hal_slot_config_t *slot_cfg = &p_i2s[i2s_num]->slot_cfg; uint32_t mask = 0; #if SOC_I2S_SUPPORTS_TDM if (p_i2s[i2s_num]->mode == I2S_COMM_MODE_TDM) { @@ -1154,13 +1159,11 @@ esp_err_t i2s_set_pdm_rx_down_sample(i2s_port_t i2s_num, i2s_pdm_dsr_t downsampl ESP_RETURN_ON_FALSE((p_i2s[i2s_num]->mode == I2S_COMM_MODE_PDM), ESP_ERR_INVALID_ARG, TAG, "i2s mode is not PDM mode"); xSemaphoreTake(p_i2s[i2s_num]->rx->mux, portMAX_DELAY); i2s_stop(i2s_num); - i2s_pdm_rx_slot_config_t *slot_cfg = (i2s_pdm_rx_slot_config_t*)p_i2s[i2s_num]->slot_cfg; - i2s_pdm_rx_clk_config_t *clk_cfg = (i2s_pdm_rx_clk_config_t*)p_i2s[i2s_num]->clk_cfg; - clk_cfg->dn_sample_mode = downsample; + p_i2s[i2s_num]->clk_cfg.dn_sample_mode = downsample; i2s_ll_rx_set_pdm_dsr(p_i2s[i2s_num]->hal.dev, downsample); i2s_start(i2s_num); xSemaphoreGive(p_i2s[i2s_num]->rx->mux); - return i2s_set_clk(i2s_num, clk_cfg->sample_rate_hz, slot_cfg->data_bit_width, slot_cfg->slot_mode); + 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); } #endif @@ -1172,14 +1175,12 @@ esp_err_t i2s_set_pdm_tx_up_sample(i2s_port_t i2s_num, const i2s_pdm_tx_upsample ESP_ERR_INVALID_ARG, TAG, "i2s mode is not PDM mode"); xSemaphoreTake(p_i2s[i2s_num]->tx->mux, portMAX_DELAY); i2s_stop(i2s_num); - i2s_pdm_tx_clk_config_t *clk_cfg = (i2s_pdm_tx_clk_config_t *)p_i2s[i2s_num]->clk_cfg; - i2s_pdm_tx_slot_config_t *slot_cfg = (i2s_pdm_tx_slot_config_t *)p_i2s[i2s_num]->slot_cfg; - clk_cfg->up_sample_fp = upsample_cfg->fp; - clk_cfg->up_sample_fs = upsample_cfg->fs; + p_i2s[i2s_num]->clk_cfg.up_sample_fp = upsample_cfg->fp; + p_i2s[i2s_num]->clk_cfg.up_sample_fs = upsample_cfg->fs; i2s_ll_tx_set_pdm_fpfs(p_i2s[i2s_num]->hal.dev, upsample_cfg->fp, upsample_cfg->fs); i2s_start(i2s_num); xSemaphoreGive(p_i2s[i2s_num]->tx->mux); - return i2s_set_clk(i2s_num, clk_cfg->sample_rate_hz, slot_cfg->data_bit_width, slot_cfg->slot_mode); + 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); } #endif @@ -1237,33 +1238,31 @@ static void i2s_mode_identify(i2s_port_t i2s_num, const i2s_config_t *i2s_config static esp_err_t i2s_config_transfer(i2s_port_t i2s_num, const i2s_config_t *i2s_config) { + #define SLOT_CFG(m) p_i2s[i2s_num]->slot_cfg.m + #define CLK_CFG() p_i2s[i2s_num]->clk_cfg /* Convert legacy configuration into general part of slot and clock configuration */ - i2s_slot_config_t slot_cfg = {}; - slot_cfg.mode = p_i2s[i2s_num]->mode; - slot_cfg.data_bit_width = i2s_config->bits_per_sample; - slot_cfg.slot_bit_width = (int)i2s_config->bits_per_chan < (int)i2s_config->bits_per_sample ? + p_i2s[i2s_num]->slot_cfg.mode = p_i2s[i2s_num]->mode; + p_i2s[i2s_num]->slot_cfg.data_bit_width = i2s_config->bits_per_sample; + p_i2s[i2s_num]->slot_cfg.slot_bit_width = (int)i2s_config->bits_per_chan < (int)i2s_config->bits_per_sample ? i2s_config->bits_per_sample : i2s_config->bits_per_chan; + slot_cfg.slot_mode = i2s_config->channel_format < I2S_CHANNEL_FMT_ONLY_RIGHT ? I2S_SLOT_MODE_STEREO : I2S_SLOT_MODE_MONO; - i2s_clk_config_t clk_cfg = {}; - clk_cfg.sample_rate_hz = i2s_config->sample_rate; - clk_cfg.mclk_multiple = i2s_config->mclk_multiple == 0 ? I2S_MCLK_MULTIPLE_256 : i2s_config->mclk_multiple; - clk_cfg.clk_src = I2S_CLK_D2CLK; + CLK_CFG().sample_rate_hz = i2s_config->sample_rate; + CLK_CFG().mclk_multiple = i2s_config->mclk_multiple == 0 ? I2S_MCLK_MULTIPLE_256 : i2s_config->mclk_multiple; + CLK_CFG().clk_src = I2S_CLK_160M_PLL; p_i2s[i2s_num]->fixed_mclk = i2s_config->fixed_mclk; p_i2s[i2s_num]->use_apll = false; - #if SOC_I2S_SUPPORTS_APLL - clk_cfg.clk_src = i2s_config->use_apll ? I2S_CLK_APLL : I2S_CLK_D2CLK; +#if SOC_I2S_SUPPORTS_APLL + CLK_CFG().clk_src = i2s_config->use_apll ? I2S_CLK_APLL : I2S_CLK_160M_PLL; p_i2s[i2s_num]->use_apll = i2s_config->use_apll; - #endif // SOC_I2S_SUPPORTS_APLL +#endif // SOC_I2S_SUPPORTS_APLL /* Convert legacy configuration into particular part of slot and clock configuration */ if (p_i2s[i2s_num]->mode == I2S_COMM_MODE_STD) { /* Generate STD slot configuration */ - i2s_std_slot_config_t *std_slot = (i2s_std_slot_config_t *)calloc(1, sizeof(i2s_std_slot_config_t)); - ESP_RETURN_ON_FALSE(std_slot, ESP_ERR_NO_MEM, TAG, "no memory for slot configuration struct"); - memcpy(std_slot, &slot_cfg, sizeof(i2s_slot_config_t)); - std_slot->ws_width = i2s_config->bits_per_sample; - std_slot->ws_pol = false; + SLOT_CFG(std).ws_width = i2s_config->bits_per_sample; + SLOT_CFG(std).ws_pol = false; if (i2s_config->channel_format == I2S_CHANNEL_FMT_RIGHT_LEFT) { std_slot->slot_sel = I2S_STD_SLOT_LEFT_RIGHT; } else if (i2s_config->channel_format == I2S_CHANNEL_FMT_ALL_LEFT || @@ -1273,59 +1272,45 @@ static esp_err_t i2s_config_transfer(i2s_port_t i2s_num, const i2s_config_t *i2s std_slot->slot_sel = I2S_STD_SLOT_ONLY_RIGHT; } if (i2s_config->communication_format == I2S_COMM_FORMAT_STAND_I2S) { - std_slot->bit_shift = true; + SLOT_CFG(std).bit_shift = true; } if (i2s_config->communication_format & I2S_COMM_FORMAT_STAND_PCM_SHORT) { - std_slot->bit_shift = true; - std_slot->ws_width = 1; - std_slot->ws_pol = true; + SLOT_CFG(std).bit_shift = true; + SLOT_CFG(std).ws_width = 1; + SLOT_CFG(std).ws_pol = true; } - #if SOC_I2S_HW_VERSION_1 - std_slot->msb_right = false; - #elif SOC_I2S_HW_VERSION_2 - std_slot->left_align = i2s_config->left_align; - std_slot->big_endian = i2s_config->big_edin; - std_slot->bit_order_lsb = i2s_config->bit_order_msb; // The old name is incorrect - #endif // SOC_I2S_HW_VERSION_1 - p_i2s[i2s_num]->slot_cfg = std_slot; + #if SOC_I2S_HW_VERSION_1 + SLOT_CFG(std).msb_right = false; + #elif SOC_I2S_HW_VERSION_2 + SLOT_CFG(std).left_align = i2s_config->left_align; + SLOT_CFG(std).big_endian = i2s_config->big_edin; + SLOT_CFG(std).bit_order_lsb = i2s_config->bit_order_msb; // The old name is incorrect + #endif // SOC_I2S_HW_VERSION_1 - /* Generate STD clock configuration */ - i2s_std_clk_config_t *std_clk = (i2s_std_clk_config_t *)calloc(1, sizeof(i2s_std_clk_config_t)); - ESP_RETURN_ON_FALSE(std_clk, ESP_ERR_NO_MEM, TAG, "no memory for clock configuration struct"); - memcpy(std_clk, &clk_cfg, sizeof(i2s_clk_config_t)); - p_i2s[i2s_num]->clk_cfg = std_clk; - p_i2s[i2s_num]->active_slot = (int)std_slot->slot_mode; + p_i2s[i2s_num]->active_slot = (int)p_i2s[i2s_num]->slot_cfg.slot_mode == I2S_SLOT_MODE_MONO ? 1 : 2; p_i2s[i2s_num]->total_slot = 2; goto finish; } #if SOC_I2S_SUPPORTS_PDM_TX if (p_i2s[i2s_num]->mode == I2S_COMM_MODE_PDM) { /* Generate PDM TX slot configuration */ - i2s_pdm_tx_slot_config_t *pdm_tx_slot = (i2s_pdm_tx_slot_config_t *)calloc(1, sizeof(i2s_pdm_tx_slot_config_t)); - ESP_RETURN_ON_FALSE(pdm_tx_slot, ESP_ERR_NO_MEM, TAG, "no memory for slot configuration struct"); - memcpy(pdm_tx_slot, &slot_cfg, sizeof(i2s_slot_config_t)); - pdm_tx_slot->sd_prescale = 0; - pdm_tx_slot->sd_scale = I2S_PDM_SIG_SCALING_MUL_1; - pdm_tx_slot->hp_scale = I2S_PDM_SIG_SCALING_MUL_1; - pdm_tx_slot->lp_scale = I2S_PDM_SIG_SCALING_MUL_1; - pdm_tx_slot->sinc_scale = I2S_PDM_SIG_SCALING_MUL_1; + SLOT_CFG(pdm_tx).sd_prescale = 0; + SLOT_CFG(pdm_tx).sd_scale = I2S_PDM_SIG_SCALING_MUL_1; + SLOT_CFG(pdm_tx).hp_scale = I2S_PDM_SIG_SCALING_MUL_1; + SLOT_CFG(pdm_tx).lp_scale = I2S_PDM_SIG_SCALING_MUL_1; + SLOT_CFG(pdm_tx).sinc_scale = I2S_PDM_SIG_SCALING_MUL_1; #if SOC_I2S_HW_VERSION_2 - pdm_tx_slot->sd_en = true; - pdm_tx_slot->hp_en = true; - pdm_tx_slot->hp_cut_off_freq_hz = 49; - pdm_tx_slot->sd_dither = 0; - pdm_tx_slot->sd_dither2 = 0; + SLOT_CFG(pdm_tx).sd_en = true; + SLOT_CFG(pdm_tx).hp_en = true; + SLOT_CFG(pdm_tx).hp_cut_off_freq_hz = 49; + SLOT_CFG(pdm_tx).sd_dither = 0; + SLOT_CFG(pdm_tx).sd_dither2 = 0; #endif // SOC_I2S_HW_VERSION_2 - p_i2s[i2s_num]->slot_cfg = pdm_tx_slot; /* Generate PDM TX clock configuration */ - i2s_pdm_tx_clk_config_t *pdm_tx_clk = (i2s_pdm_tx_clk_config_t *)calloc(1, sizeof(i2s_pdm_tx_clk_config_t)); - ESP_RETURN_ON_FALSE(pdm_tx_clk, ESP_ERR_NO_MEM, TAG, "no memory for clock configuration struct"); - memcpy(pdm_tx_clk, &clk_cfg, sizeof(i2s_clk_config_t)); - pdm_tx_clk->up_sample_fp = 960; - pdm_tx_clk->up_sample_fs = i2s_config->sample_rate / 100; - p_i2s[i2s_num]->clk_cfg = pdm_tx_clk; - p_i2s[i2s_num]->active_slot = (int)pdm_tx_slot->slot_mode; + CLK_CFG().up_sample_fp = 960; + CLK_CFG().up_sample_fs = i2s_config->sample_rate / 100; + p_i2s[i2s_num]->active_slot = (int)p_i2s[i2s_num]->slot_cfg.slot_mode == I2S_SLOT_MODE_MONO ? 1 : 2; p_i2s[i2s_num]->total_slot = 2; goto finish; } @@ -1333,20 +1318,9 @@ static esp_err_t i2s_config_transfer(i2s_port_t i2s_num, const i2s_config_t *i2s #if SOC_I2S_SUPPORTS_PDM_RX if (p_i2s[i2s_num]->mode == I2S_COMM_MODE_PDM) { - /* Generate PDM RX slot configuration */ - i2s_pdm_rx_slot_config_t *pdm_rx_slot = (i2s_pdm_rx_slot_config_t *)calloc(1, sizeof(i2s_pdm_rx_slot_config_t)); - ESP_RETURN_ON_FALSE(pdm_rx_slot, ESP_ERR_NO_MEM, TAG, "no memory for slot configuration struct"); - memcpy(pdm_rx_slot, &slot_cfg, sizeof(i2s_slot_config_t)); - p_i2s[i2s_num]->slot_cfg = pdm_rx_slot; - - /* Generate PDM RX clock configuration */ - i2s_pdm_rx_clk_config_t *pdm_rx_clk = (i2s_pdm_rx_clk_config_t *)calloc(1, sizeof(i2s_pdm_rx_clk_config_t)); - ESP_RETURN_ON_FALSE(pdm_rx_clk, ESP_ERR_NO_MEM, TAG, "no memory for clock configuration struct"); - memcpy(pdm_rx_clk, &clk_cfg, sizeof(i2s_clk_config_t)); - pdm_rx_clk->dn_sample_mode = I2S_PDM_DSR_8S; - p_i2s[i2s_num]->clk_cfg = pdm_rx_clk; - p_i2s[i2s_num]->active_slot = (int)pdm_rx_slot->slot_mode; + CLK_CFG().dn_sample_mode = I2S_PDM_DSR_8S; + p_i2s[i2s_num]->active_slot = (int)p_i2s[i2s_num]->slot_cfg.slot_mode == I2S_SLOT_MODE_MONO ? 1 : 2; p_i2s[i2s_num]->total_slot = 2; goto finish; } @@ -1355,55 +1329,42 @@ static esp_err_t i2s_config_transfer(i2s_port_t i2s_num, const i2s_config_t *i2s #if SOC_I2S_SUPPORTS_TDM if (p_i2s[i2s_num]->mode == I2S_COMM_MODE_TDM) { /* Generate TDM slot configuration */ - i2s_tdm_slot_config_t *tdm_slot = (i2s_tdm_slot_config_t *)calloc(1, sizeof(i2s_tdm_slot_config_t)); - ESP_RETURN_ON_FALSE(tdm_slot, ESP_ERR_NO_MEM, TAG, "no memory for slot configuration struct"); - memcpy(tdm_slot, &slot_cfg, sizeof(i2s_slot_config_t)); - tdm_slot->slot_mask = i2s_config->chan_mask >> 16; - uint32_t mx_slot = i2s_get_max_channel_num(tdm_slot->slot_mask); - tdm_slot->total_slot = mx_slot < i2s_config->total_chan ? mx_slot : i2s_config->total_chan; - tdm_slot->ws_width = I2S_TDM_AUTO_WS_WIDTH; - tdm_slot->ws_pol = false; + SLOT_CFG(tdm).slot_mask = i2s_config->chan_mask >> 16; + + SLOT_CFG(tdm).ws_width = I2S_TDM_AUTO_WS_WIDTH; + tdm_slot->slot_mode = I2S_SLOT_MODE_STEREO; + SLOT_CFG(tdm).ws_pol = false; if (i2s_config->communication_format == I2S_COMM_FORMAT_STAND_I2S) { - tdm_slot->bit_shift = true; + SLOT_CFG(tdm).bit_shift = true; } else if (i2s_config->communication_format == I2S_COMM_FORMAT_STAND_PCM_SHORT) { - tdm_slot->bit_shift = true; - tdm_slot->ws_width = 1; - tdm_slot->ws_pol = true; + SLOT_CFG(tdm).bit_shift = true; + SLOT_CFG(tdm).ws_width = 1; + SLOT_CFG(tdm).ws_pol = true; } else if (i2s_config->communication_format == I2S_COMM_FORMAT_STAND_PCM_LONG) { - tdm_slot->bit_shift = true; - tdm_slot->ws_width = tdm_slot->slot_bit_width; - tdm_slot->ws_pol = true; + SLOT_CFG(tdm).bit_shift = true; + SLOT_CFG(tdm).ws_width = SLOT_CFG(tdm).slot_bit_width; + SLOT_CFG(tdm).ws_pol = true; } - tdm_slot->left_align = i2s_config->left_align; - tdm_slot->big_endian = i2s_config->big_edin; - tdm_slot->bit_order_lsb = i2s_config->bit_order_msb; // The old name is incorrect - tdm_slot->skip_mask = i2s_config->skip_msk; - p_i2s[i2s_num]->slot_cfg = tdm_slot; + SLOT_CFG(tdm).left_align = i2s_config->left_align; + SLOT_CFG(tdm).big_endian = i2s_config->big_edin; + SLOT_CFG(tdm).bit_order_lsb = i2s_config->bit_order_msb; // The old name is incorrect + SLOT_CFG(tdm).skip_mask = i2s_config->skip_msk; /* Generate TDM clock configuration */ - i2s_tdm_clk_config_t *tdm_clk = (i2s_tdm_clk_config_t *)calloc(1, sizeof(i2s_tdm_clk_config_t)); - ESP_RETURN_ON_FALSE(tdm_clk, ESP_ERR_NO_MEM, TAG, "no memory for clock configuration struct"); - memcpy(tdm_clk, &clk_cfg, sizeof(i2s_clk_config_t)); - p_i2s[i2s_num]->clk_cfg = tdm_clk; - p_i2s[i2s_num]->active_slot = i2s_get_active_channel_num(tdm_slot->slot_mask); - p_i2s[i2s_num]->total_slot = tdm_slot->total_slot; + p_i2s[i2s_num]->active_slot = __builtin_popcount(tdm_slot->slot_mode); + uint32_t mx_slot = 32 - __builtin_clz(SLOT_CFG(tdm).slot_mask); + mx_slot = mx_slot < 2 ? 2 : mx_slot; + p_i2s[i2s_num]->.total_slot = mx_slot < i2s_config->total_chan ? mx_slot : i2s_config->total_chan; goto finish; } #endif // SOC_I2S_SUPPORTS_TDM #if SOC_I2S_SUPPORTS_ADC_DAC if ((int)p_i2s[i2s_num]->mode == I2S_COMM_MODE_ADC_DAC) { - i2s_slot_config_t *adc_dac_slot = (i2s_slot_config_t *)calloc(1, sizeof(i2s_slot_config_t)); - ESP_RETURN_ON_FALSE(adc_dac_slot, ESP_ERR_NO_MEM, TAG, "no memory for slot configuration struct"); - memcpy(adc_dac_slot, &slot_cfg, sizeof(i2s_slot_config_t)); - p_i2s[i2s_num]->slot_cfg = adc_dac_slot; - - i2s_clk_config_t *adc_dac_clk = (i2s_clk_config_t *)calloc(1, sizeof(i2s_clk_config_t)); - ESP_RETURN_ON_FALSE(adc_dac_clk, ESP_ERR_NO_MEM, TAG, "no memory for clock configuration struct"); - memcpy(adc_dac_clk, &clk_cfg, sizeof(i2s_clk_config_t)); - p_i2s[i2s_num]->clk_cfg = adc_dac_clk; + p_i2s[i2s_num]->slot_cfg.slot_mode = (p_i2s[i2s_num]->dir & I2S_DIR_TX) ? + I2S_SLOT_MODE_STEREO : I2S_SLOT_MODE_MONO; p_i2s[i2s_num]->active_slot = (p_i2s[i2s_num]->dir & I2S_DIR_TX) ? 2 : 1; p_i2s[i2s_num]->total_slot = 2; } @@ -1554,10 +1515,10 @@ esp_err_t i2s_driver_uninstall(i2s_port_t i2s_num) if (obj->use_apll) { // switch back to PLL clock source if (obj->dir & I2S_DIR_TX) { - i2s_ll_tx_clk_set_src(obj->hal.dev, I2S_CLK_D2CLK); + i2s_ll_tx_clk_set_src(obj->hal.dev, I2S_CLK_160M_PLL); } if (obj->dir & I2S_DIR_RX) { - i2s_ll_rx_clk_set_src(obj->hal.dev, I2S_CLK_D2CLK); + i2s_ll_rx_clk_set_src(obj->hal.dev, I2S_CLK_160M_PLL); } periph_rtc_apll_release(); } @@ -1578,15 +1539,7 @@ esp_err_t i2s_driver_uninstall(i2s_port_t i2s_num) } #endif /* Disable module clock */ - i2s_priv_deregister_object(i2s_num); - if (obj->clk_cfg) { - free(obj->clk_cfg); - obj->clk_cfg = NULL; - } - if (obj->slot_cfg) { - free(obj->slot_cfg); - obj->slot_cfg = NULL; - } + i2s_platform_release_occupation(i2s_num); free(obj); p_i2s[i2s_num] = NULL; return ESP_OK; @@ -1603,7 +1556,7 @@ esp_err_t i2s_driver_install(i2s_port_t i2s_num, const i2s_config_t *i2s_config, /* Step 2: Allocate driver object and register to platform */ i2s_obj_t *i2s_obj = calloc(1, sizeof(i2s_obj_t)); ESP_RETURN_ON_FALSE(i2s_obj, ESP_ERR_NO_MEM, TAG, "no mem for I2S driver"); - if (i2s_priv_register_object(i2s_obj, i2s_num) != ESP_OK) { + if (i2s_platform_acquire_occupation(i2s_num, "i2s_legacy") != ESP_OK) { free(i2s_obj); ESP_LOGE(TAG, "register I2S object to platform failed"); return ESP_ERR_INVALID_STATE; @@ -1913,31 +1866,3 @@ esp_err_t i2s_set_pin(i2s_port_t i2s_num, const i2s_pin_config_t *pin) gpio_matrix_in_check_and_set(pin->data_in_num, i2s_periph_signal[i2s_num].data_in_sig, 0); return ESP_OK; } - -esp_err_t i2s_priv_register_object(void *driver_obj, int port_id) -{ - esp_err_t ret = ESP_ERR_NOT_FOUND; - ESP_RETURN_ON_FALSE(driver_obj && (port_id < SOC_I2S_NUM), ESP_ERR_INVALID_ARG, TAG, "invalid arguments"); - portENTER_CRITICAL(&i2s_platform_spinlock); - if (!p_i2s[port_id]) { - ret = ESP_OK; - p_i2s[port_id] = driver_obj; - periph_module_enable(i2s_periph_signal[port_id].module); - } - portEXIT_CRITICAL(&i2s_platform_spinlock); - return ret; -} - -esp_err_t i2s_priv_deregister_object(int port_id) -{ - esp_err_t ret = ESP_ERR_INVALID_STATE; - ESP_RETURN_ON_FALSE(port_id < SOC_I2S_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid arguments"); - portENTER_CRITICAL(&i2s_platform_spinlock); - if (p_i2s[port_id]) { - ret = ESP_OK; - p_i2s[port_id] = NULL; - periph_module_disable(i2s_periph_signal[port_id].module); - } - portEXIT_CRITICAL(&i2s_platform_spinlock); - return ret; -} diff --git a/components/driver/i2s/i2s_pdm.c b/components/driver/i2s/i2s_pdm.c new file mode 100644 index 0000000000..ac7d40ce47 --- /dev/null +++ b/components/driver/i2s/i2s_pdm.c @@ -0,0 +1,533 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "hal/i2s_hal.h" +#include "driver/gpio.h" +#include "driver/i2s_pdm.h" +#include "i2s_private.h" +#include "clk_ctrl_os.h" +#include "esp_intr_alloc.h" +#include "esp_check.h" + +static const char *TAG = "I2S_PDM"; + +/*--------------------------------------------------------------- + PDM TX + ---------------------------------------------------------------*/ + +#if SOC_I2S_SUPPORTS_PDM_TX +static esp_err_t i2s_pdm_tx_calculate_clock(i2s_chan_handle_t handle, const i2s_pdm_tx_clk_config_t *clk_cfg, i2s_hal_clock_info_t *clk_info) +{ + uint32_t rate = clk_cfg->sample_rate_hz; + i2s_pdm_tx_clk_config_t *pdm_tx_clk = (i2s_pdm_tx_clk_config_t *)clk_cfg; + + clk_info->bclk = rate * I2S_LL_PDM_BCK_FACTOR * pdm_tx_clk->up_sample_fp / pdm_tx_clk->up_sample_fs; + clk_info->bclk_div = 8; + clk_info->mclk = clk_info->bclk * clk_info->bclk_div; +#if SOC_I2S_SUPPORTS_APLL + clk_info->sclk = clk_cfg->clk_src == I2S_CLK_160M_PLL ? I2S_LL_BASE_CLK : i2s_set_get_apll_freq(clk_info->mclk); +#else + clk_info->sclk = I2S_LL_BASE_CLK; +#endif + 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"); + /* Set upsampling configuration */ + i2s_ll_tx_set_pdm_fpfs(handle->parent->hal.dev, pdm_tx_clk->up_sample_fp, pdm_tx_clk->up_sample_fs); + + return ESP_OK; +} + +static esp_err_t i2s_pdm_tx_set_clock(i2s_chan_handle_t handle, const i2s_pdm_tx_clk_config_t *clk_cfg) +{ + esp_err_t ret = ESP_OK; + i2s_pdm_tx_config_t *pdm_tx_cfg = (i2s_pdm_tx_config_t *)(handle->mode_info); + + /* If Power Management enabled, a PM lock will be created when there is no PM lock or clock source changed */ +#ifdef CONFIG_PM_ENABLE + // Create/Re-create power management lock + if (handle->pm_lock == NULL || pdm_tx_cfg->clk_cfg.clk_src != clk_cfg->clk_src) { + if (handle->pm_lock) { + ESP_RETURN_ON_ERROR(esp_pm_lock_delete(handle->pm_lock), TAG, "I2S delete old pm lock failed"); + } + esp_pm_lock_type_t pm_type = ESP_PM_APB_FREQ_MAX; +#if SOC_I2S_SUPPORTS_APLL + if (clk_cfg->clk_src == I2S_CLK_APLL) { + pm_type = ESP_PM_NO_LIGHT_SLEEP; + } +#endif // SOC_I2S_SUPPORTS_APLL + ESP_RETURN_ON_ERROR(esp_pm_lock_create(pm_type, 0, "i2s_driver", &handle->pm_lock), err, TAG, "I2S pm lock create failed"); + } +#endif //CONFIG_PM_ENABLE + +#if SOC_I2S_SUPPORTS_APLL + /* Enable APLL and acquire its lock when initializing or clock source changed to APLL */ + if (clk_cfg->clk_src == I2S_CLK_APLL && (handle->state == I2S_CHAN_STATE_INIT || pdm_tx_cfg->clk_cfg.clk_src == I2S_CLK_160M_PLL)) { + periph_rtc_apll_acquire(); + handle->apll_en = true; + } + /* Disable APLL and release its lock when clock source is changed to D2CLK */ + if (clk_cfg->clk_src == I2S_CLK_160M_PLL && pdm_tx_cfg->clk_cfg.clk_src == I2S_CLK_APLL) { + periph_rtc_apll_release(); + handle->apll_en = false; + } +#endif + + i2s_hal_clock_info_t clk_info; + /* Calculate clock parameters */ + ESP_RETURN_ON_ERROR(i2s_pdm_tx_calculate_clock(handle, clk_cfg, &clk_info), TAG, "clock calculate failed"); + ESP_LOGD(TAG, "Clock division info: [sclk] %d Hz [mdiv] %d [mclk] %d Hz [bdiv] %d [bclk] %d Hz", + clk_info.sclk, clk_info.mclk_div, clk_info.mclk, clk_info.bclk_div, clk_info.bclk); + + portENTER_CRITICAL(&s_i2s.spinlock); + /* Set clock configurations in HAL*/ + i2s_hal_set_tx_clock(&handle->parent->hal, &clk_info, clk_cfg->clk_src); + portEXIT_CRITICAL(&s_i2s.spinlock); + + return ret; +} + +static esp_err_t i2s_pdm_tx_set_slot(i2s_chan_handle_t handle, const i2s_pdm_tx_slot_config_t *slot_cfg) +{ + 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 */ + 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_alloc_dma_desc(handle, handle->dma.desc_num, buf_size), + TAG, "allocate memory for dma descriptor failed"); + } + /* Share bck and ws signal in full-duplex mode */ + i2s_ll_share_bck_ws(handle->parent->hal.dev, handle->parent->full_duplex); + + portENTER_CRITICAL(&s_i2s.spinlock); + /* Configure the hardware to apply PDM format */ + bool is_slave = handle->role == I2S_ROLE_SLAVE; + i2s_hal_pdm_set_tx_slot(&(handle->parent->hal), is_slave, (i2s_hal_slot_config_t*)slot_cfg); + portEXIT_CRITICAL(&s_i2s.spinlock); + + /* Update the total slot num and active slot num */ + handle->total_slot = 2; + handle->active_slot = slot_cfg->slot_mode == I2S_SLOT_MODE_MONO ? 1 : 2; + + return ESP_OK; +} + +static esp_err_t i2s_pdm_tx_set_gpio(i2s_chan_handle_t handle, const i2s_pdm_tx_gpio_config_t *gpio_cfg) +{ + int id = handle->parent->id; + + /* Check validity of selected pins */ + ESP_RETURN_ON_FALSE((gpio_cfg->clk == -1 || GPIO_IS_VALID_GPIO(gpio_cfg->clk)), + ESP_ERR_INVALID_ARG, TAG, "clk gpio is invalid"); + ESP_RETURN_ON_FALSE((gpio_cfg->dout == -1 || GPIO_IS_VALID_GPIO(gpio_cfg->dout)), + ESP_ERR_INVALID_ARG, TAG, "dout gpio is invalid"); + /* Set data output GPIO */ + i2s_gpio_check_and_set(gpio_cfg->dout, i2s_periph_signal[id].data_out_sig, false); + + if (handle->role == I2S_ROLE_SLAVE) { + /* For "tx + slave" mode, select TX signal index for ws and bck */ + if (!handle->parent->full_duplex) { + i2s_gpio_check_and_set(gpio_cfg->clk, i2s_periph_signal[id].s_tx_ws_sig, true); + /* For "tx + rx + slave" or "rx + slave" mode, select RX signal index for ws and bck */ + } else { + i2s_gpio_check_and_set(gpio_cfg->clk, i2s_periph_signal[id].s_rx_ws_sig, true); + } + } else { + i2s_gpio_check_and_set(gpio_cfg->clk, i2s_periph_signal[id].m_tx_ws_sig, false); + } +#if SOC_I2S_HW_VERSION_2 + i2s_ll_mclk_bind_to_tx_clk(handle->parent->hal.dev); +#endif + + return ESP_OK; +} + +esp_err_t i2s_init_pdm_tx_channel(i2s_chan_handle_t handle, const i2s_pdm_tx_config_t *pdm_tx_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + ESP_RETURN_ON_FALSE(handle->dir == I2S_DIR_TX, ESP_ERR_INVALID_ARG, TAG, "This channel handle is not a TX handle"); + ESP_RETURN_ON_FALSE(handle->parent->id == I2S_NUM_0, ESP_ERR_INVALID_ARG, TAG, "This channel handle is registered on I2S1, but PDM is only supported on I2S0"); + + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_REGISTER, ESP_ERR_INVALID_STATE, err, TAG, "the channel has initialized already"); + ESP_GOTO_ON_ERROR(i2s_pdm_tx_set_gpio(handle, &pdm_tx_cfg->gpio_cfg), err, TAG, "initialize channel failed while setting gpio pins"); + /* i2s_set_slot should be called before i2s_set_clock while initializing, because clock is relay on the slot */ + ESP_GOTO_ON_ERROR(i2s_pdm_tx_set_slot(handle, &pdm_tx_cfg->slot_cfg), err, TAG, "initialize channel failed while setting slot"); + ESP_GOTO_ON_ERROR(i2s_pdm_tx_set_clock(handle, &pdm_tx_cfg->clk_cfg), err, TAG, "initialize channel failed while setting clock"); + ESP_GOTO_ON_ERROR(i2s_init_dma_intr(handle, ESP_INTR_FLAG_LEVEL1), err, TAG, "initialize dma interrupt failed"); + /* Store the configurations of standard mode */ + i2s_pdm_tx_config_t *mode_info = calloc(1, sizeof(i2s_pdm_tx_config_t)); + ESP_GOTO_ON_FALSE(mode_info, ESP_ERR_NO_MEM, err, TAG, "no memory for storing the configurations"); + memcpy(mode_info, pdm_tx_cfg, sizeof(i2s_pdm_tx_config_t)); + handle->mode_info = mode_info; + + i2s_ll_tx_enable_pdm(handle->parent->hal.dev); +#if SOC_I2S_HW_VERSION_2 + /* Enable clock to start outputting mclk signal. Some codecs will reset once mclk stop */ + i2s_ll_tx_enable_clock(handle->parent->hal.dev); +#endif + + /* Initialization finished, mark state as ready */ + handle->state = I2S_CHAN_STATE_READY; + xSemaphoreGive(handle->mutex); + return ret; + +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +esp_err_t i2s_reconfig_pdm_tx_clock(i2s_chan_handle_t handle, const i2s_pdm_tx_clk_config_t *clk_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + I2S_NULL_POINTER_CHECK(TAG, clk_cfg); + ESP_RETURN_ON_FALSE(handle->dir == I2S_DIR_TX, ESP_ERR_INVALID_ARG, TAG, "This channel handle is not a TX handle"); + + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be stopped before reconfiguring the clock"); + + i2s_pdm_tx_config_t *pdm_tx_cfg = (i2s_pdm_tx_config_t*)handle->mode_info; + ESP_GOTO_ON_FALSE(pdm_tx_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); + + ESP_GOTO_ON_ERROR(i2s_pdm_tx_set_clock(handle, &pdm_tx_cfg->clk_cfg), err, TAG, "update clock failed"); + /* Update the stored clock information */ + memcpy(&pdm_tx_cfg->clk_cfg, clk_cfg, sizeof(i2s_pdm_tx_clk_config_t)); + + xSemaphoreGive(handle->mutex); + + return ESP_OK; +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +esp_err_t i2s_reconfig_pdm_tx_slot(i2s_chan_handle_t handle, const i2s_pdm_tx_slot_config_t *slot_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + I2S_NULL_POINTER_CHECK(TAG, slot_cfg); + ESP_RETURN_ON_FALSE(handle->dir == I2S_DIR_TX, ESP_ERR_INVALID_ARG, TAG, "This channel handle is not a TX handle"); + + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be stopped before reconfiguring the slot"); + + i2s_pdm_tx_config_t *pdm_tx_cfg = (i2s_pdm_tx_config_t*)handle->mode_info; + ESP_GOTO_ON_FALSE(pdm_tx_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); + + ESP_GOTO_ON_ERROR(i2s_pdm_tx_set_slot(handle, slot_cfg), err, TAG, "set i2s standard slot failed"); + /* Update the stored slot information */ + memcpy(&pdm_tx_cfg->slot_cfg, slot_cfg, sizeof(i2s_pdm_tx_slot_config_t)); + + /* If the slot bit width changed, then need to update the clock */ + uint32_t slot_bits = slot_cfg->slot_bit_width == I2S_SLOT_BIT_WIDTH_AUTO ? slot_cfg->data_bit_width : slot_cfg->slot_bit_width; + if (pdm_tx_cfg->slot_cfg.slot_bit_width == slot_bits) { + ESP_GOTO_ON_ERROR(i2s_pdm_tx_set_clock(handle, &pdm_tx_cfg->clk_cfg), err, TAG, "update clock failed"); + } + + xSemaphoreGive(handle->mutex); + + return ESP_OK; +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +esp_err_t i2s_reconfig_pdm_tx_gpio(i2s_chan_handle_t handle, const i2s_pdm_tx_gpio_config_t *gpio_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + I2S_NULL_POINTER_CHECK(TAG, gpio_cfg); + ESP_RETURN_ON_FALSE(handle->dir == I2S_DIR_TX, ESP_ERR_INVALID_ARG, TAG, "This channel handle is not a TX handle"); + + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "This handle is not working in standard moded"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "Invalid state, I2S should be stopped before reconfiguring the gpio"); + + i2s_pdm_tx_config_t *pdm_tx_cfg = (i2s_pdm_tx_config_t*)handle->mode_info; + ESP_GOTO_ON_FALSE(pdm_tx_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); + + ESP_GOTO_ON_ERROR(i2s_pdm_tx_set_gpio(handle, gpio_cfg), err, TAG, "set i2s standard slot failed"); + + /* Update the stored slot information */ + memcpy(&pdm_tx_cfg->gpio_cfg, gpio_cfg, sizeof(i2s_pdm_tx_gpio_config_t)); + xSemaphoreGive(handle->mutex); + + return ESP_OK; +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +#endif + + +/*--------------------------------------------------------------- + PDM RX + ---------------------------------------------------------------*/ + +#if SOC_I2S_SUPPORTS_PDM_RX +static esp_err_t i2s_pdm_rx_calculate_clock(i2s_chan_handle_t handle, const i2s_pdm_rx_clk_config_t *clk_cfg, i2s_hal_clock_info_t *clk_info) +{ + uint32_t rate = clk_cfg->sample_rate_hz; + i2s_pdm_rx_clk_config_t *pdm_rx_clk = (i2s_pdm_rx_clk_config_t *)clk_cfg; + + clk_info->bclk = rate * I2S_LL_PDM_BCK_FACTOR * (pdm_rx_clk->dn_sample_mode == I2S_PDM_DSR_16S ? 2 : 1); + clk_info->bclk_div = 8; + clk_info->mclk = clk_info->bclk * clk_info->bclk_div; +#if SOC_I2S_SUPPORTS_APLL + clk_info->sclk = clk_cfg->clk_src == I2S_CLK_160M_PLL ? I2S_LL_BASE_CLK : i2s_set_get_apll_freq(clk_info->mclk); +#else + clk_info->sclk = I2S_LL_BASE_CLK; +#endif + 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"); + /* Set down-sampling configuration */ + i2s_ll_rx_set_pdm_dsr(handle->parent->hal.dev, pdm_rx_clk->dn_sample_mode); + return ESP_OK; +} + +static esp_err_t i2s_pdm_rx_set_clock(i2s_chan_handle_t handle, const i2s_pdm_rx_clk_config_t *clk_cfg) +{ + esp_err_t ret = ESP_OK; + i2s_pdm_rx_config_t *pdm_rx_cfg = (i2s_pdm_rx_config_t *)(handle->mode_info); + + /* If Power Management enabled, a PM lock will be created when there is no PM lock or clock source changed */ +#ifdef CONFIG_PM_ENABLE + // Create/Re-create power management lock + if (handle->pm_lock == NULL || pdm_rx_cfg->clk_cfg.clk_src != clk_cfg->clk_src) { + if (handle->pm_lock) { + ESP_RETURN_ON_ERROR(esp_pm_lock_delete(handle->pm_lock), TAG, "I2S delete old pm lock failed"); + } + esp_pm_lock_type_t pm_type = ESP_PM_APB_FREQ_MAX; +#if SOC_I2S_SUPPORTS_APLL + if (clk_cfg->clk_src == I2S_CLK_APLL) { + pm_type = ESP_PM_NO_LIGHT_SLEEP; + } +#endif // SOC_I2S_SUPPORTS_APLL + ESP_RETURN_ON_ERROR(esp_pm_lock_create(pm_type, 0, "i2s_driver", &handle->pm_lock), err, TAG, "I2S pm lock create failed"); + } +#endif //CONFIG_PM_ENABLE + +#if SOC_I2S_SUPPORTS_APLL + /* Enable APLL and acquire its lock when initializing or clock source changed to APLL */ + if (clk_cfg->clk_src == I2S_CLK_APLL && (handle->state == I2S_CHAN_STATE_INIT || pdm_rx_cfg->clk_cfg.clk_src == I2S_CLK_160M_PLL)) { + periph_rtc_apll_acquire(); + handle->apll_en = true; + } + /* Disable APLL and release its lock when clock source is changed to D2CLK */ + if (clk_cfg->clk_src == I2S_CLK_160M_PLL && pdm_rx_cfg->clk_cfg.clk_src == I2S_CLK_APLL) { + periph_rtc_apll_release(); + handle->apll_en = false; + } +#endif + + i2s_hal_clock_info_t clk_info; + /* Calculate clock parameters */ + ESP_RETURN_ON_ERROR(i2s_pdm_rx_calculate_clock(handle, clk_cfg, &clk_info), TAG, "clock calculate failed"); + ESP_LOGD(TAG, "Clock division info: [sclk] %d Hz [mdiv] %d [mclk] %d Hz [bdiv] %d [bclk] %d Hz", + clk_info.sclk, clk_info.mclk_div, clk_info.mclk, clk_info.bclk_div, clk_info.bclk); + + portENTER_CRITICAL(&s_i2s.spinlock); + /* Set clock configurations in HAL*/ + i2s_hal_set_rx_clock(&handle->parent->hal, &clk_info, clk_cfg->clk_src); + portEXIT_CRITICAL(&s_i2s.spinlock); + + return ret; +} + +static esp_err_t i2s_pdm_rx_set_slot(i2s_chan_handle_t handle, const i2s_pdm_rx_slot_config_t *slot_cfg) +{ + 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 */ + 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_alloc_dma_desc(handle, handle->dma.desc_num, buf_size), + TAG, "allocate memory for dma descriptor failed"); + } + /* Share bck and ws signal in full-duplex mode */ + i2s_ll_share_bck_ws(handle->parent->hal.dev, handle->parent->full_duplex); + + portENTER_CRITICAL(&s_i2s.spinlock); + /* Configure the hardware to apply PDM format */ + bool is_slave = (handle->role == I2S_ROLE_SLAVE) | handle->parent->full_duplex; + i2s_hal_pdm_set_rx_slot(&(handle->parent->hal), is_slave, (i2s_hal_slot_config_t*)slot_cfg); + portEXIT_CRITICAL(&s_i2s.spinlock); + + /* Update the total slot num and active slot num */ + handle->total_slot = 2; + handle->active_slot = slot_cfg->slot_mode == I2S_SLOT_MODE_MONO ? 1 : 2; + + return ESP_OK; +} + +static esp_err_t i2s_pdm_rx_set_gpio(i2s_chan_handle_t handle, const i2s_pdm_rx_gpio_config_t *gpio_cfg) +{ + int id = handle->parent->id; + + /* Check validity of selected pins */ + ESP_RETURN_ON_FALSE((gpio_cfg->clk == -1 || GPIO_IS_VALID_GPIO(gpio_cfg->clk)), + ESP_ERR_INVALID_ARG, TAG, "clk gpio is invalid"); + ESP_RETURN_ON_FALSE((gpio_cfg->din == -1 || GPIO_IS_VALID_GPIO(gpio_cfg->din)), + ESP_ERR_INVALID_ARG, TAG, "dout gpio is invalid"); + /* Set data input GPIO */ + i2s_gpio_check_and_set(gpio_cfg->din, i2s_periph_signal[id].data_in_sig, true); + + if (handle->role == I2S_ROLE_SLAVE) { + /* For "tx + rx + slave" or "rx + slave" mode, select RX signal index for ws and bck */ + i2s_gpio_check_and_set(gpio_cfg->clk, i2s_periph_signal[id].s_rx_ws_sig, true); + } else { + if (!handle->parent->full_duplex) { + i2s_gpio_check_and_set(gpio_cfg->clk, i2s_periph_signal[id].m_rx_ws_sig, false); + } else { + i2s_gpio_check_and_set(gpio_cfg->clk, i2s_periph_signal[id].m_tx_ws_sig, false); + } + } +#if SOC_I2S_HW_VERSION_2 + i2s_ll_mclk_bind_to_rx_clk(handle->parent->hal.dev); +#endif + + return ESP_OK; +} + +esp_err_t i2s_init_pdm_rx_channel(i2s_chan_handle_t handle, const i2s_pdm_rx_config_t *pdm_rx_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + ESP_RETURN_ON_FALSE(handle->dir == I2S_DIR_RX, ESP_ERR_INVALID_ARG, TAG, "This channel handle is not a RX handle"); + ESP_RETURN_ON_FALSE(handle->parent->id == I2S_NUM_0, ESP_ERR_INVALID_ARG, TAG, "This channel handle is registered on I2S1, but PDM is only supported on I2S0"); + + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_REGISTER, ESP_ERR_INVALID_STATE, err, TAG, "the channel has initialized already"); + ESP_GOTO_ON_ERROR(i2s_pdm_rx_set_gpio(handle, &pdm_rx_cfg->gpio_cfg), err, TAG, "initialize channel failed while setting gpio pins"); + /* i2s_set_slot should be called before i2s_set_clock while initializing, because clock is relay on the slot */ + ESP_GOTO_ON_ERROR(i2s_pdm_rx_set_slot(handle, &pdm_rx_cfg->slot_cfg), err, TAG, "initialize channel failed while setting slot"); + ESP_GOTO_ON_ERROR(i2s_pdm_rx_set_clock(handle, &pdm_rx_cfg->clk_cfg), err, TAG, "initialize channel failed while setting clock"); + ESP_GOTO_ON_ERROR(i2s_init_dma_intr(handle, ESP_INTR_FLAG_LEVEL1), err, TAG, "initialize dma interrupt failed"); + /* Store the configurations of standard mode */ + i2s_pdm_rx_config_t *mode_info = calloc(1, sizeof(i2s_pdm_rx_config_t)); + ESP_GOTO_ON_FALSE(mode_info, ESP_ERR_NO_MEM, err, TAG, "no memory for storing the configurations"); + memcpy(mode_info, pdm_rx_cfg, sizeof(i2s_pdm_rx_config_t)); + handle->mode_info = mode_info; + + i2s_ll_rx_enable_pdm(handle->parent->hal.dev); +#if SOC_I2S_HW_VERSION_2 + /* Enable clock to start outputting mclk signal. Some codecs will reset once mclk stop */ + i2s_ll_rx_enable_clock(handle->parent->hal.dev); +#endif + + /* Initialization finished, mark state as ready */ + handle->state = I2S_CHAN_STATE_READY; + xSemaphoreGive(handle->mutex); + return ret; + +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +esp_err_t i2s_reconfig_pdm_rx_clock(i2s_chan_handle_t handle, const i2s_pdm_rx_clk_config_t *clk_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + I2S_NULL_POINTER_CHECK(TAG, clk_cfg); + ESP_RETURN_ON_FALSE(handle->dir == I2S_DIR_RX, ESP_ERR_INVALID_ARG, TAG, "This channel handle is not a RX handle"); + + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be stopped before reconfiguring the clock"); + + i2s_pdm_rx_config_t *pdm_rx_cfg = (i2s_pdm_rx_config_t*)handle->mode_info; + ESP_GOTO_ON_FALSE(pdm_rx_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); + + ESP_GOTO_ON_ERROR(i2s_pdm_rx_set_clock(handle, &pdm_rx_cfg->clk_cfg), err, TAG, "update clock failed"); + /* Update the stored clock information */ + memcpy(&pdm_rx_cfg->clk_cfg, clk_cfg, sizeof(i2s_pdm_rx_clk_config_t)); + + xSemaphoreGive(handle->mutex); + + return ESP_OK; +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +esp_err_t i2s_reconfig_pdm_rx_slot(i2s_chan_handle_t handle, const i2s_pdm_rx_slot_config_t *slot_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + I2S_NULL_POINTER_CHECK(TAG, slot_cfg); + ESP_RETURN_ON_FALSE(handle->dir == I2S_DIR_RX, ESP_ERR_INVALID_ARG, TAG, "This channel handle is not a RX handle"); + + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be stopped before reconfiguring the slot"); + + i2s_pdm_rx_config_t *pdm_rx_cfg = (i2s_pdm_rx_config_t*)handle->mode_info; + ESP_GOTO_ON_FALSE(pdm_rx_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); + + ESP_GOTO_ON_ERROR(i2s_pdm_rx_set_slot(handle, slot_cfg), err, TAG, "set i2s standard slot failed"); + /* Update the stored slot information */ + memcpy(&pdm_rx_cfg->slot_cfg, slot_cfg, sizeof(i2s_pdm_rx_slot_config_t)); + + /* If the slot bit width changed, then need to update the clock */ + uint32_t slot_bits = slot_cfg->slot_bit_width == I2S_SLOT_BIT_WIDTH_AUTO ? slot_cfg->data_bit_width : slot_cfg->slot_bit_width; + if (pdm_rx_cfg->slot_cfg.slot_bit_width == slot_bits) { + ESP_GOTO_ON_ERROR(i2s_pdm_rx_set_clock(handle, &pdm_rx_cfg->clk_cfg), err, TAG, "update clock failed"); + } + + xSemaphoreGive(handle->mutex); + + return ESP_OK; +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +esp_err_t i2s_reconfig_pdm_rx_gpio(i2s_chan_handle_t handle, const i2s_pdm_rx_gpio_config_t *gpio_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + I2S_NULL_POINTER_CHECK(TAG, gpio_cfg); + + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "This handle is not working in standard moded"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "Invalid state, I2S should be stopped before reconfiguring the gpio"); + + i2s_pdm_rx_config_t *pdm_rx_cfg = (i2s_pdm_rx_config_t*)handle->mode_info; + ESP_GOTO_ON_FALSE(pdm_rx_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); + + ESP_GOTO_ON_ERROR(i2s_pdm_rx_set_gpio(handle, gpio_cfg), err, TAG, "set i2s standard slot failed"); + + /* Update the stored slot information */ + memcpy(&pdm_rx_cfg->gpio_cfg, gpio_cfg, sizeof(i2s_pdm_rx_gpio_config_t)); + xSemaphoreGive(handle->mutex); + + return ESP_OK; +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +#endif // SOC_I2S_SUPPORTS_PDM_RX diff --git a/components/driver/i2s/i2s_private.h b/components/driver/i2s/i2s_private.h new file mode 100644 index 0000000000..cfd021e904 --- /dev/null +++ b/components/driver/i2s/i2s_private.h @@ -0,0 +1,131 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "freertos/FreeRTOS.h" +#include "soc/lldesc.h" +#include "soc/soc_caps.h" +#include "hal/i2s_types.h" +#include "freertos/semphr.h" +#include "freertos/queue.h" +#if SOC_GDMA_SUPPORTED +#include "esp_private/gdma.h" +#endif +#include "esp_pm.h" +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define I2S_NULL_POINTER_CHECK(tag, p) ESP_RETURN_ON_FALSE((p), ESP_ERR_INVALID_ARG, tag, "[%s:%d] input parameter '"#p"' is NULL",__FUNCTION__,__LINE__) + +/** + * @brief i2s channel state for checking if the operation in under right driver state + */ +typedef enum { + I2S_CHAN_STATE_REGISTER, /*!< i2s channel is registered (not initialized) */ + I2S_CHAN_STATE_INIT, /*!< i2s channel is initializing */ + I2S_CHAN_STATE_READY, /*!< i2s channel is stopped (initialized) */ + I2S_CHAN_STATE_IDLE, /*!< i2s channel is idling (initialized and started) */ + I2S_CHAN_STATE_WRITING, /*!< i2s channel is writing (initialized and started) */ + I2S_CHAN_STATE_READING /*!< i2s channel is reading (initialized and started) */ +} i2s_state_t; + +/** + * @brief i2s channel level configurations + * @note It performs as channel handle + */ +typedef struct { +#if SOC_GDMA_SUPPORTED + gdma_channel_handle_t dma_chan; /*!< gdma channel handler */ +#endif + uint32_t desc_num; /*!< I2S DMA buffer number, it is also the number of DMA descriptor */ + uint32_t frame_num; /*!< I2S frame number in one DMA buffer. One frame means one-time sample data in all slots */ + uint32_t buf_size; /*!< dma buffer size */ + bool auto_clear; /*!< Set to auto clear DMA TX descriptor, i2s will always send zero automatically if no data to send */ + uint32_t rw_pos; /*!< reading/writing pointer position */ + void *curr_ptr; /*!< Pointer to current dma buffer */ + lldesc_t **desc; /*!< dma descriptor array */ + uint8_t **bufs; /*!< dma buffer array */ +} i2s_dma_t; + +/** + * @brief i2s controller level configurations + * @note Both i2s rx and tx channel are under its control + */ +typedef struct { + i2s_port_t id; /*!< i2s port id */ + i2s_hal_context_t hal; /*!< hal context */ + uint32_t chan_occupancy; /*!< channel occupancy (rx/tx) */ + bool full_duplex; /*!< is full_duplex */ + i2s_chan_handle_t tx_chan; /*!< tx channel handler */ + i2s_chan_handle_t rx_chan; /*!< rx channel handler */ + int mclk; /*!< MCK out pin, shared by tx/rx*/ + +#if !SOC_GDMA_SUPPORTED + intr_handle_t i2s_isr_handle; /*!< i2s interrupt handler */ +#endif +} i2s_controller_t; + +struct i2s_channel_t { + /* Channel basic information */ + i2s_controller_t *parent; /*!< Parent pointer to controller object */ + i2s_comm_mode_t mode; /*!< i2s channel communication mode */ + i2s_role_t role; /*!< i2s role */ + i2s_dir_t dir; /*!< i2s channel direction */ + i2s_dma_t dma; /*!< i2s dma object */ + i2s_state_t state; /*!< i2s driver state. Ensuring the driver working in a correct sequence */ + /* Stored configurations */ + void *mode_info; /*!< Slot, clock and gpio information of each mode */ +#if SOC_I2S_SUPPORTS_APLL + bool apll_en; /*!< Flag of wether APLL enabled */ +#endif + uint32_t active_slot; /*!< Active slot number */ + uint32_t total_slot; /*!< Total slot number */ + /* Locks and queues */ + SemaphoreHandle_t mutex; /*!< Mutex for DMA buffer related operations like reading/writing */ + esp_pm_lock_handle_t pm_lock; /*!< Power management lock, to avoid apb clock frequency changes while i2s is working */ + QueueHandle_t msg_queue; /*!< Message queue handler, used for transporting data between interrupt and read/write task */ + QueueHandle_t event_queue; /*!< Event queue handler, used for transporting interrupt event to user */ + + /* Function pointers of the corresponding mode */ + void (*start)(i2s_chan_handle_t); /*!< start tx/rx channel */ + void (*stop)(i2s_chan_handle_t); /*!< stop tx/rx channel */ +}; + +/** + * @brief i2s platform level configurations + * @note All i2s controllers are under its control + */ +typedef struct { + portMUX_TYPE spinlock; /*!< Platform level lock */ + i2s_controller_t *controller[I2S_NUM_MAX]; /*!< Controller object */ + const char *comp_name[I2S_NUM_MAX]; /*!< The component name that occupied i2s controller */ +} i2s_platform_t; + +extern i2s_platform_t s_i2s; + +esp_err_t i2s_init_dma_intr(i2s_chan_handle_t handle, int intr_flag); + +esp_err_t i2s_free_dma_desc(i2s_chan_handle_t handle); + +esp_err_t i2s_alloc_dma_desc(i2s_chan_handle_t handle, uint32_t num, uint32_t bufsize); + +uint32_t i2s_get_buf_size(i2s_chan_handle_t handle, uint32_t data_bit_width, uint32_t dma_frame_num); + +#if SOC_I2S_SUPPORTS_APLL +uint32_t i2s_set_get_apll_freq(uint32_t mclk_freq); +#endif + +void i2s_gpio_check_and_set(gpio_num_t gpio, uint32_t signal_idx, bool is_input); + +esp_err_t i2s_check_set_mclk(i2s_port_t id, gpio_num_t gpio_num); + +#ifdef __cplusplus +} +#endif diff --git a/components/driver/i2s/i2s_std.c b/components/driver/i2s/i2s_std.c new file mode 100644 index 0000000000..9548333643 --- /dev/null +++ b/components/driver/i2s/i2s_std.c @@ -0,0 +1,315 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "hal/i2s_hal.h" +#include "driver/gpio.h" +#include "driver/i2s_std.h" +#include "i2s_private.h" +#include "clk_ctrl_os.h" +#include "esp_intr_alloc.h" +#include "esp_check.h" + +const static char *TAG = "I2S_STD"; + +static esp_err_t i2s_std_calculate_clock(i2s_chan_handle_t handle, const i2s_std_clk_config_t *clk_cfg, i2s_hal_clock_info_t *clk_info) +{ + uint32_t rate = clk_cfg->sample_rate_hz; + i2s_std_slot_config_t *slot_cfg = &((i2s_std_config_t *)(handle->mode_info))->slot_cfg; + uint32_t slot_bits = (slot_cfg->slot_bit_width == I2S_SLOT_BIT_WIDTH_AUTO) || + ((int)slot_cfg->slot_bit_width < (int)slot_cfg->data_bit_width) ? + slot_cfg->data_bit_width : slot_cfg->slot_bit_width; + /* Calculate multiple + * Fmclk = bck_div*fbck = fsclk/(mclk_div+b/a) */ + if (handle->role == I2S_ROLE_MASTER) { + clk_info->bclk = rate * handle->total_slot * slot_bits; + clk_info->mclk = rate * clk_cfg->mclk_multiple; + clk_info->bclk_div = clk_info->mclk / clk_info->bclk; + } else { + /* For slave mode, mclk >= bclk * 8, so fix bclk_div to 2 first */ + clk_info->bclk_div = 8; + clk_info->bclk = rate * handle->total_slot * slot_bits; + clk_info->mclk = clk_info->bclk * clk_info->bclk_div; + } +#if SOC_I2S_SUPPORTS_APLL + clk_info->sclk = clk_cfg->clk_src == I2S_CLK_160M_PLL ? I2S_LL_BASE_CLK : i2s_set_get_apll_freq(clk_info->mclk); +#else + clk_info->sclk = I2S_LL_BASE_CLK; +#endif + 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"); + + return ESP_OK; +} + +static esp_err_t i2s_std_set_clock(i2s_chan_handle_t handle, const i2s_std_clk_config_t *clk_cfg) +{ + esp_err_t ret = ESP_OK; + i2s_std_config_t *std_cfg = (i2s_std_config_t *)(handle->mode_info); + + /* If Power Management enabled, a PM lock will be created when there is no PM lock or clock source changed */ +#ifdef CONFIG_PM_ENABLE + // Create/Re-create power management lock + if (handle->pm_lock == NULL || std_cfg->clk_cfg.clk_src != clk_cfg->clk_src) { + if (handle->pm_lock) { + ESP_RETURN_ON_ERROR(esp_pm_lock_delete(handle->pm_lock), TAG, "I2S delete old pm lock failed"); + } + esp_pm_lock_type_t pm_type = ESP_PM_APB_FREQ_MAX; +#if SOC_I2S_SUPPORTS_APLL + if (clk_cfg->clk_src == I2S_CLK_APLL) { + pm_type = ESP_PM_NO_LIGHT_SLEEP; + } +#endif // SOC_I2S_SUPPORTS_APLL + ESP_RETURN_ON_ERROR(esp_pm_lock_create(pm_type, 0, "i2s_driver", &handle->pm_lock), err, TAG, "I2S pm lock create failed"); + } +#endif //CONFIG_PM_ENABLE + +#if SOC_I2S_SUPPORTS_APLL + /* Enable APLL and acquire its lock when initializing or clock source changed to APLL */ + if (clk_cfg->clk_src == I2S_CLK_APLL && (handle->state == I2S_CHAN_STATE_INIT || std_cfg->clk_cfg.clk_src == I2S_CLK_160M_PLL)) { + periph_rtc_apll_acquire(); + handle->apll_en = true; + } + /* Disable APLL and release its lock when clock source is changed to D2CLK */ + if (clk_cfg->clk_src == I2S_CLK_160M_PLL && std_cfg->clk_cfg.clk_src == I2S_CLK_APLL) { + periph_rtc_apll_release(); + handle->apll_en = false; + } +#endif + + i2s_hal_clock_info_t clk_info; + /* Calculate clock parameters */ + ESP_RETURN_ON_ERROR(i2s_std_calculate_clock(handle, clk_cfg, &clk_info), TAG, "clock calculate failed"); + ESP_LOGD(TAG, "Clock division info: [sclk] %d Hz [mdiv] %d [mclk] %d Hz [bdiv] %d [bclk] %d Hz", + clk_info.sclk, clk_info.mclk_div, clk_info.mclk, clk_info.bclk_div, clk_info.bclk); + + portENTER_CRITICAL(&s_i2s.spinlock); + /* Set clock configurations in HAL*/ + if (handle->dir == I2S_DIR_TX) { + i2s_hal_set_tx_clock(&handle->parent->hal, &clk_info, clk_cfg->clk_src); + } else { + i2s_hal_set_rx_clock(&handle->parent->hal, &clk_info, clk_cfg->clk_src); + } + portEXIT_CRITICAL(&s_i2s.spinlock); + + return ret; +} + +static esp_err_t i2s_std_set_slot(i2s_chan_handle_t handle, const i2s_std_slot_config_t *slot_cfg) +{ + 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 */ + 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_alloc_dma_desc(handle, handle->dma.desc_num, buf_size), + TAG, "allocate memory for dma descriptor failed"); + } + bool is_slave = handle->role == I2S_ROLE_SLAVE; + /* Share bck and ws signal in full-duplex mode */ + if (handle->parent->full_duplex) { + i2s_ll_share_bck_ws(handle->parent->hal.dev, true); + /* Since bck and ws are shared, only tx or rx can be master + Force to set rx as slave to avoid conflict of clock signal */ + if (handle->dir == I2S_DIR_RX) { + is_slave = true; + } + } else { + i2s_ll_share_bck_ws(handle->parent->hal.dev, false); + } + + portENTER_CRITICAL(&s_i2s.spinlock); + /* Configure the hardware to apply STD format */ + if (handle->dir == I2S_DIR_TX) { + i2s_hal_std_set_tx_slot(&(handle->parent->hal), is_slave, (i2s_hal_slot_config_t*)slot_cfg); + } else { + i2s_hal_std_set_rx_slot(&(handle->parent->hal), is_slave, (i2s_hal_slot_config_t*)slot_cfg); + } + portEXIT_CRITICAL(&s_i2s.spinlock); + + /* Update the total slot num and active slot num */ + handle->total_slot = 2; + handle->active_slot = slot_cfg->slot_mode == I2S_SLOT_MODE_MONO ? 1 : 2; + + return ESP_OK; +} + +static esp_err_t i2s_std_set_gpio(i2s_chan_handle_t handle, const i2s_std_gpio_config_t *gpio_cfg) +{ + int id = handle->parent->id; + + /* Check validity of selected pins */ + ESP_RETURN_ON_FALSE((gpio_cfg->bclk == -1 || GPIO_IS_VALID_GPIO(gpio_cfg->bclk)), + ESP_ERR_INVALID_ARG, TAG, "bclk invalid"); + ESP_RETURN_ON_FALSE((gpio_cfg->ws == -1 || GPIO_IS_VALID_GPIO(gpio_cfg->ws)), + ESP_ERR_INVALID_ARG, TAG, "ws invalid"); + if (handle->dir == I2S_DIR_TX) { + /* Set data output GPIO */ + i2s_gpio_check_and_set(gpio_cfg->dout, i2s_periph_signal[id].data_out_sig, false); + } else { + /* Set data input GPIO */ + i2s_gpio_check_and_set(gpio_cfg->din, i2s_periph_signal[id].data_in_sig, true); + } + + if (handle->role == I2S_ROLE_SLAVE) { + /* For "tx + slave" mode, select TX signal index for ws and bck */ + if (handle->dir == I2S_DIR_TX && !handle->parent->full_duplex) { +#if SOC_I2S_HW_VERSION_2 + i2s_ll_mclk_bind_to_tx_clk(handle->parent->hal.dev); +#endif + i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].s_tx_ws_sig, true); + i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].s_tx_bck_sig, true); + /* For "tx + rx + slave" or "rx + slave" mode, select RX signal index for ws and bck */ + } else { + i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].s_rx_ws_sig, true); + i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].s_rx_bck_sig, true); + } + } else { + /* mclk only available in master mode */ + ESP_RETURN_ON_ERROR(i2s_check_set_mclk(id, handle->parent->mclk), TAG, "mclk config failed"); + /* For "rx + master" mode, select RX signal index for ws and bck */ + if (handle->dir == I2S_DIR_RX && !handle->parent->full_duplex) { +#if SOC_I2S_HW_VERSION_2 + i2s_ll_mclk_bind_to_rx_clk(handle->parent->hal.dev); +#endif + i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].m_rx_ws_sig, false); + i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].m_rx_bck_sig, false); + /* For "tx + rx + master" or "tx + master" mode, select TX signal index for ws and bck */ + } else { + i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].m_tx_ws_sig, false); + i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].m_tx_bck_sig, false); + } + } + + return ESP_OK; +} + +esp_err_t i2s_init_std_channel(i2s_chan_handle_t handle, const i2s_std_config_t *std_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_REGISTER, ESP_ERR_INVALID_STATE, err, TAG, "the channel has initialized already"); + ESP_GOTO_ON_ERROR(i2s_std_set_gpio(handle, &std_cfg->gpio_cfg), err, TAG, "initialize channel failed while setting gpio pins"); + /* i2s_set_slot should be called before i2s_set_clock while initializing, because clock is relay on the slot */ + ESP_GOTO_ON_ERROR(i2s_std_set_slot(handle, &std_cfg->slot_cfg), err, TAG, "initialize channel failed while setting slot"); + ESP_GOTO_ON_ERROR(i2s_std_set_clock(handle, &std_cfg->clk_cfg), err, TAG, "initialize channel failed while setting clock"); + ESP_GOTO_ON_ERROR(i2s_init_dma_intr(handle, ESP_INTR_FLAG_LEVEL1), err, TAG, "initialize dma interrupt failed"); + /* Store the configurations of standard mode */ + i2s_std_config_t *mode_info = calloc(1, sizeof(i2s_std_config_t)); + ESP_GOTO_ON_FALSE(mode_info, ESP_ERR_NO_MEM, err, TAG, "no memory for storing the configurations"); + memcpy(mode_info, std_cfg, sizeof(i2s_std_config_t)); + handle->mode_info = mode_info; + +#if SOC_I2S_HW_VERSION_2 + /* Enable clock to start outputting mclk signal. Some codecs will reset once mclk stop */ + if (handle->dir == I2S_DIR_TX) { + i2s_ll_tx_enable_std(handle->parent->hal.dev); + i2s_ll_tx_enable_clock(handle->parent->hal.dev); + } else { + i2s_ll_rx_enable_std(handle->parent->hal.dev); + i2s_ll_rx_enable_clock(handle->parent->hal.dev); + } +#endif + + /* Initialization finished, mark state as ready */ + handle->state = I2S_CHAN_STATE_READY; + xSemaphoreGive(handle->mutex); + return ret; + +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +esp_err_t i2s_reconfig_std_clock(i2s_chan_handle_t handle, const i2s_std_clk_config_t *clk_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + I2S_NULL_POINTER_CHECK(TAG, clk_cfg); + + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_STD, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be stopped before reconfiguring the clock"); + + i2s_std_config_t *std_cfg = (i2s_std_config_t*)handle->mode_info; + ESP_GOTO_ON_FALSE(std_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); + + ESP_GOTO_ON_ERROR(i2s_std_set_clock(handle, &std_cfg->clk_cfg), err, TAG, "update clock failed"); + /* Update the stored clock information */ + memcpy(&std_cfg->clk_cfg, clk_cfg, sizeof(i2s_std_clk_config_t)); + + xSemaphoreGive(handle->mutex); + + return ESP_OK; +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +esp_err_t i2s_reconfig_std_slot(i2s_chan_handle_t handle, const i2s_std_slot_config_t *slot_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + I2S_NULL_POINTER_CHECK(TAG, slot_cfg); + + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_STD, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be stopped before reconfiguring the slot"); + + i2s_std_config_t *std_cfg = (i2s_std_config_t*)handle->mode_info; + ESP_GOTO_ON_FALSE(std_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); + + ESP_GOTO_ON_ERROR(i2s_std_set_slot(handle, slot_cfg), err, TAG, "set i2s standard slot failed"); + /* Update the stored slot information */ + memcpy(&std_cfg->slot_cfg, slot_cfg, sizeof(i2s_std_slot_config_t)); + + /* If the slot bit width changed, then need to update the clock */ + uint32_t slot_bits = slot_cfg->slot_bit_width == I2S_SLOT_BIT_WIDTH_AUTO ? slot_cfg->data_bit_width : slot_cfg->slot_bit_width; + if (std_cfg->slot_cfg.slot_bit_width == slot_bits) { + ESP_GOTO_ON_ERROR(i2s_std_set_clock(handle, &std_cfg->clk_cfg), err, TAG, "update clock failed"); + } + + xSemaphoreGive(handle->mutex); + + return ESP_OK; +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +esp_err_t i2s_reconfig_std_gpio(i2s_chan_handle_t handle, const i2s_std_gpio_config_t *gpio_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + I2S_NULL_POINTER_CHECK(TAG, gpio_cfg); + + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_STD, ESP_ERR_INVALID_ARG, err, TAG, "This handle is not working in standard moded"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "Invalid state, I2S should be stopped before reconfiguring the gpio"); + + i2s_std_config_t *std_cfg = (i2s_std_config_t*)handle->mode_info; + ESP_GOTO_ON_FALSE(std_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); + + ESP_GOTO_ON_ERROR(i2s_std_set_gpio(handle, gpio_cfg), err, TAG, "set i2s standard slot failed"); + + /* Update the stored slot information */ + memcpy(&std_cfg->gpio_cfg, gpio_cfg, sizeof(i2s_std_gpio_config_t)); + xSemaphoreGive(handle->mutex); + + return ESP_OK; +err: + xSemaphoreGive(handle->mutex); + return ret; +} diff --git a/components/driver/i2s/i2s_tdm.c b/components/driver/i2s/i2s_tdm.c new file mode 100644 index 0000000000..c8d7c663c5 --- /dev/null +++ b/components/driver/i2s/i2s_tdm.c @@ -0,0 +1,317 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "hal/i2s_hal.h" +#include "driver/gpio.h" +#include "driver/i2s_tdm.h" +#include "i2s_private.h" +#include "clk_ctrl_os.h" +#include "esp_intr_alloc.h" +#include "esp_check.h" + +const static char *TAG = "I2S_TDM"; + +// Same with standard mode except total slot number +static esp_err_t i2s_tdm_calculate_clock(i2s_chan_handle_t handle, const i2s_tdm_clk_config_t *clk_cfg, i2s_hal_clock_info_t *clk_info) +{ + uint32_t rate = clk_cfg->sample_rate_hz; + i2s_tdm_slot_config_t *slot_cfg = &((i2s_tdm_config_t *)(handle->mode_info))->slot_cfg; + uint32_t slot_bits = (slot_cfg->slot_bit_width == I2S_SLOT_BIT_WIDTH_AUTO) || + ((int)slot_cfg->slot_bit_width < (int)slot_cfg->data_bit_width) ? + slot_cfg->data_bit_width : slot_cfg->slot_bit_width; + /* Calculate multiple + * Fmclk = bck_div*fbck = fsclk/(mclk_div+b/a) */ + if (handle->role == I2S_ROLE_MASTER) { + clk_info->bclk = rate * handle->total_slot * slot_bits; + clk_info->mclk = rate * clk_cfg->mclk_multiple; + clk_info->bclk_div = clk_info->mclk / clk_info->bclk; + } else { + /* For slave mode, mclk >= bclk * 8, so fix bclk_div to 2 first */ + clk_info->bclk_div = 8; + clk_info->bclk = rate * handle->total_slot * slot_bits; + clk_info->mclk = clk_info->bclk * clk_info->bclk_div; + } +#if SOC_I2S_SUPPORTS_APLL + clk_info->sclk = clk_cfg->clk_src == I2S_CLK_160M_PLL ? I2S_LL_BASE_CLK : i2s_set_get_apll_freq(clk_info->mclk); +#else + clk_info->sclk = I2S_LL_BASE_CLK; +#endif + 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"); + + return ESP_OK; +} + +static esp_err_t i2s_tdm_set_clock(i2s_chan_handle_t handle, const i2s_tdm_clk_config_t *clk_cfg) +{ + esp_err_t ret = ESP_OK; + i2s_tdm_config_t *tdm_cfg = (i2s_tdm_config_t *)(handle->mode_info); + + /* If Power Management enabled, a PM lock will be created when there is no PM lock or clock source changed */ +#ifdef CONFIG_PM_ENABLE + // Create/Re-create power management lock + if (handle->pm_lock == NULL || tdm_cfg->clk_cfg.clk_src != clk_cfg->clk_src) { + if (handle->pm_lock) { + ESP_RETURN_ON_ERROR(esp_pm_lock_delete(handle->pm_lock), TAG, "I2S delete old pm lock failed"); + } + esp_pm_lock_type_t pm_type = ESP_PM_APB_FREQ_MAX; +#if SOC_I2S_SUPPORTS_APLL + if (clk_cfg->clk_src == I2S_CLK_APLL) { + pm_type = ESP_PM_NO_LIGHT_SLEEP; + } +#endif // SOC_I2S_SUPPORTS_APLL + ESP_RETURN_ON_ERROR(esp_pm_lock_create(pm_type, 0, "i2s_driver", &handle->pm_lock), err, TAG, "I2S pm lock create failed"); + } +#endif //CONFIG_PM_ENABLE + +#if SOC_I2S_SUPPORTS_APLL + /* Enable APLL and acquire its lock when initializing or clock source changed to APLL */ + if (clk_cfg->clk_src == I2S_CLK_APLL && (handle->state == I2S_CHAN_STATE_INIT || tdm_cfg->clk_cfg.clk_src == I2S_CLK_160M_PLL)) { + periph_rtc_apll_acquire(); + handle->apll_en = true; + } + /* Disable APLL and release its lock when clock source is changed to D2CLK */ + if (clk_cfg->clk_src == I2S_CLK_160M_PLL && tdm_cfg->clk_cfg.clk_src == I2S_CLK_APLL) { + periph_rtc_apll_release(); + handle->apll_en = false; + } +#endif + + i2s_hal_clock_info_t clk_info; + /* Calculate clock parameters */ + ESP_RETURN_ON_ERROR(i2s_tdm_calculate_clock(handle, clk_cfg, &clk_info), TAG, "clock calculate failed"); + ESP_LOGD(TAG, "Clock division info: [sclk] %d Hz [mdiv] %d [mclk] %d Hz [bdiv] %d [bclk] %d Hz", + clk_info.sclk, clk_info.mclk_div, clk_info.mclk, clk_info.bclk_div, clk_info.bclk); + + portENTER_CRITICAL(&s_i2s.spinlock); + /* Set clock configurations in HAL*/ + if (handle->dir == I2S_DIR_TX) { + i2s_hal_set_tx_clock(&handle->parent->hal, &clk_info, clk_cfg->clk_src); + } else { + i2s_hal_set_rx_clock(&handle->parent->hal, &clk_info, clk_cfg->clk_src); + } + portEXIT_CRITICAL(&s_i2s.spinlock); + + return ret; +} + +static esp_err_t i2s_tdm_set_slot(i2s_chan_handle_t handle, const i2s_tdm_slot_config_t *slot_cfg) +{ + 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 */ + 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_alloc_dma_desc(handle, handle->dma.desc_num, buf_size), + TAG, "allocate memory for dma descriptor failed"); + } + bool is_slave = handle->role == I2S_ROLE_SLAVE; + /* Share bck and ws signal in full-duplex mode */ + if (handle->parent->full_duplex) { + i2s_ll_share_bck_ws(handle->parent->hal.dev, true); + /* Since bck and ws are shared, only tx or rx can be master + Force to set rx as slave to avoid conflict of clock signal */ + if (handle->dir == I2S_DIR_RX) { + is_slave = true; + } + } else { + i2s_ll_share_bck_ws(handle->parent->hal.dev, false); + } + + portENTER_CRITICAL(&s_i2s.spinlock); + /* Configure the hardware to apply TDM format */ + if (handle->dir == I2S_DIR_TX) { + i2s_hal_tdm_set_tx_slot(&(handle->parent->hal), is_slave, slot_cfg); + } else { + i2s_hal_tdm_set_rx_slot(&(handle->parent->hal), is_slave, slot_cfg); + } + portEXIT_CRITICAL(&s_i2s.spinlock); + + /* Update the total slot num and active slot num */ + handle->active_slot = slot_cfg->slot_mode == I2S_SLOT_MODE_MONO ? 1 : __builtin_popcount(slot_cfg->slot_mask); + uint32_t max_slot_num = 32 - __builtin_clz(slot_cfg->slot_mask); + handle->total_slot = slot_cfg->total_slot < max_slot_num ? max_slot_num : slot_cfg->total_slot; + handle->total_slot = handle->total_slot < 2 ? 2 : handle->total_slot; // At least two slots in a frame + + return ESP_OK; +} + +static esp_err_t i2s_tdm_set_gpio(i2s_chan_handle_t handle, const i2s_tdm_gpio_config_t *gpio_cfg) +{ + int id = handle->parent->id; + + /* Check validity of selected pins */ + ESP_RETURN_ON_FALSE((gpio_cfg->bclk == -1 || GPIO_IS_VALID_GPIO(gpio_cfg->bclk)), + ESP_ERR_INVALID_ARG, TAG, "bclk invalid"); + ESP_RETURN_ON_FALSE((gpio_cfg->ws == -1 || GPIO_IS_VALID_GPIO(gpio_cfg->ws)), + ESP_ERR_INVALID_ARG, TAG, "ws invalid"); + if (handle->dir == I2S_DIR_TX) { + /* Set data output GPIO */ + i2s_gpio_check_and_set(gpio_cfg->dout, i2s_periph_signal[id].data_out_sig, false); + } else { + /* Set data input GPIO */ + i2s_gpio_check_and_set(gpio_cfg->din, i2s_periph_signal[id].data_in_sig, true); + } + + if (handle->role == I2S_ROLE_SLAVE) { + /* For "tx + slave" mode, select TX signal index for ws and bck */ + if (handle->dir == I2S_DIR_TX && !handle->parent->full_duplex) { +#if SOC_I2S_HW_VERSION_2 + i2s_ll_mclk_bind_to_tx_clk(handle->parent->hal.dev); +#endif + i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].s_tx_ws_sig, true); + i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].s_tx_bck_sig, true); + /* For "tx + rx + slave" or "rx + slave" mode, select RX signal index for ws and bck */ + } else { + i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].s_rx_ws_sig, true); + i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].s_rx_bck_sig, true); + } + } else { + /* mclk only available in master mode */ + ESP_RETURN_ON_ERROR(i2s_check_set_mclk(id, handle->parent->mclk), TAG, "mclk config failed"); + /* For "rx + master" mode, select RX signal index for ws and bck */ + if (handle->dir == I2S_DIR_RX && !handle->parent->full_duplex) { +#if SOC_I2S_HW_VERSION_2 + i2s_ll_mclk_bind_to_rx_clk(handle->parent->hal.dev); +#endif + i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].m_rx_ws_sig, false); + i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].m_rx_bck_sig, false); + /* For "tx + rx + master" or "tx + master" mode, select TX signal index for ws and bck */ + } else { + i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].m_tx_ws_sig, false); + i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].m_tx_bck_sig, false); + } + } + + return ESP_OK; +} + + +esp_err_t i2s_init_tdm_channel(i2s_chan_handle_t handle, const i2s_tdm_config_t *tdm_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_REGISTER, ESP_ERR_INVALID_STATE, err, TAG, "the channel has initialized already"); + ESP_GOTO_ON_ERROR(i2s_tdm_set_gpio(handle, &tdm_cfg->gpio_cfg), err, TAG, "initialize channel failed while setting gpio pins"); + /* i2s_set_slot should be called before i2s_set_clock while initializing, because clock is relay on the slot */ + ESP_GOTO_ON_ERROR(i2s_tdm_set_slot(handle, &tdm_cfg->slot_cfg), err, TAG, "initialize channel failed while setting slot"); + ESP_GOTO_ON_ERROR(i2s_tdm_set_clock(handle, &tdm_cfg->clk_cfg), err, TAG, "initialize channel failed while setting clock"); + ESP_GOTO_ON_ERROR(i2s_init_dma_intr(handle, ESP_INTR_FLAG_LEVEL1), err, TAG, "initialize dma interrupt failed"); + /* Store the configurations of standard mode */ + i2s_tdm_config_t *mode_info = calloc(1, sizeof(i2s_tdm_config_t)); + ESP_GOTO_ON_FALSE(mode_info, ESP_ERR_NO_MEM, err, TAG, "no memory for storing the configurations"); + memcpy(mode_info, tdm_cfg, sizeof(i2s_tdm_config_t)); + handle->mode_info = mode_info; + +#if SOC_I2S_HW_VERSION_2 + /* Enable clock to start outputting mclk signal. Some codecs will reset once mclk stop */ + if (handle->dir == I2S_DIR_TX) { + i2s_ll_tx_enable_tdm(handle->parent->hal.dev); + i2s_ll_tx_enable_clock(handle->parent->hal.dev); + } else { + i2s_ll_rx_enable_tdm(handle->parent->hal.dev); + i2s_ll_rx_enable_clock(handle->parent->hal.dev); + } +#endif + + /* Initialization finished, mark state as ready */ + handle->state = I2S_CHAN_STATE_READY; + xSemaphoreGive(handle->mutex); + return ret; + +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +esp_err_t i2s_reconfig_tdm_clock(i2s_chan_handle_t handle, const i2s_tdm_clk_config_t *clk_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + I2S_NULL_POINTER_CHECK(TAG, clk_cfg); + + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_TDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be stopped before reconfiguring the clock"); + + i2s_tdm_config_t *tdm_cfg = (i2s_tdm_config_t*)handle->mode_info; + ESP_GOTO_ON_FALSE(tdm_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); + + ESP_GOTO_ON_ERROR(i2s_tdm_set_clock(handle, &tdm_cfg->clk_cfg), err, TAG, "update clock failed"); + /* Update the stored clock information */ + memcpy(&tdm_cfg->clk_cfg, clk_cfg, sizeof(i2s_tdm_clk_config_t)); + xSemaphoreGive(handle->mutex); + + return ESP_OK; +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +esp_err_t i2s_reconfig_tdm_slot(i2s_chan_handle_t handle, const i2s_tdm_slot_config_t *slot_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + I2S_NULL_POINTER_CHECK(TAG, slot_cfg); + + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_TDM, ESP_ERR_INVALID_ARG, err, TAG, "this handle is not working in standard moded"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "invalid state, I2S should be stopped before reconfiguring the slot"); + + i2s_tdm_config_t *tdm_cfg = (i2s_tdm_config_t*)handle->mode_info; + ESP_GOTO_ON_FALSE(tdm_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); + + ESP_GOTO_ON_ERROR(i2s_tdm_set_slot(handle, slot_cfg), err, TAG, "set i2s standard slot failed"); + /* Update the stored slot information */ + memcpy(&tdm_cfg->slot_cfg, slot_cfg, sizeof(i2s_tdm_slot_config_t)); + + /* If the slot bit width changed, then need to update the clock */ + uint32_t slot_bits = slot_cfg->slot_bit_width == I2S_SLOT_BIT_WIDTH_AUTO ? slot_cfg->data_bit_width : slot_cfg->slot_bit_width; + if (tdm_cfg->slot_cfg.slot_bit_width == slot_bits) { + ESP_GOTO_ON_ERROR(i2s_tdm_set_clock(handle, &tdm_cfg->clk_cfg), err, TAG, "update clock failed"); + } + xSemaphoreGive(handle->mutex); + + return ESP_OK; +err: + xSemaphoreGive(handle->mutex); + return ret; +} + +esp_err_t i2s_reconfig_tdm_gpio(i2s_chan_handle_t handle, const i2s_tdm_gpio_config_t *gpio_cfg) +{ + I2S_NULL_POINTER_CHECK(TAG, handle); + I2S_NULL_POINTER_CHECK(TAG, gpio_cfg); + + esp_err_t ret = ESP_OK; + + xSemaphoreTake(handle->mutex, portMAX_DELAY); + ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_TDM, ESP_ERR_INVALID_ARG, err, TAG, "This handle is not working in standard moded"); + ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "Invalid state, I2S should be stopped before reconfiguring the gpio"); + + i2s_tdm_config_t *tdm_cfg = (i2s_tdm_config_t*)handle->mode_info; + ESP_GOTO_ON_FALSE(tdm_cfg, ESP_ERR_INVALID_STATE, err, TAG, "initialization not complete"); + + ESP_GOTO_ON_ERROR(i2s_tdm_set_gpio(handle, gpio_cfg), err, TAG, "set i2s standard slot failed"); + + /* Update the stored slot information */ + memcpy(&tdm_cfg->gpio_cfg, gpio_cfg, sizeof(i2s_tdm_gpio_config_t)); + xSemaphoreGive(handle->mutex); + + return ESP_OK; +err: + xSemaphoreGive(handle->mutex); + return ret; +} diff --git a/components/driver/include/driver/i2s_common.h b/components/driver/include/driver/i2s_common.h new file mode 100644 index 0000000000..fdd7fb7beb --- /dev/null +++ b/components/driver/include/driver/i2s_common.h @@ -0,0 +1,266 @@ +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "freertos/FreeRTOS.h" +#include "freertos/queue.h" + +#include "hal/i2s_types.h" + +#include "esp_types.h" +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef I2S_DRIVER_SELECTED + #error "Only one set of APIs is allowed to use" +#else + #define I2S_DRIVER_SELECTED +#endif + +/** + * @brief get default I2S property + */ +#define I2S_CHANNEL_CONFIG(i2s_role, i2s_mode, pin_config) { \ + .id = I2S_NUM_AUTO, \ + .role = i2s_role, \ + .mode = i2s_mode, \ + .io = pin_config, \ +} + +#define I2S_GPIO_UNUSED GPIO_NUM_NC /*!< Used in i2s_gpio_config_t for signals which are not used */ + +/** + * @brief I2S controller channel configuration +*/ +typedef struct { + i2s_port_t id; /*!< I2S port id */ + i2s_role_t role; /*!< I2S role, I2S_ROLE_MASTER or I2S_ROLE_SLAVE */ + + /* DMA configurations */ + uint32_t dma_desc_num; /*!< I2S DMA buffer number, it is also the number of DMA descriptor */ + uint32_t dma_frame_num; /*!< I2S frame number in one DMA buffer. One frame means one-time sample data in all slots */ + bool auto_clear; /*!< Set to auto clear DMA TX descriptor, i2s will always send zero automatically if no data to send */ + +} i2s_chan_config_t; + +/** + * @brief Allocate a new i2s channel + * @note The new i2s channel handle will at REGISTERED state after it is allocated successfully. + * @note When the port id in channel configuration is I2S_NUM_AUTO, driver will allocate i2s port automatically + * Otherwise driver will try to allocate the new channel on the selected port. + * @note If both tx_handle and rx_handle are not NULL, it means this I2S port will work at duplex mode, + * and these rx and tx channel will be allocated on a same I2S port as well. + * Note that tx/rx channel will be affected by each other on ESP32 and ESP32S2, + * so please make sure them are working in same condition and have same status(start/stop). + * @note If tx_handle or rx_handle is NULL, it means this I2S port will work at simplex mode, + * For ESP32 and ESP32S2, the whole I2S port will be occupied as well even if only simplex is working. + * For the other targets, another channel on this port will still available. + * + * @param[in] chan_cfg I2S controller channel configurations + * @param[out] tx_handle I2S channel handler used for managing the sending channel(optional) + * @param[out] rx_handle I2S channel handler used for managing the receiving channel(optional) + * @return + * - ESP_OK Allocate a new channel success + * - ESP_ERR_NOT_SUPPORTED The communication mode is not supported on the current chip + * - ESP_ERR_INVALID_ARG NULL pointer or illegal parameter in i2s_chan_config_t + * - ESP_ERR_NOT_FOUND No available I2S channel found + */ +esp_err_t i2s_new_channel(const i2s_chan_config_t *chan_cfg, i2s_chan_handle_t *tx_handle, i2s_chan_handle_t *rx_handle); + +/** + * @brief Delete the i2s channel + * @note The i2s channel will be stopped to ensure the i2s channel is not at READING or WRITING state. + * @note Resource will be free automatically if all channels in one port are deleted + * + * @param[in] handle I2S channel handler + * - ESP_OK Delete successfully + * - ESP_ERR_INVALID_ARG NULL pointer + */ +esp_err_t i2s_del_channel(i2s_chan_handle_t handle); + +/** + * @brief Initialize i2s channel + * @note Only allowed to be called when the channel state is REGISTERED, (i.e., channel has been allocated, but not initialized) + * and the state will be updated to INITIALIZING while during the initialization, + * finally it will be READY if initialization is success, otherwise the state will return to REGISTERED. + * @note Will initialize i2s channel according to the i2s mode + * For different modes, we should input corresponding configurations. + * + * @param[in] handle I2S channel handler + * @param[in] clk_config Clock configuration, should input correct type of clock configuration according to i2s communication mode that set in 'i2s_chan_config_t'. + * For I2S_COMM_MODE_STD mode, please input 'i2s_std_clk_config_t' type. + * For I2S_COMM_MODE_PDM mode, please input 'i2s_pdm_tx_clk_config_t' type for tx channel and 'i2s_pdm_rx_clk_config_t' type for rx channel. + * For I2S_COMM_MODE_TDM mode, please input 'i2s_tdm_clk_config_t' type. + * @param[in] slot_config Slot configuration, should input correct type of slot configuration according to i2s communication mode that set in 'i2s_chan_config_t'. + * For I2S_COMM_MODE_STD mode, please input 'i2s_std_slot_config_t' type. + * For I2S_COMM_MODE_PDM mode, please input 'i2s_pdm_tx_slot_config_t' type for tx channel and 'i2s_pdm_rx_slot_config_t' type for rx channel. + * For I2S_COMM_MODE_TDM mode, please input 'i2s_tdm_slot_config_t' type. + * @return + * - ESP_OK Initialize successfully + * - ESP_ERR_INVALID_ARG NULL pointer + * - ESP_ERR_INVALID_STATE This channel is not registered + */ +esp_err_t i2s_init_channel(i2s_chan_handle_t handle, const void *clk_config, const void *slot_config); + +/** + * @brief Reconfigure the I2S clock + * @note Only allowed to be called when the channel state is READY, (i.e., channel has been initialized, but not started) + * this function won't change the state. + * @note Normally the clock has been configured after 'i2s_init_channel' is called + * This function is for re-configuring the clock. + * 'i2s_stop_channel' should be called before calling this function if i2s has started. + * + * @param[in] handle I2S channel handler + * @param[in] clk_config Clock configuration, should input correct type of clock configuration according to i2s communication mode + * For I2S_COMM_MODE_STD mode, please input 'i2s_std_clk_config_t' type. + * For I2S_COMM_MODE_PDM mode, please input 'i2s_pdm_tx_clk_config_t' type for tx channel and 'i2s_pdm_rx_clk_config_t' type for rx channel. + * For I2S_COMM_MODE_TDM mode, please input 'i2s_tdm_clk_config_t' type. + * @return + * - ESP_OK Set clock successfully + * - ESP_ERR_NOT_SUPPORTED The input communication mode is not supported + * - ESP_ERR_INVALID_ARG NULL pointer + * - ESP_ERR_INVALID_STATE This channel is not initialized + */ +esp_err_t i2s_set_clock(i2s_chan_handle_t handle, const void *clk_config); + +/** + * @brief Reconfigure the I2S slot + * @note Only allowed to be called when the channel state is READY, (i.e., channel has been initialized, but not started) + * this function won't change the state. + * @note Normally the slot has been configured after 'i2s_init_channel' is called + * This function is for re-configuring the slot + * 'i2s_stop_channel' should be called before calling this function if i2s has started. + * + * @param[in] handle I2S channel handler + * @param[in] slot_config Slot configuration, should input correct type of clock configuration according to i2s communication mode + * For I2S_COMM_MODE_STD mode, please input 'i2s_std_slot_config_t' type. + * For I2S_COMM_MODE_PDM mode, please input 'i2s_pdm_tx_slot_config_t' type for tx channel and 'i2s_pdm_rx_slot_config_t' type for rx channel. + * For I2S_COMM_MODE_TDM mode, please input 'i2s_tdm_slot_config_t' type. + * @return + * - ESP_OK Set slot successfully + * - ESP_ERR_INVALID_ARG NULL pointer or unmatched slot configuration type + * - ESP_ERR_INVALID_STATE This channel is not initialized + */ +esp_err_t i2s_set_slot(i2s_chan_handle_t handle, const void *slot_config); + +/** + * @brief Get I2S event queue handler + * @note Can be called at any time + * + * @param[in] handle I2S channel handler + * @param[in] que_len Queue length (if the queue has not been created yet) + * @return + * - NULL Failed to create the event queue + * - else Event queue handler + */ +QueueHandle_t i2s_get_event_queue(i2s_chan_handle_t handle, uint32_t que_len); + +/** + * @brief Start i2s channel + * @note Only allowed to be called when the channel state is READY, (i.e., channel has been initialized, but not started) + * the channel will enter IDLE state once it is started successfully. + * + * @param[in] handle I2S channel handler + * - ESP_OK Start successfully + * - ESP_ERR_INVALID_ARG NULL pointer + * - ESP_ERR_INVALID_STATE This channel has not initialized or already started + */ +esp_err_t i2s_start_channel(i2s_chan_handle_t handle); + +/** + * @brief Stop i2s channel + * @note Only allowed to be called when the channel state is READY / IDLE / WRITING / READING, (i.e., channel has been initialized) + * the channel will enter READY state once it is stopped successfully. + * @note It will stop bclk and ws signal but not mclk signal + * + * @param[in] handle I2S channel handler + * @return + * - ESP_OK Stop successfully + * - ESP_ERR_INVALID_ARG NULL pointer + * - ESP_ERR_INVALID_STATE This channel has not stated + */ +esp_err_t i2s_stop_channel(i2s_chan_handle_t handle); + +/** + * @brief I2S write data + * @note Only allowed to be called when the channel state is IDLE, (i.e., tx channel has been started and is not writing now) + * the channel will enter WRITING state once start to write, + * and it will switch back to IDLE when quit the writing, + * but the IDLE only stands for the software state, it doesn't mean there is no the signal transporting on line. + * + * @param[in] handle I2S channel handler + * @param[in] src The pointer of sent data buffer + * @param[in] size Max data buffer length + * @param[out] bytes_written Byte number that actually be sent + * @param[in] ticks_to_wait Max block time + * @return + * - ESP_OK Write successfully + * - ESP_ERR_INVALID_ARG NULL pointer or this handle is not tx handle + * - ESP_ERR_TIMEOUT Writing timeout, no writing event received from ISR within ticks_to_wait + * - ESP_ERR_INVALID_STATE I2S is not ready to write + */ +esp_err_t i2s_write_channel(i2s_chan_handle_t handle, const void *src, size_t size, size_t *bytes_written, TickType_t ticks_to_wait); + +/** + * @brief I2S read data + * @note Only allowed to be called when the channel state is IDLE + * the channel will enter READING state once start to read, + * and it will switch back to IDLE when quit the reading, + * but the IDLE only stands for the software state, it doesn't mean there is no the signal transporting on line. + * + * @param[in] handle I2S channel handler + * @param[in] dest The pointer of receiving data buffer + * @param[in] size Max data buffer length + * @param[out] bytes_read Byte number that actually be read + * @param[in] ticks_to_wait Max block time + * @return + * - ESP_OK Read successfully + * - ESP_ERR_INVALID_ARG NULL pointer or this handle is not rx handle + * - ESP_ERR_TIMEOUT Reading timeout, no reading event received from ISR within ticks_to_wait + * - ESP_ERR_INVALID_STATE I2S is not ready to read + */ +esp_err_t i2s_read_channel(i2s_chan_handle_t handle, void *dest, size_t size, size_t *bytes_read, TickType_t ticks_to_wait); + +/** + * @brief Clear the DMA buffer + * @note Only allowed to be called when the channel state is READY / IDLE / WRITING / READING, (i.e., channel has been initialized) + * it won't change the current channel state. + * @note The legacy data in DMA buffer will be cleared immediately once it is called + * That means i2s will keep send zero if no other data to send + * It has same effect with 'auto_clear' field in slot configuration struct + * but it should be called manually and won't lower the interrupt performance + * + * @param[in] handle I2S channel handler + * @return + * - ESP_OK Clear successfully + * - ESP_ERR_INVALID_STATE I2S is not initialized + */ +esp_err_t i2s_clear_dma_buffer(i2s_chan_handle_t handle); + +/** + * @brief Abort i2s reading or writing function + * @note Only allowed to be called when the channel state is IDLE / WRITING / READING, (i.e., channel has been started) + * it will change to IDLE after aborting the current reading or writing. + * @note Since reading or writing will be blocked for a long time while transporting a large quantity of data, + * This function can help to terminate reading/writing in its next reading/writing loop, + * but if reading/writing is bolcked on receiving dma queue(i.e. dma can't send or receive data), this function won't take effect + * And it will only abort for one time, so reading/writing thread won't stop though it is called + * + * @param[in] handle I2S channel handler + * @return + * - ESP_OK Abort successfully + * - ESP_ERR_INVALID_STATE I2S is stopped or not initialized + */ +esp_err_t i2s_abort_reading_writing(i2s_chan_handle_t handle); + + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/i2s_pdm.h b/components/driver/include/driver/i2s_pdm.h similarity index 88% rename from components/hal/include/hal/i2s_pdm.h rename to components/driver/include/driver/i2s_pdm.h index 611ff9718d..732265a77c 100644 --- a/components/hal/include/hal/i2s_pdm.h +++ b/components/driver/include/driver/i2s_pdm.h @@ -14,6 +14,7 @@ #pragma once #include "hal/i2s_types.h" +#include "hal/gpio_types.h" #ifdef __cplusplus extern "C" { @@ -29,7 +30,7 @@ extern "C" { #define I2S_PDM_RX_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \ .mode = I2S_COMM_MODE_PDM, \ .data_bit_width = bits_per_sample, \ - .slot_bit_width = I2S_SLOT_BIT_WIDTH_DEFAULT, \ + .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ } @@ -39,7 +40,7 @@ extern "C" { */ #define I2S_PDM_RX_CLK_DEFAULT_CONFIG(rate) { \ .sample_rate_hz = rate, \ - .clk_src = I2S_CLK_D2CLK, \ + .clk_src = I2S_CLK_160M_PLL, \ .mclk_multiple = I2S_MCLK_MULTIPLE_256, \ .dn_sample_mode = I2S_PDM_DSR_8S \ } @@ -69,6 +70,21 @@ typedef struct { i2s_pdm_dsr_t dn_sample_mode; /*!< Down-sampling rate mode */ } i2s_pdm_rx_clk_config_t; +/** + * @brief I2S PDM tx mode GPIO pins configuration + */ +typedef struct { + gpio_num_t clk; /*!< PDM clk pin, output */ + gpio_num_t din; /*!< DATA pin, input */ +} i2s_pdm_rx_gpio_config_t; + +typedef struct +{ + i2s_pdm_rx_clk_config_t clk_cfg; + i2s_pdm_rx_slot_config_t slot_cfg; + i2s_pdm_rx_gpio_config_t gpio_cfg; +} i2s_pdm_rx_config_t; + #endif // SOC_I2S_SUPPORTS_PDM_RX @@ -82,7 +98,7 @@ typedef struct { #define I2S_PDM_TX_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \ .mode = I2S_COMM_MODE_PDM, \ .data_bit_width = bits_per_sample, \ - .slot_bit_width = I2S_SLOT_BIT_WIDTH_DEFAULT, \ + .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ .sd_prescale = 0, \ .sd_scale = I2S_PDM_SIG_SCALING_MUL_1, \ @@ -104,7 +120,7 @@ typedef struct { #define I2S_PDM_TX_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \ .mode = I2S_COMM_MODE_PDM, \ .data_bit_width = bits_per_sample, \ - .slot_bit_width = I2S_SLOT_BIT_WIDTH_DEFAULT, \ + .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .dma_desc_num = 8, \ .dma_frame_num = 200, \ .auto_clear = false, \ @@ -128,7 +144,7 @@ typedef struct { */ #define I2S_PDM_TX_CLK_DEFAULT_CONFIG(rate) { \ .sample_rate_hz = rate, \ - .clk_src = I2S_CLK_D2CLK, \ + .clk_src = I2S_CLK_160M_PLL, \ .mclk_multiple = I2S_MCLK_MULTIPLE_256, \ .up_sample_fp = 960, \ .up_sample_fs = ((rate) / 100), \ @@ -188,6 +204,22 @@ typedef struct { uint32_t up_sample_fs; /*!< Up-sampling param fs */ } i2s_pdm_tx_clk_config_t; +/** + * @brief I2S PDM tx mode GPIO pins configuration + */ +typedef struct { + gpio_num_t clk; /*!< PDM clk pin, output */ + gpio_num_t dout; /*!< DATA pin, output */ +} i2s_pdm_tx_gpio_config_t; + +typedef struct +{ + i2s_pdm_tx_clk_config_t clk_cfg; + i2s_pdm_tx_slot_config_t slot_cfg; + i2s_pdm_tx_gpio_config_t gpio_cfg; +} i2s_pdm_tx_config_t; + + #endif // SOC_I2S_SUPPORTS_PDM_TX #ifdef __cplusplus diff --git a/components/hal/include/hal/i2s_std.h b/components/driver/include/driver/i2s_std.h similarity index 80% rename from components/hal/include/hal/i2s_std.h rename to components/driver/include/driver/i2s_std.h index 48e1fcf367..c0db201bac 100644 --- a/components/hal/include/hal/i2s_std.h +++ b/components/driver/include/driver/i2s_std.h @@ -13,6 +13,7 @@ #pragma once #include "hal/i2s_types.h" +#include "hal/gpio_types.h" #ifdef __cplusplus extern "C" { @@ -25,9 +26,8 @@ extern "C" { * @param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO */ #define I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \ - .mode = I2S_COMM_MODE_STD, \ .data_bit_width = bits_per_sample, \ - .slot_bit_width = I2S_SLOT_BIT_WIDTH_DEFAULT, \ + .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ .ws_width = bits_per_sample, \ .ws_pol = false, \ @@ -44,9 +44,8 @@ extern "C" { * @param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO */ #define I2S_STD_PCM_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \ - .mode = I2S_COMM_MODE_STD, \ .data_bit_width = bits_per_sample, \ - .slot_bit_width = I2S_SLOT_BIT_WIDTH_DEFAULT, \ + .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ .ws_width = 1, \ .ws_pol = true, \ @@ -62,9 +61,8 @@ extern "C" { * @param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO */ #define I2S_STD_MSB_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \ - .mode = I2S_COMM_MODE_STD, \ .data_bit_width = bits_per_sample, \ - .slot_bit_width = I2S_SLOT_BIT_WIDTH_DEFAULT, \ + .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ .ws_width = bits_per_sample, \ .ws_pol = false, \ @@ -81,9 +79,8 @@ extern "C" { * @param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO */ #define I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \ - .mode = I2S_COMM_MODE_STD, \ .data_bit_width = bits_per_sample, \ - .slot_bit_width = I2S_SLOT_BIT_WIDTH_DEFAULT, \ + .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ .ws_width = bits_per_sample, \ .ws_pol = false, \ @@ -102,9 +99,8 @@ extern "C" { * @param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO */ #define I2S_STD_PCM_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \ - .mode = I2S_COMM_MODE_STD, \ .data_bit_width = bits_per_sample, \ - .slot_bit_width = I2S_SLOT_BIT_WIDTH_DEFAULT, \ + .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ .ws_width = 1, \ .ws_pol = true, \ @@ -122,9 +118,8 @@ extern "C" { * @param mono_or_stereo I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO */ #define I2S_STD_MSB_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo) { \ - .mode = I2S_COMM_MODE_STD, \ .data_bit_width = bits_per_sample, \ - .slot_bit_width = I2S_SLOT_BIT_WIDTH_DEFAULT, \ + .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ .ws_width = bits_per_sample, \ .ws_pol = false, \ @@ -145,7 +140,7 @@ extern "C" { */ #define I2S_STD_CLK_DEFAULT_CONFIG(rate) { \ .sample_rate_hz = rate, \ - .clk_src = I2S_CLK_D2CLK, \ + .clk_src = I2S_CLK_160M_PLL, \ .mclk_multiple = I2S_MCLK_MULTIPLE_256, \ } @@ -154,7 +149,6 @@ extern "C" { */ typedef struct { /* General fields */ - i2s_comm_mode_t mode; /*!< I2S communication mode, this field is for identification (MUST match the communication mode in 'i2s_chan_config_t') */ i2s_data_bit_width_t data_bit_width; /*!< I2S sample data bit width (valid data bits per sample) */ i2s_slot_bit_width_t slot_bit_width; /*!< I2S slot bit width (total bits per slot) */ i2s_slot_mode_t slot_mode; /*!< Set mono or stereo mode with I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO */ @@ -183,6 +177,31 @@ typedef struct { i2s_mclk_multiple_t mclk_multiple; /*!< The multiple of mclk to the sample rate */ } i2s_std_clk_config_t; +/** + * @brief I2S standard mode GPIO pins configuration + */ +typedef struct { + gpio_num_t mclk; /*!< MCK pin, output */ + gpio_num_t bclk; /*!< BCK pin, input in slave role, output in master role */ + gpio_num_t ws; /*!< WS pin, input in slave role, output in master role */ + gpio_num_t dout; /*!< DATA pin, output */ + gpio_num_t din; /*!< DATA pin, input */ +} i2s_std_gpio_config_t; + +typedef struct { + i2s_std_clk_config_t clk_cfg; /*!< Standard mode clock configuration */ + i2s_std_slot_config_t slot_cfg; /*!< Standard mode slot configuration */ + i2s_std_gpio_config_t gpio_cfg; /*!< Standard mode gpio configuration */ +} i2s_std_config_t; + +esp_err_t i2s_init_std_channel(i2s_chan_handle_t handle, const i2s_std_config_t *std_cfg); + +esp_err_t i2s_reconfig_std_clock(i2s_chan_handle_t handle, const i2s_std_clk_config_t *clk_cfg); + +esp_err_t i2s_reconfig_std_slot(i2s_chan_handle_t handle, const i2s_std_slot_config_t *slot_cfg); + +esp_err_t i2s_reconfig_std_gpio(i2s_chan_handle_t handle, const i2s_std_gpio_config_t *gpio_cfg); + #ifdef __cplusplus } #endif diff --git a/components/hal/include/hal/i2s_tdm.h b/components/driver/include/driver/i2s_tdm.h similarity index 81% rename from components/hal/include/hal/i2s_tdm.h rename to components/driver/include/driver/i2s_tdm.h index b5290bc020..e5e1b2ff84 100644 --- a/components/hal/include/hal/i2s_tdm.h +++ b/components/driver/include/driver/i2s_tdm.h @@ -12,6 +12,7 @@ #pragma once #include "hal/i2s_types.h" +#include "hal/gpio_types.h" #if SOC_I2S_SUPPORTS_TDM @@ -31,7 +32,7 @@ extern "C" { #define I2S_TDM_PHILIP_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo, mask) { \ .mode = I2S_COMM_MODE_TDM, \ .data_bit_width = (bits_per_sample), \ - .slot_bit_width = I2S_SLOT_BIT_WIDTH_DEFAULT, \ + .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ .ws_width = I2S_TDM_AUTO_WS_WIDTH, \ .ws_pol = false, \ @@ -53,7 +54,7 @@ extern "C" { #define I2S_TDM_MSB_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo, mask) { \ .mode = I2S_COMM_MODE_TDM, \ .data_bit_width = (bits_per_sample), \ - .slot_bit_width = I2S_SLOT_BIT_WIDTH_DEFAULT, \ + .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ .ws_width = I2S_TDM_AUTO_WS_WIDTH, \ .ws_pol = false, \ @@ -75,7 +76,7 @@ extern "C" { #define I2S_TDM_PCM_SHORT_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo, mask) { \ .mode = I2S_COMM_MODE_TDM, \ .data_bit_width = (bits_per_sample), \ - .slot_bit_width = I2S_SLOT_BIT_WIDTH_DEFAULT, \ + .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ .ws_width = 1, \ .ws_pol = true, \ @@ -97,7 +98,7 @@ extern "C" { #define I2S_TDM_PCM_LONG_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo, mask) { \ .mode = I2S_COMM_MODE_TDM, \ .data_bit_width = (bits_per_sample), \ - .slot_bit_width = I2S_SLOT_BIT_WIDTH_DEFAULT, \ + .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, \ .slot_mode = mono_or_stereo, \ .ws_width = (bits_per_sample), \ .ws_pol = true, \ @@ -118,7 +119,7 @@ extern "C" { */ #define I2S_TDM_CLK_DEFAULT_CONFIG(rate) { \ .sample_rate_hz = rate, \ - .clk_src = I2S_CLK_D2CLK, \ + .clk_src = I2S_CLK_160M_PLL, \ .mclk_multiple = I2S_MCLK_MULTIPLE_256, \ } @@ -156,6 +157,32 @@ typedef struct { i2s_mclk_multiple_t mclk_multiple; /*!< The multiple of mclk to the sample rate */ } i2s_tdm_clk_config_t; +/** + * @brief I2S TDM mode GPIO pins configuration + */ +typedef struct { + gpio_num_t mclk; /*!< MCK pin, output */ + gpio_num_t bclk; /*!< BCK pin, input in slave role, output in master role */ + gpio_num_t ws; /*!< WS pin, input in slave role, output in master role */ + gpio_num_t dout; /*!< DATA pin, output */ + gpio_num_t din; /*!< DATA pin, input */ +} i2s_tdm_gpio_config_t; + +typedef struct { + i2s_tdm_clk_config_t clk_cfg; /*!< TDM mode clock configuration */ + i2s_tdm_slot_config_t slot_cfg; /*!< TDM mode slot configuration */ + i2s_tdm_gpio_config_t gpio_cfg; /*!< TDM mode gpio configuration */ +} i2s_tdm_config_t; + +esp_err_t i2s_init_tdm_channel(i2s_chan_handle_t handle, const i2s_tdm_config_t *std_cfg); + +esp_err_t i2s_reconfig_tdm_clock(i2s_chan_handle_t handle, const i2s_tdm_clk_config_t *clk_cfg); + +esp_err_t i2s_reconfig_tdm_slot(i2s_chan_handle_t handle, const i2s_tdm_slot_config_t *slot_cfg); + +esp_err_t i2s_reconfig_tdm_gpio(i2s_chan_handle_t handle, const i2s_tdm_gpio_config_t *gpio_cfg); + + #ifdef __cplusplus } #endif diff --git a/components/driver/include/esp_private/i2s_platform.h b/components/driver/include/esp_private/i2s_platform.h index 6b5d294e76..7b7a07514e 100644 --- a/components/driver/include/esp_private/i2s_platform.h +++ b/components/driver/include/esp_private/i2s_platform.h @@ -10,38 +10,39 @@ #pragma once #include "esp_err.h" +#include "soc/soc_caps.h" #ifdef __cplusplus extern "C" { #endif /** - * @brief Register an I2S or I2S variant driver object to platform + * @brief Hold the I2S port occupation * * @note This private API is used to avoid applications from using the same I2S instance for different purpose. * @note This function will help enable the peripheral APB clock as well. * - * @param driver_obj Driver object - * @param port_id I2S port number + * @param id I2S port number + * @param comp_name The name of compnant that occupied this i2s controller * @return * - ESP_OK: The specific I2S port is free and register the new device object successfully * - ESP_ERR_INVALID_ARG: Invalid argument, e.g. wrong port_id - * - ESP_ERR_NOT_FOUND: Specific I2S port is not available + * - ESP_ERR_NOT_FOUND Specific I2S port is not available */ -esp_err_t i2s_priv_register_object(void *driver_obj, int port_id); +esp_err_t i2s_platform_acquire_occupation(int id, const char *comp_name); /** - * @brief Deregister I2S or I2S variant driver object from platform + * @brief Release the I2S port occupation * * @note This function will help disable the peripheral APB clock as well. * - * @param port_id I2S port number + * @param id I2S port number * @return * - ESP_OK: Deregister I2S port successfully (i.e. that I2S port can used used by other users after this function returns) * - ESP_ERR_INVALID_ARG: Invalid argument, e.g. wrong port_id * - ESP_ERR_INVALID_STATE: Specific I2S port is free already */ -esp_err_t i2s_priv_deregister_object(int port_id); +esp_err_t i2s_platform_release_occupation(int id); #ifdef __cplusplus } diff --git a/components/driver/test/adc_dma_test/test_esp32.c b/components/driver/test/adc_dma_test/test_esp32.c deleted file mode 100644 index 454dc16ce6..0000000000 --- a/components/driver/test/adc_dma_test/test_esp32.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/* - Tests for the adc device driver on ESP32 only -*/ -#include "sdkconfig.h" -#if CONFIG_IDF_TARGET_ESP32 - -#include "esp_system.h" -#include "driver/adc.h" -#include "driver/rtc_io.h" -#include "driver/gpio.h" -#include "unity.h" -#include "esp_system.h" -#include "esp_event.h" -#include "esp_wifi.h" -#include "esp_log.h" -#include "nvs_flash.h" -#include "test_utils.h" -#include "esp_rom_sys.h" -#include "driver/dac.h" - -/* - * ADC DMA testcase - */ -#include "driver/i2s.h" -#include "test/test_common_adc.h" - -//i2s number -#define EXAMPLE_I2S_NUM (0) -//i2s sample rate -#define EXAMPLE_I2S_SAMPLE_RATE (150000) -//i2s data bits -#define EXAMPLE_I2S_SAMPLE_BITS (16) -//enable display buffer for debug -#define EXAMPLE_I2S_BUF_DEBUG (0) -//I2S read buffer length -#define EXAMPLE_I2S_READ_LEN (16 * 1024) -//I2S data format, ADC-I2S only support mono. -#define EXAMPLE_I2S_FORMAT I2S_CHANNEL_FMT_ONLY_RIGHT -//I2S built-in ADC unit -#define I2S_ADC_UNIT ADC_UNIT_1 -//I2S built-in ADC channel -#define I2S_ADC_CHANNEL ADC1_CHANNEL_4 - -/** - * @brief I2S ADC/DAC mode init. - */ -static void example_i2s_init(void) -{ - int i2s_num = EXAMPLE_I2S_NUM; - i2s_config_t i2s_config = { - .mode = I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_ADC_BUILT_IN, - .sample_rate = EXAMPLE_I2S_SAMPLE_RATE, - .bits_per_sample = EXAMPLE_I2S_SAMPLE_BITS, - .channel_format = EXAMPLE_I2S_FORMAT, - .intr_alloc_flags = 0, - .dma_desc_num = 2, - .dma_frame_num = 1024, - .use_apll = 0, - }; - - //install and start i2s driver - TEST_ESP_OK( i2s_driver_install(i2s_num, &i2s_config, 0, NULL) ); - //init ADC pad - TEST_ESP_OK( i2s_set_adc_mode(I2S_ADC_UNIT, I2S_ADC_CHANNEL) ); -} - -static void example_i2s_deinit(void) -{ - TEST_ESP_OK( i2s_driver_uninstall(EXAMPLE_I2S_NUM) ); -} - -/** - * @brief debug buffer data - */ -static void example_disp_buf(uint8_t *buf, int length) -{ - printf("\n======"); - for (int i = 0; i < length; i += 2) { - uint16_t data = ((uint16_t)buf[i+1] << 8) | (uint16_t)buf[i]; - adc_digi_output_data_t *p = (adc_digi_output_data_t *)&data; - if ((i) % 16 == 0) printf("\n"); - printf("[%d_%d] ", p->type1.channel, p->type1.data); - } - printf("\n======\n"); -} - -static esp_err_t adc_dma_data_check(uint8_t *buf, int length, int ideal_level) -{ - for (int i = 0; i < length; i += 2) { - uint16_t data = ((uint16_t)buf[i+1] << 8) | (uint16_t)buf[i]; - adc_digi_output_data_t *p = (adc_digi_output_data_t *)&data; - if (p->type1.channel != I2S_ADC_CHANNEL) { - TEST_FAIL_MESSAGE("I2S-DMA data channel error!"); - } - if (ideal_level == 1) { // high level 3.3v - TEST_ASSERT_EQUAL( 0xFFF, p->type1.data ); - } else if (ideal_level == 0) { // low level 0v - TEST_ASSERT_LESS_THAN( 10, p->type1.data ); - } else if (ideal_level == 2) { // middle level 1.4v - TEST_ASSERT_INT_WITHIN( 128, 1586, p->type1.data ); - } else if (ideal_level == 3) { // normal level - } else { // no check - } - } - return ESP_OK; -} - -static void adc_dma_read(uint8_t *buf, int length) -{ - size_t bytes_read = 0; - int flash_wr_size = 0; - - vTaskDelay(pdTICKS_TO_MS(100)); - while (flash_wr_size < length) { - //read data from I2S bus, in this case, from ADC. - TEST_ESP_OK( i2s_read(EXAMPLE_I2S_NUM, (void *) buf + flash_wr_size, length - flash_wr_size, &bytes_read, portMAX_DELAY) ); - flash_wr_size += bytes_read; - example_disp_buf((uint8_t *) buf, 128); - } -} - -TEST_CASE("ADC DMA read", "[adc dma]") -{ - int i2s_read_len = EXAMPLE_I2S_READ_LEN; - char *i2s_read_buff = (char *) calloc(i2s_read_len, sizeof(char)); - - example_i2s_init(); - TEST_ESP_OK( i2s_adc_enable(EXAMPLE_I2S_NUM) ); - - adc_fake_tie_low(I2S_ADC_UNIT, I2S_ADC_CHANNEL); - adc_dma_read((uint8_t *)i2s_read_buff, i2s_read_len); - adc_dma_data_check((uint8_t *)i2s_read_buff, i2s_read_len, 0); - - adc_fake_tie_middle(I2S_ADC_UNIT, I2S_ADC_CHANNEL); - adc_dma_read((uint8_t *)i2s_read_buff, i2s_read_len); - adc_dma_data_check((uint8_t *)i2s_read_buff, i2s_read_len, 2); - - adc_fake_tie_high(I2S_ADC_UNIT, I2S_ADC_CHANNEL); - adc_dma_read((uint8_t *)i2s_read_buff, i2s_read_len); - adc_dma_data_check((uint8_t *)i2s_read_buff, i2s_read_len, 1); - - adc_io_normal(I2S_ADC_UNIT, I2S_ADC_CHANNEL); - - TEST_ESP_OK( i2s_adc_disable(EXAMPLE_I2S_NUM) ); - if (i2s_read_buff) { - free(i2s_read_buff); - i2s_read_buff = NULL; - } - - example_i2s_deinit(); -} - -#endif // CONFIG_IDF_TARGET_ESP32 diff --git a/components/driver/test/dac_dma_test/test_esp32.c b/components/driver/test/dac_dma_test/test_esp32.c deleted file mode 100644 index c68b5654a6..0000000000 --- a/components/driver/test/dac_dma_test/test_esp32.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/* - Tests for the dac device driver on ESP32 only - Hardware connection: - - ESP32: GPIO25 <---> GPIO26 -*/ -#include "sdkconfig.h" -#if CONFIG_IDF_TARGET_ESP32 - -#include "esp_system.h" -#include "driver/adc.h" -#include "unity.h" -#include "esp_system.h" -#include "esp_event.h" -#include "esp_wifi.h" -#include "esp_log.h" -#include "nvs_flash.h" -#include "test_utils.h" -#include "test_dac_audio_file.h" -#include "driver/i2s.h" -#include "driver/dac.h" - -/* - * DAC DMA config. - */ - -//enable record sound and save in flash -#define RECORD_IN_FLASH_EN (1) -//enable replay recorded sound in flash -#define REPLAY_FROM_FLASH_EN (1) - -//i2s number -#define EXAMPLE_I2S_NUM (0) -//i2s sample rate -#define EXAMPLE_I2S_SAMPLE_RATE (16000) -//i2s data bits -#define EXAMPLE_I2S_SAMPLE_BITS (16) -//enable display buffer for debug -#define EXAMPLE_I2S_BUF_DEBUG (0) -//I2S read buffer length -#define EXAMPLE_I2S_READ_LEN (16 * 1024) -//I2S data format -#define EXAMPLE_I2S_FORMAT (I2S_CHANNEL_FMT_RIGHT_LEFT) -//I2S channel number -#define EXAMPLE_I2S_CHANNEL_NUM ((EXAMPLE_I2S_FORMAT < I2S_CHANNEL_FMT_ONLY_RIGHT) ? (2) : (1)) - -/** - * @brief I2S ADC/DAC mode init. - */ -static void example_i2s_init(void) -{ - int i2s_num = EXAMPLE_I2S_NUM; - i2s_config_t i2s_config = { - .mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN, - .sample_rate = EXAMPLE_I2S_SAMPLE_RATE, - .bits_per_sample = EXAMPLE_I2S_SAMPLE_BITS, - .channel_format = EXAMPLE_I2S_FORMAT, - .intr_alloc_flags = 0, - .dma_desc_num = 2, - .dma_frame_num = 1024, - .use_apll = 0, - }; - //install and start i2s driver - TEST_ESP_OK( i2s_driver_install(i2s_num, &i2s_config, 0, NULL) ); - //init DAC pad - TEST_ESP_OK( i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN) ); -} - -static void example_i2s_deinit(void) -{ - TEST_ESP_OK( i2s_set_dac_mode(I2S_DAC_CHANNEL_DISABLE) ); - TEST_ESP_OK( i2s_driver_uninstall(EXAMPLE_I2S_NUM) ); -} - -/** - * @brief Set i2s clock for example audio file - */ -static void example_set_file_play_mode(void) -{ - TEST_ESP_OK( i2s_set_clk(EXAMPLE_I2S_NUM, 16000, EXAMPLE_I2S_SAMPLE_BITS, 1) ); -} - -/** - * @brief Scale data to 16bit/32bit for I2S DMA output. - * DAC can only output 8bit data value. - * I2S DMA will still send 16 bit or 32bit data, the highest 8bit contains DAC data. - */ -static int example_i2s_dac_data_scale(uint8_t *d_buff, uint8_t *s_buff, uint32_t len) -{ - uint32_t j = 0; -#if (EXAMPLE_I2S_SAMPLE_BITS == 16) - for (int i = 0; i < len; i++) { - d_buff[j++] = 0; - d_buff[j++] = s_buff[i]; - } - return (len * 2); -#else - for (int i = 0; i < len; i++) { - d_buff[j++] = 0; - d_buff[j++] = 0; - d_buff[j++] = 0; - d_buff[j++] = s_buff[i]; - } - return (len * 4); -#endif -} -/** - * @brief debug buffer data - */ -static void example_disp_buf(uint8_t *buf, int length) -{ - printf("======\n"); - for (int i = 0; i < length; i++) { - printf("%02x ", buf[i]); - if ((i + 1) % 8 == 0) { - printf("\n"); - } - } - printf("======\n"); -} - -/** - * @brief Reset i2s clock and mode - */ -static void example_reset_play_mode(void) -{ - TEST_ESP_OK( i2s_set_clk(EXAMPLE_I2S_NUM, EXAMPLE_I2S_SAMPLE_RATE, EXAMPLE_I2S_SAMPLE_BITS, EXAMPLE_I2S_CHANNEL_NUM) ); -} - -TEST_CASE("DAC DMA output", "[dac]") -{ - size_t bytes_written; - int i2s_read_len = EXAMPLE_I2S_READ_LEN; - uint8_t *i2s_write_buff = (uint8_t *) calloc(i2s_read_len, sizeof(char)); - int offset = 0; - int tot_size = sizeof(audio_table); - printf("Playing file example: \n"); - - example_i2s_init(); - example_set_file_play_mode(); - - while (offset < tot_size) { - int play_len = ((tot_size - offset) > (4 * 1024)) ? (4 * 1024) : (tot_size - offset); - int i2s_wr_len = example_i2s_dac_data_scale(i2s_write_buff, (uint8_t *)(audio_table + offset), play_len); - i2s_write(EXAMPLE_I2S_NUM, i2s_write_buff, i2s_wr_len, &bytes_written, portMAX_DELAY); - offset += play_len; - example_disp_buf((uint8_t *) i2s_write_buff, 32); - } - - example_reset_play_mode(); - free(i2s_write_buff); - - example_i2s_deinit(); -} - -#endif // CONFIG_IDF_TARGET_ESP32 diff --git a/components/driver/test/test_adc2_with_wifi.c b/components/driver/test/test_adc2_with_wifi.c index e5c494df20..3d944d3c00 100644 --- a/components/driver/test/test_adc2_with_wifi.c +++ b/components/driver/test/test_adc2_with_wifi.c @@ -219,35 +219,44 @@ TEST_CASE("adc2 work with wifi","[adc]") #ifdef CONFIG_IDF_TARGET_ESP32 -#include "driver/i2s.h" +#include "driver/adc.h" #define ADC1_CHANNEL_4_IO (32) -#define SAMPLE_RATE (36000) -#define SAMPLE_BITS (16) +#define ADC_SAMPLE_RATE (36000) +#define ADC_TEST_CHANNEL ADC1_CHANNEL_4 -static void i2s_adc_init(void) +static void adc_dma_init(void) { - i2s_config_t i2s_config = { - .mode = I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_ADC_BUILT_IN, - .sample_rate = SAMPLE_RATE, - .bits_per_sample = SAMPLE_BITS, - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, - .intr_alloc_flags = 0, - .dma_desc_num = 2, - .dma_frame_num = 1024, - .use_apll = 0, + adc_digi_init_config_t adc_dma_config = { + .max_store_buf_size = 1024, + .conv_num_each_intr = 256, + .adc1_chan_mask = 1 << ADC_TEST_CHANNEL, + .adc2_chan_mask = 0, }; - // install and start I2S driver - i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); - // init ADC pad - i2s_set_adc_mode(ADC_UNIT_1, ADC1_CHANNEL_4); - // enable adc sampling, ADC_WIDTH_BIT_12, ADC_ATTEN_DB_11 hard-coded in adc_i2s_mode_init - i2s_adc_enable(I2S_NUM_0); + TEST_ESP_OK(adc_digi_initialize(&adc_dma_config)); + + adc_digi_pattern_config_t adc_pattern = { + .atten = ADC_ATTEN_DB_0, + .channel = ADC_TEST_CHANNEL, + .unit = 0, + .bit_width = SOC_ADC_DIGI_MAX_BITWIDTH + }; + adc_digi_configuration_t dig_cfg = { + .conv_limit_en = 1, + .conv_limit_num = 250, + .sample_freq_hz = ADC_SAMPLE_RATE, + .conv_mode = ADC_CONV_SINGLE_UNIT_1, + .format = ADC_DIGI_OUTPUT_FORMAT_TYPE1, + .pattern_num = 1, + .adc_pattern = &adc_pattern + }; + TEST_ESP_OK(adc_digi_controller_configure(&dig_cfg)); + TEST_ESP_OK(adc_digi_start()); } -static void i2s_adc_test(void) +static void continuous_adc_test(void) { - uint16_t *i2sReadBuffer = (uint16_t *)calloc(1024, sizeof(uint16_t)); + uint16_t *adcReadBuffer = (uint16_t *)calloc(1024, sizeof(uint16_t)); size_t bytesRead; for (int loop = 0; loop < 10; loop++) { for (int level = 0; level <= 1; level++) { @@ -258,12 +267,11 @@ static void i2s_adc_test(void) } vTaskDelay(200 / portTICK_PERIOD_MS); // read data from adc, will block until buffer is full - i2s_read(I2S_NUM_0, (void *)i2sReadBuffer, 1024 * sizeof(uint16_t), &bytesRead, portMAX_DELAY); - + adc_digi_read_bytes((uint8_t *)adcReadBuffer, 1024 * sizeof(uint16_t), &bytesRead, ADC_MAX_DELAY); // calc average int64_t adcSumValue = 0; for (size_t i = 0; i < 1024; i++) { - adcSumValue += i2sReadBuffer[i] & 0xfff; + adcSumValue += adcReadBuffer[i] & 0xfff; } int adcAvgValue = adcSumValue / 1024; printf("adc average val: %d\n", adcAvgValue); @@ -275,19 +283,19 @@ static void i2s_adc_test(void) } } } - free(i2sReadBuffer); + free(adcReadBuffer); } -static void i2s_adc_release(void) +static void adc_deinit(void) { - i2s_adc_disable(I2S_NUM_0); - i2s_driver_uninstall(I2S_NUM_0); + adc_digi_stop(); + TEST_ESP_OK(adc_digi_deinitialize()); } TEST_CASE("adc1 and i2s work with wifi","[adc][ignore]") { - i2s_adc_init(); + adc_dma_init(); //init wifi printf("nvs init\n"); esp_err_t r = nvs_flash_init(); @@ -310,12 +318,12 @@ TEST_CASE("adc1 and i2s work with wifi","[adc][ignore]") }; TEST_ESP_OK(esp_wifi_set_mode(WIFI_MODE_STA)); TEST_ESP_OK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); - i2s_adc_test(); + continuous_adc_test(); //now start wifi printf("wifi start...\n"); TEST_ESP_OK(esp_wifi_start()); //test reading during wifi on - i2s_adc_test(); + continuous_adc_test(); //wifi stop again printf("wifi stop...\n"); @@ -326,8 +334,8 @@ TEST_CASE("adc1 and i2s work with wifi","[adc][ignore]") event_deinit(); nvs_flash_deinit(); - i2s_adc_test(); - i2s_adc_release(); + continuous_adc_test(); + adc_deinit(); printf("test passed...\n"); TEST_IGNORE_MESSAGE("this test case is ignored due to the critical memory leak of esp_netif and event_loop."); } diff --git a/components/driver/test/test_dac.c b/components/driver/test/test_dac.c index 2eace253e8..0537f23148 100644 --- a/components/driver/test/test_dac.c +++ b/components/driver/test/test_dac.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,7 +19,6 @@ #include "soc/soc_caps.h" #if SOC_DAC_SUPPORTED -#include "driver/i2s.h" #include "driver/dac.h" #include "esp_adc_cal.h" diff --git a/components/driver/test_apps/i2s/CMakeLists.txt b/components/driver/test_apps/i2s/CMakeLists.txt new file mode 100644 index 0000000000..3d2e9717ee --- /dev/null +++ b/components/driver/test_apps/i2s/CMakeLists.txt @@ -0,0 +1,5 @@ +# This is the project CMakeLists.txt file for the test subproject +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(i2s_test) diff --git a/components/driver/test_apps/i2s/app_test.py b/components/driver/test_apps/i2s/app_test.py new file mode 100644 index 0000000000..1583ff5709 --- /dev/null +++ b/components/driver/test_apps/i2s/app_test.py @@ -0,0 +1,30 @@ +# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 +import glob +import os + +import ttfw_idf +from tiny_test_fw import Utility + + +@ttfw_idf.idf_component_unit_test(env_tag='COMPONENT_UT_GENERIC', target=['esp32', 'esp32s2', 'esp32s3', 'esp32c3']) +def test_component_ut_i2s(env, _): # type: (ttfw_idf.TinyFW.Env, None) -> None + # Get the names of all configs (sdkconfig.ci.* files) + config_files = glob.glob(os.path.join(os.path.dirname(__file__), 'sdkconfig.ci.*')) + config_names = [os.path.basename(s).replace('sdkconfig.ci.', '') for s in config_files] + + # Run test once with binaries built for each config + for name in config_names: + Utility.console_log(f'Checking config "{name}"... ', end='') + dut = env.get_dut('i2s', 'components/driver/test_apps/i2s', app_config_name=name) + dut.start_app() + stdout = dut.expect('Press ENTER to see the list of tests', full_stdout=True) + dut.write('*') + stdout = dut.expect("Enter next test, or 'enter' to see menu", full_stdout=True, timeout=30) + ttfw_idf.ComponentUTResult.parse_result(stdout,ttfw_idf.TestFormat.UNITY_BASIC) + env.close_dut(dut.name) + Utility.console_log(f'Test config "{name}" done') + + +if __name__ == '__main__': + test_component_ut_i2s() diff --git a/components/driver/test_apps/i2s/main/CMakeLists.txt b/components/driver/test_apps/i2s/main/CMakeLists.txt new file mode 100644 index 0000000000..1eb45d8776 --- /dev/null +++ b/components/driver/test_apps/i2s/main/CMakeLists.txt @@ -0,0 +1,16 @@ +set(srcs "test_app_main.c") + +if(CONFIG_SOC_I2S_SUPPORTED) + list(APPEND srcs "test_i2s_controller.c" + "test_i2s_legacy.c") +endif() + + +idf_component_register(SRCS ${srcs} + PRIV_REQUIRES driver hal soc unity) + +if(CONFIG_SOC_I2S_SUPPORTED) + target_link_libraries(${COMPONENT_LIB} INTERFACE + "-u test_app_include_i2s_controller" + "-u test_app_include_i2s_legacy") +endif() diff --git a/components/driver/test_apps/i2s/main/test_app_main.c b/components/driver/test_apps/i2s/main/test_app_main.c new file mode 100644 index 0000000000..b49226f575 --- /dev/null +++ b/components/driver/test_apps/i2s/main/test_app_main.c @@ -0,0 +1,53 @@ +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "unity.h" +#include "unity_test_runner.h" +#include "esp_heap_caps.h" + +// Some resources are lazy allocated in I2S driver, the threadhold is left for that case +#define TEST_MEMORY_LEAK_THRESHOLD (-300) + +static size_t before_free_8bit; +static size_t before_free_32bit; + +static void check_leak(size_t before_free, size_t after_free, const char *type) +{ + ssize_t delta = after_free - before_free; + printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d)\n", type, before_free, after_free, delta); + TEST_ASSERT_MESSAGE(delta >= TEST_MEMORY_LEAK_THRESHOLD, "memory leak"); +} + +void setUp(void) +{ + before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); + before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); +} + +void tearDown(void) +{ + size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); + size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); + check_leak(before_free_8bit, after_free_8bit, "8BIT"); + check_leak(before_free_32bit, after_free_32bit, "32BIT"); +} + +void app_main(void) +{ + // ___ ____ ____ _____ _ + // |_ _|___ \/ ___| |_ _|__ ___| |_ + // | | __) \___ \ | |/ _ \/ __| __| + // | | / __/ ___) | | | __/\__ \ |_ + // |___|_____|____/ |_|\___||___/\__| + + printf(" ___ ____ ____ _____ _ \r\n"); + printf(" |_ _|___ \\/ ___| |_ _|__ ___| |_ \r\n"); + printf(" | | __) \\___ \\ | |/ _ \\/ __| __|\r\n"); + printf(" | | / __/ ___) | | | __/\\__ \\ |_ \r\n"); + printf(" |___|_____|____/ |_|\\___||___/\\__|\r\n"); + + unity_run_menu(); +} diff --git a/components/driver/test_apps/i2s/main/test_i2s_controller.c b/components/driver/test_apps/i2s/main/test_i2s_controller.c new file mode 100644 index 0000000000..0c1cf8d00f --- /dev/null +++ b/components/driver/test_apps/i2s/main/test_i2s_controller.c @@ -0,0 +1,512 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * I2S test environment UT_T1_I2S: + * We use internal signals instead of external wiring, but please keep the following IO connections, or connect nothing to prevent the signal from being disturbed. + * connect GPIO15 and GPIO19, GPIO25(ESP32)/GPIO17(ESP32-S2) and GPIO26, GPIO21 and GPIO22(ESP32)/GPIO20(ESP32-S2) + * Please do not connect GPIO32(ESP32) any pull-up resistors externally, it will be used to test i2s adc function. + */ + + +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/semphr.h" +#include "driver/gpio.h" +#include "hal/gpio_hal.h" +#include "esp_err.h" +#include "unity.h" +#include "math.h" +#include "esp_rom_gpio.h" +#include "soc/i2s_periph.h" +#include "driver/i2s_controller.h" +#include "hal/i2s_hal.h" +#include "esp_private/i2s_platform.h" +#if SOC_PCNT_SUPPORTED +#include "driver/pcnt.h" +#include "soc/pcnt_periph.h" +#endif + +#define SAMPLE_RATE (48000) +#define SAMPLE_BITS (16) + +#if CONFIG_IDF_TARGET_ESP32 +#define MASTER_MCK_IO 0 +#define MASTER_BCK_IO 15 +#define MASTER_WS_IO 25 +#define SLAVE_BCK_IO 19 +#define SLAVE_WS_IO 26 +#define DATA_IN_IO 21 +#define DATA_OUT_IO 22 +#define ADC1_CHANNEL_4_IO 32 +#elif CONFIG_IDF_TARGET_ESP32S2 +#define MASTER_MCK_IO 0 +#define MASTER_BCK_IO 4 +#define MASTER_WS_IO 5 +#define SLAVE_BCK_IO 14 +#define SLAVE_WS_IO 15 +#define DATA_IN_IO 19 +#define DATA_OUT_IO 18 +#elif CONFIG_IDF_TARGET_ESP32C3 +#define MASTER_MCK_IO 0 +#define MASTER_BCK_IO 4 +#define MASTER_WS_IO 5 +#define SLAVE_BCK_IO 14 +#define SLAVE_WS_IO 15 +#define DATA_IN_IO 19 +#define DATA_OUT_IO 18 +#elif CONFIG_IDF_TARGET_ESP32S3 +#define MASTER_MCK_IO 0 +#define MASTER_BCK_IO 4 +#define MASTER_WS_IO 5 +#define SLAVE_BCK_IO 14 +#define SLAVE_WS_IO 15 +#define DATA_IN_IO 19 +#define DATA_OUT_IO 18 +#endif + +#define I2S_TEST_MODE_SLAVE_TO_MASTER 0 +#define I2S_TEST_MODE_MASTER_TO_SLAVE 1 +#define I2S_TEST_MODE_LOOPBACK 2 + +#define I2S_TEST_MASTER_DEFAULT_PIN { \ + .mclk = MASTER_MCK_IO, \ + .bclk = MASTER_BCK_IO, \ + .ws = MASTER_WS_IO, \ + .dout = DATA_OUT_IO, \ + .din = DATA_IN_IO \ + }; + +#define I2S_TEST_SLAVE_DEFAULT_PIN { \ + .mclk = -1, \ + .bclk = SLAVE_BCK_IO, \ + .ws = SLAVE_WS_IO, \ + .dout = DATA_OUT_IO, \ + .din = DATA_IN_IO \ + }; + +// This empty function is used to force the compiler link this file +void test_app_include_i2s_controller(void) +{ +} + +// mode: 0, master rx, slave tx. mode: 1, master tx, slave rx. mode: 2, master tx rx loop-back +// Since ESP32-S2 has only one I2S, only loop back test can be tested. +static void i2s_test_io_config(int mode) +{ + // Connect internal signals using IO matrix. + gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[MASTER_BCK_IO], PIN_FUNC_GPIO); + gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[MASTER_WS_IO], PIN_FUNC_GPIO); + gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[DATA_OUT_IO], PIN_FUNC_GPIO); + + gpio_set_direction(MASTER_BCK_IO, GPIO_MODE_INPUT_OUTPUT); + gpio_set_direction(MASTER_WS_IO, GPIO_MODE_INPUT_OUTPUT); + gpio_set_direction(DATA_OUT_IO, GPIO_MODE_INPUT_OUTPUT); + + switch (mode) { +#if SOC_I2S_NUM > 1 + case I2S_TEST_MODE_SLAVE_TO_MASTER: { + esp_rom_gpio_connect_out_signal(MASTER_BCK_IO, i2s_periph_signal[0].m_rx_bck_sig, 0, 0); + esp_rom_gpio_connect_in_signal(MASTER_BCK_IO, i2s_periph_signal[1].s_tx_bck_sig, 0); + + esp_rom_gpio_connect_out_signal(MASTER_WS_IO, i2s_periph_signal[0].m_rx_ws_sig, 0, 0); + esp_rom_gpio_connect_in_signal(MASTER_WS_IO, i2s_periph_signal[1].s_tx_ws_sig, 0); + + esp_rom_gpio_connect_out_signal(DATA_OUT_IO, i2s_periph_signal[1].data_out_sig, 0, 0); + esp_rom_gpio_connect_in_signal(DATA_OUT_IO, i2s_periph_signal[0].data_in_sig, 0); + } + break; + + case I2S_TEST_MODE_MASTER_TO_SLAVE: { + esp_rom_gpio_connect_out_signal(MASTER_BCK_IO, i2s_periph_signal[0].m_tx_bck_sig, 0, 0); + esp_rom_gpio_connect_in_signal(MASTER_BCK_IO, i2s_periph_signal[1].s_rx_bck_sig, 0); + + esp_rom_gpio_connect_out_signal(MASTER_WS_IO, i2s_periph_signal[0].m_tx_ws_sig, 0, 0); + esp_rom_gpio_connect_in_signal(MASTER_WS_IO, i2s_periph_signal[1].s_rx_ws_sig, 0); + + esp_rom_gpio_connect_out_signal(DATA_OUT_IO, i2s_periph_signal[0].data_out_sig, 0, 0); + esp_rom_gpio_connect_in_signal(DATA_OUT_IO, i2s_periph_signal[1].data_in_sig, 0); + } + break; +#endif + case I2S_TEST_MODE_LOOPBACK: { + esp_rom_gpio_connect_out_signal(DATA_OUT_IO, i2s_periph_signal[0].data_out_sig, 0, 0); + esp_rom_gpio_connect_in_signal(DATA_OUT_IO, i2s_periph_signal[0].data_in_sig, 0); + } + break; + + default: { + TEST_FAIL_MESSAGE("error: mode not supported"); + } + break; + } +} + +static void i2s_read_write_test(i2s_chan_handle_t tx_chan, i2s_chan_handle_t rx_chan) +{ +#define I2S_SEND_BUF_LEN 100 +#define I2S_RECV_BUF_LEN 10000 + + size_t bytes_write = 0; + size_t bytes_read = 0; + + bool is_success = false; + + uint8_t *send_buf = (uint8_t *)calloc(I2S_SEND_BUF_LEN, sizeof(uint8_t)); + TEST_ASSERT_NOT_NULL(send_buf); + uint8_t *recv_buf = (uint8_t *)calloc(I2S_RECV_BUF_LEN, sizeof(uint8_t)); + TEST_ASSERT_NOT_NULL(recv_buf); + + for (int i = 0; i < I2S_SEND_BUF_LEN; i++) { + send_buf[i] = i + 1; + } + + // write data to slave + TEST_ESP_OK(i2s_write_channel(tx_chan, send_buf, I2S_SEND_BUF_LEN, &bytes_write, 1000 / portTICK_PERIOD_MS)); + TEST_ESP_OK(i2s_read_channel(rx_chan, recv_buf, I2S_RECV_BUF_LEN, &bytes_read, 1000 / portTICK_PERIOD_MS)); + TEST_ASSERT_EQUAL_INT32(I2S_SEND_BUF_LEN, bytes_write); + TEST_ASSERT_EQUAL_INT32(I2S_RECV_BUF_LEN, bytes_read); + // test the read data right or not + for (int i = 0, j = 0; i < (I2S_RECV_BUF_LEN - I2S_SEND_BUF_LEN); i++) { + if (recv_buf[i] == 1) { + for (j = 1; (j < I2S_SEND_BUF_LEN) && (recv_buf[i+j] == j + 1); j++) {} + if (j == I2S_SEND_BUF_LEN) { + is_success = true; + goto finish; + } + i += j; + } + } +finish: + free(send_buf); + free(recv_buf); + TEST_ASSERT(is_success); +} + +// To check if the software logic of I2S driver is correct +TEST_CASE("I2S basic driver apply, delete test", "[i2s]") +{ + i2s_gpio_config_t i2s_pin = I2S_TEST_MASTER_DEFAULT_PIN; + + i2s_chan_handle_t tx_handle; + i2s_chan_handle_t rx_handle; + + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO); + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(SAMPLE_RATE); + + /* TX channel basic test */ + TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, NULL)); + + TEST_ESP_OK(i2s_init_channel(tx_handle, &clk_cfg, &slot_cfg)); + slot_cfg.data_bit_width = I2S_DATA_BIT_WIDTH_32BIT; + TEST_ESP_OK(i2s_set_slot(tx_handle, &slot_cfg)); + clk_cfg.sample_rate = 44100; + TEST_ESP_OK(i2s_set_clock(tx_handle, &clk_cfg)); + TEST_ESP_OK(i2s_start_channel(tx_handle)); + TEST_ESP_OK(i2s_del_channel(tx_handle)); + + /* Duplex channel basic test */ + chan_cfg.id = I2S_NUM_0; // Specify port id to I2S port 0 + TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); + TEST_ESP_OK(i2s_init_channel(tx_handle, &clk_cfg, &slot_cfg)); + TEST_ESP_OK(i2s_init_channel(rx_handle, &clk_cfg, &slot_cfg)); + TEST_ESP_OK(i2s_del_channel(tx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); + + /* Repeat to check if a same port can be applied again */ + TEST_ESP_OK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); + + /* Hold the occupation */ + TEST_ESP_OK(i2s_platform_acquire_occupation(I2S_NUM_0, "test_i2s")); + TEST_ASSERT(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle) == ESP_ERR_NOT_FOUND); + TEST_ESP_OK(i2s_platform_release_occupation(I2S_NUM_0)); + TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); + TEST_ESP_OK(i2s_del_channel(tx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); +} + +TEST_CASE("I2S memory leak test", "[i2s]") +{ + i2s_gpio_config_t i2s_pin = I2S_TEST_MASTER_DEFAULT_PIN; + + i2s_chan_handle_t tx_handle; + i2s_chan_handle_t rx_handle; + + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + + /* The first operation will always take some memory */ + TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); + TEST_ESP_OK(i2s_del_channel(tx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); + + int memory_left = esp_get_free_heap_size(); + printf("\r\nHeap size before: %d\n", memory_left); + for (int i = 0; i < 100; i++) { + TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); + TEST_ESP_OK(i2s_del_channel(tx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); + TEST_ASSERT(memory_left == esp_get_free_heap_size()); + } + printf("\r\nHeap size after: %d\n", esp_get_free_heap_size()); +} + +TEST_CASE("I2S loopback test", "[i2s]") +{ + i2s_gpio_config_t i2s_pin = I2S_TEST_MASTER_DEFAULT_PIN; + + i2s_chan_handle_t tx_handle; + i2s_chan_handle_t rx_handle; + + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO); + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(SAMPLE_RATE); + chan_cfg.id = I2S_NUM_0; + TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); + TEST_ESP_OK(i2s_init_channel(tx_handle, &clk_cfg, &slot_cfg)); + TEST_ESP_OK(i2s_init_channel(rx_handle, &clk_cfg, &slot_cfg)); + i2s_test_io_config(I2S_TEST_MODE_LOOPBACK); + + TEST_ESP_OK(i2s_start_channel(tx_handle)); + TEST_ESP_OK(i2s_start_channel(rx_handle)); + + i2s_read_write_test(tx_handle, rx_handle); + + TEST_ESP_OK(i2s_del_channel(tx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); +} + +#if SOC_I2S_NUM > 1 +TEST_CASE("I2S master write slave read test", "[i2s]") +{ + i2s_gpio_config_t mst_pin = I2S_TEST_MASTER_DEFAULT_PIN; + i2s_gpio_config_t slv_pin = I2S_TEST_SLAVE_DEFAULT_PIN; + + i2s_chan_handle_t tx_handle; + i2s_chan_handle_t rx_handle; + + i2s_chan_config_t mst_chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &mst_pin); + mst_chan_cfg.id = I2S_NUM_0; + i2s_chan_config_t slv_chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_SLAVE, I2S_COMM_MODE_STD, &slv_pin); + slv_chan_cfg.id = I2S_NUM_1; + i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO); + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(SAMPLE_RATE); + + TEST_ESP_OK(i2s_new_channel(&mst_chan_cfg, &tx_handle, NULL)); + TEST_ESP_OK(i2s_new_channel(&slv_chan_cfg, NULL, &rx_handle)); + TEST_ESP_OK(i2s_init_channel(tx_handle, &clk_cfg, &slot_cfg)); + TEST_ESP_OK(i2s_init_channel(rx_handle, &clk_cfg, &slot_cfg)); + i2s_test_io_config(I2S_TEST_MODE_MASTER_TO_SLAVE); + + TEST_ESP_OK(i2s_start_channel(tx_handle)); + TEST_ESP_OK(i2s_start_channel(rx_handle)); + + i2s_read_write_test(tx_handle, rx_handle); + + TEST_ESP_OK(i2s_del_channel(tx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); +} + +TEST_CASE("I2S master read slave write test", "[i2s]") +{ + i2s_gpio_config_t mst_pin = I2S_TEST_MASTER_DEFAULT_PIN; + i2s_gpio_config_t slv_pin = I2S_TEST_SLAVE_DEFAULT_PIN; + + i2s_chan_handle_t tx_handle; + i2s_chan_handle_t rx_handle; + + i2s_chan_config_t mst_chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &mst_pin); + mst_chan_cfg.id = I2S_NUM_0; + i2s_chan_config_t slv_chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_SLAVE, I2S_COMM_MODE_STD, &slv_pin); + slv_chan_cfg.id = I2S_NUM_1; + i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO); + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(SAMPLE_RATE); + + TEST_ESP_OK(i2s_new_channel(&mst_chan_cfg, NULL, &rx_handle)); + TEST_ESP_OK(i2s_new_channel(&slv_chan_cfg, &tx_handle, NULL)); + TEST_ESP_OK(i2s_init_channel(tx_handle, &clk_cfg, &slot_cfg)); + TEST_ESP_OK(i2s_init_channel(rx_handle, &clk_cfg, &slot_cfg)); + i2s_test_io_config(I2S_TEST_MODE_SLAVE_TO_MASTER); + + TEST_ESP_OK(i2s_start_channel(tx_handle)); + TEST_ESP_OK(i2s_start_channel(rx_handle)); + + i2s_read_write_test(tx_handle, rx_handle); + + TEST_ESP_OK(i2s_del_channel(tx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); +} +#endif + +/*------------------------------ Clock Test --------------------------------*/ +#if SOC_PCNT_SUPPORTED +#define TEST_I2S_PERIOD_MS 100 +static void i2s_test_common_sample_rate(i2s_chan_handle_t rx_chan, i2s_clk_config_t* clk_cfg) +{ + TEST_ASSERT_NOT_NULL(rx_chan); + TEST_ASSERT_NOT_NULL(clk_cfg); + + /* Prepare configuration for the PCNT unit */ + pcnt_config_t pcnt_cfg = { + // Set PCNT input signal and control GPIOs + .pulse_gpio_num = MASTER_WS_IO, + .ctrl_gpio_num = -1, + .channel = PCNT_CHANNEL_0, + .unit = PCNT_UNIT_0, + .pos_mode = PCNT_COUNT_INC, // Count up on the positive edge + .neg_mode = PCNT_COUNT_DIS, // Keep the counter value on the negative edge + .lctrl_mode = PCNT_MODE_KEEP, + .hctrl_mode = PCNT_MODE_KEEP, + .counter_h_lim = (int16_t)0x7fff, + .counter_l_lim = (int16_t)0x8000, + }; + TEST_ESP_OK(pcnt_unit_config(&pcnt_cfg)); + + // Reconfig GPIO signal + gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[MASTER_WS_IO], PIN_FUNC_GPIO); + gpio_set_direction(MASTER_WS_IO, GPIO_MODE_INPUT_OUTPUT); + esp_rom_gpio_connect_out_signal(MASTER_WS_IO, i2s_periph_signal[0].m_rx_ws_sig, 0, 0); + esp_rom_gpio_connect_in_signal(MASTER_WS_IO, pcnt_periph_signals.groups[0].units[0].channels[0].pulse_sig, 0); + + // pcnt_set_filter_value(PCNT_UNIT_0, 10); + pcnt_filter_disable(PCNT_UNIT_0); + + // Test common sample rate + uint32_t test_freq[15] = {8000, 11025, 12000, 16000, 22050, 24000, + 32000, 44100, 48000, 64000, 88200, 96000, + 128000, 144000, 196000}; + int16_t real_pulse = 0; + for (int i = 0; i < 15; i++) { + int16_t expt_pulse = (int16_t)((float)test_freq[i] * (TEST_I2S_PERIOD_MS / 1000.0)); + clk_cfg->sample_rate = test_freq[i]; + TEST_ESP_OK(i2s_set_clock(rx_chan, clk_cfg)); + TEST_ESP_OK(i2s_start_channel(rx_chan)); + vTaskDelay(1); // Waiting for hardware totally started + // pcnt will count the pulse number on WS signal in 100ms + TEST_ESP_OK(pcnt_counter_clear(PCNT_UNIT_0)); + TEST_ESP_OK(pcnt_counter_resume(PCNT_UNIT_0)); + vTaskDelay(pdMS_TO_TICKS(TEST_I2S_PERIOD_MS)); + TEST_ESP_OK(pcnt_counter_pause(PCNT_UNIT_0)); + TEST_ESP_OK(pcnt_get_counter_value(PCNT_UNIT_0, &real_pulse)); + printf("[%d Hz] %d pulses, expected %d, err %d\n", test_freq[i], real_pulse, expt_pulse, real_pulse - expt_pulse); + TEST_ESP_OK(i2s_stop_channel(rx_chan)); + // Check if the error between real pulse number and expected pulse number is within 1% + TEST_ASSERT_INT_WITHIN(expt_pulse * 0.01, expt_pulse, real_pulse); + } +} + +TEST_CASE("I2S D2CLK clock test", "[i2s]") +{ + i2s_gpio_config_t i2s_pin = I2S_TEST_MASTER_DEFAULT_PIN; + + i2s_chan_handle_t rx_handle; + + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO); + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(SAMPLE_RATE); + chan_cfg.id = I2S_NUM_0; + + TEST_ESP_OK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); + TEST_ESP_OK(i2s_init_channel(rx_handle, &clk_cfg, &slot_cfg)); + + i2s_test_common_sample_rate(rx_handle, (i2s_clk_config_t *)&clk_cfg); + TEST_ESP_OK(i2s_del_channel(rx_handle)); +} + +#if SOC_I2S_SUPPORTS_APLL +TEST_CASE("I2S APLL clock test", "[i2s]") +{ + i2s_gpio_config_t i2s_pin = I2S_TEST_MASTER_DEFAULT_PIN; + + i2s_chan_handle_t rx_handle; + + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO); + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(SAMPLE_RATE); + chan_cfg.id = I2S_NUM_0; + clk_cfg.clk_src = I2S_CLK_APLL; + + TEST_ESP_OK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); + TEST_ESP_OK(i2s_init_channel(rx_handle, &clk_cfg, &slot_cfg)); + + i2s_test_common_sample_rate(rx_handle, (i2s_clk_config_t *)&clk_cfg); + TEST_ESP_OK(i2s_del_channel(rx_handle)); +} +#endif // SOC_I2S_SUPPORTS_APLL +#endif // SOC_PCNT_SUPPORTED + +static void i2s_event_monitor(void *args) +{ + i2s_chan_handle_t rx_handle = *((i2s_chan_handle_t *)args); + QueueHandle_t evt_que = i2s_get_event_queue(rx_handle, 16); + TEST_ASSERT_NOT_NULL(evt_que); + i2s_event_t evnet; + while (1) { + xQueueReceive(evt_que, &evnet, portMAX_DELAY); + if (evnet.type == I2S_EVENT_RX_Q_OVF) { + break; + } + } + vTaskDelete(NULL); +} + +TEST_CASE("I2S package lost test", "[i2s]") +{ + /* Steps of calculate appropriate parameters of I2S buffer: + * Known by user: sample_rate = 144k, data_bit_width = 32, slot_num = 2, polling_cycle = 10 ms + * 1. dma_buffer_size = dma_frame_num * slot_num * data_bit_width / 8 <= 4092 + * dma_frame_num <= 511, dma_frame_num is as big as possible. + * interrupt_interval = dma_frame_num / sample_rate = 3.549 ms + * 2. dma_desc_num > polling_cycle / interrupt_interval = cell(2.818) = 3 + * 3. recv_buffer_size > dma_desc_num * dma_buffer_size = 3 * 4092 = 12276 bytes */ + #define TEST_RECV_BUF_LEN 12276 + i2s_gpio_config_t i2s_pin = I2S_TEST_MASTER_DEFAULT_PIN; + i2s_chan_handle_t rx_handle; + + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO); + slot_cfg.dma_desc_num = 3; + slot_cfg.dma_frame_num = 511; + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(SAMPLE_RATE); + + TEST_ESP_OK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); + TEST_ESP_OK(i2s_init_channel(rx_handle, &clk_cfg, &slot_cfg)); + + TaskHandle_t h_monitor_task; + xTaskCreate(i2s_event_monitor, "event monitor task", 4096, &rx_handle, 5, &h_monitor_task); + + uint32_t test_freq[] = {16000, 32000, 48000, 64000, 96000, 128000, 144000}; + uint32_t test_num = sizeof(test_freq) / sizeof(uint32_t); + uint8_t *data = (uint8_t *)calloc(TEST_RECV_BUF_LEN, sizeof(uint8_t)); + size_t bytes_read = 0; + int i; + for (i = 0; i < test_num; i++) { + printf("Testing %d Hz sample rate\n", test_freq[i]); + clk_cfg.sample_rate = test_freq[i]; + TEST_ESP_OK(i2s_set_clock(rx_handle, &clk_cfg)); + TEST_ESP_OK(i2s_start_channel(rx_handle)); + for (int j = 0; j < 10; j++) { + TEST_ESP_OK(i2s_read_channel(rx_handle, (void *)data, TEST_RECV_BUF_LEN, &bytes_read, portMAX_DELAY)); + // To simulate 10ms delay caused by other statements like data process + vTaskDelay(1); + } + TEST_ESP_OK(i2s_stop_channel(rx_handle)); + if (eTaskGetState(h_monitor_task) == eDeleted) { + printf("package lost detected at %d Hz\n", test_freq[i]); + goto finish; + } + } + vTaskDelete(h_monitor_task); +finish: + TEST_ESP_OK(i2s_del_channel(rx_handle)); + free(data); + // Test failed if package lost within 96000 + TEST_ASSERT(i == test_num); +} diff --git a/components/driver/test/test_i2s.c b/components/driver/test_apps/i2s/main/test_i2s_legacy.c similarity index 97% rename from components/driver/test/test_i2s.c rename to components/driver/test_apps/i2s/main/test_i2s_legacy.c index a518b6ac20..03cad7ed12 100644 --- a/components/driver/test/test_i2s.c +++ b/components/driver/test_apps/i2s/main/test_i2s_legacy.c @@ -1,7 +1,7 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 + * SPDX-License-Identifier: Apache-2.0 */ /** @@ -11,19 +11,17 @@ * Please do not connect GPIO32(ESP32) any pull-up resistors externally, it will be used to test i2s adc function. */ - #include #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/queue.h" +#include "driver/i2s.h" #include "driver/gpio.h" #include "hal/gpio_hal.h" #include "unity.h" #include "math.h" #include "esp_rom_gpio.h" -#if SOC_I2S_SUPPORTED -#include "driver/i2s.h" #define SAMPLE_RATE (36000) #define SAMPLE_BITS (16) @@ -78,7 +76,12 @@ #define I2S_TEST_MODE_MASTER_TO_SLAVE 1 #define I2S_TEST_MODE_LOOPBACK 2 -// mode: 0, master rx, slave tx. mode: 1, master tx, slave rx. mode: 2, master tx rx loopback +// This empty function is used to force the compiler link this file +void test_app_include_i2s_legacy(void) +{ +} + +// mode: 0, master rx, slave tx. mode: 1, master tx, slave rx. mode: 2, master tx rx loop-back // Since ESP32-S2 has only one I2S, only loop back test can be tested. static void i2s_test_io_config(int mode) { @@ -136,7 +139,7 @@ static void i2s_test_io_config(int mode) * 1. i2s_driver_install * 2. i2s_set_pin */ -TEST_CASE("I2S basic driver install, uninstall, set pin test", "[i2s]") +TEST_CASE("I2S basic driver install, uninstall, set pin test", "[i2s_legacy]") { // dac, adc i2s i2s_config_t i2s_config = { @@ -183,7 +186,7 @@ TEST_CASE("I2S basic driver install, uninstall, set pin test", "[i2s]") TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, i2s_driver_uninstall(I2S_NUM_0)); } -TEST_CASE("I2S Loopback test(master tx and rx)", "[i2s]") +TEST_CASE("I2S Loopback test(master tx and rx)", "[i2s_legacy]") { // master driver installed and send data i2s_config_t master_i2s_config = { @@ -256,7 +259,7 @@ TEST_CASE("I2S Loopback test(master tx and rx)", "[i2s]") } #if SOC_I2S_SUPPORTS_TDM -TEST_CASE("I2S TDM Loopback test(master tx and rx)", "[i2s]") +TEST_CASE("I2S TDM Loopback test(master tx and rx)", "[i2s_legacy]") { // master driver installed and send data i2s_config_t master_i2s_config = { @@ -325,7 +328,7 @@ TEST_CASE("I2S TDM Loopback test(master tx and rx)", "[i2s]") #if SOC_I2S_NUM > 1 /* ESP32S2 and ESP32C3 has only single I2S port and hence following test cases are not applicable */ -TEST_CASE("I2S write and read test(master tx and slave rx)", "[i2s]") +TEST_CASE("I2S write and read test(master tx and slave rx)", "[i2s_legacy]") { // master driver installed and send data i2s_config_t master_i2s_config = { @@ -429,7 +432,7 @@ TEST_CASE("I2S write and read test(master tx and slave rx)", "[i2s]") i2s_driver_uninstall(I2S_NUM_1); } -TEST_CASE("I2S write and read test(master rx and slave tx)", "[i2s]") +TEST_CASE("I2S write and read test(master rx and slave tx)", "[i2s_legacy]") { // master driver installed and send data i2s_config_t master_i2s_config = { @@ -535,7 +538,7 @@ TEST_CASE("I2S write and read test(master rx and slave tx)", "[i2s]") } #endif -TEST_CASE("I2S memory leaking test", "[i2s]") +TEST_CASE("I2S memory leaking test", "[i2s_legacy]") { i2s_config_t master_i2s_config = { .mode = I2S_MODE_MASTER | I2S_MODE_RX, @@ -585,7 +588,7 @@ TEST_CASE("I2S memory leaking test", "[i2s]") * and the APLL clock generate for it. The TEST_CASE passes PERCENT_DIFF variation from the provided sample rate in APLL generated clock * The percentage difference calculated as (mod((obtained clock rate - desired clock rate)/(desired clock rate))) * 100. */ -TEST_CASE("I2S APLL clock variation test", "[i2s]") +TEST_CASE("I2S APLL clock variation test", "[i2s_legacy]") { i2s_pin_config_t pin_config = { .mck_io_num = -1, @@ -643,7 +646,7 @@ TEST_CASE("I2S APLL clock variation test", "[i2s]") #if SOC_I2S_SUPPORTS_ADC /* Only ESP32 need I2S adc/dac test */ -TEST_CASE("I2S adc test", "[i2s]") +TEST_CASE("I2S adc test", "[i2s_legacy]") { // init I2S ADC i2s_config_t i2s_config = { @@ -673,7 +676,7 @@ TEST_CASE("I2S adc test", "[i2s]") } else { gpio_set_pull_mode(ADC1_CHANNEL_4_IO, GPIO_PULLUP_ONLY); } - vTaskDelay(200 / portTICK_PERIOD_MS); + vTaskDelay(pdMS_TO_TICKS(200)); // read data from adc, will block until buffer is full i2s_read(I2S_NUM_0, (void *)i2sReadBuffer, 1024 * sizeof(uint16_t), &bytesRead, portMAX_DELAY); @@ -710,7 +713,7 @@ TEST_CASE("I2S adc test", "[i2s]") #endif #if SOC_I2S_SUPPORTS_DAC -TEST_CASE("I2S dac test", "[i2s]") +TEST_CASE("I2S dac test", "[i2s_legacy]") { // dac, adc i2s i2s_config_t i2s_config = { @@ -733,5 +736,3 @@ TEST_CASE("I2S dac test", "[i2s]") TEST_ESP_OK(i2s_driver_uninstall(I2S_NUM_0)); } #endif - -#endif //SOC_I2S_SUPPORTED diff --git a/components/driver/test_apps/i2s/sdkconfig.defaults b/components/driver/test_apps/i2s/sdkconfig.defaults new file mode 100644 index 0000000000..16e72deaf9 --- /dev/null +++ b/components/driver/test_apps/i2s/sdkconfig.defaults @@ -0,0 +1,3 @@ +CONFIG_I2S_SUPPRESS_DEPRECATE_WARN=y +CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN=y +CONFIG_ESP_TASK_WDT=n diff --git a/components/esp_hw_support/clk_ctrl_os.c b/components/esp_hw_support/clk_ctrl_os.c index 1d6ff03909..3cf14aebc1 100644 --- a/components/esp_hw_support/clk_ctrl_os.c +++ b/components/esp_hw_support/clk_ctrl_os.c @@ -121,4 +121,4 @@ esp_err_t periph_rtc_apll_freq_set(uint32_t expt_freq, uint32_t *real_freq) return ESP_OK; } -#endif // SOC_I2S_SUPPORTS_APLL +#endif // SOC_CLK_APLL_SUPPORTED diff --git a/components/esp_hw_support/include/clk_ctrl_os.h b/components/esp_hw_support/include/clk_ctrl_os.h index 88478663bb..9d1084c149 100644 --- a/components/esp_hw_support/include/clk_ctrl_os.h +++ b/components/esp_hw_support/include/clk_ctrl_os.h @@ -5,6 +5,7 @@ */ #include "soc/rtc.h" +#include "soc/soc_caps.h" #include "esp_err.h" #ifdef __cplusplus diff --git a/components/esp_lcd/src/esp_lcd_panel_io_i2s.c b/components/esp_lcd/src/esp_lcd_panel_io_i2s.c index f722463933..f341f2be36 100644 --- a/components/esp_lcd/src/esp_lcd_panel_io_i2s.c +++ b/components/esp_lcd/src/esp_lcd_panel_io_i2s.c @@ -152,7 +152,7 @@ esp_err_t esp_lcd_new_i80_bus(const esp_lcd_i80_bus_config_t *bus_config, esp_lc // LCD mode can't work with other modes at the same time, we need to register the driver object to the I2S platform int bus_id = -1; for (int i = 0; i < SOC_LCD_I80_BUSES; i++) { - if (i2s_priv_register_object(bus, i) == ESP_OK) { + if (i2s_platform_acquire_occupation(0, "esp_lcd_panel_io_i2s") == ESP_OK) { bus_id = i; break; } @@ -214,7 +214,7 @@ err: esp_intr_free(bus->intr); } if (bus->bus_id >= 0) { - i2s_priv_deregister_object(bus->bus_id); + i2s_platform_release_occupation(bus->bus_id); } if (bus->format_buffer) { free(bus->format_buffer); @@ -233,7 +233,7 @@ esp_err_t esp_lcd_del_i80_bus(esp_lcd_i80_bus_handle_t bus) ESP_GOTO_ON_FALSE(bus, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument"); ESP_GOTO_ON_FALSE(LIST_EMPTY(&bus->device_list), ESP_ERR_INVALID_STATE, err, TAG, "device list not empty"); int bus_id = bus->bus_id; - i2s_priv_deregister_object(bus_id); + i2s_platform_release_occupation(bus_id); esp_intr_free(bus->intr); if (bus->pm_lock) { esp_pm_lock_delete(bus->pm_lock); @@ -593,9 +593,9 @@ static esp_err_t i2s_lcd_select_periph_clock(esp_lcd_i80_bus_handle_t bus, lcd_c switch (src) { case LCD_CLK_SRC_PLL160M: bus->resolution_hz = 160000000 / LCD_PERIPH_CLOCK_PRE_SCALE; - i2s_ll_tx_clk_set_src(bus->hal.dev, I2S_CLK_D2CLK); + i2s_ll_tx_clk_set_src(bus->hal.dev, I2S_CLK_160M_PLL); #if CONFIG_PM_ENABLE - ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "i2s_bus_lcd", &bus->pm_lock); + ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "i2s_controller_lcd", &bus->pm_lock); ESP_RETURN_ON_ERROR(ret, TAG, "create ESP_PM_APB_FREQ_MAX lock failed"); ESP_LOGD(TAG, "installed ESP_PM_APB_FREQ_MAX lock"); #endif diff --git a/components/esp_lcd/test_apps/i80_lcd/main/test_i80_lcd_panel.c b/components/esp_lcd/test_apps/i80_lcd/main/test_i80_lcd_panel.c index 4d3be8bc5f..4062f7fae1 100644 --- a/components/esp_lcd/test_apps/i80_lcd/main/test_i80_lcd_panel.c +++ b/components/esp_lcd/test_apps/i80_lcd/main/test_i80_lcd_panel.c @@ -1,7 +1,7 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: CC0-1.0 + * SPDX-License-Identifier: Apache-2.0 */ #include @@ -18,7 +18,7 @@ #include "test_i80_board.h" #if SOC_I2S_LCD_I80_VARIANT -#include "driver/i2s.h" +#include "driver/i2s_controller.h" TEST_CASE("i80_and_i2s_driver_co-existence", "[lcd][i2s]") { @@ -42,17 +42,19 @@ TEST_CASE("i80_and_i2s_driver_co-existence", "[lcd][i2s]") }; TEST_ESP_OK(esp_lcd_new_i80_bus(&bus_config, &i80_bus)); - i2s_config_t i2s_config = { - .mode = I2S_MODE_MASTER | I2S_MODE_TX, - .sample_rate = 36000, - .bits_per_sample = 16, - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, - .communication_format = I2S_COMM_FORMAT_STAND_I2S, - .dma_desc_num = 6, - .dma_frame_num = 60, + + i2s_chan_handle_t tx_handle = NULL; + i2s_gpio_config_t i2s_pin = { + .mclk = I2S_GPIO_UNUSED, + .bclk = I2S_GPIO_UNUSED, + .ws = I2S_GPIO_UNUSED, + .dout = I2S_GPIO_UNUSED, + .din = I2S_GPIO_UNUSED }; + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + chan_cfg.id = 0; // I2S driver won't be installed as the same I2S port has been used by LCD - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, i2s_driver_install(0, &i2s_config, 0, NULL)); + TEST_ASSERT_EQUAL(ESP_ERR_NOT_FOUND, i2s_new_channel(&chan_cfg, &tx_handle, NULL)); TEST_ESP_OK(esp_lcd_del_i80_bus(i80_bus)); } #endif // SOC_I2S_LCD_I80_VARIANT @@ -459,3 +461,43 @@ TEST_CASE("lcd_panel_with_i80_interface_(st7789, 8bits)", "[lcd]") free(img); #undef TEST_IMG_SIZE } + +#if SOC_I2S_LCD_I80_VARIANT +#include "driver/i2s_controller.h" + +TEST_CASE("i80 and i2s driver coexistance", "[lcd][i2s]") +{ + esp_lcd_i80_bus_handle_t i80_bus = NULL; + esp_lcd_i80_bus_config_t bus_config = { + .dc_gpio_num = TEST_LCD_DC_GPIO, + .wr_gpio_num = TEST_LCD_PCLK_GPIO, + .data_gpio_nums = { + TEST_LCD_DATA0_GPIO, + TEST_LCD_DATA1_GPIO, + TEST_LCD_DATA2_GPIO, + TEST_LCD_DATA3_GPIO, + TEST_LCD_DATA4_GPIO, + TEST_LCD_DATA5_GPIO, + TEST_LCD_DATA6_GPIO, + TEST_LCD_DATA7_GPIO, + }, + .bus_width = 8, + .max_transfer_bytes = 20, + }; + TEST_ESP_OK(esp_lcd_new_i80_bus(&bus_config, &i80_bus)); + + i2s_gpio_config_t i2s_pin = { + .mclk = 0, + .bclk = 15, + .ws = 25, + .dout = 21, + .din = 22 + }; + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + chan_cfg.id = I2S_NUM_0; + i2s_chan_handle_t tx_handle; + // I2S driver won't be installed as the same I2S port has been used by LCD + TEST_ASSERT_EQUAL(ESP_ERR_NOT_FOUND, i2s_new_channel(&chan_cfg, &tx_handle, NULL)); + TEST_ESP_OK(esp_lcd_del_i80_bus(i80_bus)); +} +#endif // SOC_I2S_LCD_I80_VARIANT diff --git a/components/hal/adc_hal.c b/components/hal/adc_hal.c index 9af9079a76..efb28c154a 100644 --- a/components/hal/adc_hal.c +++ b/components/hal/adc_hal.c @@ -189,7 +189,7 @@ static void adc_hal_digi_sample_freq_config(adc_hal_dma_ctx_t *hal, uint32_t fre adc_ll_digi_controller_clk_div(ADC_LL_CLKM_DIV_NUM_DEFAULT, ADC_LL_CLKM_DIV_B_DEFAULT, ADC_LL_CLKM_DIV_A_DEFAULT); adc_ll_digi_clk_sel(0); //use APB #else - i2s_ll_rx_clk_set_src(hal->dev, I2S_CLK_D2CLK); /*!< Clock from PLL_D2_CLK(160M)*/ + i2s_ll_rx_clk_set_src(hal->dev, I2S_CLK_160M_PLL); /*!< Clock from PLL_D2_CLK(160M)*/ uint32_t bck = I2S_BASE_CLK / (ADC_LL_CLKM_DIV_NUM_DEFAULT + ADC_LL_CLKM_DIV_B_DEFAULT / ADC_LL_CLKM_DIV_A_DEFAULT) / 2 / freq; i2s_ll_set_raw_mclk_div(hal->dev, ADC_LL_CLKM_DIV_NUM_DEFAULT, ADC_LL_CLKM_DIV_A_DEFAULT, ADC_LL_CLKM_DIV_B_DEFAULT); i2s_ll_rx_set_bck_div_num(hal->dev, bck); diff --git a/components/hal/esp32/include/hal/i2s_ll.h b/components/hal/esp32/include/hal/i2s_ll.h index 82f1baffcb..f8f4aa197c 100644 --- a/components/hal/esp32/include/hal/i2s_ll.h +++ b/components/hal/esp32/include/hal/i2s_ll.h @@ -19,7 +19,6 @@ #include "soc/i2s_periph.h" #include "soc/i2s_struct.h" #include "hal/i2s_types.h" -#include "hal/i2s_types_priv.h" #ifdef __cplusplus extern "C" { diff --git a/components/hal/esp32c3/include/hal/i2s_ll.h b/components/hal/esp32c3/include/hal/i2s_ll.h index 686cd6bf50..860214db67 100644 --- a/components/hal/esp32c3/include/hal/i2s_ll.h +++ b/components/hal/esp32c3/include/hal/i2s_ll.h @@ -200,7 +200,7 @@ static inline void i2s_ll_tx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) * @brief Set RX source clock * * @param hw Peripheral I2S hardware instance address. - * @param src I2S source clock, ESP32-C3 only support `I2S_CLK_D2CLK` + * @param src I2S source clock, ESP32-C3 only support `I2S_CLK_160M_PLL` */ static inline void i2s_ll_rx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) { diff --git a/components/hal/esp32h2/include/hal/i2s_ll.h b/components/hal/esp32h2/include/hal/i2s_ll.h index cd8418dda1..f610367dfb 100644 --- a/components/hal/esp32h2/include/hal/i2s_ll.h +++ b/components/hal/esp32h2/include/hal/i2s_ll.h @@ -201,7 +201,7 @@ static inline void i2s_ll_tx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) * @brief Set RX source clock * * @param hw Peripheral I2S hardware instance address. - * @param src I2S source clock, ESP32-H2 only support `I2S_CLK_D2CLK` + * @param src I2S source clock, ESP32-H2 only support `I2S_CLK_160M_PLL` */ static inline void i2s_ll_rx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) { diff --git a/components/hal/esp32s3/include/hal/i2s_ll.h b/components/hal/esp32s3/include/hal/i2s_ll.h index 0d33d13de8..e2712aed7b 100644 --- a/components/hal/esp32s3/include/hal/i2s_ll.h +++ b/components/hal/esp32s3/include/hal/i2s_ll.h @@ -190,7 +190,7 @@ static inline void i2s_ll_rx_reset_fifo(i2s_dev_t *hw) * @brief Set TX source clock * * @param hw Peripheral I2S hardware instance address. - * @param src I2S source clock, ESP32-S3 only support `I2S_CLK_D2CLK` + * @param src I2S source clock, ESP32-S3 only support `I2S_CLK_160M_PLL` * TX and RX share the same clock setting */ static inline void i2s_ll_tx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) @@ -202,7 +202,7 @@ static inline void i2s_ll_tx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) * @brief Set RX source clock * * @param hw Peripheral I2S hardware instance address. - * @param src I2S source clock, ESP32-S3 only support `I2S_CLK_D2CLK` + * @param src I2S source clock, ESP32-S3 only support `I2S_CLK_160M_PLL` * TX and RX share the same clock setting */ static inline void i2s_ll_rx_clk_set_src(i2s_dev_t *hw, i2s_clock_src_t src) diff --git a/components/hal/i2s_hal.c b/components/hal/i2s_hal.c index f0fce8ff69..39af05752b 100644 --- a/components/hal/i2s_hal.c +++ b/components/hal/i2s_hal.c @@ -10,10 +10,6 @@ #include "soc/soc.h" #include "hal/i2s_hal.h" -#include "hal/i2s_std.h" -#include "hal/i2s_pdm.h" -#include "hal/i2s_tdm.h" - #if SOC_I2S_HW_VERSION_2 && SOC_I2S_SUPPORTS_PDM_TX /* PDM tx high pass filter cut-off frequency and coeffecients list * [0]: cut-off frequency; [1]: param0; [2]: param5 */ @@ -33,7 +29,7 @@ void i2s_hal_init(i2s_hal_context_t *hal, int port_id) hal->dev = I2S_LL_GET_HW(port_id); } -void i2s_hal_set_tx_clock(i2s_hal_context_t *hal, const i2s_clock_info_t *clk_info, i2s_clock_src_t clk_src) +void i2s_hal_set_tx_clock(i2s_hal_context_t *hal, const i2s_hal_clock_info_t *clk_info, i2s_clock_src_t clk_src) { #if SOC_I2S_HW_VERSION_2 i2s_ll_tx_enable_clock(hal->dev); @@ -44,7 +40,7 @@ void i2s_hal_set_tx_clock(i2s_hal_context_t *hal, const i2s_clock_info_t *clk_in i2s_ll_tx_set_bck_div_num(hal->dev, clk_info->bclk_div); } -void i2s_hal_set_rx_clock(i2s_hal_context_t *hal, const i2s_clock_info_t *clk_info, i2s_clock_src_t clk_src) +void i2s_hal_set_rx_clock(i2s_hal_context_t *hal, const i2s_hal_clock_info_t *clk_info, i2s_clock_src_t clk_src) { #if SOC_I2S_HW_VERSION_2 i2s_ll_rx_enable_clock(hal->dev); @@ -58,55 +54,52 @@ void i2s_hal_set_rx_clock(i2s_hal_context_t *hal, const i2s_clock_info_t *clk_in /*------------------------------------------------------------------------- | STD Specific Slot Configurations | -------------------------------------------------------------------------*/ -void i2s_hal_std_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_slot_config_t *slot_config) +void i2s_hal_std_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_cfg) { - i2s_std_slot_config_t *slot_cfg = (i2s_std_slot_config_t*)slot_config; uint32_t slot_bit_width = (int)slot_cfg->slot_bit_width < (int)slot_cfg->data_bit_width ? slot_cfg->data_bit_width : slot_cfg->slot_bit_width; i2s_ll_tx_reset(hal->dev); i2s_ll_tx_set_slave_mod(hal->dev, is_slave); //TX Slave i2s_ll_tx_set_sample_bit(hal->dev, slot_bit_width, slot_cfg->data_bit_width); i2s_ll_tx_enable_mono_mode(hal->dev, slot_cfg->slot_mode == I2S_SLOT_MODE_MONO); - i2s_ll_tx_enable_msb_shift(hal->dev, slot_cfg->bit_shift); - i2s_ll_tx_set_ws_width(hal->dev, slot_cfg->ws_width); - i2s_ll_tx_select_slot(hal->dev, slot_cfg->slot_sel); + i2s_ll_tx_enable_msb_shift(hal->dev, slot_cfg->std.bit_shift); + i2s_ll_tx_set_ws_width(hal->dev, slot_cfg->std.ws_width); #if SOC_I2S_HW_VERSION_1 - i2s_ll_tx_enable_msb_right(hal->dev, slot_cfg->msb_right); - i2s_ll_tx_enable_right_first(hal->dev, slot_cfg->ws_pol); + i2s_ll_tx_enable_msb_right(hal->dev, slot_cfg->std.msb_right); + i2s_ll_tx_enable_right_first(hal->dev, slot_cfg->std.ws_pol); /* Should always enable fifo */ i2s_ll_tx_force_enable_fifo_mod(hal->dev, true); #elif SOC_I2S_HW_VERSION_2 i2s_ll_tx_set_half_sample_bit(hal->dev, slot_bit_width); - i2s_ll_tx_set_ws_idle_pol(hal->dev, slot_cfg->ws_pol); - i2s_ll_tx_set_bit_order(hal->dev, slot_cfg->bit_order_lsb); - i2s_ll_tx_enable_left_align(hal->dev, slot_cfg->left_align); - i2s_ll_tx_enable_big_endian(hal->dev, slot_cfg->big_endian); + i2s_ll_tx_set_ws_idle_pol(hal->dev, slot_cfg->std.ws_pol); + i2s_ll_tx_set_bit_order(hal->dev, slot_cfg->std.bit_order_lsb); + i2s_ll_tx_enable_left_align(hal->dev, slot_cfg->std.left_align); + i2s_ll_tx_enable_big_endian(hal->dev, slot_cfg->std.big_endian); #endif } -void i2s_hal_std_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_slot_config_t *slot_config) +void i2s_hal_std_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_cfg) { - i2s_std_slot_config_t *slot_cfg = (i2s_std_slot_config_t*)slot_config; uint32_t slot_bit_width = (int)slot_cfg->slot_bit_width < (int)slot_cfg->data_bit_width ? slot_cfg->data_bit_width : slot_cfg->slot_bit_width; i2s_ll_rx_reset(hal->dev); i2s_ll_rx_set_slave_mod(hal->dev, is_slave); //RX Slave i2s_ll_rx_set_sample_bit(hal->dev, slot_bit_width, slot_cfg->data_bit_width); i2s_ll_rx_enable_mono_mode(hal->dev, slot_cfg->slot_mode == I2S_SLOT_MODE_MONO); - i2s_ll_rx_enable_msb_shift(hal->dev, slot_cfg->bit_shift); - i2s_ll_rx_set_ws_width(hal->dev, slot_cfg->ws_width); - i2s_ll_rx_select_slot(hal->dev, slot_cfg->slot_sel); + i2s_ll_rx_enable_msb_shift(hal->dev, slot_cfg->std.bit_shift); + i2s_ll_rx_set_ws_width(hal->dev, slot_cfg->std.ws_width); + i2s_ll_rx_select_slot(hal->dev, slot_cfg->std.slot_sel); #if SOC_I2S_HW_VERSION_1 - i2s_ll_rx_enable_msb_right(hal->dev, slot_cfg->msb_right); - i2s_ll_rx_enable_right_first(hal->dev, slot_cfg->ws_pol); + i2s_ll_rx_enable_msb_right(hal->dev, slot_cfg->std.msb_right); + i2s_ll_rx_enable_right_first(hal->dev, slot_cfg->std.ws_pol); /* Should always enable fifo */ i2s_ll_rx_force_enable_fifo_mod(hal->dev, true); #elif SOC_I2S_HW_VERSION_2 i2s_ll_rx_set_half_sample_bit(hal->dev, slot_bit_width); - i2s_ll_rx_set_ws_idle_pol(hal->dev, slot_cfg->ws_pol); - i2s_ll_rx_set_bit_order(hal->dev, slot_cfg->bit_order_lsb); - i2s_ll_rx_enable_left_align(hal->dev, slot_cfg->left_align); - i2s_ll_rx_enable_big_endian(hal->dev, slot_cfg->big_endian); + i2s_ll_rx_set_ws_idle_pol(hal->dev, slot_cfg->std.ws_pol); + i2s_ll_rx_set_bit_order(hal->dev, slot_cfg->std.bit_order_lsb); + i2s_ll_rx_enable_left_align(hal->dev, slot_cfg->std.left_align); + i2s_ll_rx_enable_big_endian(hal->dev, slot_cfg->std.big_endian); #endif } @@ -124,9 +117,8 @@ void i2s_hal_std_enable_rx_channel(i2s_hal_context_t *hal) | PDM Specific Slot Configurations | -------------------------------------------------------------------------*/ #if SOC_I2S_SUPPORTS_PDM_TX -void i2s_hal_pdm_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_slot_config_t *slot_config) +void i2s_hal_pdm_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_cfg) { - i2s_pdm_tx_slot_config_t *slot_cfg = (i2s_pdm_tx_slot_config_t *)slot_config; uint32_t slot_bit_width = (int)slot_cfg->slot_bit_width < (int)slot_cfg->data_bit_width ? slot_cfg->data_bit_width : slot_cfg->slot_bit_width; i2s_ll_tx_reset(hal->dev); @@ -134,21 +126,21 @@ void i2s_hal_pdm_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_sl i2s_ll_tx_set_sample_bit(hal->dev, slot_bit_width, slot_cfg->data_bit_width); i2s_ll_tx_enable_mono_mode(hal->dev, slot_cfg->slot_mode == I2S_SLOT_MODE_MONO); - i2s_ll_tx_set_pdm_prescale(hal->dev, slot_cfg->sd_prescale); - i2s_ll_tx_set_pdm_hp_scale(hal->dev, slot_cfg->hp_scale); - i2s_ll_tx_set_pdm_lp_scale(hal->dev, slot_cfg->lp_scale); - i2s_ll_tx_set_pdm_sinc_scale(hal->dev, slot_cfg->sinc_scale); - i2s_ll_tx_set_pdm_sd_scale(hal->dev, slot_cfg->sd_scale); + i2s_ll_tx_set_pdm_prescale(hal->dev, slot_cfg->pdm_tx.sd_prescale); + i2s_ll_tx_set_pdm_hp_scale(hal->dev, slot_cfg->pdm_tx.hp_scale); + i2s_ll_tx_set_pdm_lp_scale(hal->dev, slot_cfg->pdm_tx.lp_scale); + i2s_ll_tx_set_pdm_sinc_scale(hal->dev, slot_cfg->pdm_tx.sinc_scale); + i2s_ll_tx_set_pdm_sd_scale(hal->dev, slot_cfg->pdm_tx.sd_scale); #if SOC_I2S_HW_VERSION_1 i2s_ll_tx_force_enable_fifo_mod(hal->dev, true); #elif SOC_I2S_HW_VERSION_2 /* Still need to enable the first 2 TDM channel mask to get the correct number of frame */ i2s_ll_tx_set_active_chan_mask(hal->dev, I2S_TDM_SLOT0 | I2S_TDM_SLOT1); - i2s_ll_tx_enable_pdm_hp_filter(hal->dev, slot_cfg->hp_en); + i2s_ll_tx_enable_pdm_hp_filter(hal->dev, slot_cfg->pdm_tx.hp_en); uint8_t cnt = 0; float min = 1000; - float expt_cut_off = slot_cfg->hp_cut_off_freq_hz; + float expt_cut_off = slot_cfg->pdm_tx.hp_cut_off_freq_hz; /* Find the closest cut-off frequency and its coefficients */ for (int i = 0; i < 21; i++) { float tmp = cut_off_coef[i][0] < expt_cut_off ? expt_cut_off - cut_off_coef[i][0] : cut_off_coef[i][0] - expt_cut_off; @@ -159,9 +151,9 @@ void i2s_hal_pdm_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_sl } i2s_ll_tx_set_pdm_hp_filter_param0(hal->dev, cut_off_coef[cnt][1]); i2s_ll_tx_set_pdm_hp_filter_param5(hal->dev, cut_off_coef[cnt][2]); - i2s_ll_tx_enable_pdm_sd_codec(hal->dev, slot_cfg->sd_en); - i2s_ll_tx_set_pdm_sd_dither(hal->dev, slot_cfg->sd_dither); - i2s_ll_tx_set_pdm_sd_dither2(hal->dev, slot_cfg->sd_dither2); + i2s_ll_tx_enable_pdm_sd_codec(hal->dev, slot_cfg->pdm_tx.sd_en); + i2s_ll_tx_set_pdm_sd_dither(hal->dev, slot_cfg->pdm_tx.sd_dither); + i2s_ll_tx_set_pdm_sd_dither2(hal->dev, slot_cfg->pdm_tx.sd_dither2); #endif } @@ -172,9 +164,8 @@ void i2s_hal_pdm_enable_tx_channel(i2s_hal_context_t *hal) #endif #if SOC_I2S_SUPPORTS_PDM_RX -void i2s_hal_pdm_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_slot_config_t *slot_config) +void i2s_hal_pdm_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_cfg) { - i2s_pdm_rx_slot_config_t *slot_cfg = (i2s_pdm_rx_slot_config_t *)slot_config; uint32_t slot_bit_width = (int)slot_cfg->slot_bit_width < (int)slot_cfg->data_bit_width ? slot_cfg->data_bit_width : slot_cfg->slot_bit_width; i2s_ll_rx_reset(hal->dev); @@ -199,74 +190,72 @@ void i2s_hal_pdm_enable_rx_channel(i2s_hal_context_t *hal) | TDM Specific Slot Configurations | -------------------------------------------------------------------------*/ #if SOC_I2S_SUPPORTS_TDM -void i2s_hal_tdm_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_slot_config_t *slot_config) +void i2s_hal_tdm_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_cfg) { - i2s_tdm_slot_config_t *slot_cfg = (i2s_tdm_slot_config_t*)slot_config; uint32_t slot_bit_width = (int)slot_cfg->slot_bit_width < (int)slot_cfg->data_bit_width ? slot_cfg->data_bit_width : slot_cfg->slot_bit_width; uint32_t cnt; - uint32_t msk = slot_cfg->slot_mask; + uint32_t msk = slot_cfg->tdm.slot_mask; /* Get the maximum slot number */ cnt = 32 - __builtin_clz(msk); /* There should be at least 2 slots in total even for mono mode */ cnt = cnt < 2 ? 2 : cnt; - uint32_t total_slot = slot_cfg->total_slot > cnt ? slot_cfg->total_slot : cnt; + uint32_t total_slot = slot_cfg->tdm.total_slot > cnt ? slot_cfg->tdm.total_slot : cnt; i2s_ll_tx_reset(hal->dev); i2s_ll_tx_set_slave_mod(hal->dev, is_slave); //TX Slave i2s_ll_tx_set_sample_bit(hal->dev, slot_bit_width, slot_cfg->data_bit_width); i2s_ll_tx_enable_mono_mode(hal->dev, slot_cfg->slot_mode == I2S_SLOT_MODE_MONO); - i2s_ll_tx_enable_msb_shift(hal->dev, slot_cfg->bit_shift); - if (slot_cfg->ws_width == I2S_TDM_AUTO_WS_WIDTH) { + i2s_ll_tx_enable_msb_shift(hal->dev, slot_cfg->tdm.bit_shift); + if (slot_cfg->tdm.ws_width == I2S_TDM_AUTO_WS_WIDTH) { i2s_ll_tx_set_ws_width(hal->dev, (total_slot * slot_bit_width) / 2); } else { - i2s_ll_tx_set_ws_width(hal->dev, slot_cfg->ws_width); + i2s_ll_tx_set_ws_width(hal->dev, slot_cfg->tdm.ws_width); } - i2s_ll_tx_set_ws_idle_pol(hal->dev, slot_cfg->ws_pol); + i2s_ll_tx_set_ws_idle_pol(hal->dev, slot_cfg->tdm.ws_pol); i2s_ll_tx_set_chan_num(hal->dev, total_slot); /* In mono mode, there only should be one slot enabled, other inactive slots will transmit same data as enabled slot */ i2s_ll_tx_set_active_chan_mask(hal->dev, (slot_cfg->slot_mode == I2S_SLOT_MODE_MONO) ? - I2S_TDM_SLOT0 : (uint32_t)slot_cfg->slot_mask); - i2s_ll_tx_set_skip_mask(hal->dev, slot_cfg->skip_mask); + I2S_TDM_SLOT0 : (uint32_t)slot_cfg->tdm.slot_mask); + i2s_ll_tx_set_skip_mask(hal->dev, slot_cfg->tdm.skip_mask); i2s_ll_tx_set_half_sample_bit(hal->dev, total_slot * slot_bit_width / 2); - i2s_ll_tx_set_bit_order(hal->dev, slot_cfg->bit_order_lsb); - i2s_ll_tx_enable_left_align(hal->dev, slot_cfg->left_align); - i2s_ll_tx_enable_big_endian(hal->dev, slot_cfg->big_endian); + i2s_ll_tx_set_bit_order(hal->dev, slot_cfg->tdm.bit_order_lsb); + i2s_ll_tx_enable_left_align(hal->dev, slot_cfg->tdm.left_align); + i2s_ll_tx_enable_big_endian(hal->dev, slot_cfg->tdm.big_endian); } -void i2s_hal_tdm_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_slot_config_t *slot_config) +void i2s_hal_tdm_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_cfg) { - i2s_tdm_slot_config_t *slot_cfg = (i2s_tdm_slot_config_t*)slot_config; uint32_t slot_bit_width = (int)slot_cfg->slot_bit_width < (int)slot_cfg->data_bit_width ? slot_cfg->data_bit_width : slot_cfg->slot_bit_width; uint32_t cnt; - uint32_t msk = slot_cfg->slot_mask; + uint32_t msk = slot_cfg->tdm.slot_mask; for (cnt = 0; msk; cnt++, msk >>= 1); /* Get the maximum slot number */ cnt = 32 - __builtin_clz(msk); /* There should be at least 2 slots in total even for mono mode */ cnt = cnt < 2 ? 2 : cnt; - uint32_t total_slot = slot_cfg->total_slot > cnt ? slot_cfg->total_slot : cnt; + uint32_t total_slot = slot_cfg->tdm.total_slot > cnt ? slot_cfg->tdm.total_slot : cnt; i2s_ll_rx_reset(hal->dev); i2s_ll_rx_set_slave_mod(hal->dev, is_slave); //RX Slave i2s_ll_rx_set_sample_bit(hal->dev, slot_bit_width, slot_cfg->data_bit_width); i2s_ll_rx_enable_mono_mode(hal->dev, slot_cfg->slot_mode == I2S_SLOT_MODE_MONO); - i2s_ll_rx_enable_msb_shift(hal->dev, slot_cfg->bit_shift); - if (slot_cfg->ws_width == I2S_TDM_AUTO_WS_WIDTH) { + i2s_ll_rx_enable_msb_shift(hal->dev, slot_cfg->tdm.bit_shift); + if (slot_cfg->tdm.ws_width == I2S_TDM_AUTO_WS_WIDTH) { i2s_ll_rx_set_ws_width(hal->dev, (total_slot * slot_bit_width) / 2); } else { - i2s_ll_rx_set_ws_width(hal->dev, slot_cfg->ws_width); + i2s_ll_rx_set_ws_width(hal->dev, slot_cfg->tdm.ws_width); } - i2s_ll_rx_set_ws_idle_pol(hal->dev, slot_cfg->ws_pol); + i2s_ll_rx_set_ws_idle_pol(hal->dev, slot_cfg->tdm.ws_pol); i2s_ll_rx_set_chan_num(hal->dev, total_slot); /* In mono mode, there only should be one slot enabled, other inactive slots will transmit same data as enabled slot */ i2s_ll_rx_set_active_chan_mask(hal->dev, (slot_cfg->slot_mode == I2S_SLOT_MODE_MONO) ? - I2S_TDM_SLOT0 : (uint32_t)slot_cfg->slot_mask); + I2S_TDM_SLOT0 : (uint32_t)slot_cfg->tdm.slot_mask); i2s_ll_rx_set_half_sample_bit(hal->dev, total_slot * slot_bit_width / 2); - i2s_ll_rx_set_bit_order(hal->dev, slot_cfg->bit_order_lsb); - i2s_ll_rx_enable_left_align(hal->dev, slot_cfg->left_align); - i2s_ll_rx_enable_big_endian(hal->dev, slot_cfg->big_endian); + i2s_ll_rx_set_bit_order(hal->dev, slot_cfg->tdm.bit_order_lsb); + i2s_ll_rx_enable_left_align(hal->dev, slot_cfg->tdm.left_align); + i2s_ll_rx_enable_big_endian(hal->dev, slot_cfg->tdm.big_endian); } void i2s_hal_tdm_enable_tx_channel(i2s_hal_context_t *hal) diff --git a/components/hal/include/hal/i2s_hal.h b/components/hal/include/hal/i2s_hal.h index 0de6904552..54a424b17b 100644 --- a/components/hal/include/hal/i2s_hal.h +++ b/components/hal/include/hal/i2s_hal.h @@ -17,23 +17,12 @@ #include "soc/soc_caps.h" #include "hal/i2s_types.h" -#include "hal/i2s_types_priv.h" #include "hal/i2s_ll.h" #ifdef __cplusplus extern "C" { #endif -/** - * @brief General clock configuration information - * @note It is a general purpose struct, not supposed to be used directly by user - */ -typedef struct { - uint32_t sample_rate_hz; /*!< I2S sample rate */ - i2s_clock_src_t clk_src; /*!< Choose clock source */ - i2s_mclk_multiple_t mclk_multiple; /*!< The multiple of mclk to the sample rate */ -} i2s_clk_config_t; - /** * @brief General slot configuration information * @note It is a general purpose struct, not supposed to be used directly by user @@ -43,7 +32,58 @@ typedef struct { i2s_data_bit_width_t data_bit_width; /*!< I2S sample data bit width (valid data bits per sample) */ i2s_slot_bit_width_t slot_bit_width; /*!< I2S slot bit width (total bits per slot) */ i2s_slot_mode_t slot_mode; /*!< Set mono or stereo mode with I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO */ -} i2s_slot_config_t; + union { + /* STD configurations */ + struct { + uint32_t ws_width; /*!< WS signal width (i.e. the number of bclk ticks that ws signal is high) */ + bool ws_pol; /*!< WS signal polarity, set true to enable high lever first */ + bool bit_shift; /*!< Set to enbale bit shift in Philip mode */ + #if SOC_I2S_HW_VERSION_1 // For esp32/esp32-s2 + bool msb_right; /*!< Set to place right channel data at the MSB in the FIFO */ + #else + bool left_align; /*!< Set to enable left alignment */ + bool big_endian; /*!< Set to enable big endian */ + bool bit_order_lsb; /*!< Set to enable lsb first */ + #endif + } std; + + #if SOC_I2S_SUPPORTS_TDM + /* TDM configurations */ + struct { + uint32_t ws_width; /*!< WS signal width ((i.e. the number of bclk ticks that ws signal is high)) */ + bool ws_pol; /*!< WS signal polarity, set true to enable high lever first */ + bool bit_shift; /*!< Set true to enable bit shift in Philip mode */ + + bool left_align; /*!< Set true to enable left alignment */ + bool big_endian; /*!< Set true to enable big endian */ + bool bit_order_lsb; /*!< Set true to enable lsb first */ + + bool skip_mask; /*!< Set true to enable skip mask. If it is enabled, only the data of the enabled channels will be sent, otherwise all data stored in DMA TX buffer will be sent */ + i2s_tdm_slot_mask_t slot_mask; /*!< Slot mask. Activating slots by setting 1 to corresponding bits. When the activated slots is not consecutive, those data in unactivated slots will be ignored */ + uint32_t total_slot; /*!< I2S total number of slots. If it is smaller than the biggest activated channel number, it will be set to this number automatically. */ + } tdm; + #endif + + #if SOC_I2S_SUPPORTS_PDM_TX + /* PDM TX configurations */ + struct { + uint32_t sd_prescale; /*!< Sigma-delta filter prescale */ + i2s_pdm_sig_scale_t sd_scale; /*!< Sigma-delta filter scaling value */ + i2s_pdm_sig_scale_t hp_scale; /*!< High pass filter scaling value */ + i2s_pdm_sig_scale_t lp_scale; /*!< Low pass filter scaling value */ + i2s_pdm_sig_scale_t sinc_scale; /*!< Sinc filter scaling value */ + #if SOC_I2S_HW_VERSION_2 + bool sd_en; /*!< Sigma-delta filter enable */ + bool hp_en; /*!< High pass filter enable */ + float hp_cut_off_freq_hz; /*!< High pass filter cut-off frequency, range 23.3Hz ~ 185Hz, see cut-off frequency sheet above */ + uint32_t sd_dither; /*!< Sigma-delta filter dither */ + uint32_t sd_dither2; /*!< Sigma-delta filter dither2 */ + #endif // SOC_I2S_HW_VERSION_2 + } pdm_tx; + #endif + }; + +} i2s_hal_slot_config_t; /** * @brief I2S clock configuration @@ -54,7 +94,7 @@ typedef struct { uint32_t bclk; /*!< I2S bit clock */ uint16_t mclk_div; /*!< I2S master clock division */ uint16_t bclk_div; /*!< I2S bit clock division*/ -} i2s_clock_info_t; +} i2s_hal_clock_info_t; /** * Context that should be maintained by both the driver and the HAL @@ -78,7 +118,7 @@ void i2s_hal_init(i2s_hal_context_t *hal, int port_id); * @param clk_info clock information * @param clk_src clock source */ -void i2s_hal_set_tx_clock(i2s_hal_context_t *hal, const i2s_clock_info_t *clk_info, i2s_clock_src_t clk_src); +void i2s_hal_set_tx_clock(i2s_hal_context_t *hal, const i2s_hal_clock_info_t *clk_info, i2s_clock_src_t clk_src); /** * @brief Set rx channel clock @@ -87,7 +127,7 @@ void i2s_hal_set_tx_clock(i2s_hal_context_t *hal, const i2s_clock_info_t *clk_in * @param clk_info clock information * @param clk_src clock source */ -void i2s_hal_set_rx_clock(i2s_hal_context_t *hal, const i2s_clock_info_t *clk_info, i2s_clock_src_t clk_src); +void i2s_hal_set_rx_clock(i2s_hal_context_t *hal, const i2s_hal_clock_info_t *clk_info, i2s_clock_src_t clk_src); /*------------------------------------------------------------------------- @@ -100,7 +140,7 @@ void i2s_hal_set_rx_clock(i2s_hal_context_t *hal, const i2s_clock_info_t *clk_in * @param is_slave If is slave role * @param slot_config General slot configuration pointer, but will specified to i2s standard mode */ -void i2s_hal_std_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_slot_config_t *slot_config); +void i2s_hal_std_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_config); /** * @brief Set rx slot to standard mode @@ -109,7 +149,7 @@ void i2s_hal_std_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_sl * @param is_slave If is slave role * @param slot_config General slot configuration pointer, but will specified to i2s standard mode */ -void i2s_hal_std_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_slot_config_t *slot_config); +void i2s_hal_std_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_config); /** * @brief Enable tx channel as standard mode @@ -138,7 +178,7 @@ void i2s_hal_std_enable_rx_channel(i2s_hal_context_t *hal); * @param is_slave If is slave role * @param slot_config General slot configuration pointer, but will specified to i2s pdm tx mode */ -void i2s_hal_pdm_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_slot_config_t *slot_config); +void i2s_hal_pdm_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_config); /** * @brief Enable tx channel as pdm mode @@ -156,7 +196,7 @@ void i2s_hal_pdm_enable_tx_channel(i2s_hal_context_t *hal); * @param is_slave If is slave role * @param slot_config General slot configuration pointer, but will specified to i2s pdm rx mode */ -void i2s_hal_pdm_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_slot_config_t *slot_config); +void i2s_hal_pdm_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_config); /** * @brief Enable rx channel as pdm mode @@ -178,7 +218,7 @@ void i2s_hal_pdm_enable_rx_channel(i2s_hal_context_t *hal); * @param is_slave If is slave role * @param slot_config General slot configuration pointer, but will specified to i2s tdm mode */ -void i2s_hal_tdm_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_slot_config_t *slot_config); +void i2s_hal_tdm_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_config); /** * @brief Set rx slot to tdm mode @@ -187,7 +227,7 @@ void i2s_hal_tdm_set_tx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_sl * @param is_slave If is slave role * @param slot_config General slot configuration pointer, but will specified to i2s tdm mode */ -void i2s_hal_tdm_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_slot_config_t *slot_config); +void i2s_hal_tdm_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_hal_slot_config_t *slot_config); /** * @brief Enable tx channel as tdm mode @@ -261,7 +301,7 @@ void i2s_hal_tdm_enable_rx_channel(i2s_hal_context_t *hal); #define i2s_hal_rx_reset_fifo(hal) i2s_ll_rx_reset_fifo((hal)->dev) -#if !SOC_GDMA_SUPPORTED +#if !SOC_I2S_SUPPORTS_GDMA /** * @brief Enable I2S TX DMA * diff --git a/components/hal/include/hal/i2s_types.h b/components/hal/include/hal/i2s_types.h index dcf0ab4d0b..5f60a408b2 100644 --- a/components/hal/include/hal/i2s_types.h +++ b/components/hal/include/hal/i2s_types.h @@ -10,6 +10,7 @@ #include #include #include +#include "esp_bit_defs.h" #include "soc/soc_caps.h" #ifdef __cplusplus @@ -17,149 +18,113 @@ extern "C" { #endif /** - * @brief I2S bit width per sample. - * + * @brief I2S controller port number, the max port number is (I2S_NUM_MAX -1). */ typedef enum { - I2S_BITS_PER_SAMPLE_8BIT = 8, /*!< data bit-width: 8 */ - I2S_BITS_PER_SAMPLE_16BIT = 16, /*!< data bit-width: 16 */ - I2S_BITS_PER_SAMPLE_24BIT = 24, /*!< data bit-width: 24 */ - I2S_BITS_PER_SAMPLE_32BIT = 32, /*!< data bit-width: 32 */ -} i2s_bits_per_sample_t; + I2S_NUM_0 = 0, /*!< I2S controller port 0 */ +#if SOC_I2S_NUM > 1 + I2S_NUM_1 = 1, /*!< I2S controller port 1 */ +#endif + I2S_NUM_MAX, /*!< I2S controller port max */ + I2S_NUM_AUTO, /*!< Select whichever port is available */ +} i2s_port_t; /** - * @brief I2S bit width per chan. - * + * @brief I2S controller communication mode */ typedef enum { - I2S_BITS_PER_CHAN_DEFAULT = (0), /*!< channel bit-width equals to data bit-width */ - I2S_BITS_PER_CHAN_8BIT = (8), /*!< channel bit-width: 8 */ - I2S_BITS_PER_CHAN_16BIT = (16), /*!< channel bit-width: 16 */ - I2S_BITS_PER_CHAN_24BIT = (24), /*!< channel bit-width: 24 */ - I2S_BITS_PER_CHAN_32BIT = (32), /*!< channel bit-width: 32 */ -} i2s_bits_per_chan_t; - -/** - * @brief I2S channel. - * - */ -typedef enum { - I2S_CHANNEL_MONO = 1, /*!< I2S channel (mono), one channel activated. In this mode, you only need to send one channel data but the fifo will copy same data for the other unactivated channels automatically, then both channels will transmit same data. */ - I2S_CHANNEL_STEREO = 2, /*!< I2S channel (stereo), two (or more) channels activated. In this mode, these channels will transmit different data. */ + I2S_COMM_MODE_STD, /*!< I2S controller using standard communication mode, support philip/MSB/PCM format */ +#if SOC_I2S_SUPPORTS_PDM + I2S_COMM_MODE_PDM, /*!< I2S controller using PDM communication mode, support PDM output or input */ +#endif #if SOC_I2S_SUPPORTS_TDM - // Bit map of activated chan. - // There are 16 channels in TDM mode. - // For TX module, only the activated channel send the audio data, the unactivated channel send a constant(configurable) or will be skiped if 'skip_msk' is set. - // For RX module, only receive the audio data in activated channels, the data in unactivated channels will be ignored. - // the bit map of activated channel can not exceed the maximum enabled channel number (i.e. 0x10000 << total_chan_num). - // e.g: active_chan_mask = (I2S_TDM_ACTIVE_CH0 | I2S_TDM_ACTIVE_CH3), here the active_chan_number is 2 and total_chan_num is not supposed to be smaller than 4. - I2S_TDM_ACTIVE_CH0 = (0x1 << 16), /*!< I2S channel 0 activated */ - I2S_TDM_ACTIVE_CH1 = (0x1 << 17), /*!< I2S channel 1 activated */ - I2S_TDM_ACTIVE_CH2 = (0x1 << 18), /*!< I2S channel 2 activated */ - I2S_TDM_ACTIVE_CH3 = (0x1 << 19), /*!< I2S channel 3 activated */ - I2S_TDM_ACTIVE_CH4 = (0x1 << 20), /*!< I2S channel 4 activated */ - I2S_TDM_ACTIVE_CH5 = (0x1 << 21), /*!< I2S channel 5 activated */ - I2S_TDM_ACTIVE_CH6 = (0x1 << 22), /*!< I2S channel 6 activated */ - I2S_TDM_ACTIVE_CH7 = (0x1 << 23), /*!< I2S channel 7 activated */ - I2S_TDM_ACTIVE_CH8 = (0x1 << 24), /*!< I2S channel 8 activated */ - I2S_TDM_ACTIVE_CH9 = (0x1 << 25), /*!< I2S channel 9 activated */ - I2S_TDM_ACTIVE_CH10 = (0x1 << 26), /*!< I2S channel 10 activated */ - I2S_TDM_ACTIVE_CH11 = (0x1 << 27), /*!< I2S channel 11 activated */ - I2S_TDM_ACTIVE_CH12 = (0x1 << 28), /*!< I2S channel 12 activated */ - I2S_TDM_ACTIVE_CH13 = (0x1 << 29), /*!< I2S channel 13 activated */ - I2S_TDM_ACTIVE_CH14 = (0x1 << 30), /*!< I2S channel 14 activated */ - I2S_TDM_ACTIVE_CH15 = (0x1 << 31), /*!< I2S channel 15 activated */ + I2S_COMM_MODE_TDM, /*!< I2S controller using TDM communication mode, support up to 16 slots per frame */ #endif -} i2s_channel_t; + I2S_COMM_MODE_NONE, /*!< Unspecific I2S controller mode */ +} i2s_comm_mode_t; /** - * @brief I2S communication standard format + * @brief I2S channel slot mode + */ +typedef enum { + I2S_SLOT_MODE_MONO = 1, /*!< I2S channel slot format mono, transmit same data in all slots for tx mode, only receive the data in the first slots for rx mode. */ + I2S_SLOT_MODE_STEREO = 2, /*!< I2S channel slot format stereo, transmit different data in different slots for tx mode, receive the data in all slots for rx mode. */ +} i2s_slot_mode_t; + +/** + * @brief I2S slot select in standard mode + */ +typedef enum { + I2S_STD_SLOT_ONLY_LEFT = 0x01, /*!< I2S only transmits or receives left slot */ + I2S_STD_SLOT_ONLY_RIGHT = 0x02, /*!< I2S only transmits or receives right slot */ + I2S_STD_SLOT_LEFT_RIGHT = 0x03, /*!< I2S only transmits or receives both left and right slot */ +} i2s_std_slot_sel_t; + +/** + * @brief I2S channel direction + */ +typedef enum { + I2S_DIR_RX = BIT(0), /*!< I2S channel direction RX */ + I2S_DIR_TX = BIT(1), /*!< I2S channel direction TX */ +} i2s_dir_t; + +/** + * @brief I2S controller role + */ +typedef enum { + I2S_ROLE_MASTER, /*!< I2S controller master role, bclk and ws signal will be set to output */ + I2S_ROLE_SLAVE /*!< I2S controller slave role, bclk and ws signal will be set to input */ +} i2s_role_t; + +/** + * @brief Available data bit width in one slot + */ +typedef enum { + I2S_DATA_BIT_WIDTH_8BIT = 8, /*!< I2S channel data bit-width: 8 */ + I2S_DATA_BIT_WIDTH_16BIT = 16, /*!< I2S channel data bit-width: 16 */ + I2S_DATA_BIT_WIDTH_24BIT = 24, /*!< I2S channel data bit-width: 24 */ + I2S_DATA_BIT_WIDTH_32BIT = 32, /*!< I2S channel data bit-width: 32 */ +} i2s_data_bit_width_t; + +/** + * @brief Total slot bit width in one slot * */ typedef enum { - I2S_COMM_FORMAT_STAND_I2S = 0X01, /*!< I2S communication I2S Philips standard, data launch at second BCK*/ - I2S_COMM_FORMAT_STAND_MSB = 0X02, /*!< I2S communication MSB alignment standard, data launch at first BCK*/ - I2S_COMM_FORMAT_STAND_PCM_SHORT = 0x04, /*!< PCM Short standard, also known as DSP mode. The period of synchronization signal (WS) is 1 bck cycle.*/ - I2S_COMM_FORMAT_STAND_PCM_LONG = 0x0C, /*!< PCM Long standard. The period of synchronization signal (WS) is channel_bit*bck cycles.*/ - I2S_COMM_FORMAT_STAND_MAX, /*!< standard max*/ - - //old definition will be removed in the future. - I2S_COMM_FORMAT_I2S __attribute__((deprecated)) = 0x01, /*!< I2S communication format I2S, correspond to `I2S_COMM_FORMAT_STAND_I2S`*/ - I2S_COMM_FORMAT_I2S_MSB __attribute__((deprecated)) = 0x01, /*!< I2S format MSB, (I2S_COMM_FORMAT_I2S |I2S_COMM_FORMAT_I2S_MSB) correspond to `I2S_COMM_FORMAT_STAND_I2S`*/ - I2S_COMM_FORMAT_I2S_LSB __attribute__((deprecated)) = 0x02, /*!< I2S format LSB, (I2S_COMM_FORMAT_I2S |I2S_COMM_FORMAT_I2S_LSB) correspond to `I2S_COMM_FORMAT_STAND_MSB`*/ - I2S_COMM_FORMAT_PCM __attribute__((deprecated)) = 0x04, /*!< I2S communication format PCM, correspond to `I2S_COMM_FORMAT_STAND_PCM_SHORT`*/ - I2S_COMM_FORMAT_PCM_SHORT __attribute__((deprecated)) = 0x04, /*!< PCM Short, (I2S_COMM_FORMAT_PCM | I2S_COMM_FORMAT_PCM_SHORT) correspond to `I2S_COMM_FORMAT_STAND_PCM_SHORT`*/ - I2S_COMM_FORMAT_PCM_LONG __attribute__((deprecated)) = 0x08, /*!< PCM Long, (I2S_COMM_FORMAT_PCM | I2S_COMM_FORMAT_PCM_LONG) correspond to `I2S_COMM_FORMAT_STAND_PCM_LONG`*/ -} i2s_comm_format_t; - -/** - * @brief I2S channel format type - */ -typedef enum { - I2S_CHANNEL_FMT_RIGHT_LEFT, /*!< Separated left and right channel */ - I2S_CHANNEL_FMT_ALL_RIGHT, /*!< Load right channel data in both two channels */ - I2S_CHANNEL_FMT_ALL_LEFT, /*!< Load left channel data in both two channels */ - I2S_CHANNEL_FMT_ONLY_RIGHT, /*!< Only load data in right channel (mono mode) */ - I2S_CHANNEL_FMT_ONLY_LEFT, /*!< Only load data in left channel (mono mode) */ -#if SOC_I2S_SUPPORTS_TDM - // Multiple channels are available with TDM feature - I2S_CHANNEL_FMT_MULTIPLE, /*!< More than two channels are used */ -#endif -} i2s_channel_fmt_t; - -/** - * @brief I2S Mode - */ -typedef enum { - I2S_MODE_MASTER = (0x1 << 0), /*!< Master mode*/ - I2S_MODE_SLAVE = (0x1 << 1), /*!< Slave mode*/ - I2S_MODE_TX = (0x1 << 2), /*!< TX mode*/ - I2S_MODE_RX = (0x1 << 3), /*!< RX mode*/ -#if SOC_I2S_SUPPORTS_DAC - //built-in DAC functions are only supported on I2S0 for ESP32 chip. - I2S_MODE_DAC_BUILT_IN = (0x1 << 4), /*!< Output I2S data to built-in DAC, no matter the data format is 16bit or 32 bit, the DAC module will only take the 8bits from MSB*/ -#endif // SOC_I2S_SUPPORTS_DAC -#if SOC_I2S_SUPPORTS_ADC - I2S_MODE_ADC_BUILT_IN = (0x1 << 5), /*!< Input I2S data from built-in ADC, each data can be 12-bit width at most*/ -#endif // SOC_I2S_SUPPORTS_ADC - // PDM functions are only supported on I2S0 (all chips). - I2S_MODE_PDM = (0x1 << 6), /*!< I2S PDM mode*/ -} i2s_mode_t; - -/** - * @brief I2S source clock - */ -typedef enum { - I2S_CLK_D2CLK = 0, /*!< Clock from PLL_D2_CLK(160M)*/ -#if SOC_I2S_SUPPORTS_APLL - I2S_CLK_APLL, /*!< Clock from APLL*/ -#endif -} i2s_clock_src_t; + I2S_SLOT_BIT_WIDTH_AUTO = (0), /*!< I2S channel slot bit-width equals to data bit-width */ + I2S_SLOT_BIT_WIDTH_8BIT = (8), /*!< I2S channel slot bit-width: 8 */ + I2S_SLOT_BIT_WIDTH_16BIT = (16), /*!< I2S channel slot bit-width: 16 */ + I2S_SLOT_BIT_WIDTH_24BIT = (24), /*!< I2S channel slot bit-width: 24 */ + I2S_SLOT_BIT_WIDTH_32BIT = (32), /*!< I2S channel slot bit-width: 32 */ +} i2s_slot_bit_width_t; /** * @brief The multiple of mclk to sample rate */ typedef enum { - I2S_MCLK_MULTIPLE_DEFAULT = 0, /*!< Default value. mclk = sample_rate * 256 */ I2S_MCLK_MULTIPLE_128 = 128, /*!< mclk = sample_rate * 128 */ I2S_MCLK_MULTIPLE_256 = 256, /*!< mclk = sample_rate * 256 */ I2S_MCLK_MULTIPLE_384 = 384, /*!< mclk = sample_rate * 384 */ } i2s_mclk_multiple_t; -#if SOC_I2S_SUPPORTS_DAC +typedef enum { + I2S_CLK_160M_PLL = 0, /*!< I2S controller clock source PLL_D2_CLK(160M)*/ +#if SOC_I2S_SUPPORTS_APLL + I2S_CLK_APLL, /*!< I2S controller clock source APLL*/ +#endif +} i2s_clock_src_t; + /** - * @brief I2S DAC mode for i2s_set_dac_mode. - * - * @note Built-in DAC functions are only supported on I2S0 for current ESP32 chip. + * @brief I2S event queue types */ typedef enum { - I2S_DAC_CHANNEL_DISABLE = 0, /*!< Disable I2S built-in DAC signals*/ - I2S_DAC_CHANNEL_RIGHT_EN = 1, /*!< Enable I2S built-in DAC right channel, maps to DAC channel 1 on GPIO25*/ - I2S_DAC_CHANNEL_LEFT_EN = 2, /*!< Enable I2S built-in DAC left channel, maps to DAC channel 2 on GPIO26*/ - I2S_DAC_CHANNEL_BOTH_EN = 0x3, /*!< Enable both of the I2S built-in DAC channels.*/ - I2S_DAC_CHANNEL_MAX = 0x4, /*!< I2S built-in DAC mode max index*/ -} i2s_dac_mode_t; -#endif //SOC_I2S_SUPPORTS_DAC + I2S_EVENT_DMA_ERROR, + I2S_EVENT_TX_DONE, /*!< I2S DMA finish sent 1 buffer*/ + I2S_EVENT_RX_DONE, /*!< I2S DMA finish received 1 buffer*/ + I2S_EVENT_TX_Q_OVF, /*!< I2S DMA sent queue overflow*/ + I2S_EVENT_RX_Q_OVF, /*!< I2S DMA receive queue overflow*/ + I2S_EVENT_MAX, /*!< I2S event max index*/ +} i2s_event_type_t; #if SOC_I2S_SUPPORTS_PCM /** @@ -167,33 +132,75 @@ typedef enum { * */ typedef enum { - I2S_PCM_DISABLE = 0, /*!< Disable A/U law decopress or compress*/ + I2S_PCM_DISABLE = 0, /*!< Disable A/U law decompress or compress*/ I2S_PCM_A_DECOMPRESS, /*!< A-law decompress*/ I2S_PCM_A_COMPRESS, /*!< A-law compress*/ I2S_PCM_U_DECOMPRESS, /*!< U-law decompress*/ I2S_PCM_U_COMPRESS, /*!< U-law compress*/ } i2s_pcm_compress_t; -#endif +#endif // SOC_I2S_SUPPORTS_PCM #if SOC_I2S_SUPPORTS_PDM_RX /** - * @brief I2S PDM RX downsample mode + * @brief I2S PDM RX down-sampling mode */ typedef enum { I2S_PDM_DSR_8S = 0, /*!< downsampling number is 8 for PDM RX mode*/ I2S_PDM_DSR_16S, /*!< downsampling number is 16 for PDM RX mode*/ I2S_PDM_DSR_MAX, } i2s_pdm_dsr_t; -#endif +#endif // SOC_I2S_SUPPORTS_PDM_RX #if SOC_I2S_SUPPORTS_PDM_TX +/** + * @brief pdm tx singnal scaling mode + */ typedef enum { - I2S_PDM_SIG_SCALING_DIV_2 = 0, /*!< I2S TX PDM sigmadelta signal scaling: /2 */ - I2S_PDM_SIG_SCALING_MUL_1 = 1, /*!< I2S TX PDM sigmadelta signal scaling: x1 */ - I2S_PDM_SIG_SCALING_MUL_2 = 2, /*!< I2S TX PDM sigmadelta signal scaling: x2 */ - I2S_PDM_SIG_SCALING_MUL_4 = 3, /*!< I2S TX PDM sigmadelta signal scaling: x4 */ + I2S_PDM_SIG_SCALING_DIV_2 = 0, /*!< I2S TX PDM signal scaling: /2 */ + I2S_PDM_SIG_SCALING_MUL_1 = 1, /*!< I2S TX PDM signal scaling: x1 */ + I2S_PDM_SIG_SCALING_MUL_2 = 2, /*!< I2S TX PDM signal scaling: x2 */ + I2S_PDM_SIG_SCALING_MUL_4 = 3, /*!< I2S TX PDM signal scaling: x4 */ } i2s_pdm_sig_scale_t; -#endif +#endif // SOC_I2S_SUPPORTS_PDM_TX + +#if SOC_I2S_SUPPORTS_TDM +/** + * @brief tdm slot number + * @note There are 16 slots in TDM mode. + * For TX module, only the active slot send the audio data, the inactive slot send a constant or will be skipped if 'skip_msk' is set. + * For RX module, only receive the audio data in active slots, the data in inactive slots will be ignored. + * the bit map of active slot can not exceed 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 literal 0 HcmV?d00001 diff --git a/docs/_static/diagrams/i2s/i2s_state_machine.png b/docs/_static/diagrams/i2s/i2s_state_machine.png new file mode 100644 index 0000000000000000000000000000000000000000..493e938723b1197549650c9660ba255adbe9b837 GIT binary patch literal 55870 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 z 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 literal 0 HcmV?d00001 diff --git a/docs/_static/diagrams/i2s/std_pcm.png b/docs/_static/diagrams/i2s/std_pcm.png new file mode 100644 index 0000000000000000000000000000000000000000..31e8b523d68979498868b96141001c1d909f1905 GIT binary patch literal 20415 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 Sl?z4qWi!Fv@|d}6$o~Tb>A0f+ literal 0 HcmV?d00001 diff --git a/docs/_static/diagrams/i2s/tdm_pcm_long.png b/docs/_static/diagrams/i2s/tdm_pcm_long.png new file mode 100644 index 0000000000000000000000000000000000000000..3e2416f3d848c7364a912728495a928c083da0e0 GIT binary patch literal 63728 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≺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 D8&2hM literal 0 HcmV?d00001 diff --git a/docs/_static/diagrams/i2s/tdm_pcm_short.png b/docs/_static/diagrams/i2s/tdm_pcm_short.png new file mode 100644 index 0000000000000000000000000000000000000000..c1c46ff4a635352a4a7d8b38f5912048f4b6997e GIT binary patch literal 71424 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

l4Ll-{Nn3$N@P_su=G3KW!#?@Z{BZOjT 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èUk)GiIq6#3<(Xf}B@ph{9~i87 z_0IO*K};?_-0L&T`pt@Lg#<^0btTkdnJZ@)C}GW7wYs{D1ne*BmKqeCYb4qv4t7R0 zwPh#afqgLnBa-OcQkVE&iPZ``Qs!! zVvNos&i*-cmZGY^AMGwmdgOx?erUeLke7jGZWusTk6+kbN<=3KOURxpWA1xLnOWBqSmZH(ynf5)tn+mi9Z26-uQF zJSpELOP-XJ)Gybac=Eo{ijN93s}~rlDn9r?2W8IXLogtAo8EL#GmN?o8Eq!z^3a5( z?(U%zNXzct$g6th!u{n~Ybtm7-qMb8agN#&m||b88#&-%=}>s4h7Ga;{yYA&XsyVa zCPm-k#XHAU9EnN4wC2Pexczgsx3;Cm4Ce!2DE&q7n%aMmfx2Sg;4s{aLP9zqZ3P2` zJl^uUXze0B+rB~+0BS~ETz&sQ+(9;i(9L8e18%S*$qwt1iy&-0>p}OZnO_#o^*a>k9=Lo!%*dj)8$c`3q}kGS(dHtE3{=S4LbMmJK-8DE7@yH|cBj$-lpDXYP>N z@IOOVHKy(Pz4RRYm^ii1q?DVYq7eNc>MBspeqBGP_LQ^4uTqx*&$=&q?OH#mCU8Nn zLCOUZO1JdI&%nc&)|4o7FUiqPY_NDkuIY6 zjqZo`2|emVEwX4)zd@dtC5nT6Qq4rb7Yudq|6}~_@x2{~RY{Qt;`m;@`uMxhm6~ep zZsI^zyq}@+=d6An;Ys$PdGi5f2=a0ho0Cc;HjC9}$tT_lKWQT#u}3WW=*EDO#72ct zlG0YPU$Y0Hl_M7kzb*|xg7I{ow4|9G)XfAQ32i__6PMlp@g zNj$N6`@QEMC3cA!_fiZMX?3y_`{%ztCWw`%Coi;!XsLsANM#dL>8U=r1B!b$I@wc} z<;Lt?;f{nXVHY=yN^R(~N@4$Ttxl}%QHKQnN22<^ z;8aDShfDM2@t(klo@G0}ErEN)K=J!D!6SE-JS+{f6FaOrLSceznatn5{a+Vh^g`;# z`uXYyM_Rrp?A0pq|9r_$sqD(OssU3!cK`Pc`uFY1cJCt=R3CAEOp@h)-obypAR<<{ zmf@cH^WE#LCxrgx{VzOeSNSB*h)u%B?uo0- z(&W5kGzavNtOsSE)e!<#2m?J+J`K-E+8OrXgD@TtSAB@}z11{q2M0~mGBYcOJ7R%sNlxfI5$X*^vv)5UjvdOq-J3cgjAmCF;>66ars(&Zj;l{u#1Y2`@M z8Rr3c*SpP8&RxvHXdeke1UNeql|4RYyXy*woUp_$cLyORV)87TC~m-TN8?v?-$?1}6UVJE;w6?Q_A@5kipB9iS7_4V`S%rW$p+_!vlcg&=A-@MrYLwIOzdt{xQ znYiDBmav)LfwRj0;(N#!m)@D+9k7C}O`j5|BtY7|-ARu)Pp%3`(orP(qwsW>llSdOFE`mwO~B1-K)_WIj)NEG97%@orp>PpZv?H-yHaL~$T$batz zjtK7Eubyka{gVq&c68HrYjKW|=%apB!D72rjC=kw$p7`61uSWG{jUe@o{s`iWKbZg z#XOgnJY*guj0`(_wmD+Z>G|2+X}*9H_w2ffo~lG~ppRdNf|QJmy7{_Gm?U+aj&PM! z59>K#1`JI^IsVzR1@@;|TWM1KeR8Dv*^(|budwlTt&O;_yb_(iSW z-VtIj5*#VTOV+7fOwUSJ5jYQ(A zoc2gm7;6$h?JRh z9sh!;xE)!E>I|wQdV`HVJ`;z0s z`rqE#(BMbbM*Fazt?90jQc{@wwzRc@TFQveOYByt<%dZPAn=P3Qzc*KXoGk><`kiH zP*bn78Z0@aQ^tpOtwH6@83?^WL1^Ah9%Z&1uQ|BYzaMRi%5oZaQ_*V5t^%)bfo3kY zt-ISoo$tK)%1c|;{|>#VruH&~S(B3lgR>&N&z32PdhJr#YT=sqa{AfpD)Pmf9_)Kw zr7M;7X|T9oZPraYTXSytLvuiJX^~BH^XuM!i)!wtdxT~+C%H)^cEGl_65Dp|wp@F@ zlk!8!|9W9qY`oaPksbbfCWN?*)r;?^^A5H}HD^D;QkWj$`be4Uai0fo^^mO@{8(bTe3%tmKv!{5;wZ5%8bgK1 zcvmTX*D;DNNI<8a)Hnw;#QtO?_~tQ30S12`P09_M9O`faeVpXjDfAM<>Scde^%Lze zoHgIq*OED^C+wnZx>$rkZ=}sh)f!gcRd@mR%jmbTLf)m*yKC>CA`CcS%VI8O)-X3r zLuQ4rK<{?T=+aEt7L>8I9&L;F>j4T5y&Oe+^x3nY-M>k-hL7%aFF>Vkep0rzt$R`C zl7|@*y>kv_XZ-VLR$x_NI1zVxf4r-uC$>;quKL!dWX|IM$CgkOKGCkL;;qM=GsK(1&mIHP4dFHDLJ)^c)jQSI3i z&#&iE*NyHuX+6Z@8|DR4cBO-xEaZHI@13}Hvi2L$hcET@uPlF^fV#01%?2}rCT;C3 zZjFOdM9z+3=8jDlxu(P67Y z#XRLfTa~kg8YrH(FnKC$FO>Fg-@k{Ghp2thq&?sN=zGd>-#JTZ0t7AXf)1IH^u{=# z(2Bh^zDOqx!>Qt2qtfwqRaC2h2{hPOltD7@si5FjohvPT=#K0t9d4p#bbD0E0HAi? zCMDyU21)jxpjf+*90!y-m?})cX#^gv$Ul z%E;kwv)nDqL|_20wR)K>Wmq6uhWhj#W2c}ro6w$>7`asZ;n9Mrwrpjf0UYrBvHQ~A zxpcduI2w$8(H#gvJR8TU@ryg)BW{C4vfO-Wkzkg!f=L_u4e%@FmXfk+Bh> z(DCr=#rte1zs02lfkAV7i{$l{J)|~j6sdIGBwT+<3O;UG6nDIoCP9#$yl-%k2w4zA zrop}X;p%?%9>Q&8^TN=Gk4<|s!qK5|f z8t|oz$qfA;Tsd%9S7)=8*5=KdF^^rqG(Eu@&Cl;a&FhNTgiw-QHXh30Pjz)SSZz>; z4xjJrs})^x^l*B1=8n*6;>BG5NT=|lB47s`o%yCPK2zpq(v2R1*#!XY*mt+uHFt$# z^8s)|4FTcrJ#WVafJ@emvvX4Fdp*-@f01{ZCXd?0u1TJ*Svct*vchr@px;c zU4{0Tc`eVMuVJ1XG65Piw;B6)qE_ie0jD`-G2%UZDc7lUYMpu2Zvh+63C#zqk(Fw8h#?d9gzkB%~hIM z!cY)2GGtr7OunqjejP3;uO#e3Cx@;fqj@q^xY!! zVGrb^vnXrEP64Tg`J&T(#-!^FA*v(C=nTPbjfsR~ACXk?y%?7mNclr^_VKV2!z<@L z-c;2&J!=f2F(5P#Y;eaifKs2etMVk(6r0G2o`DL1>2e#iyJ=xhm+)v!P*#0{JUsz9?P`*!|| z7lBAu9}gZ_z1HLB8+~_g@5}S^y3#dQ+ybn`1ou-2OsTy;gFioBS!1soM;U?6JilJ$ zlHchbRvq=}0rhSoYi34t_!_qlmy#y#SZru_(Ng#k!3+<98o1s<^GRO?DO|cy37mnU z{8b;HY?F_7JhxcJWed`TXEW!)%?PmyLSB~^((zkh2U+!cJF}v+6psDUE#Ib3ojRKZ z&kTtf&0wV@^>}vdy_dIZYZRPPIgt*3D1AP%0`aTfWgil984!C@z-lRuOiI)QGpjRjhEZ`bl+X5g0w40V=5> zDJ|~hI^ z!!v4F!nERp9dHezA|tU|#e&)KDUXky)E_dE%C|p!7vwOsAh)QY3`EPUU8&(QYgcbH ziGr^VeQJE$cAY;vx@D2>! zbX5+W?C`{D9ZsdL+j%KbIMOF5WjRhR9kV+R=LF_d7&;V1%hcA-M&Vi{0PZnAqQ33S ze}gFHrU@7#-5LfiZ`mdlF4N28+{KHE6V7d88Z36fQeC^^TSz{> z(%*k1)4*t2(lg-#+dRf&)=`F+QJB_U{(kHGAZ{pk4!zG90nnhUL`*NkGm&Rh{c2%f z=jyiaDC^>XT19BVjd}Xy$;%tTL9oVG$>x-Z8OSPr92j;usNV0Ua?J;mZBvvx4cd#r zlCZg0S5#IBi!uJDiHSwTg38^);%t&I>YL!WBYs#tqBG$+(tSXP{@CXdRW3#Bx0dyE z-yFriSHS*)O^`i7V(+~LLlY7^Y3;P*c2*q8*sns}=uOT{odQY)FuT2xXDL0L%&+5q%WWJx#We7y)7W z1Z{^8%$-`OsoZrFSkHQkdA|)G_v735R#(@RYZXsZ2Y{ltX~y3HET)|RxXlIc-o2V$ z3%y2g>qU#C!tol1v1Q<9OFz@->Cm19+aMmk3hAgwUxJ!m*r;H}EJawi6LofO*D#M> zurpa(U5?SM9>YZgoHSy)6l;>?5lazGF3@{CT<}QYJQ#N1zW1;M$0R2^y?73n6K&c1 z%(ZsF{bzV1wYyx@G2+0_GRq{V7tf!ctV)4F#v-73Hyyh^Kt2;5r52f{c$= zMo3CTwW52Vk0O0kLMVA3hN<=e3%A46pcEePQzpsz3`g_hBPy@9&ec+Yg71&<4|k{P z4`-Ia?%gL+Qf{J{Gz?m}Q2)Sv$*F6tXHz^u2>IBsx#QhPb-9LVeoGPOVSwcx`_t(?zp%W@WRMF>n2@514{Fw>vIKi zWY&s*d}=C$=y!YPamUL_O9=vJjvoC6`0+s1NS}2PvYD!eS$P_93>@ipz+!8`)&DCzv zB{$~-^#}J_Q&(GSJZzY)f>(9!7BY4w>+mA{iz_fANxcxz5wMpr4v0O1Vuok4j4BU0YSdneHUGF+6+ngxQ*WK&KQr*pVC;{i2V8`a^t1?SPz(7CeuQ z=Hu3wn9kob0FfbT;4?NxFCIkLvgK_&Z>uymvsVx-#LH=EwhDrwtbtNwRMeB2Rb4m5 z?cZPaLGfI2vT}!a*vuNcdptNkj&ULA#TRs3Iz)aJd?12(Q%ik(Hf!AlIVXk2q?q+g z!$PPVjG88CDIl~2LSaeC%E(MQY$mO|O&zWord$&z#@Hl*Bcev^DibVtU^BDPCP~oE zmX{xNIB_i_1Cr@cgZ;RZBO}y{pLyPO!LnueQ0U=9vtx%?*B|7I+z&}J zBJWwx{Q}6BeKD4)9Ijtq=OftXzZ_Hy>V^=j1d%S4?U4b)icFQHsD`MO?Bp-LcGK=I z`r6dweZeI-v6TU7z~v%qI!lL+9C_fKM&FyvzXgL(56^n8F8~+#>C+kI0Te&<=cg-x zVv{UaqorR z-mNVyH2{hQZ+RC;HNDP_{n7n)hNf*_HB z6orMKu;D>aakU)K1_GdxaUEZ-jPr!q($Pn`ceoxvRKsS3E+XkD=pve=aZ`Sv#*+#M zLqoGS2G>*4!$=ZY)7*X8Tl4E2x_XblSLRJnPHA9Y@DNI`Sf*#>7|BRi z*@$h=dec}Exk5=NF(pM4(?w>BB_v?8mKo2y10!5-4&VH}X0OWDD;F<*f&@sYU`a5I zo?~tjTh~f!o9dAH?86toM2zG*f#$(qDL8KCg*+-8^5hkt=U|uk-5Vi#bQc6Ry zc$(C-k(gC;;C^voA@dAenyyXU(;V{O)~d5$1= zSXPl2jbQ#sO0s@G*J$f%;wniXv=IIzqEZ2xt9SP$SzWSZYm8-p{^bupAuu+X6+WFS z%-o>i1sbkt>L<3oOm*Z6!8|$jkFEyM7^_CuH)6Vh3&L5-PSlw>KVs16V;7EVRWn1n z**d&I=V-2d)~wP?i-Z|=r1V0qh5X2Gf`JnGEo4m;qY%&FU*VB(3^!|CU13xfbUgka z{(Hu%nmE!kJljhSy^{)u(EJ`2v9PyDo`dZ4ItHRKgiubGHAJ~)7wA6!WEPl8h5PvU zKxP?eWTc>>-EX4&oy|RrMvR!3>Tb<$X43bMJ=0tYd3;DfJT2RlvGc5-J(^JmBIRlg zQ$NAIqAIop?W_Bn2R2EN&z?gsqP5OkSPU$nsv|R^jz_u6@yvlO)bRutd@eC~7pwj7 zHIQe*ZxL}Yov?#32v`n`_v>cHZ2M; zVe0`s6cip375U-qrT~ArGum$l|Nx3 zhy##fcj{riXJ0E;W8$RuCYA#_Y!;KJZ7Tq$}EMqcNR=Q~K4{}d7$>PPX zE-vok{ptrb#9L_z#Z4D^4bj{>GFK*;q)uS|Dte!DuszV%{`se3iZ)ZxDVB)JTmfSx zj*pRTL1soqO|-hf1Epxe?EonQY;_WHHa8ssc-~1)`Qv>vm$etGG!-xE0kSK%nRn~9zS-jP1~Pw zkL(|l@?XR5kDoJGDq`VXf_|Q5P}pI4AIMtO++qv7ID~7GlthOSrr!YrhcyfsT7tk@G_S?jC?~@|;M&_Q4~mLp@XRO;f)caZ-@gSu z6*Nuo8!R%gwK59%-A;{%$7&KDcHWwmg@yg~^v31*=2pxaq|}v%ham#!Q{ZTw96u6I z_6l;J_f)h1FH~k|I!L0jy@s;aNlJ0rYi(~?`L$7;Vpa0hDjowd60OdVdbAzMbFT8K zOhswI@j11?2A#spnJTgQL6}rUA2rj6z4wj~fAdOnGQ%c1(gQwtOet@c$X_^kkEivN zYl(r@F1w8jj!nLPG&a18!=JjJ-t06Pe)+_V3--qQOeRlkd+M|8jC7JHR!hgt%;o$H z%|-ji7%v-sMzy|A<7QQ*2Dk1zZf9+HaJ#v=Hf^rQ*n_i@n|}|_9QM6s!_Ab0g$pf) zy=s}nI1h{wU#D7`GZ(UkIL=Lm1hH;0%?BFrL=|wHQU3Exx(vVqVVctqwLB8YKy$7v> z4k_SExQON6o)Z1s8!|IcIbosx>6s^>&Sd}BiT6y7z(2BN?QQF6Rs57w^k&O_U#0Vt zZFBP82*cyO)2=4rvuTqXu^9R4UnbLhEF}uC*vx6uR)No6x|=??|L#I}BP8)S;4?U+ zq=&_kY*L zqp&3_%=B1nyq~sxUp+k%=2@qnfK=&XLL?JO=;;-6XQtcQclnmT{W&k_UV#$L?c3LW z6!6i!j@Ageqb%D!XaIQCU-S*X+`VCNNXtEfie+1En*WRiKJMVv1l8~fGLIG-t5tZ9>~N!DmFHm-cO2kvw7T4(Nh%5oT$5x;aBI_- z&)1jE^{vQ_o$oGp?9sG+jyDZ(cV(4V~&;5r8t}QsBEZ^CTAkQVwri*CGZx`VTm|XdcheR1+V|YmA4m zof~~^%@;KV1uA%BwHVVUMhEU=szM3oeD)drn(D=yKKqYJDG>;^SC_Yew#T}ql+>)M zE*O0FnJfAx2HD!j&8rw6cN|fQeVp2pfn(1;qewV2t-t@VJnuB=Y)k|MC(*d$g@q28 z6&v0c{jsyivhnHEiD_|5&I1+x%$Y64S_fZCfl0pdfw_Lu4k5;TD;&VS>l?Ip!eP^{ z(mS#Sh$gs97Ka$cEG4$WuMd_TEo3Z0KGC@UqhQeCn7}l>*ZnpQ{Vpl1=4GVH40*cB zfL*?MHU)(rwLR7GXWBrg8fb!)Olvj{yEu@8ooc8R5X{qiR&ekrf*g!vLUT4;3Cro%v)jf5@RpBM2gzzdnw~ zg=7I*%-Qo=+38Gq%Nad+!nIkle+UJYjgTo>(r98+S)&nkXyJn;Rf;rSqJHt7{&Qjnj?DF#>-Q@Y=X(ki?mIa;eL> z@~+?Bmk{Bo)~@YQRZ=qcy1PTzp`1aDH&$h@_Bh$y$Ifco?uJ|42CoNIpwuDSt@-i= zc>Yf!oB4ZBYuTP(TABd|qQ5#pH}A-N^=p#M@MiFmPmQgR^)r*tI-fb%q0NCbZN-{#!=LMX?~fuuxIPW|KSONFa@a$l#2d({tIyzZ22aELdB8_4Ubur<{6%k1B3M^an@p^*0M?_zpey3$M+o<^EpRVUG!`}DBbces8slN32Yd^cV zx9h4;JD=gyffPP!@zc}HTY>r8h#Oh8+Y=rcSHJ&VQxFb=JQb`9n0@>nRK>qXEj_?V zj*jb%f&xal7%KZG<$I@59B$b=a`Xoi4;?){Jsll%C=D?qDpf5vTpxF=pMk-{&yCz= zjiZd$TEu(Jf04xW2cgaR<)tt|@BZ%ZFTXS~>GgwYHU(Pg!Xv?-&tDn0UHwe1eOi}4 zywmMF?RJ1KYJ&L}5ubhN$qFGB^b9F(`)q+7&bJM>F;ap>pUcfocDYbZVn-yzOsti_ znufdVmD-B*<(%;R0^WfhA9jDUpg3 zdkynuHy3doOlbHP($V&cE5C|mCM%xGu>4{`$>ThKEc7_%L6|IFoVmaHb<`vj9au3e z;HhCUT5ZAT9cD_@Q|Q&cUYfts#ou#YoUZ?(N*`n9Bi~-Vn;>0Vk=e`{5~rJR|2>5j zty{z;?=(Cii!sS^H5l0GNLbmdV7K5##<;zB|HY`f@RqT7Y=5h!->2sr4oR{z$uW^mQ~sX3;NF`4_3-w zeOqGI$6ysWscHx>)|InQY#CFr>L6 z0Kh=7l%@;8&_KQ)b^5$=_q7`@zMFmN+&RZ>8OhHUbEuos`<1_Ky|p&0@)k?SjL^H+ zZQUZwW>{AQy_*2TM;MP6f22LPZRBCvb@uj*6DnuIHwXpE_6zQOCkaVp0~ad`w`z8g zQQg6VJakBSoV#@DjFm=<|A^3bz9l}^h_;ACQ^oA zRq^?=1^D4a$by)zu~?#l(i$VzwQI^s+ESe0AWQ0Yv*rB(&ecDOBHU<{^{G)+;H~iY zzCrE7jrQx)sgtiZ^=U}m6E!PBQkGfpvv5!ru$V6|>5Z#sX#B=fFw@PZF?C(Hghq-w zyu3=6UqQqQ@`OMXR}YWm=Ci$~PTqMNLPp5*bF;u5=doXiU!-nC%1F81f97VD@>s}K zAa&KfxbOxrg)Jm6E8E+A-74f5X43+BBd&_1c5v1YXX=PKM-Ke;wJ`m=O0I%Nk>q(z zUHKv-RTfFh&)bb_4ZgyOcTIHgQ$?`Z-Intd6myDuWKfoXT1It&U^nYaEc8y+3a%<8JQGYWXnn7h7z z_inA--QIHl@ULZ}$CydqpsHGa@_2E+{A6%?=~6mT#s}`tI6K{|xVoYW8Z&_mlmk8` ztZnbxz5fEDWp_lQ6p6HNq0pj z+fH^_nKc_rt4BU0ivwKey15CH3@BPjbnEMJ{QFd2kGF5nv{G92wQKBWU-}`ucZ%Ej zG;ShCdt zSlv+aQbb+8Jmb2-M^vaVNI12CsOV^ARV)vo?&rG$#E$LqlgbeTX2||!OE2@a+ge+N z?kOjd>vIv7CTx+!{Z#ejXJjjNUJ?Bf`CfWWfr>%d+Ek)(Q^id&S z%QoKko=qDfN^^rL`3%_sh05AG{SF~dBV$jbpI z=N_o?Gv%CWqJeVi#EG6ND)^EK{=~DsP2ZZgf{9AR(z2x{JUTjgcsSa}<@(LTbVo`~ zF8RzE0ex{ev95ZHKE-ctM4|H56Kua3XP+%K5opvLHhgVLe5|&rYpMz2Y@+Dyj}C?m zwrqbbPagF7)mHZ*2kx_laPjUwc*h8}7|?8?>ZGX1?bvtruX;{@bVQ)Rb9i z^XAP*K41ol&CghW5S7Bi!-a?IcK!5>vn<3P>w>xW_yAWd zmzR^fT)LF9lPl!eWb!XcO&FJXz3!p7XDQSE1epy;D+Pa4S5Q#s-ktVLZl|NXl4F%h zborI7o(XyLAwps8IaDpC|L#v@t{9yX^8Og|a@IVSBA>nFSTmeox9%U&mk=NEGW~>`p z;VoLjz(KNFLl|I{T?Q6ZzATE|@HUbbMKbwMNXPH4zkILF_(&?#e|P^;qpl4p{Rzif zIA(4V!D03U8%g-f-dnY`r$N7dYe@wF*(|AVqbjvkZogz`AnQ2ua3|xZqtZ&-V?)|K z!H_~)pByPK9;oKJ>DBE0RvsR&y8Ux)+DJy1mox-TXWFqCE0RP!W% zWmo+&rhEyxBlG5pTihNff40g~Q#2*TAmbx(#I@(izL#z6e^5|qIk`2#Dps~RExkL9 z?R>Yg=excc&f>~j#~ynW__{FMS=Q&3f1bDk?)9GiBWTz*jbf}7{H*OxX&J8!u>pvpsc z=jE3lFFzSNcurfN)xOU%x2iPlnDNE--RzXmYmGAw?e7yRCN8D*?>`<+65XwQSrB=Vyf$T3NKm- zJ%a2q%j#mEzFbspp^HibvNQ&c1w(y*8v< znqyE8Kv=4A2fT=3?E5Y|l@+7(B5mPhusd5X!aqo(x9_1y{4&#nHUh}bnWLid@#vav`Fz^ zcP-SBZ#UFhQL>Xr!$Id~?+CLiud?oY-kaWkIt2{Y zy8%t(Vpn^3ck4+6HA!%!Ni^`%hG}Q7cDAvxany^yc{60?%#Gh>pALQGW1QefF#N}_ zDO#`_6s%t}b#}#O+w!P2#h*qlglL83Q{m|G7lG+_J0J`!OVyva$}7sx8D|+B z<+DOz#?qJKz*w5Y7f&PDmaQ4KXl{IGZD~+uQMJgKH&1QFl;m&3H}_T%Q6!# zB^QWut~0~8TFpPc)2v5JxCL&ZtSx=AWHou;H`iH8Pd|xptuF9dy!zS6Ta`*u zXW9bO#uP4|D}LwNh4xr4@+Un#`=qS?!zu7IehKFLqNOwd$^I zQEOT=T;xEPs9ArH8(LKpJ2lth53qCb@QRwOtI`JD{uZLbI#e*+J5yrw&d>DIp`6(N z^$rhhL>c!hZA?VZ{uVr~60JL3Y?fTKFYIq$%&J>=S~J?c!WaKXCh=FGe3;1j8DU)X zzusw+)Q+qxJ7leg|3`5C>qS0JM%kieM6!4GDiX3+Lz09L%1qfJBU?j}UACe`cG-J; zk2jysb$8vL>v#WmKOVn7?(2{1(Wl;M${glq1q1Zydg@}lV;@nvo zWg?=Dr-+D1wvv5`t}O4?y$_(Dc6;i!gTT9&_Lyg6^1QkEfqkiiC#Q+HWOK8aMfTw8v0?WZ-7 zH?v4l`Sq2t$S3YU3x4+><9s=rV^Y~?M?yo&OhimBNkl^BMfCR{(`CKdQ?gHG|M6FU z|8XgXXvo=(@<05HBGI(laHnbI?mxe2?Z?Wmczx@u4o^-_rr zynp|*(e{rYWh3^)+x&+Q zuXuVlH8tJ2b7ytc!Tnl5>*TecHG3pH+}wu^_x$~)e>@EL5vo0V+ReoR`@iQFi@4nU z*J}LznM2w{)5Y1h8YTYm!?ArEmFn}05C7i}{og{Y2gm+s?JzR}UqlH%g~`$WP*Ll1;kAE2)KlqiS4WD<8vdPOHt=DF&zVZ)8e%CnZ6 zrKk=ZIB>1MPC!6_f|4@qEZbe1ON?tJqUqwdt`b)=GBWi{z00yLC*#K6+}f(Ar+gS1A#!T`1CyDtv69u{I=AKN)}KFr=FUhJ6cp?~eeXqXZhG$Q1)Uv}>p9(9 zjivkwttM-g>DIG}pB_GZn3I!(*FGR7rh90oU`MD9&vpt5-7*jNQ>ShvBqY3idCkPc z#L&*;Gs+)K)d3l`|2Csj72o!M~85kN$iHi%0h;Sb5$o>3W5v#^@ z+}5kUUtL9I=dN94nOwWJ+&XpY)ZOkb4o*&?D_?f+*m2aRt2pAAS$6x}9l^qi20}IV z`bhfD@T#)%r^)_$&-uP^EzkPy@Q|}?3xm&N97j7UjQJL)292z(b=1^mrUpN6+RixA znSX?ZCGO($^Q2Oh#@X8WSKKFSg^uW#;gFE9V@E-SP6{OqXF`=%l~x|8eJK+B)#ZemMzVq}Dwl+^23 zsT-A(yA?)Q_wP5tYeq&!?%1&d;bg+M`kR$9OJgq+ljpZ`;*|2bj~^qCnVmN@?D-hV z8P21dl8_)h6B87)gO1LzzwXIw^BBd`3%a@`uCu@Pi8yj;=UKnKO(Dvd>HXem>spwo z@H_|({*X+00v!M-PzyWzrTHx%+OX{0<9a~xk? zyoeMOYM-Uu5?l+!*ptKz3{h!mTt3VvrKNEkzCM)y)m6et?e|PE<~;2rsnpo~Qe(oI z?RXDq=^G=x{V|?c*N#&6B46K4{uQjd_;zm-5h+U7&i~opFLWTxFe)V_1rHuA?k>#C zT;AFmE-aefM)r5uw;b?tDRsDBIOQ5N!(`uZ^(6%4;l$;tUw8M7ZapsJ=e zG4DopLn`$)>L`RO9>cKIbrVAG? zn3|emrJvt*PBG&Nm(vSTfus`ku=Icjr&99}6N_IfY#iv(Se^_6>eA(K%rnZ(gQ?916va+gbu>GZ(FXcXQ(Gvwa9$0@I z+WUKsnbt>(Ei5cBbscnBN4?WKcZ<2?goZX_m9N>^oepHYY-D6)VPSFUQk>J=9P%J7 zE$#j@_pO887TFcJ&HnnzAasRr~!ZI{DcJa`|_u2p`1X~5uP4O)F1ce_LA8NDQ# z$+v9jD0ZHV@mz6UoVhF*#Z5&nY(Kzj`0kGLN!0MpYTBsjCZ>)RSpNAHNze z7tX^)XSKXA?dRwB=kx8}b~`n782P2{@d=upJA3>4TQl{`rlzJS7zE`b`45YTL@|?7 z`o1;b)iOS^f9ICKeIhNX>PO;~URgG$T>ssb>nPc~ef=!Pk}B0--1%reoG857!OkvH z)OjLBHTC=x;m`*U#+GNh4<0zMyfj%)Dz%$|!OGII)M-3^@OtHH>a1tkBf-lZ$fhJ4 zHpGa#4~>p0ctk8-rz!R!lwxne1F?yTeLX#VM(^)U54XmMxe6XVdUa-`J&;jM*lCPe ziVA0!i_YIIdUz9MRD~fShnm$#Pft!3*$;kF*LPP{QJL~~H*{EUIlLmtW24nWDB`C0 zBRwt^%djT9^66i^`1!*JU*6If`R+bTp|H;^#IqIVUHloLu$Or%&73 z+6n`z^e?1ecm8^do}S+5!+il>-nm~zzu6U|-By<7y}Z2WPE6_x(S`lhWtr1SiYXp* z;v~P0J;Ubt$*@-V=sQkcNxP!bD%S z>-3O-!%!1q9tBuUMdeG;_21>*8-OD;^Q`w2v>-o`kdTzFt}F)aKZCcLsIURqUv9a5>CJ9iqJm}F^iNlU+-U1rzO(fKmc{_@Pd z-AAu{IW8h1;w`D9rsjy9NH`NXGtg+%RqSlsG5NDr?(A7)3wo?NRxVSoev zR8`19UkZlPxoJsBcLD<3r-wp&oJ6kwl4tZ%(=j(SrK6_iyY^Gw)6Z%88zuMR zxBp}zwDqygn`5JG9HK_b4(O<;@L%nDhZnwkcMA@jO?T;w7rb~vAf80U81d;D0o!lo z<3B#&f1Ak2_#)&dw(jw-7y?E!Fkn`_Iq6i4CVqH$c+qhAU_E*z^e=3@*rGc)V& z?|+`2t}vsoqLSk>J*1^Sayo#1dN{MJML|+s9jCg4k&zMgJvS?Bd}2a*=}B?nXcp;u zaX&P+Fg=W;Kus#uGKnJJ_3Ek-P=b$-4;L5Lkb?D_o0}D*MbDi*`^t5eC#u#oOT(_< zadqE)dI3woj@!3y_iBMUK+NhEIWCXpcOx~PjW!CeGA8jhKt}WM@KEWGh=@S>GUZ!! zsQSJ%KPhy%Lnb%QG%Y=S`##~RcC(mt{jx3`soGkK17f#s>{&b4<_;uD{n}sI7i~6g zCG|PwPuDCgRM$U=MPDktkC&WY{9RV&GR<-L@Zlpz6uIao=iP8T&z$+7B{8|5ik$9< zo~X&khX)m-i`^I1xaful2JDAhYU}Fm*Z0$qvV>F>7Z>Bj)rIKh(-L;=Oty{eZB^A_QPCv?L@p)&#ml@K*3+^%H_5gN zkr=B3C17F{q6Bqc*(vEC>D z8|`EXSfZCMxGC8Cub%0@{+0h6%4*1?2J*G2`ICK$Rl`O#TV7*c-?#rFv8cQxLr_A5 z{5A*t`T2FS>woE2CD#gRWf@igi2#3@?@kU6Z$;_`d@{dti)tO}QIdRqrZ71%5q~h` z+qZ95f4moSn|ly#duJVirqCWbe0UFff=B@?m8jb(@h??rcVBIm{Ra4eQX3?j$Zt%$ zZyzuOS|W-pDw4JJXp;JdU?TDMik7FQp+UbC#;tu?@wm+TIyP^)BNLyLlr%JC+59Xn zW#G6(CWrI8TmM{ReWL#UD4W)>mZrwWqrAKZyu10g$to%a*7tv=@xT3@nRFfDaKvV2 z*7r{`Ty9~dASJ=kBldl35!BVNdF`K*3W$Iyd3hTe8!t?XhCXB*az5}nFZ&AKNkdsV zJ}yp5x(oT|Z)F2P+UwiYd<$7Qa3vz$D^?UR8Bq+P`A|joxg*Heywzu`;sp`m#7X64F%v7^;nwom9Z`v zj*qq}>CA|$0Y?4(wdi1|EQ96Kv9362UsSk(m4^qM>9LTq!qI&(PUSPJZ^>ISWGxw5NdeQzOJtkEkQ1a1PD; zNzCdVJEMQ3*}=iVf!}kVQLN+L%;mH_L-T@pQmftHH8eGyot$1373r6_s2W|xbd5)a>Hh#K|1#Flh6?PmsZr#Sq#1vDux>7Xw;ePW+DW32$=Sga;WNX%xStpER?^rv=krD>cfmC8c1$fu$-Fw0g0odBWgD# z1x3K!y9*;P>)qVlL4OGF^K0D-lxKGZ(06j0vng8!tUR`LtN-BV=f@(Bzis5mW88P{ zu1q{YaY#^2O-{HQb>71sQ~$dunP%l!-W^M;-^OF#UQ<$15>mK~%+08%&TxGXv@EZ`+iESodKe@z z+dV(tI{AIQA4PA@O6Q-OlY_2-_tKl2 zj~?yzVcxy%{fkR)Bj?KYA3WIqyKL11zuCefIV>y;$Q#T7-W-jB4$th^*emx%K`E-v zd>j2zH|ODwlY~yPC0%>7&m-Xd)F&##&J$BmP@rwzx{If`w|B3&+i_M_!=873 z)!|3-^YhgwfA=^$JAVjd>IU(IzpGl@h`#xXm6hCcM#E$oW(kRyrNz^y%y@SLD?fYo z>;@S{c78tovsW9M#LUbLsg&*U$KaB@H*8W)?bBBrlzI_1W-iG05z@7maXm}J?c2p z2K1q9bYVp5a=+)|Xg*MsT;eAjR=roYQhR(mnjJ^Zj<}Pc)5GV`%bu5$>nym|k8*hw zip8z1yRdm^`_t z$akLU%C&0k=`nOEz1iN@W^QiY#PPWD+618NSF8|z3yMdC9@=8W_RfnHZmu+_SY-3N zxep$EzHuuZe^K=6k3fl~8j9W$*7jk&S;? zT5=0I%NA0FpNp!cBPRuOvwidC!L}@;w_@LP$#YJ71NCg*&FdxlJ2)bu;BsdkTK}3T zA)EL2_JD6tD_5?7^kO{+E(|Tz{Z@Ho(sYOX)f|h@wt3H+ z-Dku_FYVvIAKZshGl?;yZxpP&co%!9R?*1;N84O`L#Kh=phKCpD z#*HQxqvY8+xwyW72PQ;R#V&m=t(?j)UmlCrf}$l59a?6bonDeOzNpN8O6l1V1qJh< z;XIbc&s3D4s(mLUB&_1O5O#!=P2~d?F1qTPntORW(B6jLRn^jR8EQ&K?0`H;`t_2> z-rhcpM_1N;-_w>i+en9Ksr+O>sdDk~n7(WW*Si&JZj9;m#|x@@ZUA< zsCqq4g#(B6h-M89=~3g#2l!jhsm3$lb+WRuTxUkmIwTj-Nm1d2K{V;`w4yr@_Box$ z_B#g*R_IwaH}P(e0&Q&?<4)JoDZ$br^CT)Kmz0P($fT(;Ovqc<+3|%}k0RHkUwml% z1E(3>;pST>-QC@-tcIWMtqhS(L_O2g)KpGZLH_*sF{MRg=$ZF{QK|CgW(UA_EP9hc zpWTW1L!VJt&qwlG41P*1ahW#ci$JzkVKAxR-6C)N@bTlv=oKeUM-_e;*+xMT&ZVh5 ztW09^+;^o}>RW!d2g7mOSQ%E3o6llmnC8EP95btXFkKuL*77{YL(3)_c@f~1R0>TN z|H93k5%OW+i&2DGb@13pHl(`&-{C!>-20s}*-?aaKsB2wi+-(EjaA z;%P-&q^N*{@J)tUuRv}i;oiOcRM`Tx`26|vCMFOf1dbj(dhD3hw~qXwp&{`3!NI{9 zx<$&qRXau4`jMJrBs_Vj{m}Uhm)wZW&IW4`j4KVVY8f85z&p;kB(pMLCUUN9)KE{a>&B+-Luv)9hhHQoAC9TV>B!851|sY{(MymIDEH3Q3UxOu<%kXq zEo|6C$;QUkBz#aYu>)DArl!1K0gixmFF*~UhR8)8O-M~eTJ3(O!c{x4H#Nym(!*l~ zsK*0J2l~5Y71?M}h%j^4yWP!fY?yZK61wz;bm-uAG?N87zmVne?$<}!q$s60LY1$x zpc`xzyQ`w3vv=oCnXb(}Lqn*LmX|I`WputYtKUq+e$&@Cq+k9}2r4!K%|JOoK0$BT z(&AVh#x3njd7$1nSmJ}OrsiQff5cHpRqwbH9$qikvKbJdGR31gMYU{Yfm4bKblX*X z`!5C84$i+220@0CkM=R(wSkJNs{3@adQeahsg#qmbCyOLvih4hC)qyHa8YjEDq=sNq^wMR!i~-! z#aIMqlE7~`>nkSL9Zk^k2J(`?+1qgK#mkqe`M%H!fa9V?u3rJsu$7K$;PdnC;FR(c z`RG0xXXC?XWMt5ruOd@4iRt7T7QA}(rOZ=*yj(w>Ou^a0*toZ+=Tmvmt7rB;g8W;@ z=G`U&yHMl^nIt0OT=Y2m=R+JEtcumw3cdipYiMiJkY3QyDMq0~MS0-qi@Hh>KA4z} zgj9hhI(hQs&T3ab8EOWGBD=niuU;L`(x~aPJ1GC?1%v|{nh-2O0D};ZkWlzNf$P6? z>;h>({kTjGXi4|SK^Wz7`T1D z*?)<}4>=LEY$2$uVok|2XZrn*l+Mj`+H}tji2KRdp-AGH-+%ZJk{q0$H$C{dKTu+& z{OIut?u@!g6w|YcimT<@_U+q8JM5g2KQc0cO0kL`2T_Ksljg8dyg5y`rgF_j63KiA zkg>RIbJvCVa>yY=bhIDmlpt}Y=@bMnd1SsDKV-i=(I+P)B;-=sc|t@4?Z;`BBzAlCMLeSTEWlHKPM2PbSRCX59!%>yS1PzxK6%^v?~k+Iy@m&1m$o=qPexz>}5N6 z*e#a0a{}cFB=E#%&w`&UE-VD=T3A_GnVaKTQaGU) zJ$=enprd!;!cmitJ2_aNo5n{@k9G=yV;>m>op(1d%!NJT;X@gB#+9W>#R@3-ya zcUus7heBnUM4ig}CzH!QVU4~_H!Zp^5>8^*C6ou{SgB7Z(=@8$+_v(m#-vj9-F6 z45~$DpK}xUeH(Y*a?hSUUke@lt;3!?QCKlUVuO~9V$(ZK0`24D!^6EhMiI*)EVn85 zY3b=EBH#XRUt4n2%|jh!W|g+P0j)P+B&FRjMcJ+ zlaks1MnR{4T|Eq-_4@T|;4cVbjq#^?cRawa2j`5=OK_vq)t!&jg^0n8PLwbEvSH8n zQBzNpGNP;T_pipcA!^RoAJyTbQCG)#k(^-MGx5c=WDjHn@cKO)B&rZAsk4EnOLk-_ zDUiN-`xdbanxAgZo^xGJCReWf8Xa9OokGe$Lnx&;@cq{>ahopD{reNp-zW)OPN$8K z|B1YeT+dAHN69F9R(xOTbmvH4B73#p+iY1 zO%f8TKWn1^aKdC0(a{t*4ATXE(1tSuLjQ@q=b_3RjByKo^28l*8p*e1pA(k;?Afz= zdW^tRXzu~xp$ukcXI}x-$A`8rZBIQeS;MJq&|4YAl5KI6`N|oVyfxlg)2Hpf=p1Ir6)qFjKM0V&E6q`Wbw5qAI$5+!xur=%#O5&AO)CI z(^Y&9Wuh+hc4$r4{?KQKSTD6|%{U+zMyT)DU!Y`%-_}rA9vw5Ibof^6Ek3SRM0@DS zk%Oxr(TL(%piSI(8p~tiHZ>50?}xHl#WcY}9uE~7p>`nZLX0rk4M;q%W_7RW4F|#C zVMPBRM!>2C3$kb1d%#$n2LK6TNIsYO8T!Z)C!@z)*`CLHlh^xycj1M z5LTzut>DFr2Mep`PjMYStck*Z|2}0d>9J861N63l6~&1`RmQ@{k6U+_J}Ev@qUW8I zbSV4L?}oUyuWxJudXuD*0W(|@fYy@1i%9AZdQii-8MwE@Dz zzj}I3uGGku=pOdCWz};j0aV%wAmU!iGps>6h4yG{?=#;4+6r105f<)fYb%Cy14jUA z>c)*5n~cY&L^T3UiWTDA(}vOUKlBq-VDUih)|)WC(WF41l-63#Xq*bz{U!@a#tICb#RK>JSi zqnvgzWT_>gv3$0DvzD%|7!s9>YeP#5wzn)MrW?eV23N~nT25e$#Aff;mubPNP9JG<$R_W}G(llT~fFC;erJG5~fFU|RK{iY&hJZX>DRydb(LRH z?CTkh&{B_OmvS%SfQ<9Hy_xCh>Cc~^VKihedtB8wG2EI73@HZ0c;rZ+=CKRgtCg1Y zB~O31E9ebB$j!|?RCQX#m4gQ0D6AW0p=s45Thq}|aDFd^pG-NV0GY{(L zpBJ*4ZQHgDq#Yvz16(h9#ZJ(gwa@?<7<>aS*WW)2nXcI~Fnm;j`NWBNAi^X8OTnno zZ{J=RS5aTTem#2xDIeLBpnuG3(=yq#!iqcz(O6hmn3L0g zsY=ySH-#eiW|gsWc=`p!H>sWXitGKE$+0?O7BOGi;VudC-P~*E3_py8#o_i7p~fYO zN}n1U2v!C_9)ExT&!0Ylt;eb0)VlGXK<$7=sskT0~m6iSY^jt{gC&MqVuA)7F!vfhFC-1To z%?pjRXZP+@_q7yqfjSJ4Ln=h^O!l3>@O`L+^?rpRw^mLPVjli7G&o>E!2W>CDnsId zGY+gh+8?QDuL#FOR6BP*jEt0}Kx0@?Sm@&F>gw#==_Bq?0vOYwbvO&j|}tGdCYVjYtmbl~14PJ&95RP=&qq1@`{%;ra9D z{e6A3bae0Ez57z)nvbOBpg7n%M0cd~wwDZRJNjy8vn?lB1*4W>5G3F{bhJ&YAM=j3 zZQrwTQd;eO;Skpt-W>gI@Sg1U5%grEZCU%lIfC*Tx>$433w?cE-4zhJ=zH~F7!W&r zmoznH7ub?=)U@NdmkP%L&jYVUR-+*Q;ILNeA3`1neG9>|5k7k`AfG;^WMq^g;$YZn zCJHxfloQW>^{e2jorAmkGLU!hD5S}jO#PUL4^@DJl$6E*Jxu_M^@<-AD#v=?=>>uE zmDPV9@)f}g$jod28xe9xKt|gL8P;z9>W}A7pX!u(JgG9aY?TLBfkY0)B4hS219BwD zOIt_Bu9s$t#>U3h)+6BXD~-N`d}3NLpEBLPi8JMfBz%YfnU(T$ZXN&~Fr%O(kN)_P zAYLK55td3_9UXAQgeDXX1inAGzn2Lk1HZnUNZDiB5$F{i-K8k8EW`K(c|r?RbI;)i zT9i$1Wf>(rmQbNVXl7^gW!GdhXZsyVF4^wT=Un2-Bp4-T)xtIL#v4&Hzqlyjxl){D zDtq?q+{)r_vzkZaKvC>u3g^zTcov4f{SK$5EgEv9c)ZM&o}pUvmMo()*REZg$lrj2 z0Tv5t3rvMD)Pg`gA1xXY9ITw*32*?z8^Xn=GY|HRYhc14=&>;Iql;n?8`I5~=CVj6 zK`???*b-5kmp6m3hoA!%@G27M&dIx-J6k(BEpw9RaoE6p-f?^J0)0T5=F22j&C4H> zP_F0Zqh}ZrDM3$=Vv`2S*#5 z-(zF8@EGHFBM5+OU!edYL-+>nf?k`x zgglDf`%=!qG^d7Nh?KLJkr4!7<#VPW#c8>7=jP$3s5Db;qPU=<();^&Cdf7LLz^~j z;^t0=o)jV!G~rY{yIiOA)#Js}(amSsf??|9MuS~t4ByU=)XY*CW)m_p)H}yvN2a9b zAAoKG2}j&%>>Gp|8P*F*N)0gQCW~k`2|Ba2^pHTkK;fL7oaE%@c89PAou8GJb;$j} zM{I|as2+fZv-3Ql<&(#cEA^jRIm&`yHr`hXj0vDjFk{giR4zO9ye%Dj11gA7-0cvZ zKWua}@Ps--KY4AycHlseVp-;_q?h6LCQ*mDFnM-JA5gp$<>ZQNzmqh_R+vFnLA6~0 zkOQ;@lt4B?${ZRVhH?RdOF~?H1>`6}h3VOH>kS~b6dN@@AS@yRCrh!%a%3@|4@#g! zld=_Uv9&7+cqinI{Y))mjc1rJz~h1}=k(=V2?PDKTM1XX$0ZAkLF69TGhq_b{%w?M z70^&ucb<*j{OeYdxFoPoCrrj^QEc4!fbncdqLM$tI$j6Xj@Rb$x3G+|3Xp42Pa_m zLeQ7O9f|}7PTzJ{37?>ErB}qaHg7iVNGZqT!TCt=F2F|R4!6Oy$I*oMb>D3l5D_J= z*DcQ#MM{Zv3kuDmm&E(NzrWAw(xt|S9PTI$hFOoIW70%irVibBoisalJw4!(l~obA zcj%OlVcnFFV0u1aHJ=j_j+kI_pSnc>5jOIGhkDj&4d#N{Tq9K0iA;oauVI$Eu zhlhoM^6YGH4`7n$YHyDyPH%kw{l2*}n@@J}!cGU+Ty>ynbqCpv?{K%@e^@LUy~ekK znW}ws^ammh<%*k&3+@?|MaY&+g4Vm8dE=pJ8mmLFA(gU+ONNcD7cCh+3BMV{1~5_3 zM+p97C2_Edg@jyGQc{9> z5kCuhzj;j1+vV7YH$OL{pHOn88ImLSuh7aiK8Mt2Xviu>g`ahv8;iSfV?%rJ+wV#n z`#}H}UjOX@r5@cjxX1uTu?2KSoq3n{Z?6pYO(i9fBGdtYe{f7mzg57;!3=6wP>gQ6 zNu7_0i3#ion29p?MJUUWYeH6ujShgoR!YiJyz{z!S8dH!bji$2$ga22V|gJ+@5+*G&_49Ar1LEIzZtod=2-azjK^6sQhJltHug7jqw=?6lM79%H>O-+L1H z(rzaK+EIgPwJd8-l-p&;lH1v1d%W9ivKDfd3v7qbvEWDblQA?lZbD6jXcclMCm>~1BiZoVkV8pQ9mS5EA+hrXI} zGO)bhLd?8-s?oZoE+wC^f-f5es<&gC-Wdgo@-mP?Pf(FDRhjaCE{3-vL zUtj%g4$mb?#%|m=W)|@dMZx~sHEkHMkR#{B^&ZD~#>fxrb%ospJ(={QG~G3o*_B|| zx_l}&VAQ0e&9>v?bNQ0@1oJff-C(6b;=;F#=@@bOcUYv>)?F3FE|e7H#NQ(0HX?x_)8{9pxr7c4EK7f6lZ6l#)&C#~5?gn8>9 z=0XSBM*>!ag5F)?s;;HQ5pHG|f?j_x|FE*zoA(%_-3IP1$SURz2D7zUt1=Na{pGp-i z-{d`d)Z$yKVrSrn(_4rIb{^v7oSdF^u(d@c37~)WeB_~RNlErC?K7+BFDbTe#h4EN zQ&(glKr-0w=wa(#H^<#5hiHxU(sbeTgCMeXYjs`Svx9r%*Sua{mK#C2X=t<|#jlzF z5~9^ZMSK2Ot+kI4kwzYYwmt8tLGuq2TPz1mY$?HKbpBYb^*>5ZZX6RW{@IzEC;({D zW-TZtG1&!2Gh^U~@3tM(%b{7y{OZR(o&DDGkzKCUb@R0 z;eJM^jfiR%lul&7?V^`loc?SQdeGTKWqQUdid64V$RHV@qe*R)ieIzSja?!Eo`U6u zspZVY)@U(T!pPD%4Tr+?NfE;HrR%^cJd4n`b`;^Z?i_rfJ@1>>_xbtD!j{HHi+SSM zGiz_5WJD~yI$_l$Z+XwVY3+Gp4{U^$C?n&F+)P`_!kgvEbjxcjn*V(J0K(WZ)!L8z zm#dWUi~ky1{#dEO5h@GHc}gc=(V|x6`iXVxyred5?BtO$FlT4kkeSjA4RzLDNJ$RI z5JO{HTRW@dnkGk$rG@wi25cdrd}wT^J96K30tait91C7i&i=Oe`qR>q*E~M)xwA7W zS_X_h)O`?o1Dkyht$k;#mN!U1d;_?P6hR8rQy(VBR0uvt;8-I=!+{fN4wF9>yd{~D zi~Wh(*Mh<86KRHi84nft!{5YDpQ^)S_HuAelyuW38d51mu4(1dYco?FsRXOK1;YYbNQm2mCr&DK#{T62 z?K&8nn(7Ksh3v+7DcNP$6Z@vMJL#+$5)vj|w{y(rjYqsbMA!~~U9Y;br5YGB3*ru} zFP0;*@GReu>8-{7=F9%fO#gUa$sceVGYFmhGaape$g2=ed-Z(o_((T2$g;Asy>=%k zz7s4i)zyQ3r{3EB<<+I9J%lRH$!V3N>CaEK?}Gq3=#785(Y6*8zv^~{>U+2zP=yO0S;ENK?VN$ zRSYEPzZ;Cv@NFk2SGr7}a`%4!_hebUk{)p&EOz$O9HE~csKE#+$xP*6@uxc%zCLeB zNkw*aWa!cHhJS9}JHv61LIZBa`IaBFIfd)$TS;F3(+w`kNrkk$MUYzgpR@H%)RJQQ zTSgA)#$(TG3DyJ^-WpL0u^d2N%G(!J0(BkokAZfr^T;o?f$v!DN;rzHY061Ca4 z`JdT_W2dB8=1I4k1P|=G5q)jb39)#QFgNzSqsPwjZM;yQO4!?l#l@n60*Eh-55n^E38E5) zJ}v%mq+>jztE+3un3|fp=jTtlUAxZwVIF@N7FJkPl&M>!mTQs3AslT3_xSYPC^#>^ zz24wb7Xju&gPH0q8}&4+%a>x5iaSWo~b8T|w}fSKuOB&-A$x|8cAN0=NoVkcME&mrf`&6A>{wBaB6 z!>g~Pr8R^oqN0lJ;8&sDSD&vQid?RssOUM~vr(+S1}?UZB;G0Z zQj?R)4zK9%BXB~n%7Hvx)w;WD?R+$x-pEE>1qT#N<8A+|Ma%+}3}hLI82s;6ptQDI z3&zwx|KrU;huyAyHpuw_Y+r6}Zjrvo5ZFFaK8;@foO4aJ z{`G!NSpt#SRGe)FpZc>AssX08&2EzY26s&ycgzj}n#(*dsTMt zYwb*>Vv74`R;)!L>6Sm9M)r?$p%e$C^FQUK*7s_13JQ?6lI7VGF6ls}KX>jN`iMVD z^%xw*H*b=<@L>?pd11-|?(jeMmpSMx=87Z3!k(?|?{slWZ!_mFXq;cad?AdzoV9`p z6P}B?XQws@tc8pc4KaMN@HBr4kzbD(OqKrejsH1f(7k$K(oKiwIZHbHtK_64E*TqR zFCG62Q3PxO%S%q`b2=*b>*x&g(Pkrw^6gx0R zAAXGQ+{Izxf$1J=L2aC=bIS?Z>s3R@8x3^CTGW7~gR{fJ#wPO$dF7_HD0s*co1R_* z@C1^8GvV6w?~rFtQWvCiCbxklxYj``Dkf&(e@k*b!YD}y>?(J_%D+WSY+T&;;o<+y zh#{aUzycMH#7jC?uU^HdY%p4!Kc;uUt-h|vZNz4V3`RE5C2THm1VtP?<0k-3294CksXBEuV24li=MhEz4Na^4As)F zsK`}P(#!I*lB&IEx1Q?65N$rRWFaASp775P)G!by$&7mV$5Rqd9FY)hgwV%UT^yQj=s4L9vCCBzX;Y&pWGD?dSRLHCi%uo>19sd^Uv5f1FyRDZq1SZvjs4J zhRJ%7-$6w**4v^EKRmK5A%iriw%M{O_udAwx`<^uk z%;F}#3a49BYwPN_ca6kr8o`U@mz!H#c|q;xiR>^;Da?wI9>6vxAw*F*TKz zo3-8|<%oL&-XryZlm8U90RB~?!;pn)?J1gQaoLE%`STe?I_KnWo{S52QJcI10P&kF zJ1>u5hm>KBW2t!X02U;9dXm5BfgD9*wADZy^zRw*2O64VnCeBrrhoI-2bwqyjEx`0 z#OVLl<}P}Xooxrwox9VFb7<{>)1aFHhu@E0icd(mQ2$vvV6Cr&c6a}N-FAs3$+vB% zSTD%S--CGtOqT55s{y3a+t-)d@4|?I>(LLHVyFAZoq(=i8{~X=ZB(TKSS7sFvV9t`YG&XAr&Ek!BE1f3QogJ4==;R2v? zq1*ffKcsK^cI;gxkKc{31>{#!vLdI z<{{>6kL(V^i>a|O%y79^#Eyi@Vg}s)$9oDKGWL+FqzF7WF2wokcACD!xTqjF816L3 z;g)phxp37}k@~(J{8BIp)ug{Z#>U(no~`51V^mYs4!2AqX0QTSB22H*gj7MK`2vvv zjxjj6W}!SqMMPX+>8QU4q8Vs1Pit|{anOi_2<0aStie=kMF=TB>8bTuST8SG(t*@| zJX^rMdpOdVYe?4mm07kDT-}FxHAvnnV&KO0wX|?2lkLRL1<-Bb+}b~Td#Ao$?}h_Z zmnR%HM)W<4$Y5rLiYsXDF&9IyiW;Zu%SiSfpEj5*4@7}b`%p-IJYY8GN=gL=M z2y{q4mLaI+&aSQ~K(J5*>^<@6-MgnbIa7e;W$2diR*TcaXH4aC51OH=pySq>0yzx= zuqIN#U&q|ivhdPdGB~u5>S05&EBK;il{+5}>!m#VMQ!b(+Q6L~))|0>jf9I>zzacf zU69_-x}G7tOodye`h&`2Wl zpkDeggRsQ(Jc=sxIl}zkK5{U{Eui1|jvY%r07)G78tfEQhSkkM)qRw^d1EodU_1qj z#|dF!Tx?(wkq5K?luUbqRy(3yr0jearR_v;${zc9{A;}TnP8dMq zi{N5szrFW6&ODGL&Xnop%P{zPhHSlc@)E`ZVB^Ky#%7-+wETw;4>rWzz|gg7Ar0y4 zK0BywzT5Vkxah=U)H&GSKVe0&cqML4#AJ-Dc4_ip=NU*@52!c_xju2Xj# z+BztZxV8tQ+>@n(3Oaf)swpdD5zp#T!BGt(>S-zrp==8LklMK!CeJL5yVV$|7PRSt z3$qdK%`~mt6t$y@c{%y{zuRB-qjN>I?J0cp-w`_~mQ!9WE~U_x(9uGws;aL)NKSY> zWJ>%E;U)zr?{GqI_Bksj=L!o3SnevmwuS~<%&>sj)OVj&MYxvD_4s4{0irp)KOAar z1_uX`oq&Cwoo^K~8O!a!v^_?TR+oQ!ep&S`nY{1cqs6o`lKrA7@%l~~sZ-@7j(4dK zZ{e~uq~9INKqFA4+GO7Q-ilvc!B8�*$NP=ur+;$qS?-JEXF_nD0#CmJau>`r+c= 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

2E z!Tpe5Xx&?=@r*&FI-l^Xvzjg$?#s8vZtpOH0TgoD)zmx}H3hb?X2 zK0XWL?Qqk6UmHfc7jc?`796o(qpQV~hGfCgJ&ZP+!x;jr`?c7P=WA8phyrx|r%M7i5o9a2QHQ@?B?gIRsT!y_m{z?`pTTe%vW znj-HBg!2a~-O zu%PybiKnhNd_hvaj@PG7Xtc)=PQ&#R(q@)E5f+H_&-QRM!{s?_n1D1<@T!$xd<}?G z*_6^W-hyl25@fKdbFSjEfGaI^KLQ8)d3KvFqVMHC!x!%u=#_KoGn_2g8OYR8I|Ytd zR_b28+Qdd1Q#k{-M|bZIVQ-AGjxCr~|EgT`FdkwU0wYkkw%GW7Q+QyPVnXTCrLxX1 zpy~@N(Ru(*ng*P@R3bN-H7&%juvb}l?>%b^S8OTs#NvP0EC|gtSh`>hg2Oef@m;!< zl%UPzDS*%gsJR^ej24Q@gNP?9JA2~cIYHvx@$uyDDfAc;cIjo-adT5sl05^Fgo2`< zsNtIfMh4ymbJ00F^^SU)%Lrh0WCc`*el=ZRh2Xv7T8l#~E?qjZu`^l+!SoWUCFqG_ z7E?>=8ya|=-KI}}lo4!|KzI&12JS<23xB`5`Pyaym_mGaK>mRcqr>B8_TyEY#;o^m z-b6%3lJvzIKi?QBxykuw&LGtfSi81(q2nD&rjlqn>j$R|m|}nOsNw1(QkFZARbT#K z<9aGRT?pf#*7o+^>`FA`>C-Jlxi%MeG*v%%=ri(9NMj05c6$aoSl;ipEAs?Bh@GJR z1dn9a5k#B9`^AlfUQL)l+aC9urydr9VCvO6vu9tfzR>exw=9p z%|TaOv>YbgHN%#%jzW0Nmt=Jwzl!5SyubIG!O9zQG^o7^NlE>FNe^Mq62{xSX=5PS z?`!(s^Em|q+%0m|$%KYLs%ChxM5FpjVZUcS6(=54yJaGfyyIb=tkgkHud) zhiXA4q0Kq5Iyx$fsMt{)jS~-jhgkph>z9xZLl<)*|L{?^%MhM~1co}K?VZch%95g> zd!7V;?T(8Z3ii2d*|PiP#zsagnq=Wtk^jrhM{%&X5_&PmE}|(;t6Aq2#+)Yqfytmk z#D}sfjaZ(`qcVJML@4Wk4G_X17o@wVgr%oVpE2Vmdsg7H0EMQW8hE*b~;S^)9_AvSl_7}1XGZ{BmRMf zIkA!Mj9=lz7A`zUC)Ot%mX(uR?&o*;>QxqwOuT{j8A%VdPHW;2B4OZV`Zy)AzeHFA z&=(#8R+Fte;DI|&7zdL9%T1J*Jmp`PmPe5O51{eD^(%BB8;}^&4zP)5Ku>!BG%W9E zdZy>pYz_;XHhnr>EB^i~Nt@KQZg&!5EosAq>>R+Bl87tkuW=Z|5Fu*b00+DH2$|Ed z_Qqt@Oq~7JWa!XjlSN&(lxutInNMFuU|jKl0xqLwqpUYh>>LF<#kpBu`dkzKwGB5|tz<;zV^AH^n&cXmE> zuaO6$-?{9~3-eE%lJC@s)9Kdr>+z>;yqyRDTD>}-J-w84hdlP~jG~vIb!=JN4Qo|K zNeLda3-rgUR*csl%0VSWN~zsH9nw+D!j!>0Yr*mDU7?}TezF}5CKB}z(?WIJHYi*y zcgtwL`<>gmu{3r@L11O+fCDjs6p|4tnB}20r-R8ZEf~O zykm&A#+3oSzS&jfs%b8GZ>ycpn5@Hj*ylA?C9C4(#argb7=~@f~X?C zi`m5doF2Bi=nb|bo?58o15Ym6D2Ybrqw?pfA2jPi1|63U6$5EE_K|AlT|A0bF7#YB zpISBdj18-8oTvCeOc<*V)YG$R8aXWH67kb|-+K+AJL517%st0NpbySlbqBp3F@*?e ztRDQ_$JoY`LPa{U;(Kmc&DE>@w6uZ;Y$d^ui*9N<%Qsiw=6stYa+XgpogBYib{Ccn z^pZL6Vo(fkFTH7%i_4Dia2r+_4x4693&jUH5LhM?BbNK^7<{XNl}BxK8ozyQmL!Zd z%gLWLHft`;`qt>^jQNISybYcLf4k(``9Rs#kN z+DPtJ{_bfxj*n_<&5VtC&{laa+qPi-e9kmJ0ifFvmCkv`*vJqjtICCTb9Wz4=wi-! z)+9n%3HhBzrye9?i;XP99Ap=AHK9#-t2@E2M;1BcB8!e`t}ReLa7D2TLSdhZ&cdAN)eek_kxIHs_HHT>C*Lc zDy=?s+vgMll!<0DLVjp=?K*$q!gZfs*kql(NW2r_asnecedwgzzBX`$;3MrQ`Log< zW+YGq2knNGa{A!;zOj*n&Q)2rF0tAAz~RF_d^_`=jqE1;X~E)UdK+!dX*DrMte)y@%^w_$!V_liwyZkC5{h0SDbwN_AO6Rq+_mp zkZ=_?{E(kyMrEaL0lLkJ{&{=$GK3bK7Y8)8xgj{L`VJTn$d-Ez^{8~_MgFk*War}9 zEmm%B@zVwn0yZ&b+2icv=O-wDdT?WW5&oY_OnHr&bD3 zd9nG{Uz?mfFD@PbJi$dmszlX?)s0yF*<>|6XXTvN$Qklvbt-o6%9Dw-N@J&O(V85! znsGwX)v#few!Wi+tpePXFY33=9jugcWA-n)GT{V8&YX<0hZUoEP`*m=ykY#gjX(%-)F%Y zsNtw}Z?I_pm~|6p%ov3$Yxz*VY2j;$wU6Jw-}&okJw55$ZgW}oRF|IFEsesuAlw5qrBsK&ixVYi~<&y4kVtPY6 zqFKdXrgdi!-iuD15Sfulsgq5WwQ*$+_s;n6?|wHJTRwgHvYwkJc(DBDvm)u1K0AnZ z#sZ+C;{@4x-cru3(1UeOaM_V4yEu_gA$z-7^2&GDq{sB%EQu7# z(SxMEiQoZ|3J*>+0L;gosSOy{($XnXl7+f4Y`SMAt7w$qzT=3&NUh~xD;cT<{7dmW zdp5bCqZ2a-xG^r6Vd%8e=l0vxxDx5bz3BtG4%^^hv*fCY5Yc$}FqwA${4AFTK6$75 zQDu>XlM~BLvuE!o-~Gb}=NAL~uP<2an!+3?OhZo$UR4R|eb6|ONVH=;CH1m! zkLDdKF7CDB5ceqIA{Q=r@w=86^~p@+kp?rHG)eW`=8@ZM2|pqDSm;x~XLq*T!ERt+ z9PYDsza2!D03*wu7MXZeh);CAaiN1I%#~2=+2GE>RJ`-56@n5TUweCTWX@dAKbTdD z3JP8^0Zp0WWx_DP&g9&u3oY@B5sSP?`cb(328Dyh8V zThe3OMt(zY&i)vlApHsZ#~&XE!c8FnhynLijg?Z^jrm;Reda+L z9%BRxJ`K|TA>MM+ua!MFrA=%4u+JIi;FXelKlC$M zZbYM;x5^q#2;ZV}(JXF9LJxszX!m=IL(_d`%uxU4wx?pML7qepdE4>hu_kkupGcXx zUR89WDQ^{LBX%e44ZZZt#+2>f!@{^TXbJ}m*jjPsk&&9Q`V#I;ZXL7}1G-*Af?}IN zxF3gh-05k9Vha-z?ql;K2TQI~r#v0eui^!6Zfb=S64-5P*nRP^o|Zc}qeDhny;&K+ zYWT)8Ho3c#jQ2cxQLjPL5R-wf!$jN%j6K>#mK+Ix09+O?ij@fKF!@|Jdj8 zdheRrb)6#K&8(XDW7E)Owfok846J>Zyl%zEC!O*~*G={J^wiS#zZN@-%(l`knu{lB zExTbMz)|}8q#qTYJv-NI`aK_Gq&k3l&D#bliG$Cqu&|JL9cL0^ArZIA$|@89IVnld zRx?rZG-hS>eQht5S;(gdJ(bfeR(>{*@EQ$g zdVJkRb4IMv=jRLt4eEN&Zm`Ibzr)|;@0VWiL&(6Y`G$rqKX#+V#I;Ppf_tY2r;m8O zypVrSTp!tCabLBlGiQd!T@j_ZSk5=gU79$mbyB8apm%kZ++vkkE2nyuTMd)T;Uh=p zt{EwL&$h7%-?wiT7j?w20MF?=rCy8Ou{D5D zCZ7CjcO5)&S^D{`tShy(vuDm+?>@w}A8Cp7!cXXZZL zlaLS|^E;$H0+D%q0%}>=j)9)x<#nZveVUuPYiQiOd>P6zadfMMKL7_Mxd<5s zFGy?#-T;a)neX|tUs!bAROYv8Rk+Sp>LZKg0FAu5Jkn?xz`l-o-rjW*e-5AZDmnW5 z?X9ml=GUcJ5{`4Ku5Qkbo-LemT+$cGN5Kbfc^ZO^kyHic&=tq*x)@#g$}ow2&J*nI z3HFRhY(3ww*gW^+4@x76F!Xul8>>E!JU7WThg^8DijU3DQJYcQAP}lG2BaMR$VW07 zK3t~nTM|Jd3;TAsEM1sG$_e{@kxE)xhHzm=e0#1fPQT;B!Axm6eA{1DJ9y3p>N61^ zf=h2(PthU*%zfw1W%VgJUsva!{zbzzwo&US|KzI`2FvyT)<+RJN;rF7>K%jWJI7sD&dty7dP%0P zfT_+GrB!hGd(g-i)j<_6KXF^?sx;y`fHok7o1we;+c#!Pjj4Ld{mX7;7ZLl#i#jpaO6Lt7U!3~%eRwr|`(vDF57hFH+Yi^iPyc+Zq+0nm>+4s6?!q?B&%A`y-oTFDh&#UpNp{y|ok#bNm=bcnPm{48>1mgI#yx!*K9(=U% zQ@q8YyeDu^FfZUBpi0gr#$1r-qcELFQf#Cd}y9mTvyzXI?rK{xsQm^7R>2z zX6BYTwbp7{DBI{@p-3<#-ne}E`SL>QvQTT&cvJi1lwCQAAL`sve140(S$7{R;+sEXJfdUmOq z519qQOc56|DDJ*CaPZ)EOniKamBy(y(~vG;vE-} zweLOFPlHo^9#+`8Yt4vWolDmuQs9Y@$Y^aFf#{XrKpW0IgIfenxZ=zjiJKFtBD_57 z2FGYQP79~W)KBkb6%wQb!Kt%6R?iUU!gvEuTHP6g}&4epO0Kbm!= z7WM9HuVm5N#nn}aeZqEHc0~HstnpVxQrcW?)?*AD=oHxJdPw$&UQ3BGvKBHnVsFf! zo8Io0D6z($LqL8~S;ngiA9wIpcjTH93KV$qIxapM`?8z%Fr%;gE{-jssRBG>WTN!b zq0&>n7_G;dQ99qqZ=-d#_JhwbY5Z3nIJ)pkU2)s(wPR+}&`!GvK@z#_#A+Iei4#dr z*nj29jPbV}s{gD|Qrf-2j115AKfh_dxzmRk8nWhzZ;L*J1HsgE-=&w@+UJPizHC?7 z@P!G}nRp@W+@z_4MvibEu=^Sr;ldIdriWPnV&aYcsEZSzYPcD2UR2ciQCukFRI%>8 zdRaT>oj4)D@Sva;T0D=;xS)5WU4F$!kmFt`^=>)$2sgRBq9WCaVs<7sS0X7hGqW9k zG%?kCLPIZ9#oR;jSy@q0n&&_*GyBu}l3_9M`_nZRMzm_HeR+c6FF(F~xdOg|CFQbN z-=3Y=8y`<_ky`ie5$+4w;s{3uSG>u(3|Nv|m^#5B$4}22s~vZRW08mY_wV0ayD=Jy zTgvY=uC%kWtLxq!x`NHKQ86)^8XBwp{7Q#S@77dEL&mWrFcsj6z4GE+UzB>|g{0MG zw_C-6&e98vdiClhP<2gBGv8bJ}(cY#_is%C@+8g`gNjpMnqTA_*m6=(v)bL28b@14(i)?;nJlYFAb+t;nTpd z>>2-{s>*oiPy!HW#a@5;K}Ug;hCr@rQ}m5MtHS|da&m4_{^0f8_Znrvj=QsMm`EXK z=g#@-p7(L(&Ryc^`P{tyN6fT+9eH|q)12$@TlD75wUW&{L}kq(`M9T${bQioQf|~; ze%!cgG|tsi$MJHw%v-xr2;t5wEGz(CF-AeXm^wVuJM*Vb485l+4r2v})`TR9oV5@N zd?Iluk=2M3%FZrg!xH}-ITG!7kn2YJJ0L8j%w0<<*tO~TbFKdUqpj{!c3>^&2XVa5 zJQp}}xqoQ7+HXkSAoxaM#B6>Z(t5Psz!cO7=7u1i(7i`pjnh4ZuAyg7L`np3S3iE- zDP=3$FODBOHmkr-dyGHXSBws0P`UHKc9$n@5rz{%hu>aD2M3-%ht_qLN(bn8z#)OY z!E7dFxdjCU9az(I`HYa%_FET_wjshCgFA=`n!A)@&Xfp*2Ox`0}HM_?rBs8E;`(SCKpsfvP&7TxI2FQ`t`k~MLUw4hS#Szj7^XV@kBUCop%G-hDa(p zd-nU+uUc2=k9dHI{auU7!mPdBsh)4`0Xeh7hl2%MPW=3%4V*+NB;)ManOaJQd#>}Y zX$jKeIW73ww`ds*8KQCp@iVtmoc)1_2(g=K0U1c0x(>)ab?P0y_uUpp6Zk5GKrtcy z_n^dU=yX~%?O1!Rvb{e@0%?6f#58g!sp-I!L_D0Iezd{+v)hCH8=EpaH~%NGC0C?L{)HgwP;`wBe?f~YZF!qU+0r!TQuMZM6sanPNK}&d@3W-Y z%E3Vv6$$`dRaJak+)OqGAQy{LELaT2*w$iqa3Y*!$N^bJMOI1jeba?;zI)pAWHPJs z!vK?(kpm&Yj>LeN+J(1HLY$#tu$?_G z60zz)YN~|oW#+9u>e}#eXd-HAijE)eoVEEt+kPECZg@)SjjcONZQLnb*B|EI2K=*9 zdiD10HLpDSxw17cxg|UcJ>`m)?`bQR6TL;G#6tEMQ-W zAy1y+wbG9kt%F{Nvw>-c{Q(quk?TiwNE*85ItkXecm3NRaQ6aickqM^RQ>Q2Cb*xT zUP5wmCp9SY^X-2|7x%+DOVSSlf-o)n>C<~0mCIlD>}LJ)OB+NK0l-++aU>?D?h400 zvq{URGO7y=2yc>`gt|eAJ%7GEdhj{ix)M69#KMr`&tWT)vTVsQ@6si~f9e`;IL;lB zREWJUJ>>Qyic=EMTkZDP$lXcW(S@jnSAirPGR&~Xxwv-!-iA5Dr{?4^eg7s_%Sx%j)37w#lj-Dwj)F1kE%dR^G&e)dh2#!! zxbZ7ef>>8_%7S~e{I2q=nGw=_oI51WkM2N&9X2rpI%pN&NF{OGJ@RPU#H{uow}K{4 zn#5e2zx1ixixl&~)@DXRL9%r9^5*h7=&rpIU0;vYRe4sRc-7O8B%?h$cP>YuEyPv! z?~n7H1De7n<9!V!3RM>|1av8Vy5yzLbEYS%+3Virks@}C4noxVJ;%1St!;W>55ri! z>#z6|kQRs&yQCpuR}8aANUOMgdj}wRLEmY#D1;%vo|Dw0Gq$v@;D1X!~|&q!q{^3O35nyYNKPzRt^$Z1^q|V-Q(%N)Y=bI(q7s zz5ImY6UCrdR`$xxo3H&w9Im4*m#~VAu9tFcB>iLT>Koud9voH_ zTIkw1pPTy&1^$9O$TL)J^eJr^6`&3ceHRxOv4Vol#h-Koz+J(z%=6UQIuGN^_oj2N zs)GG+kn|q7s(BLxq&U`IO)QEt7n2M@ymRZSfo;)B8dSlngfVpb`l0!{Gt&cd-GAdv z$IqAU!gRUcrbiorXvvnFHh4qlVMdj%FGx8c>UevPa8qVu&8TK{1eNd>*L7@}d+5Jh zfOSA8nHMgUQTF(qdt%;s$o^{($$2YO#Uneci0aau&^3|MGtat=B>2{IFlU`{Lr zBqN6geUc6}5HRSspFa`ozQWVdE|w00$uzWIs$wpd!^Vu8G#d=p2hpQ&G&gQEG)bei zQ~z2_jOCI0jNK?51f?g^pb9XMI33lcnarXo*FmSnwSzGOriQOP0g1QKs|i0Ctj4s) zjM+evU~uYP`Z)#o|*lWWVfe=r?wA=lZ|Au!xU2tVfrA#x}=k`#A_z zfqA!Uw(y7nqx+Kn9aj1NnetkP*K2eVi`)0-CZ#_J1`UD3Z%06gk0JhjIwuZ0p2WB&>rUKR;NO;vS*(#{jVe|&PLhF9IwgyMEVhfbT{ zwr#gC?u@c=yR@{F%L?AaP%+SdD}b4L-bZ$XhJ5Ifvxy^5w;jgB1H}TZjaB%>b7$41 zXJ7TfxK7 zdt&Rw;@DkQn<5>0JMc$M`aT*1-%?47NN5PKbo^$}1l+x=ab2v*HcCW|KSAkZU7f3o z%K#aN`RVYTV4qnliS05h&d<%QPV2`?R*OZ3=;bF(m2=*ta9XpUz%y-5#SL5C$tBP{ zeRa)5ViQ0d?^mF&R`p#2C7Ssk!=_H1wi7()FK=XLA1|n(mft-g!4GmGa0ZX-SmAq_ z2tT-`Y&?)1DBpOWqt9q1_j;gM6X=M_;L}M-oh}z$2V~P?k}%vaTG7XRJq)K#9bHd3 z==2%0qSvo?VYP!dXJMpku8tdSm+Nz6MH2h`v%wT$&QeELR&K*nii_i>+w;YTTkTEd zTn^^fTdDh$Z(0Jk%4K`=nfH|Wkzha{=(=zvOrmy#n2}y`aKEs;h{KeIktr^q}DL@9h2%oU+*)h-tgiucZLks5qDBSSH3xU_`> z6;O2ig$qh8)}1XLQJzMLK)cdQgY1$Ln>7cI92UHH6lv|sl`#vhaFCWPNlr)@uzkWT zC|GFp`3Wgw(n}b223}^gK1f@205R!w66@YL{e}G@D2o}X$=+&*&8vLUgHE8ZeU@~P z&=_b1HUz)8zH!9ge|^!f30X$nd-TZr&?P_>8KI55dYfkIfISl}A1D@judk|*XfqNs zg%uun)KcN(i4%=X08Z|N&8#5<*BW>}N(3xAK?zvk#Op|b$D`%5cCDrE@`Af}kx531 z)NcT%yIM@@)i)Kh(Ao5PA_wh z)_$DbT~(FY%$&cloP#DlgDgL-qb&2(Z^5`jN@}M5VL{K2u9?xg+0dc)b8@QSYQyyq z1u-He-LZt?#S04BovQsqp7BiEnn|t${c6n z81=56@)LKwkmzbAEbcXN%2~dTXUkjc3(DQC+j$tyb#+0{=jqK^(S=CtJ|H?S&U^7< zsruHvL#>g;f#&iLK9}X&LjA*3;|nroHmnst(nS=+N`ponUQ!hpfzQ32>x7HH(Yx-xrWg?xb+nwr@}V(<*uW zC-0C!XVoRhJU#24i(l&7uiw_@24bmD6aO;JDd=@!9Md7otxc#V2UL!sOQ-QGRBk@q z8Ldn^1_C#q1_#tk5(7gRC9HVy)L)S15ciAPn!9YV!)=0f(ij7S>-2(zQsa2nQ1^%c z|Eow@je5vGE;(x0?Xb-L2?_D*@Q<0K#Dc4R1DiP16Sod$SA)iI0|k*_@N2y_a@u!w zVTLEW{ld0CTWf<6A#(mFtdiC1)wTBg)*;>ABEc%0A9DP71<`VV^bj4L7dJK;eE-$S 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 literal 0 HcmV?d00001 diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile index 10856b571e..fb57d3e97b 100644 --- a/docs/doxygen/Doxyfile +++ b/docs/doxygen/Doxyfile @@ -158,6 +158,10 @@ INPUT = \ $(PROJECT_PATH)/components/hal/include/hal/i2c_types.h \ $(PROJECT_PATH)/components/hal/include/hal/i2s_types.h \ $(PROJECT_PATH)/components/hal/include/hal/lcd_types.h \ + $(PROJECT_PATH)/components/driver/include/driver/i2s_controller.h \ + $(PROJECT_PATH)/components/hal/include/hal/i2s_std.h \ + $(PROJECT_PATH)/components/hal/include/hal/i2s_pdm.h \ + $(PROJECT_PATH)/components/hal/include/hal/i2s_tdm.h \ $(PROJECT_PATH)/components/hal/include/hal/ledc_types.h \ $(PROJECT_PATH)/components/hal/include/hal/rtc_io_types.h \ $(PROJECT_PATH)/components/hal/include/hal/sdio_slave_types.h \ diff --git a/docs/en/api-reference/peripherals/i2s.rst b/docs/en/api-reference/peripherals/i2s.rst index cae7301292..36f219c031 100644 --- a/docs/en/api-reference/peripherals/i2s.rst +++ b/docs/en/api-reference/peripherals/i2s.rst @@ -3,8 +3,8 @@ Inter-IC Sound (I2S) {IDF_TARGET_I2S_NUM:default="two", esp32s2="one", esp32c3="one"} -Overview --------- +Introduction +------------ I2S (Inter-IC Sound) is a serial, synchronous communication protocol that is usually used for transmitting audio data between two digital audio devices. @@ -12,10 +12,10 @@ I2S (Inter-IC Sound) is a serial, synchronous communication protocol that is usu An I2S bus consists of the following lines: -- Master clock line (operational) -- Bit clock line -- Channel select line -- Serial data line +- MCLK: Master clock line. It's an optional signal depends on slave side, mainly for offering a reference clock to the I2S slave device. +- BCLK: Bit clock line. The bit clock for data line in common I2S applications. +- WS: Word(Slot) select line. It is usually used to identify the vocal tract except PDM mode. +- DIN/DOUT: Serial data input/output line. Each I2S controller has the following features that can be configured using the I2S driver: @@ -23,339 +23,606 @@ Each I2S controller has the following features that can be configured using the - Capable of acting as transmitter or receiver - DMA controller that allows for streaming sample data without requiring the CPU to copy each data sample -Each controller can operate in half-duplex communication mode. Thus, the two controllers can be combined to establish full-duplex communication. +.. only:: SOC_I2S_HW_VERSION_1 -.. only:: esp32 + Each controller can operate in simplex communication mode. Thus, the two controllers can be combined to establish full-duplex communication. - I2S0 output can be routed directly to the digital-to-analog converter's (DAC) output channels (GPIO 25 & GPIO 26) to produce direct analog output without involving any external I2S codecs. I2S0 can also be used for transmitting PDM (Pulse-density modulation) signals. +.. only:: SOC_I2S_HW_VERSION_2 -.. only:: esp32 or esp32s2 + Each controller has separate rx and tx channel. That means they are able to work under different clock and slot configurations with separate GPIO pins. Note that although their internal MCLK are separate, but the output MCLK signal can only be attached to one channel, we can't output two different MCLK at the same time. - The I2S peripherals also support LCD mode for communicating data over a parallel bus, as used by some LCD displays and camera modules. LCD mode has the following operational modes: +I2S Communication Mode +---------------------- - - LCD master transmitting mode - - Camera slave receiving mode - - ADC/DAC mode +Overview of All Modes +^^^^^^^^^^^^^^^^^^^^^ - For more information, see *{IDF_TARGET_NAME} Technical Reference Manual* > *I2S Controller (I2S)* > LCD Mode [`PDF <{IDF_TARGET_TRM_EN_URL}#camlcdctrl>`__]. +========= ======== ======== ======== ======== ======== ========== +Platform Standard PDM TX PDM RX TDM ADC/DAC LCD/Camera +========= ======== ======== ======== ======== ======== ========== +ESP32 port 0/1 port 0 port 0 none port 0 port 0 +ESP32S2 port 0 none none none none port 0 +ESP32C3 port 0 port 0 none port0 none none +ESP32S3 port 0/1 port 0 port 0 port 0/1 none none +========= ======== ======== ======== ======== ======== ========== + +Standard Mode +^^^^^^^^^^^^^ + +Standard mode always has left and right two sound channels which we called 'slots'. These slots can support 8/16/24/32 bits width sample data. And the communication format for the slots mainly includes the following formats: + +- **Philip Format**: Data signal have one bit shift comparing to the WS(word select) signal. And the duty of WS signal is 50%. + +.. figure:: ../../../_static/diagrams/i2s/std_philip.png + :align: center + :alt: Standard Philip Format + +- **MSB Format**: Almost same as philip format, but its data have no shift. + +.. figure:: ../../../_static/diagrams/i2s/std_msb.png + :align: center + :alt: Standard MSB Format + +- **PCM Short Format**: Data have one bit shift and meanwhile WS signal becomes a pulse lasting one BCLK(Bit Clock) cycle. + +.. figure:: ../../../_static/diagrams/i2s/std_pcm.png + :align: center + :alt: Standard PCM (Short Sync) Format + + +.. only:: SOC_I2S_SUPPORTS_PDM_TX + + PDM Mode (TX) + ^^^^^^^^^^^^^ + + PDM mode for tx channel can transfer PCM data into PDM format which always has left and right slots. PDM TX can only support 16 bits width sample data. PDM TX only need WS pin for clock signal and DOUT pin for data signal. This mode allows user to configure the up-sampling parameters :cpp:member:`i2s_pdm_tx_clk_config_t::up_sample_fp` :cpp:member:`i2s_pdm_tx_clk_config_t::up_sample_fs`. The up-sampling rate can be calculated by``up_sample_rate = fp / fs``, there are up-sampling modes in PDM TX: + + - **Fixed Clock Frequency**: In this mode the up-sampling rate will change according to the sample rate. We need to set ``fp = 960`` and ``fs = sample_rate / 100``, then the clock frequency(Fpdm) on WS pin will be fixed to 128 * 48 KHz = 6.144 MHz, note that this frequency is not equal to the sample rate(Fpcm). + - **Fixed Up-sampling Rate**: In this mode the up-sampling rate is fixed to 2. We need to set ``fp = 960`` and ``fs = 480``, then the clock frequency(Fpdm) on WS pin will be ``128 * sample_rate`` + +.. only:: SOC_I2S_SUPPORTS_PDM_RX + + PDM Mode (RX) + ^^^^^^^^^^^^^ + + PDM mode for rx channel can receive PDM format data and transfer the data into PCM format. PDM RX can only support 16 bits width sample data. PDM RX only need WS pin for clock signal and DIN pin for data signal. This mode allows user to configure the down-sampling parameter :cpp:member:`i2s_pdm_rx_slot_config_t::dn_sample_mode`, there are two down-sampling modes in PDM RX: + + - :cpp:member:`i2s_pdm_dsr_t::I2S_PDM_DSR_8S`: In this mode, the clock frequency(Fpdm) on WS pin will be sample_rate(Fpcm) * 64. + - :cpp:member:`i2s_pdm_dsr_t::I2S_PDM_DSR_16S`: In this mode, the clock frequency(Fpdm) on WS pin will be sample_rate(Fpcm) * 128. + +.. only:: SOC_I2S_SUPPORTS_PDM_TX or SOC_I2S_SUPPORTS_PDM_RX + + .. figure:: ../../../_static/diagrams/i2s/pdm.png + :align: center + :alt: PDM Format + +.. only:: SOC_I2S_SUPPORTS_TDM + + TDM Mode + ^^^^^^^^ + + TDM mode supports upto 16 slots, these slots can be enabled by :cpp:member:`i2s_tdm_slot_config_t::slot_mask`. But due to the hardware limitation, only upto 4 slots are supported while the slot is set to 32 bit-width, and 8 slots for 16 bit-width, 16 slots for 8 bit-width. The slot communication format of TDM is almost same as standard mode, but there are some small differences between them. + + - **Philip Format**: Data signal have one bit shift comparing to the WS(word select) signal. And no matter how many slots are contained in one frame, the duty of WS signal will always keep 50%. + + .. figure:: ../../../_static/diagrams/i2s/tdm_philip.png + :align: center + :alt: TDM Philip Format + + - **MSB Format**: Almost same as philip format, but its data have no shift. + + .. figure:: ../../../_static/diagrams/i2s/tdm_msb.png + :align: center + :alt: TDM MSB Format + + - **PCM Short Format**: Data have one bit shift and meanwhile WS signal becomes a pulse lasting one BCLK(Bit Clock) cycle for every frame. + + .. figure:: ../../../_static/diagrams/i2s/tdm_pcm_short.png + :align: center + :alt: TDM PCM (Short Sync) Format + + - **PCM Long Format**: Data have one bit shift and meanwhile WS signal will lasting one slot bit width for every frame. For example, if there are 4 slots enabled, then the duty of WS will be 25%, and if there are 5 slots, it will be 20%. + + .. figure:: ../../../_static/diagrams/i2s/tdm_pcm_long.png + :align: center + :alt: TDM PCM (Long Sync) Format + +.. only:: SOC_I2S_SUPPORTS_LDC_CAMERA + + LCD/Camera Mode + ^^^^^^^^^^^^^^^ + + LCD/Camera mode are only supported on I2S0 over a parallel bus. For LCD mode, I2S0 should working at master tx mode. For camera mode, I2S0 should working at slave rx mode. These two modes won't be implemented in I2S driver, please refer to :doc:`/api-reference/peripherals/lcd` for LCD implementation. For more information, see *{IDF_TARGET_NAME} Technical Reference Manual* > *I2S Controller (I2S)* > LCD Mode [`PDF <{IDF_TARGET_TRM_EN_URL}#camlcdctrl>`__]. + +.. only:: SOC_I2S_SUPPORTS_ADC_DAC + + ADC/DAC Mode + ^^^^^^^^^^^^ + + ADC/DAC mode only exist on ESP32 and are only supported on I2S0. Actually, they are two sub-modes of LCD/Camera mode. I2S0 can be routed directly to the internal analog-to-digital converter(ADC) or digital-to-analog converter(DAC). In other words, ADC/DAC peripherals can read/write continuously via I2S0 DMA. As they are not an actual communication mode, I2S driver will no longer implement them, for the full support of ADC/DAC, please refer to ADC(:doc:`/api-reference/peripherals/adc`) or DAC(:doc:`/api-reference/peripherals/dac`) driver for implementation. + +I2S Clock +--------- + +Clock Source +^^^^^^^^^^^^ + +- :cpp:member:`i2s_clock_src_t::I2S_CLK_160M_PLL`: 160 MHz PLL clock. .. only:: SOC_I2S_SUPPORTS_APLL - .. note:: + - :cpp:member:`i2s_clock_src_t::I2S_CLK_APLL`: Audio PLL clock, more precise than ``I2S_CLK_160M_PLL`` in high sample rate applications. Its frequency is configurable according to the sample rate, but if APLL has been occupied by emac or other channels already, the APLL frequency is not allowed to change, the driver will try to work under this APLL frequency, if this APLL frequency can't meet the requirements of I2S, the clock configuration will fail. - For high accuracy clock applications, use the APLL_CLK clock source, which has the frequency range of 16 ~ 128 MHz. You can enable the APLL_CLK clock source by setting :cpp:member:`i2s_config_t::use_apll` to ``TRUE``. +Clock Concepts +^^^^^^^^^^^^^^ - If :cpp:member:`i2s_config_t::use_apll` = ``TRUE`` and :cpp:member:`i2s_config_t::fixed_mclk` > ``0``, then the master clock output frequency for I2S will be equal to the value of :cpp:member:`i2s_config_t::fixed_mclk`, which means that the mclk frequency is provided by the user, instead of being calculated by the driver. +- **sample rate**: The number of sampled data in one second per slot. +- **sclk**: Source clock frequency. It is the frequency of the clock source. +- **mclk**: Master clock frequency. ``bclk`` is generate from this clock, in some cases, we need to output MCLK signal as a reference clock to synchronize BCLK and WS between I2S master role and slave role. +- **bclk**: Bit clock frequency. Every tick of this clock stands for one data bit on data pin. It means there will be 8/16/24/32 ``bclk`` ticks in one slot, because the number of ``bclk`` ticks in one slot is equal to the :cpp:member:`slot_bit_width` we set. +- **lrck** / **ws**: Left/Right clock or word select clock. For non-PDM mode, its frequency is equal to the sample rate. - The clock rate of the word select line, which is called audio left-right clock rate (LRCK) here, is always the divisor of the master clock output frequency and for which the following is always true: 0 < MCLK/LRCK/channels/bits_per_sample < 64. +.. note:: + Normally ``mclk`` should be the multiple of ``sample rate`` and ``bclk`` at the same time. This field :cpp:member:`i2s_std_clk_config_t::mclk_multiple` means the multiple of ``mclk`` to the ``sample rate``. If ``slot_bit_width`` is set to ``I2S_SLOT_BIT_WIDTH_24BIT``, to keep ``mclk`` a multiple to the ``bclk``, we need to set the :cpp:member:`i2s_std_clk_config_t::mclk_multiple` to ``I2S_MCLK_MULTIPLE_384``, otherwise the ``ws`` will be inaccurate. But in the most cases, ``I2S_MCLK_MULTIPLE_256`` should be enough. Functional Overview ------------------- +The I2S driver offers following services: -Installing the Driver -^^^^^^^^^^^^^^^^^^^^^ +Resources Management +^^^^^^^^^^^^^^^^^^^^ -Install the I2S driver by calling the function :cpp:func:`i2s_driver_install` and passing the following arguments: +There are three levels' resources in I2S driver: -- Port number -- The initialized :cpp:type:`i2s_config_t` struct defining the communication parameters -- Event queue size and handle +- ``platform level``: Resources of all I2S controllers in the current target. +- ``controller level``: Resources in one I2S controller. +- ``channel level``: Resources of tx or rx channel in one I2S controller. -An ``ESP_OK`` return value from :cpp:func:`i2s_driver_install` indictes I2S has started. +The public APIs are all channel level APIs, the channel handle :cpp:type:`i2s_chan_handle_t` can help user to manage the resources under a specific channel without considering the other two levels. The other two upper levels' resources are private and will be managed by the driver automatically. Users can call :cpp:func:`i2s_new_channel` to apply a channel handle and call :cpp:func:`i2s_del_channel` to delete it. -Configuration example: +Power Management +^^^^^^^^^^^^^^^^ -.. only:: not SOC_I2S_SUPPORTS_TDM +When power management is enabled (i.e. :ref:`CONFIG_PM_ENABLE` is on), the system will adjust or stop the source clock of I2S before going into light sleep, thus potentially changing the I2S signals and leading to transmitting or receiving invalid data. - .. code-block:: c +I2S driver can prevent the system from changing or stopping the source clock by acquiring a power management lock. When the source clock is generated from APB, the lock type will be set to :c:member:`ESP_PM_APB_FREQ_MAX` and when the source clock is APLL (if target support APLL), it will be set to :c:member:`ESP_PM_NO_LIGHT_SLEEP`. Whenever user is reading or writing via I2S, the driver will guarantee that the power management lock is acquired. Likewise, the driver releases the lock after reading or writing finished. - static const int i2s_num = 0; // i2s port number +Finite-State Machine +^^^^^^^^^^^^^^^^^^^^ - i2s_config_t i2s_config = { - .mode = I2S_MODE_MASTER | I2S_MODE_TX, - .sample_rate = 44100, - .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, - .communication_format = I2S_COMM_FORMAT_STAND_I2S - .tx_desc_auto_clear = false, - .dma_desc_num = 8, - .dma_frame_num = 64, - .use_apll = false, - .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1 // Interrupt level 1, default 0 - }; +There are six states for a I2S channel, they are ``registered``, ``initializing``, ``ready``, ``idle``, ``writing`` and ``reading``. Their relationship is shown in the following diagram: - i2s_driver_install(i2s_num, &i2s_config, 0, NULL); +.. figure:: ../../../_static/diagrams/i2s/i2s_state_machine.png + :align: center + :alt: I2S Finite-State Machine -.. only:: SOC_I2S_SUPPORTS_TDM +Data Transport +^^^^^^^^^^^^^^ - .. code-block:: c +The data transport of I2S peripheral, including sending and receiving, is realized by DMA. Before transporting data, we need to call :cpp:func:`i2s_start_channel` to start the specific channel. When we sent or received data reached the size of one DMA buffer, ``I2S_OUT_EOF`` or ``I2S_IN_SUC_EOF`` interrupt will be triggered. Note that the DMA buffer size is not equal to :cpp:member:`i2s_std_slot_config_t::dma_frame_num`, one frame here means all the sampled data in one WS circle. Therefore, ``dma_buffer_size = dma_frame_num * slot_num * slot_bit_width / 8``. For the transmit case, users input the data by :cpp:func:`i2s_write_channel`, ``i2s_write_channel`` will help user to copy the data from source buffer to the DMA tx buffer and waiting for transmit finished and then repeat until sent bytes reached the given size. For the receive case, the rx DMA buffer address will be sent from isr to :cpp:func:`i2s_read_channel`, ``i2s_read_channel`` will help user the copy the data from DMA rx buffer to the destination buffer. - static const int i2s_num = 0; // i2s port number +Configuration Setting +^^^^^^^^^^^^^^^^^^^^^^ - i2s_config_t i2s_config = { - .mode = I2S_MODE_MASTER | I2S_MODE_TX, - .sample_rate = 44100, - .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, - .communication_format = I2S_COMM_FORMAT_STAND_I2S, - .tx_desc_auto_clear = false, - .dma_desc_num = 8, - .dma_frame_num = 64, - .bits_per_chan = I2S_BITS_PER_SAMPLE_16BIT - }; +Users can initialize a channel by calling :cpp:func:`i2s_init_channel`, it will initialize a channel working at a specific mode by input corresponding clock and slot configurations. If we want to update the configuration after initialization, we need to call :cpp:func:`i2s_stop_channel` first to ensure the channel has stopped, then call :cpp:func:`i2s_set_slot` or :cpp:func:`i2s_set_clock` to update the configuration. - i2s_driver_install(i2s_num, &i2s_config, 0, NULL); +IRAM Safe +^^^^^^^^^ -Setting Communication Pins -^^^^^^^^^^^^^^^^^^^^^^^^^^ +By default, the GPTimer interrupt will be deferred when the Cache is disabled for reasons like writing/erasing Flash. Thus the EOF interrupt will not get executed in time, which is not expected in a real-time application. -Once the driver is installed, configure the physical GPIO pins to which the I2S signals will be routed. This is accomplished by calling the function :cpp:func:`i2s_set_pin` with the following arguments: +There's a Kconfig option :ref:`CONFIG_I2S_ISR_IRAM_SAFE` that will: -- Port number -- The structure :cpp:type:`i2s_pin_config_t` which defines the GPIO pin numbers for the MCK, BCK, WS, DATA out, and DATA in signals. To keep a current pin allocatopm pin for a specific signal, or to indicate an unused signal, pass the macro :c:macro:`I2S_PIN_NO_CHANGE`. See the example below. +1. Enable the interrupt being serviced even when cache is disabled -.. note:: - - MCK only takes effect in `I2S_MODE_MASTER` mode. - -.. code-block:: c - - static const i2s_pin_config_t pin_config = { - .mck_io_num = 0, - .bck_io_num = 4, - .ws_io_num = 5, - .data_out_num = 18, - .data_in_num = I2S_PIN_NO_CHANGE - }; - - i2s_set_pin(I2S_NUM, &pin_config); - -Running I2S Communication -^^^^^^^^^^^^^^^^^^^^^^^^^ - -To send data: - -- Prepare the data for sending -- Call the function :cpp:func:`i2s_write` and pass the data buffer address and data length to it - -The function will write the data to the DMA Tx buffer, and the data will be transmitted automatically by the I2S peripheral. - -.. code-block:: c - - i2s_write(I2S_NUM, samples_data, ((bits+8)/16)*SAMPLE_PER_CYCLE*4, &i2s_bytes_write, 100); - -To retrieve received data, use the function :cpp:func:`i2s_read`. It will retrieve the data from the DMA Rx buffer once the data is received by the I2S peripheral. - -.. code-block:: c - - i2s_read(I2S_NUM, data_recv, ((bits+8)/16)*SAMPLE_PER_CYCLE*4, &i2s_bytes_read, 100); - -You can temporarily halt the I2S driver by calling :cpp:func:`i2s_stop`, which disables the I2S Tx/Rx units until :cpp:func:`i2s_start` is called. The driver automatically starts the I2S peripheral after :cpp:func:`i2s_driver_install` is called, eliminating the need to call :cpp:func:`i2s_start`. - - -Deleting the Driver -^^^^^^^^^^^^^^^^^^^ - -Once I2S communication is no longer required, the driver can be removed to free allocated resources by calling :cpp:func:`i2s_driver_uninstall`. +2. Place driver object into DRAM (in case it's linked to PSRAM by accident) +This will allow the interrupt to run while the cache is disabled but will come at the cost of increased IRAM consumption. Application Example ------------------- -Code examples for the I2S driver can be found in the directory :example:`peripherals/i2s`. +The examples of the I2S driver can be found in the directory :example:`peripherals/i2s`. +Here are some simple usages of each mode: -.. only:: SOC_I2S_SUPPORTS_ADC or SOC_I2S_SUPPORTS_DAC +Standard TX/RX usage +^^^^^^^^^^^^^^^^^^^^ - Additionally, there are two short configuration examples for the I2S driver. +We can choose different helper macros to generate different slot communication format for standard mode. As described above, there are three formats in standard mode, their helper macros are: -.. only:: not SOC_I2S_SUPPORTS_ADC or SOC_I2S_SUPPORTS_DAC +- ``I2S_STD_PHILIP_SLOT_CONFIG(bits_per_sample, mono_or_stereo)`` +- ``I2S_STD_PCM_SLOT_CONFIG(bits_per_sample, mono_or_stereo)`` +- ``I2S_STD_MSB_SLOT_CONFIG(bits_per_sample, mono_or_stereo)`` - Additionally, there is a short configuration examples for the I2S driver. +The clock config helper macro is: -I2S configuration -^^^^^^^^^^^^^^^^^ +- ``I2S_STD_CLK_CONFIG(rate)`` -Example for general usage: +You can refer to :ref:`i2s-api-reference-i2s_std` for STD API information. +And for more details, please refer to :component_file:`hal/include/hal/i2s_std.h`. -.. only:: not SOC_I2S_SUPPORTS_TDM +.. code-block:: c + + #include "driver/i2s_controller.h" + #include "driver/gpio.h" + + i2s_chan_handle_t tx_handle; + i2s_gpio_config_t i2s_pin = { + .mclk = I2S_GPIO_UNUSED, + .bclk = GPIO_NUM_4, + .ws = GPIO_NUM_5, + .dout = GPIO_NUM_18, + .din = I2S_GPIO_UNUSED + }; + /* Get the default channel configuration by helper macro. + * This helper macro is defined in 'i2s_controller.h' and shared by all the i2s communication mode. + * It can help to specify the I2S role, mode and gpio pins */ + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + /* Apply a new tx channel and get the handle of this channel */ + i2s_new_channel(&chan_cfg, &tx_handle, NULL); + + /* Get the default std philip format slot config and default std clock config + * These two helper macros is defined in 'i2s_std.h' which can only be used in STD mode. + * They can help to specify the slot and clock configurations for initialization or updating */ + i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO); + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(48000); + /* Initialize the channel */ + i2s_init_channel(tx_handle, &clk_cfg, &slot_cfg); + + /* If we meed to acquire the I2S events, we can apply an event handle for receiving the events */ + // QueueHandle_t evt_que = i2s_get_event_queue(tx_handle, 15); + + /* Before write data, we have to start the tx channel */ + i2s_start_channel(tx_handle); + i2s_write_channel(tx_handle, src_buf, bytes_to_write, bytes_written, ticks_to_wait); + + /* If we need to update the configurations of slot or clock, + * we need to stop the channel first and then update it */ + // i2s_stop_channel(tx_handle); + // slot_cfg.slot_mode = I2S_SLOT_MODE_MONO; // Default is stereo + // i2s_set_slot(tx_handle, &slot_cfg); + // i2s_std_clk_config_t new_clk_cfg = I2S_STD_CLK_CONFIG(96000); + // i2s_set_clock(tx_handle, &new_clk_cfg); + + /* If the handle is not needed any more, we can delete it to release the channel resources */ + i2s_del_channel(tx_handle); + +.. code-block:: c + + #include "driver/i2s_controller.h" + #include "driver/gpio.h" + + i2s_chan_handle_t rx_handle; + i2s_gpio_config_t i2s_pin = { + .mclk = I2S_GPIO_UNUSED, + .bclk = GPIO_NUM_4, + .ws = GPIO_NUM_5, + .dout = I2S_GPIO_UNUSED, + .din = GPIO_NUM_19 + }; + /* Get the default channel configuration by helper macro. + * This helper macro is defined in 'i2s_controller.h' and shared by all the i2s communication mode. + * It can help to specify the I2S role, mode and gpio pins */ + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + /* Apply a new rx channel and get the handle of this channel */ + i2s_new_channel(&chan_cfg, NULL, &rx_handle); + + /* Get the default std philip format slot config and default std clock config + * These two helper macros is defined in 'i2s_std.h' which can only be used in STD mode. + * They can help to specify the slot and clock configurations for initialization or updating */ + i2s_std_slot_config_t slot_cfg = I2S_STD_MSB_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO); // get the default MSB format slot config + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(48000); + /* Initialize the channel */ + i2s_init_channel(rx_handle, &clk_cfg, &slot_cfg); + + /* Before read data, we have to start the rx channel */ + i2s_start_channel(rx_handle); + i2s_read_channel(rx_handle, desc_buf, bytes_to_read, bytes_read, ticks_to_wait); + + /* If the handle is not needed any more, we can delete it to release the channel resources */ + i2s_del_channel(rx_handle); + +.. only:: SOC_I2S_SUPPORTS_PDM_TX + + PDM TX usage + ^^^^^^^^^^^^ + + For PDM mode in tx channel, the slot configuration helper macro is: + + - ``I2S_PDM_TX_SLOT_CONFIG(bits_per_sample, mono_or_stereo)`` + + The clock configuration helper macro is: + + - ``I2S_PDM_TX_CLK_CONFIG(rate)`` + + You can refer to :ref:`i2s-api-reference-i2s_pdm` for PDM TX API information. + And for more details, please refer to :component_file:`hal/include/hal/i2s_pdm.h`. .. code-block:: c - #include "driver/i2s.h" + #include "driver/i2s_controller.h" + #include "driver/gpio.h" - static const int i2s_num = 0; // i2s port number - - i2s_config_t i2s_config = { - .mode = I2S_MODE_MASTER | I2S_MODE_TX, - .sample_rate = 44100, - .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, - .communication_format = I2S_COMM_FORMAT_STAND_I2S - .tx_desc_auto_clear = false, - .dma_desc_num = 8, - .dma_frame_num = 64, - .use_apll = false, - .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1 // Interrupt level 1, default 0 + i2s_chan_handle_t tx_handle; + i2s_gpio_config_t i2s_pin = { + .mclk = I2S_GPIO_UNUSED, + .bclk = I2S_GPIO_UNUSED, + .ws = GPIO_NUM_5, + .dout = GPIO_NUM_18, + .din = I2S_GPIO_UNUSED }; - static const i2s_pin_config_t pin_config = { - .bck_io_num = 4, - .ws_io_num = 5, - .data_out_num = 18, - .data_in_num = I2S_PIN_NO_CHANGE + /* Set the channel mode to PDM TX */ + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_PDM, &i2s_pin); + i2s_new_channel(&chan_cfg, &tx_handle, NULL); + + /* Get the default pdm tx format slot config and default pdm tx config */ + i2s_pdm_tx_slot_config_t tx_slot_cfg = I2S_PDM_TX_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO); + i2s_pdm_tx_clk_config_t tx_clk_cfg = I2S_PDM_TX_CLK_CONFIG(36000); + i2s_init_channel(tx_handle, &tx_clk_cfg, &tx_slot_cfg); + + ... + + +.. only:: SOC_I2S_SUPPORTS_PDM_RX + + PDM RX usage + ^^^^^^^^^^^^ + + For PDM mode in RX channel, the slot configuration helper macro is: + + - ``I2S_PDM_RX_SLOT_CONFIG(bits_per_sample, mono_or_stereo)`` + + The clock configuration helper macro is: + + - ``I2S_PDM_RX_CLK_CONFIG(rate)`` + + You can refer to :ref:`i2s-api-reference-i2s_pdm` for PDM RX API information. + And for more details, please refer to :component_file:`hal/include/hal/i2s_pdm.h`. + + .. code-block:: c + + #include "driver/i2s_controller.h" + #include "driver/gpio.h" + + i2s_chan_handle_t rx_handle; + i2s_gpio_config_t i2s_pin = { + .mclk = I2S_GPIO_UNUSED, + .bclk = I2S_GPIO_UNUSED, + .ws = GPIO_NUM_5, + .dout = I2S_GPIO_UNUSED, + .din = GPIO_NUM_19 }; - i2s_driver_install(i2s_num, &i2s_config, 0, NULL); //install and start i2s driver - i2s_set_pin(i2s_num, &pin_config); + /* Set the channel mode to PDM RX */ + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_PDM, &i2s_pin); + i2s_new_channel(&chan_cfg, &rx_handle, NULL); + + /* Get the default pdm rx format slot config and default pdm rx clock config */ + i2s_pdm_rx_slot_config_t rx_slot_cfg = I2S_PDM_RX_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO); + // rx_slot_cfg.slot_mode = I2S_SLOT_MODE_STEREO; // Default is mono + i2s_pdm_rx_clk_config_t rx_clk_cfg = I2S_PDM_RX_CLK_CONFIG(36000); + i2s_init_channel(rx_handle, &clk_cfg, &slot_cfg); - ... - /* You can reset parameters by calling 'i2s_set_clk' - * - * The low 16 bits are the valid data bits in one chan and the high 16 bits are - * the total bits in one chan. If high 16 bits is smaller than low 16 bits, it will - * be set to a same value as low 16 bits. - */ - uint32_t bits_cfg = (I2S_BITS_PER_CHAN_32BIT << 16) | I2S_BITS_PER_SAMPLE_16BIT; - i2s_set_clk(i2s_num, 22050, bits_cfg, I2S_CHANNEL_STEREO); ... - i2s_driver_uninstall(i2s_num); //stop & destroy i2s driver .. only:: SOC_I2S_SUPPORTS_TDM - .. code-block:: c + TDM TX/RX usage + ^^^^^^^^^^^^^^^ - #include "driver/i2s.h" + We can choose different helper macros to generate different slot communication format for TDM mode. As described above, there are four formats in TDM mode, their helper macros are: - static const int i2s_num = 0; // i2s port number + - ``I2S_TDM_PHILIP_SLOT_CONFIG(bits_per_sample, mono_or_stereo, mask)`` + - ``I2S_TDM_MSB_SLOT_CONFIG(bits_per_sample, mono_or_stereo, mask)`` + - ``I2S_TDM_PCM_SHORT_SLOT_CONFIG(bits_per_sample, mono_or_stereo, mask)`` + - ``I2S_TDM_PCM_LONG_SLOT_CONFIG(bits_per_sample, mono_or_stereo, mask)`` - i2s_config_t i2s_config = { - .mode = I2S_MODE_MASTER | I2S_MODE_TX, - .sample_rate = 44100, - .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, - .communication_format = I2S_COMM_FORMAT_STAND_I2S - .tx_desc_auto_clear = false, - .dma_desc_num = 8, - .dma_frame_num = 64 - }; + The clock config helper macro is: - static const i2s_pin_config_t pin_config = { - .bck_io_num = 4, - .ws_io_num = 5, - .data_out_num = 18, - .data_in_num = I2S_PIN_NO_CHANGE - }; + - ``I2S_TDM_CLK_CONFIG(rate)`` - i2s_driver_install(i2s_num, &i2s_config, 0, NULL); //install and start i2s driver - i2s_set_pin(i2s_num, &pin_config); - - ... - /* You can reset parameters by calling 'i2s_set_clk' - * - * The low 16 bits are the valid data bits in one chan and the high 16 bits are - * the total bits in one chan. If high 16 bits is smaller than low 16 bits, it will - * be set to a same value as low 16 bits. - */ - uint32_t bits_cfg = (I2S_BITS_PER_CHAN_32BIT << 16) | I2S_BITS_PER_SAMPLE_16BIT; - i2s_set_clk(i2s_num, 22050, bits_cfg, I2S_CHANNEL_STEREO); - ... - - i2s_driver_uninstall(i2s_num); //stop & destroy i2s driver - - I2S on {IDF_TARGET_NAME} support TDM mode, up to 16 channels are available in TDM mode. If you want to use TDM mode, set field ``channel_format`` of :cpp:type:`i2s_config_t` to ``I2S_CHANNEL_FMT_MULTIPLE``. Then enable the channels by setting ``chan_mask`` using masks in :cpp:type:`i2s_channel_t`, the number of active channels and total channels will be calculate automatically. You can also set a particular total channel number for it, but it shouldn't be smaller than the largest channel you use. - - If active channels are discrete, the inactive channels within total channels will be filled by a constant automatically. But if ``skip_msk`` is enabled, these inactive channels will be skiped. + You can refer to :ref:`i2s-api-reference-i2s_tdm` for TDM API information. + And for more details, please refer to :component_file:`hal/include/hal/i2s_tdm.h`. .. code-block:: c - #include "driver/i2s.h" + #include "driver/i2s_controller.h" + #include "driver/gpio.h" - static const int i2s_num = 0; // i2s port number - - i2s_config_t i2s_config = { - .mode = I2S_MODE_MASTER | I2S_MODE_TX, - .sample_rate = 44100, - .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, - .channel_format = I2S_CHANNEL_FMT_MULTIPLE, - .communication_format = I2S_COMM_FORMAT_STAND_I2S - .tx_desc_auto_clear = false, - .dma_desc_num = 8, - .dma_frame_num = 64, - .chan_mask = I2S_TDM_ACTIVE_CH0 | I2S_TDM_ACTIVE_CH2 + i2s_chan_handle_t tx_handle; + i2s_gpio_config_t i2s_pin = { + .mclk = I2S_GPIO_UNUSED, + .bclk = GPIO_NUM_4, + .ws = GPIO_NUM_5, + .dout = GPIO_NUM_18, + .din = I2S_GPIO_UNUSED }; - static const i2s_pin_config_t pin_config = { - .bck_io_num = 4, - .ws_io_num = 5, - .data_out_num = 18, - .data_in_num = I2S_PIN_NO_CHANGE - }; + /* Set the channel mode to TDM */ + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_TDM, &i2s_pin); + i2s_new_channel(&chan_cfg, &tx_handle, NULL); - i2s_driver_install(i2s_num, &i2s_config, 0, NULL); //install and start i2s driver - i2s_set_pin(i2s_num, &pin_config); + /* Get the default tdm format slot config and default tdm clock config */ + i2s_tdm_slot_config_t slot_cfg = I2S_TDM_MSB_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO, I2S_TDM_SLOT0 | I2S_TDM_SLOT1 | I2S_TDM_SLOT2 | I2S_TDM_SLOT3); + // slot_cfg.mono = true; // Default is false, set true will let all the active slots send same data + i2s_tdm_clk_config_t clk_cfg = I2S_TDM_CLK_CONFIG(44100); + i2s_init_channel(tx_handle, &clk_cfg, &slot_cfg); ... - /* You can reset parameters by calling 'i2s_set_clk' - * - * The low 16 bits are the valid data bits in one chan and the high 16 bits are - * the total bits in one chan. If high 16 bits is smaller than low 16 bits, it will - * be set to a same value as low 16 bits. - */ - uint32_t bits_cfg = (I2S_BITS_PER_CHAN_32BIT << 16) | I2S_BITS_PER_SAMPLE_16BIT; - i2s_set_clk(i2s_port_t i2s_num, 22050, bits_cfg, I2S_TDM_ACTIVE_CH0 | I2S_TDM_ACTIVE_CH1); // set clock - ... - - i2s_driver_uninstall(i2s_num); //stop & destroy i2s driver - -.. only:: SOC_I2S_SUPPORTS_ADC or SOC_I2S_SUPPORTS_DAC - - Configuring I2S to use internal DAC for analog output - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code-block:: c - #include "driver/i2s.h" - #include "freertos/queue.h" + #include "driver/i2s_controller.h" + #include "driver/gpio.h" - static const int i2s_num = 0; // i2s port number - - static const i2s_config_t i2s_config = { - .mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN, - .sample_rate = 44100, - .bits_per_sample = 16, /* the DAC module will only take the 8bits from MSB */ - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, - .intr_alloc_flags = 0, // default interrupt priority - .dma_desc_num = 8, - .dma_frame_num = 64, - .use_apll = false + i2s_chan_handle_t rx_handle; + i2s_gpio_config_t i2s_pin = { + .mclk = I2S_GPIO_UNUSED, + .bclk = GPIO_NUM_4, + .ws = GPIO_NUM_5, + .dout = I2S_GPIO_UNUSED, + .din = GPIO_NUM_19 }; + /* Set the channel mode to TDM */ + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_TDM, &i2s_pin); + i2s_new_channel(&chan_cfg, NULL, &rx_handle); + + /* Get the default tdm format slot config and default tdm clock config */ + i2s_tdm_slot_config_t slot_cfg = I2S_TDM_MSB_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO, I2S_TDM_SLOT0 | I2S_TDM_SLOT1 | I2S_TDM_SLOT2 | I2S_TDM_SLOT3); + i2s_tdm_clk_config_t clk_cfg = I2S_TDM_CLK_CONFIG(44100); + i2s_init_channel(tx_handle, &clk_cfg, &slot_cfg); ... - i2s_driver_install(i2s_num, &i2s_config, 0, NULL); //install and start i2s driver +Full-duplex +^^^^^^^^^^^ - i2s_set_pin(i2s_num, NULL); //for internal DAC, this will enable both of the internal channels +Full-duplex mode will register tx and rx channel in a I2S port at the same time, and they will share the BCLK and WS signal. Currently STD and TDM communication mode are able to apply full-duplex mode in following way, but PDM full-duplex is not supported in this way. - //You can call i2s_set_dac_mode to set built-in DAC output mode. - //i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN); +Note that since the handle is the channel handle, we have to apply same slot and clock configurations for both tx and rx channel one by one. - i2s_set_sample_rates(i2s_num, 22050); //set sample rates +Here is an example of how to apply a pair of full-duplex channels: - i2s_driver_uninstall(i2s_num); //stop & destroy i2s driver +.. code-block:: c + + #include "driver/i2s_controller.h" + #include "driver/gpio.h" + + i2s_chan_handle_t tx_handle; + i2s_chan_handle_t rx_handle; + i2s_gpio_config_t i2s_pin = { + .mclk = I2S_GPIO_UNUSED, + .bclk = GPIO_NUM_4, + .ws = GPIO_NUM_5, + .dout = GPIO_NUM_18, + .din = GPIO_NUM_19 + }; + + /* Set the channel mode to STD */ + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + /* Apply for tx and rx channel at the same time, then they will work in full-duplex mode */ + i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle); + + /* Get the default configurations */ + i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO); + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(32000); + /* Set the configurations for BOTH TWO channels, since tx and rx channel have to be same in full-duplex mode */ + i2s_init_channle(tx_handle, &clk_cfg, &slot_cfg); + i2s_init_channle(rx_handle, &clk_cfg, &slot_cfg); + + i2s_start_channel(tx_handle); + i2s_start_channel(rx_handle); + + ... + +.. only:: SOC_I2S_HW_VERSION_1 + + Simplex Mode + ^^^^^^^^^^^^ + + To apply the simplex mode, :c:func:`i2s_new_channel` should be called for each channel. The clock and gpio pins of TX/RX channel on {IDF_TARGET_NAME} are not separate, therefore TX and RX channel can't coexist on a same I2S port in simplex mode. + + .. code-block:: c + + #include "driver/i2s_controller.h" + #include "driver/gpio.h" + + i2s_chan_handle_t tx_handle; + i2s_chan_handle_t rx_handle; + i2s_gpio_config_t tx_pin = { + .mclk = GPIO_NUM_0, + .bclk = GPIO_NUM_4, + .ws = GPIO_NUM_5, + .dout = GPIO_NUM_18, + .din = I2S_GPIO_UNUSED + }; + i2s_chan_config_t tx_chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, tx_pin); + i2s_new_channel(&tx_chan_cfg, &tx_handle, NULL); + i2s_std_slot_config_t tx_slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO); + tx_slot_cfg.auto_clear = false; + i2s_std_clk_config_t tx_clk_cfg = I2S_STD_CLK_CONFIG(48000); + i2s_init_channel(tx_handle, &tx_clk_cfg, &tx_slot_cfg); + i2s_start_channel(tx_handle); + + i2s_gpio_config_t rx_pin = { + .mclk = I2S_GPIO_UNUSED, + .bclk = GPIO_NUM_6, + .ws = GPIO_NUM_7, + .dout = I2S_GPIO_UNUSED, + .din = GPIO_NUM_19 + }; + i2s_chan_config_t rx_chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, rx_pin); + /* rx channel will be registered on another I2S, if no other available I2S unit found + * it will return ESP_ERR_NOT_FOUND */ + i2s_new_channel(&rx_chan_cfg, NULL, &rx_handle); + i2s_std_slot_config_t rx_slot_cfg = I2S_STD_MSB_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO); + i2s_std_clk_config_t rx_clk_cfg = I2S_STD_CLK_CONFIG(16000); + i2s_init_channel(rx_handle, &rx_clk_cfg, &rx_slot_cfg); + i2s_start_channel(rx_handle); + +.. only:: SOC_I2S_HW_VERSION_2 + + Simplex Mode + ^^^^^^^^^^^^ + + To apply the simplex mode, :c:func:`i2s_new_channel` should be called for each channel. The clock and gpio pins of TX/RX channel on {IDF_TARGET_NAME} are separate, they can be configured in different modes and clocks, and they are able to coexist on a same I2S port in simplex mode. So PDM duplex can be realized by registering PDM TX simplex and PDM RX simplex on a same I2S port. But in this way, PDM TX/RX might work with different clocks, take care when configuring the gpio pins and clocks. + + The following codes offer an example for the simplex mode, but note that, although the internal MCLK signals for tx and rx channel are separate, the output MCLK can only be bound to one of them, if both channel initialized MCLK, it depends on which is initialized later. + +1. Determine the interrupt interval. Generally, when data lost happened, the interval should be the bigger the better, it can help to reduce the interrupt times, i.e., ``dma_frame_num`` should be as big as possible while the DMA buffer size won't exceed its maximum value 4092. The relationships are:: + + #include "driver/i2s_controller.h" + #include "driver/gpio.h" + + i2s_chan_handle_t tx_handle; + i2s_chan_handle_t rx_handle; + i2s_gpio_config_t tx_pin = { + .mclk = GPIO_NUM_0, + .bclk = GPIO_NUM_4, + .ws = GPIO_NUM_5, + .dout = GPIO_NUM_18, + .din = I2S_GPIO_UNUSED + }; + i2s_chan_config_t tx_chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, tx_pin); + tx_chan_cfg.id = I2S_NUM_0; // Specify the port id + i2s_new_channel(&tx_chan_cfg, &tx_handle, NULL); + i2s_std_slot_config_t tx_slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO); + tx_slot_cfg.auto_clear = false; + i2s_std_clk_config_t tx_clk_cfg = I2S_STD_CLK_CONFIG(48000); + i2s_init_channel(tx_handle, &tx_clk_cfg, &tx_slot_cfg); + i2s_start_channel(tx_handle); + + i2s_gpio_config_t rx_pin = { + .mclk = I2S_GPIO_UNUSED, + .bclk = GPIO_NUM_6, + .ws = GPIO_NUM_7, + .dout = I2S_GPIO_UNUSED, + .din = GPIO_NUM_19 + }; + i2s_chan_config_t rx_chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, rx_pin); + tx_chan_cfg.id = I2S_NUM_0; // Specify the port id + i2s_new_channel(&rx_chan_cfg, NULL, &rx_handle); + i2s_std_slot_config_t rx_slot_cfg = I2S_STD_MSB_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO); + i2s_std_clk_config_t rx_clk_cfg = I2S_STD_CLK_CONFIG(16000); + i2s_init_channel(rx_handle, &rx_clk_cfg, &rx_slot_cfg); + i2s_start_channel(rx_handle); Application Notes -^^^^^^^^^^^^^^^^^ +----------------- -For the applications that need a high frequency sample rate, sometimes the massive throughput of receiving data may cause data lost. Users can receive data loss event by the event queue, it will trigger an ``I2S_EVENT_RX_Q_OVF`` event.: +How to Prevent Data Lost +^^^^^^^^^^^^^^^^^^^^^^^^ - .. code-block:: c +For the applications that need a high frequency sample rate, sometimes the massive throughput of receiving data may cause data lost. Users can receive data lost event by the event queue: - QueueHandle_t evt_que; - i2s_driver_install(i2s_num, &i2s_config, 10, &evt_que); + dma_desc_num > polling_cycle / interrupt_interval + + QueueHandle_t evt_que = i2s_get_event_queue(rx_handle, 10); ... i2s_event_t evt; xQueueReceive(evt_que, &evt, portMAX_DELAY); @@ -363,31 +630,31 @@ For the applications that need a high frequency sample rate, sometimes the massi printf("RX data dropped\n"); } -Please follow these steps to calculate the parameters that can prevent data lost: +Please follow these steps to prevent data lost: 1. Determine the interrupt interval. Generally, when data lost happened, the interval should be the bigger the better, it can help to reduce the interrupt times, i.e., ``dma_frame_num`` should be as big as possible while the DMA buffer size won't exceed its maximum value 4092. The relationships are:: interrupt_interval(unit: sec) = dma_frame_num / sample_rate - dma_buffer_size = dma_frame_num * channel_num * data_bit_width / 8 <= 4092 + dma_buffer_size = dma_frame_num * slot_num * data_bit_width / 8 <= 4092 -2. Determine the ``dma_desc_num``. The ``dma_desc_num`` is decided by the max time of ``i2s_read`` polling cycle, all the data should be stored between two ``i2s_read``. This cycle can be measured by a timer or an outputting gpio signal. The relationship should be:: +2. Determine the ``dma_desc_num``. The ``dma_desc_num`` is decided by the max time of ``i2s_read_channel`` polling cycle, we need to guarantee all the data can be stored between two ``i2s_read_channel``. This cycle can be measured by a timer or an outputting gpio signal. The relationship is:: dma_desc_num > polling_cycle / interrupt_interval -3. Determine the receiving buffer size. The receiving buffer that offered by user in ``i2s_read`` should be able to take all the data in all dma buffers, that means it should be bigger than the total size of all the dma buffers:: +3. Determine the receiving buffer size. The receiving buffer that offered by user in ``i2s_read_channel`` should be able to take all the data in all dma buffers, that means it should be bigger than the total size of all the dma buffers:: recv_buffer_size > dma_desc_num * dma_buffer_size -For example, if there is a I2S application:: +For example, if there is a I2S application, we have known these values:: sample_rate = 144000 Hz data_bit_width = 32 bits - channel_num = 2 + slot_num = 2 polling_cycle = 10ms -Then we need to calculate ``dma_frame_num``, ``dma_desc_num`` and ``recv_buf_size`` according to the known values:: +Then we need to calculate ``dma_frame_num``, ``dma_desc_num`` and ``recv_buf_size`` according to the given known values:: - dma_frame_num * channel_num * data_bit_width / 8 = dma_buffer_size <= 4092 + dma_frame_num * slot_num * data_bit_width / 8 = dma_buffer_size <= 4092 dma_frame_num <= 511 interrupt_interval = dma_frame_num / sample_rate = 511 / 144000 = 0.003549 s = 3.549 ms dma_desc_num > polling_cycle / interrupt_interval = cell(10 / 3.549) = cell(2.818) = 3 @@ -397,6 +664,41 @@ Then we need to calculate ``dma_frame_num``, ``dma_desc_num`` and ``recv_buf_siz API Reference ------------- -.. include-build-file:: inc/i2s.inc -.. include-build-file:: inc/i2s_types.inc +.. _i2s-api-reference-i2s_std: +Standard Mode +^^^^^^^^^^^^^ + +.. include-build-file:: inc/i2s_std.inc + +.. only:: SOC_I2S_SUPPORTS_PDM + + .. _i2s-api-reference-i2s_pdm: + + PDM Mode + ^^^^^^^^ + + .. include-build-file:: inc/i2s_pdm.inc + +.. only:: SOC_I2S_SUPPORTS_TDM + + .. _i2s-api-reference-i2s_tdm: + + TDM Mode + ^^^^^^^^ + + .. include-build-file:: inc/i2s_tdm.inc + +.. _i2s-api-reference-i2s_driver: + +I2S Driver +^^^^^^^^^^ + +.. include-build-file:: inc/i2s_controller.inc + +.. _i2s-api-reference-i2s_types: + +I2S Types +^^^^^^^^^ + +.. include-build-file:: inc/i2s_types.inc diff --git a/docs/en/migration-guides/peripherals.rst b/docs/en/migration-guides/peripherals.rst index e951ef55cb..479894c145 100644 --- a/docs/en/migration-guides/peripherals.rst +++ b/docs/en/migration-guides/peripherals.rst @@ -254,4 +254,64 @@ LCD Dedicated GPIO Driver --------------------- - - All of the dedicated GPIO related LL functionsn in ``cpu_ll.h`` have been moved to ``dedic_gpio_cpu_ll.h`` and renamed. \ No newline at end of file + - All of the dedicated GPIO related LL functionsn in ``cpu_ll.h`` have been moved to ``dedic_gpio_cpu_ll.h`` and renamed. + +I2S driver +---------- + +Since the old driver is unable to support all the new features on ESP32-C3 & ESP32-S3, I2S driver is re-designed to make it more compatibile and flexibile to all the communication modes. New APIs are available by including :component_file:`driver/include/driver/i2s_controller.h`. Meanwhile, the old APIs in :component_file:`driver/deprecated/driver/i2s.h` are still supported for backward compatibility. But there will be warnings if you keep using the old APIs in your project, these warnings can be suppressed by the Kconfig option :ref:`CONFIG_I2S_SUPPRESS_DEPRECATE_WARN`. Here is the general overview of the current I2S files: + +.. figure:: ../../_static/diagrams/i2s/i2s_file_structure.png + :align: center + :alt: I2S File Structure + +Breaking changes in Concepts +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- The minimum control unit in new I2S driver will be tx/rx channel instead of a whole I2S controller. + + 1. The tx/rx channel in a same I2S controller can be controlled separately, that means they will be initialized, started or stopped separately. Especially for ESP32-C3 and ESP32-S3, tx and rx channels in one controller can be configured to different clocks or modes now, they are able to work in a totally separate way which can help to save the resources of I2S controller. But for ESP32 and ESP32-S2, though their tx/rx can be controlled separately, some hardware resources are still shared by tx and rx, they might affect each other if they are configured to different configurations; + 2. The channels can be registered to an available I2S controller automatically by choosing :cpp:member:`i2s_port_t::I2S_NUM_AUTO` as I2S port id. The driver will help you to search for the available tx/rx channel. Of cause, you can still choose a specific port for it; + 3. :c:type:`i2s_chan_handle_t` is the handle that used for identifying the I2S channels. All the APIs will require the channel handle, users need to maintain the channel handles by themselves; + 4. In order to distinguish tx/rx channel and sound channel, now the word 'channel' is only stand for the tx/rx channel in new driver, meanwhile the sound channel will be called 'slot'. + +- I2S communication modes are extracted into three modes. + + 1. **Standard mode**: Standard mode always has two slots, it can support Philip, MSB and PCM(short sync) format, please refer to :component_file:`hal/include/hal/i2s_std.h` for details; + 2. **PDM mode**: PDM mode only support two slots with 16 bits data width, but the configurations of PDM TX and PDM RX are little bit different. For PDM TX, the sample rate can be set by :cpp:member:`i2s_pdm_tx_clk_config_t::sample_rate`, and its clock frequency is depended on the up-sampling configuration. For PDM RX, the sample rate can be set by :cpp:member:`i2s_pdm_rx_clk_config_t::sample_rate`, and its clock frequency is depended on the down-sampling configuration. Please refer to :component_file:`hal/include/hal/i2s_pdm.h` for details; + 3. **TDM mode**: TDM mode can support upto 16 slots. It can work in Philip, MSB, PCM(short sync) and PCM(long sync) format, please refer to :component_file:`hal/include/hal/i2s_tdm.h` for details; + 4. When we allocate a new channel in a specific mode, we must initialize this channel by corresponding slot configurations and clock configurations. We strongly recommend to use the helper macros to generate the default configurations, in case the default values will be changed one day. + 5. Although there are three modes, they still share some general slot and clock configurations which are defined in :component_file:`hal/include/hal/i2s_hal.h` + +- States and state-machine are adopted in the new I2S driver to avoid APIs are called in wrong state. + +- The slot configurations and clock configurations can be configured separately. + + 1. Calling :func:`i2s_init_channel` to initialize the slot/clock/gpio_pin configurations; + 2. Calling :c:func:`i2s_set_slot` can change the slot configurations after initialization; + 3. Calling :c:func:`i2s_set_clock` can change the clock configurations after initialization. + +- ADC and DAC modes are removed. They will only be supported in their own driver and legacy I2S driver. + +- :c:func:`i2s_write_channel` and :c:func:`i2s_read_channel` can be aborted by :c:func:`i2s_abort_reading_writing` now. + +Breaking Changes in Usage +~~~~~~~~~~~~~~~~~~~~~~~~~ + +To use the new I2S driver, please follow these steps: + +1. Calling :c:func:`i2s_new_channel` to aquire the channel handles. We should specify the GPIO pins, work mode, work role and I2S port in this step. Besides, we need to input the tx or rx handle to acuire the channel handles that generated by the driver. We don't have to input both two tx and rx handles but at least one handle is needed. While we input both two handles, the driver will work in duplex mode, both tx and rx channel will be avaliable on a same port, and they will share the MCLK, BCLK and WS signal, there will be MCLK(optional), BCLK, WS, DATA_IN and DATA_OUT signals in this case. But if we only input tx or rx handle, this channel will only work in simplex mode. + +2. Calling :c:func:`i2s_init_channel` to initialize the channel that specified by the given channel handle. We are supposed to input corresponding slot and clock configurations according to the mode that we set in the first step. + +3. (Optional) We can acquire the event queue handle by :c:func:`i2s_get_event_queue` if we want to monitor the I2S event. + +4. Calling :c:func:`i2s_start_channel` to start the I2S channel. In the new driver, I2S won't start automatically after installed anymore, we are supposed to know clearly whether the channel has started or not. + +5. Reading or writing data by :c:func:`i2s_read_channel` or :c:func:`i2s_write_channel`. Of cause we can only use rx channel handle in :c:func:`i2s_read_channel` and tx channel handle in :c:func:`i2s_write_channel`. + +6. (Optional) We can clear the legacy data in DMA buffer by :c:func:`i2s_clear_dma_buffer`. If we need the driver clear the tx dma buffer automatically, we can set :c:member`auto_clear` in slot configurations. + +7. (Optional) We can change the slot and clock configurations after initialized by :c:func:`i2s_set_slot`, :c:func:`i2s_set_clock`, but we have to call :c:func:`i2s_stop_channel` before we update the configurations. + +8. (Optional) We can delete the i2s channel by calling :c:func:`i2s_del_channel` if we don't need it any more. The related resources will be released if delete function is called. diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c index eaf6f3d47b..6eb9009a9a 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c @@ -20,7 +20,12 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC +// DAC DMA mode is only supported by the legacy I2S driver, it will be replaced once DAC has its own DMA dirver #include "driver/i2s.h" +#else +#include "driver/i2s_controller.h" +#endif #include "sys/lock.h" @@ -82,6 +87,9 @@ static _lock_t s_volume_lock; static TaskHandle_t s_vcs_task_hdl = NULL; /* handle for volume change simulation task */ static uint8_t s_volume = 0; /* local volume value */ static bool s_volume_notify; /* notify volume change or not */ +#ifndef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC +i2s_chan_handle_t tx_chan = NULL; +#endif /******************************** * STATIC FUNCTION DEFINITIONS @@ -160,13 +168,10 @@ static void bt_av_notify_evt_handler(uint8_t event_id, esp_avrc_rn_param_t *even void bt_i2s_driver_install(void) { +#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC /* I2S configuration parameters */ i2s_config_t i2s_config = { -#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC .mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN, -#else - .mode = I2S_MODE_MASTER | I2S_MODE_TX, /* only TX */ -#endif .sample_rate = 44100, .bits_per_sample = 16, .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, /* 2-channels */ @@ -179,23 +184,35 @@ void bt_i2s_driver_install(void) /* enable I2S */ i2s_driver_install(0, &i2s_config, 0, NULL); -#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN); i2s_set_pin(0, NULL); #else - i2s_pin_config_t pin_config = { - .bck_io_num = CONFIG_EXAMPLE_I2S_BCK_PIN, - .ws_io_num = CONFIG_EXAMPLE_I2S_LRCK_PIN, - .data_out_num = CONFIG_EXAMPLE_I2S_DATA_PIN, - .data_in_num = -1 /* not used */ + i2s_gpio_config_t i2s_pin = { + .mclk = I2S_GPIO_UNUSED, + .bclk = CONFIG_EXAMPLE_I2S_BCK_PIN, + .ws = CONFIG_EXAMPLE_I2S_LRCK_PIN, + .dout = CONFIG_EXAMPLE_I2S_DATA_PIN, + .din = I2S_GPIO_UNUSED }; - i2s_set_pin(0, &pin_config); + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + chan_cfg.id = I2S_NUM_0; + i2s_std_slot_config_t slot_cfg = I2S_STD_MSB_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO); + slot_cfg.auto_clear = true; + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(44100); + /* enable I2S */ + i2s_new_channel(&chan_cfg, &tx_chan, NULL); + i2s_init_channel(tx_chan, &clk_cfg, &slot_cfg); + i2s_start_channel(tx_chan); #endif } void bt_i2s_driver_uninstall(void) { +#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC i2s_driver_uninstall(0); +#else + i2s_del_channel(tx_chan); +#endif } static void volume_set_by_controller(uint8_t volume) @@ -286,8 +303,12 @@ static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param) } else if (oct0 & (0x01 << 4)) { sample_rate = 48000; } + #ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC i2s_set_clk(0, sample_rate, 16, 2); - + #else + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(sample_rate); + i2s_set_clock(tx_chan, &clk_cfg); + #endif ESP_LOGI(BT_AV_TAG, "Configure audio player: %x-%x-%x-%x", a2d->audio_cfg.mcc.cie.sbc[0], a2d->audio_cfg.mcc.cie.sbc[1], diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.c b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.c index fadec503d7..5ede922e62 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.c +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_core.c @@ -14,7 +14,12 @@ #include "freertos/task.h" #include "esp_log.h" #include "bt_app_core.h" +#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC +// DAC DMA mode is only supported by the legacy I2S driver, it will be replaced once DAC has its own DMA dirver #include "driver/i2s.h" +#else +#include "driver/i2s_controller.h" +#endif #include "freertos/ringbuf.h" /******************************* @@ -38,6 +43,9 @@ static QueueHandle_t s_bt_app_task_queue = NULL; /* handle of work queue */ static TaskHandle_t s_bt_app_task_handle = NULL; /* handle of application task */ static TaskHandle_t s_bt_i2s_task_handle = NULL; /* handle of I2S task */ static RingbufHandle_t s_ringbuf_i2s = NULL; /* handle of ringbuffer for I2S */ +#ifndef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC +extern i2s_chan_handle_t tx_chan; +#endif /******************************* * STATIC FUNCTION DEFINITIONS @@ -99,7 +107,11 @@ static void bt_i2s_task_handler(void *arg) /* receive data from ringbuffer and write it to I2S DMA transmit buffer */ data = (uint8_t *)xRingbufferReceive(s_ringbuf_i2s, &item_size, (TickType_t)portMAX_DELAY); if (item_size != 0){ + #ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC i2s_write(0, data, item_size, &bytes_written, portMAX_DELAY); + #else + i2s_write_channel(tx_chan, data, item_size, &bytes_written, portMAX_DELAY); + #endif vRingbufferReturnItem(s_ringbuf_i2s, (void *)data); } } diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/main.c b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/main.c index b0b1efb7cf..5522979489 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/main.c @@ -23,7 +23,6 @@ #include "esp_gap_bt_api.h" #include "esp_a2dp_api.h" #include "esp_avrc_api.h" -#include "driver/i2s.h" /* device name */ #define LOCAL_DEVICE_NAME "ESP_SPEAKER" diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/sdkconfig.defaults b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/sdkconfig.defaults index bdbd39fdea..b3b61d904d 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/sdkconfig.defaults +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/sdkconfig.defaults @@ -7,3 +7,4 @@ CONFIG_BTDM_CTRL_MODE_BTDM=n CONFIG_BT_BLUEDROID_ENABLED=y CONFIG_BT_CLASSIC_ENABLED=y CONFIG_BT_A2DP_ENABLE=y +CONFIG_I2S_SUPPRESS_DEPRECATE_WARN=y diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/tutorial/Example_A2DP_Sink.md b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/tutorial/Example_A2DP_Sink.md index dc304ef058..80e25c90ef 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/tutorial/Example_A2DP_Sink.md +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/tutorial/Example_A2DP_Sink.md @@ -88,36 +88,29 @@ The main function installs I2S to play the audio. A loudspeaker, additional ADC ```c /* I2S configuration parameters */ - i2s_config_t i2s_config = { -#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC - .mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN, -#else - .mode = I2S_MODE_MASTER | I2S_MODE_TX, /* only TX */ -#endif - .sample_rate = 44100, - .bits_per_sample = 16, - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, /* 2-channels */ - .communication_format = I2S_COMM_FORMAT_STAND_MSB, - .dma_buf_count = 6, - .dma_buf_len = 60, - .intr_alloc_flags = 0, /* default interrupt priority */ - .tx_desc_auto_clear = true /* auto clear tx descriptor on underflow */ - }; - - /* enable I2S */ - i2s_driver_install(0, &i2s_config, 0, NULL); -#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC - i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN); - i2s_set_pin(0, NULL); -#else - i2s_pin_config_t pin_config = { - .bck_io_num = CONFIG_EXAMPLE_I2S_BCK_PIN, - .ws_io_num = CONFIG_EXAMPLE_I2S_LRCK_PIN, - .data_out_num = CONFIG_EXAMPLE_I2S_DATA_PIN, - .data_in_num = -1 /* not used */ - }; - i2s_set_pin(0, &pin_config); -#endif + #ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_ADC_DAC, NULL); + chan_cfg.id = I2S_NUM_0; + i2s_dac_slot_config_t slot_cfg = I2S_DAC_SLOT_CONFIG(I2S_DAC_CHAN_BOTH); + i2s_adc_dac_clk_config_t clk_cfg = I2S_ADC_DAC_CLK_CONFIG(44100); + #else + i2s_gpio_config_t i2s_pin = { + .mclk = I2S_GPIO_UNUSED, + .bclk = CONFIG_EXAMPLE_I2S_BCK_PIN, + .ws = CONFIG_EXAMPLE_I2S_LRCK_PIN, + .dout = CONFIG_EXAMPLE_I2S_DATA_PIN, + .din = I2S_GPIO_UNUSED + }; + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + chan_cfg.id = I2S_NUM_0; + i2s_std_slot_config_t slot_cfg = I2S_STD_MSB_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO); + slot_cfg.auto_clear = true; + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(44100); + #endif + /* enable I2S */ + i2s_new_channel(&chan_cfg, &tx_chan, NULL); + i2s_init_channel(tx_chan, &clk_cfg, &slot_cfg); + i2s_start_channel(tx_chan); ``` ### Paring Parameter Settings diff --git a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_av.c b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_av.c index 2568928ba9..ee5eb98eae 100644 --- a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_av.c +++ b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_av.c @@ -21,7 +21,12 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC +// DAC DMA mode is only supported by the legacy I2S driver, it will be replaced once DAC has its own DMA dirver #include "driver/i2s.h" +#else +#include "driver/i2s_controller.h" +#endif #include "sys/lock.h" @@ -48,6 +53,9 @@ static _lock_t s_volume_lock; static TaskHandle_t s_vcs_task_hdl = NULL; static uint8_t s_volume = 0; static bool s_volume_notify; +#ifndef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC +extern i2s_chan_handle_t tx_chan; +#endif /* callback for A2DP sink */ void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param) @@ -162,7 +170,12 @@ static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param) } else if (oct0 & (0x01 << 4)) { sample_rate = 48000; } + #ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC i2s_set_clk(0, sample_rate, 16, 2); + #else + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(sample_rate); + i2s_set_clock(tx_chan, &clk_cfg); + #endif ESP_LOGI(BT_AV_TAG, "Configure audio player %x-%x-%x-%x", a2d->audio_cfg.mcc.cie.sbc[0], diff --git a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_core.c b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_core.c index f47551fb40..0263e70144 100644 --- a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_core.c +++ b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/bt_app_core.c @@ -14,8 +14,13 @@ #include "freertos/task.h" #include "esp_log.h" #include "bt_app_core.h" -#include "driver/i2s.h" #include "freertos/ringbuf.h" +#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC +// DAC DMA mode is only supported by the legacy I2S driver, it will be replaced once DAC has its own DMA dirver +#include "driver/i2s.h" +#else +#include "driver/i2s_controller.h" +#endif static void bt_app_task_handler(void *arg); static bool bt_app_send_msg(bt_app_msg_t *msg); @@ -24,7 +29,10 @@ static void bt_app_work_dispatched(bt_app_msg_t *msg); static QueueHandle_t s_bt_app_task_queue = NULL; static TaskHandle_t s_bt_app_task_handle = NULL; static TaskHandle_t s_bt_i2s_task_handle = NULL; -static RingbufHandle_t s_ringbuf_i2s = NULL;; +static RingbufHandle_t s_ringbuf_i2s = NULL; +#ifndef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC +extern i2s_chan_handle_t tx_chan; +#endif bool bt_app_work_dispatch(bt_app_cb_t p_cback, uint16_t event, void *p_params, int param_len, bt_app_copy_cb_t p_copy_cback) { @@ -123,7 +131,11 @@ static void bt_i2s_task_handler(void *arg) for (;;) { data = (uint8_t *)xRingbufferReceive(s_ringbuf_i2s, &item_size, (TickType_t)portMAX_DELAY); if (item_size != 0){ + #ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC i2s_write(0, data, item_size, &bytes_written, portMAX_DELAY); + #else + i2s_write_channel(tx_chan, data, item_size, &bytes_written, portMAX_DELAY); + #endif vRingbufferReturnItem(s_ringbuf_i2s,(void *)data); } } diff --git a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c index 02bdff168a..517ce7f114 100644 --- a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c +++ b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -35,7 +35,12 @@ #include "esp_gap_bt_api.h" #include "esp_a2dp_api.h" #include "esp_avrc_api.h" +#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC +// DAC DMA mode is only supported by the legacy I2S driver, it will be replaced once DAC has its own DMA dirver #include "driver/i2s.h" +#else +#include "driver/i2s_controller.h" +#endif #include "esp_gap_ble_api.h" #include "esp_gatts_api.h" @@ -70,6 +75,10 @@ typedef struct { static prepare_type_env_t a_prepare_write_env; static prepare_type_env_t b_prepare_write_env; +#ifndef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC +i2s_chan_handle_t tx_chan; +#endif + //Declare the static function static void gatts_profile_a_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param); static void gatts_profile_b_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param); @@ -681,36 +690,41 @@ void app_main(void) } ESP_ERROR_CHECK(err); - i2s_config_t i2s_config = { #ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC + /* I2S configuration parameters */ + i2s_config_t i2s_config = { .mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN, -#else - .mode = I2S_MODE_MASTER | I2S_MODE_TX, // Only TX -#endif - .communication_format = I2S_COMM_FORMAT_STAND_MSB, .sample_rate = 44100, .bits_per_sample = 16, - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, //2-channels - .dma_desc_num = 6, - .dma_frame_num = 60, - .intr_alloc_flags = 0, //Default interrupt priority - .tx_desc_auto_clear = true //Auto clear tx descriptor on underflow + .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, /* 2-channels */ + .communication_format = I2S_COMM_FORMAT_STAND_MSB, + .dma_buf_count = 6, + .dma_buf_len = 60, + .intr_alloc_flags = 0, /* default interrupt priority */ + .tx_desc_auto_clear = true /* auto clear tx descriptor on underflow */ }; - + /* enable I2S */ i2s_driver_install(0, &i2s_config, 0, NULL); -#ifdef CONFIG_EXAMPLE_A2DP_SINK_OUTPUT_INTERNAL_DAC i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN); i2s_set_pin(0, NULL); #else - i2s_pin_config_t pin_config = { - .bck_io_num = CONFIG_EXAMPLE_I2S_BCK_PIN, - .ws_io_num = CONFIG_EXAMPLE_I2S_LRCK_PIN, - .data_out_num = CONFIG_EXAMPLE_I2S_DATA_PIN, - .data_in_num = -1 //Not used + i2s_gpio_config_t i2s_pin = { + .mclk = I2S_GPIO_UNUSED, + .bclk = CONFIG_EXAMPLE_I2S_BCK_PIN, + .ws = CONFIG_EXAMPLE_I2S_LRCK_PIN, + .dout = CONFIG_EXAMPLE_I2S_DATA_PIN, + .din = I2S_GPIO_UNUSED }; - - i2s_set_pin(0, &pin_config); + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + chan_cfg.id = I2S_NUM_0; + i2s_std_slot_config_t slot_cfg = I2S_STD_MSB_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO); + slot_cfg.auto_clear = true; + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(44100); + /* enable I2S */ + i2s_new_channel(&chan_cfg, &tx_chan, NULL); + i2s_init_channel(tx_chan, &clk_cfg, &slot_cfg); + i2s_start_channel(tx_chan); #endif esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); diff --git a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/sdkconfig.defaults b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/sdkconfig.defaults index ee81cabedd..a8ae54ee17 100644 --- a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/sdkconfig.defaults +++ b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/sdkconfig.defaults @@ -29,3 +29,4 @@ CONFIG_BT_ACL_CONNECTIONS=4 CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST=n CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY=n CONFIG_BT_SMP_ENABLE=y +CONFIG_I2S_SUPPRESS_DEPRECATE_WARN=y diff --git a/examples/peripherals/i2s/i2s_adc_dac/main/app_main.c b/examples/peripherals/i2s/i2s_adc_dac/main/app_main.c index 9bb0a0522c..de467a6e0c 100644 --- a/examples/peripherals/i2s/i2s_adc_dac/main/app_main.c +++ b/examples/peripherals/i2s/i2s_adc_dac/main/app_main.c @@ -1,3 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +/* ADC/DAC are supported in the new I2S driver, but still available in the legacy I2S driver for backward compatibility + * Please turn to the dedicated ADC/DAC driver instead */ +#pragma message("ADC/DAC on ESP32 will no longer supported via I2S driver") + #include #include #include "freertos/FreeRTOS.h" @@ -13,7 +23,6 @@ #include "esp_rom_sys.h" #if CONFIG_IDF_TARGET_ESP32 - static const char* TAG = "ad/da"; #define V_REF 1100 #define ADC1_TEST_CHANNEL (ADC1_CHANNEL_7) diff --git a/examples/peripherals/i2s/i2s_adc_dac/main/audio_example_file.h b/examples/peripherals/i2s/i2s_adc_dac/main/audio_example_file.h index 6723c6fc2b..b865ad74df 100644 --- a/examples/peripherals/i2s/i2s_adc_dac/main/audio_example_file.h +++ b/examples/peripherals/i2s/i2s_adc_dac/main/audio_example_file.h @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ #include const unsigned char audio_table[] = { 0x7e, 0x7e, 0x7e, 0x80, 0x7e, 0x80, 0x81, 0x81, 0x7e, 0x7a, 0x79, 0x79, 0x7c, 0x81, 0x82, 0x82, diff --git a/examples/peripherals/i2s/i2s_adc_dac/sdkconfig.defaults b/examples/peripherals/i2s/i2s_adc_dac/sdkconfig.defaults new file mode 100644 index 0000000000..71e36947d0 --- /dev/null +++ b/examples/peripherals/i2s/i2s_adc_dac/sdkconfig.defaults @@ -0,0 +1,5 @@ +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_adc_dac_example.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions_adc_dac_example.csv" +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_I2S_SUPPRESS_DEPRECATE_WARN=y diff --git a/examples/peripherals/i2s/i2s_adc_dac/tools/generate_audio_file.py b/examples/peripherals/i2s/i2s_adc_dac/tools/generate_audio_file.py index faa8d6bf2c..edc4ae3ea0 100644 --- a/examples/peripherals/i2s/i2s_adc_dac/tools/generate_audio_file.py +++ b/examples/peripherals/i2s/i2s_adc_dac/tools/generate_audio_file.py @@ -1,3 +1,5 @@ +# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Unlicense OR CC0-1.0 from __future__ import print_function import os diff --git a/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/i2s_recorder_main.c b/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/i2s_recorder_main.c index c8002b62ca..eea6b6cbf3 100644 --- a/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/i2s_recorder_main.c +++ b/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/i2s_recorder_main.c @@ -1,11 +1,10 @@ -/* I2S Digital Microphone Recording Example +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ +/* I2S Digital Microphone Recording Example */ #include #include #include @@ -17,7 +16,7 @@ #include "esp_vfs_fat.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "driver/i2s.h" +#include "driver/i2s_controller.h" #include "driver/gpio.h" #include "driver/spi_common.h" #include "sdmmc_cmd.h" @@ -36,6 +35,7 @@ static const char* TAG = "pdm_rec_example"; // toggling power to the card. sdmmc_host_t host = SDSPI_HOST_DEFAULT(); sdmmc_card_t* card; +i2s_chan_handle_t rx_handle = NULL; static int16_t i2s_readraw_buff[SAMPLE_SIZE]; size_t bytes_read; @@ -123,6 +123,11 @@ void record_wav(uint32_t rec_time) char wav_header_fmt[WAVE_HEADER_SIZE]; + if (rx_handle == NULL) { + ESP_LOGE(TAG, "I2S channel has not been registered yet"); + return; + } + uint32_t flash_rec_time = BYTE_RATE * rec_time; generate_wav_header(wav_header_fmt, flash_rec_time, CONFIG_EXAMPLE_SAMPLE_RATE); @@ -146,7 +151,7 @@ void record_wav(uint32_t rec_time) // Start recording while (flash_wr_size < flash_rec_time) { // Read the RAW samples from the microphone - i2s_read(CONFIG_EXAMPLE_I2S_CH, (char *)i2s_readraw_buff, SAMPLE_SIZE, &bytes_read, 100); + i2s_read_channel(rx_handle, (char *)i2s_readraw_buff, SAMPLE_SIZE, &bytes_read, 100); // Write the samples to the WAV file fwrite(i2s_readraw_buff, 1, bytes_read, f); flash_wr_size += bytes_read; @@ -165,32 +170,20 @@ void record_wav(uint32_t rec_time) void init_microphone(void) { - // Set the I2S configuration as PDM and 16bits per sample - i2s_config_t i2s_config = { - .mode = I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_PDM, - .sample_rate = CONFIG_EXAMPLE_SAMPLE_RATE, - .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, - .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, - .communication_format = I2S_COMM_FORMAT_STAND_I2S, - .intr_alloc_flags = ESP_INTR_FLAG_LEVEL2, - .dma_desc_num = 8, - .dma_frame_num = 200, - .use_apll = 0, + i2s_gpio_config_t i2s_pin = { + .mclk = I2S_GPIO_UNUSED, + .bclk = I2S_GPIO_UNUSED, + .ws = CONFIG_EXAMPLE_I2S_CLK_GPIO, + .dout = I2S_GPIO_UNUSED, + .din = CONFIG_EXAMPLE_I2S_DATA_GPIO }; - - // Set the pinout configuration (set using menuconfig) - i2s_pin_config_t pin_config = { - .mck_io_num = I2S_PIN_NO_CHANGE, - .bck_io_num = I2S_PIN_NO_CHANGE, - .ws_io_num = CONFIG_EXAMPLE_I2S_CLK_GPIO, - .data_out_num = I2S_PIN_NO_CHANGE, - .data_in_num = CONFIG_EXAMPLE_I2S_DATA_GPIO, - }; - - // Call driver installation function before any I2S R/W operation. - ESP_ERROR_CHECK( i2s_driver_install(CONFIG_EXAMPLE_I2S_CH, &i2s_config, 0, NULL) ); - ESP_ERROR_CHECK( i2s_set_pin(CONFIG_EXAMPLE_I2S_CH, &pin_config) ); - ESP_ERROR_CHECK( i2s_set_clk(CONFIG_EXAMPLE_I2S_CH, CONFIG_EXAMPLE_SAMPLE_RATE, I2S_BITS_PER_SAMPLE_16BIT, I2S_CHANNEL_MONO) ); + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_PDM, &i2s_pin); + chan_cfg.id = CONFIG_EXAMPLE_I2S_CH; + i2s_new_channel(&chan_cfg, NULL, &rx_handle); + i2s_pdm_rx_slot_config_t rx_slot_cfg = I2S_PDM_RX_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO); + i2s_pdm_rx_clk_config_t rx_clk_cfg = I2S_PDM_RX_CLK_CONFIG(CONFIG_EXAMPLE_SAMPLE_RATE); + i2s_init_channel(rx_handle, &rx_clk_cfg, &rx_slot_cfg); + i2s_start_channel(rx_handle); } void app_main(void) @@ -198,11 +191,11 @@ void app_main(void) ESP_LOGI(TAG, "PDM microphone recording Example start"); // Mount the SDCard for recording the audio file mount_sdcard(); - // Init the PDM digital microphone + // Acquire a I2S PDM channel for the PDM digital microphone init_microphone(); ESP_LOGI(TAG, "Starting recording for %d seconds!", CONFIG_EXAMPLE_REC_TIME); // Start Recording record_wav(CONFIG_EXAMPLE_REC_TIME); // Stop I2S driver and destroy - ESP_ERROR_CHECK( i2s_driver_uninstall(CONFIG_EXAMPLE_I2S_CH) ); + ESP_ERROR_CHECK( i2s_del_channel(rx_handle) ); } diff --git a/examples/peripherals/i2s/i2s_basic/main/i2s_example_main.c b/examples/peripherals/i2s/i2s_basic/main/i2s_example_main.c index fdb7b08320..c73d2106a5 100644 --- a/examples/peripherals/i2s/i2s_basic/main/i2s_example_main.c +++ b/examples/peripherals/i2s/i2s_basic/main/i2s_example_main.c @@ -1,18 +1,16 @@ -/* I2S Example - - This example code will output 100Hz sine wave and triangle wave to 2-channel of I2S driver - Every 5 seconds, it will change bits_per_sample [16, 24, 32] for i2s data - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +/* I2S Example + * This example code will output 100Hz sine wave and triangle wave to 2-channel of I2S driver + * Every 5 seconds, it will change bits_per_sample [16, 24, 32] for i2s data + */ #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "driver/i2s.h" +#include "driver/i2s_controller.h" #include "driver/gpio.h" #include "esp_system.h" #include "esp_log.h" @@ -30,27 +28,31 @@ #define SAMPLE_PER_CYCLE (SAMPLE_RATE/WAVE_FREQ_HZ) -static const char* TAG = "i2s_example"; +static const char *TAG = "i2s_example"; +static i2s_chan_handle_t tx_handle = NULL; static void setup_triangle_sine_waves(int bits) { - int *samples_data = malloc(((bits+8)/16)*SAMPLE_PER_CYCLE*4); + int *samples_data = malloc(((bits + 8) / 16) * SAMPLE_PER_CYCLE * 4); unsigned int i, sample_val; double sin_float, triangle_float, triangle_step = (double) pow(2, bits) / SAMPLE_PER_CYCLE; size_t i2s_bytes_write = 0; + static i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO); + static i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(SAMPLE_RATE); - printf("\r\nTest bits=%d free mem=%d, written data=%d\n", bits, esp_get_free_heap_size(), ((bits+8)/16)*SAMPLE_PER_CYCLE*4); + printf("\r\nTest bits=%d free mem=%d, written data=%d\n", bits, esp_get_free_heap_size(), ((bits + 8) / 16)*SAMPLE_PER_CYCLE * 4); - triangle_float = -(pow(2, bits)/2 - 1); + triangle_float = -(pow(2, bits) / 2 - 1); - for(i = 0; i < SAMPLE_PER_CYCLE; i++) { + for (i = 0; i < SAMPLE_PER_CYCLE; i++) { sin_float = sin(i * 2 * PI / SAMPLE_PER_CYCLE); - if(sin_float >= 0) + if (sin_float >= 0) { triangle_float += triangle_step; - else + } else { triangle_float -= triangle_step; + } - sin_float *= (pow(2, bits)/2 - 1); + sin_float *= (pow(2, bits) / 2 - 1); if (bits == 16) { sample_val = 0; @@ -59,26 +61,34 @@ static void setup_triangle_sine_waves(int bits) sample_val += (short) sin_float; samples_data[i] = sample_val; } else if (bits == 24) { //1-bytes unused - samples_data[i*2] = ((int) triangle_float) << 8; - samples_data[i*2 + 1] = ((int) sin_float) << 8; + samples_data[i * 2] = ((int) triangle_float) << 8; + samples_data[i * 2 + 1] = ((int) sin_float) << 8; } else { - samples_data[i*2] = ((int) triangle_float); - samples_data[i*2 + 1] = ((int) sin_float); + samples_data[i * 2] = ((int) triangle_float); + samples_data[i * 2 + 1] = ((int) sin_float); } } - ESP_LOGI(TAG, "set clock"); - i2s_set_clk(I2S_NUM, SAMPLE_RATE, bits, 2); - //Using push - // for(i = 0; i < SAMPLE_PER_CYCLE; i++) { - // if (bits == 16) - // i2s_push_sample(0, &samples_data[i], 100); - // else - // i2s_push_sample(0, &samples_data[i*2], 100); - // } - // or write + ESP_LOGI(TAG, "set data bit width to %d", bits); + /* Updata clock and slot information */ + slot_cfg.data_bit_width = bits; + i2s_stop_channel(tx_handle); + i2s_set_slot(tx_handle, &slot_cfg); + if (bits == 24) { + /** + * Because '24' has factor '3' + * The mclk multiple must be able to divide by '3' as well + * Otherwise the sample rate won't be accurate */ + clk_cfg.mclk_multiple = I2S_MCLK_MULTIPLE_384; + i2s_set_clock(tx_handle, &clk_cfg); + } else { + clk_cfg.mclk_multiple = I2S_MCLK_MULTIPLE_256; + i2s_set_clock(tx_handle, &clk_cfg); + } + i2s_start_channel(tx_handle); + ESP_LOGI(TAG, "write data"); - i2s_write(I2S_NUM, samples_data, ((bits+8)/16)*SAMPLE_PER_CYCLE*4, &i2s_bytes_write, 100); + i2s_write_channel(tx_handle, samples_data, ((bits + 8) / 16)*SAMPLE_PER_CYCLE * 4, &i2s_bytes_write, 100); free(samples_data); } @@ -90,35 +100,32 @@ void app_main(void) //using 6 buffers, we need 60-samples per buffer //if 2-channels, 16-bit each channel, total buffer is 360*4 = 1440 bytes //if 2-channels, 24/32-bit each channel, total buffer is 360*8 = 2880 bytes - i2s_config_t i2s_config = { - .mode = I2S_MODE_MASTER | I2S_MODE_TX, - .sample_rate = SAMPLE_RATE, - .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, - .communication_format = I2S_COMM_FORMAT_STAND_MSB, - .dma_desc_num = 6, - .dma_frame_num = 60, - .use_apll = false, - .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1 //Interrupt level 1 + i2s_gpio_config_t i2s_pin = { + .mclk = I2S_GPIO_UNUSED, + .bclk = I2S_BCK_IO, + .ws = I2S_WS_IO, + .dout = I2S_DO_IO, + .din = I2S_DI_IO }; - i2s_pin_config_t pin_config = { - .mck_io_num = I2S_PIN_NO_CHANGE, - .bck_io_num = I2S_BCK_IO, - .ws_io_num = I2S_WS_IO, - .data_out_num = I2S_DO_IO, - .data_in_num = I2S_DI_IO //Not used - }; - i2s_driver_install(I2S_NUM, &i2s_config, 0, NULL); - i2s_set_pin(I2S_NUM, &pin_config); + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + chan_cfg.id = I2S_NUM; + i2s_new_channel(&chan_cfg, &tx_handle, NULL); + i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO); + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(SAMPLE_RATE); +#if SOC_I2S_SUPPORTS_APLL + // APLL clock is more accurate when sample rate is high + clk_cfg.clk_src = I2S_CLK_APLL; +#endif + i2s_init_channel(tx_handle, &clk_cfg, &slot_cfg); + i2s_start_channel(tx_handle); int test_bits = 16; while (1) { setup_triangle_sine_waves(test_bits); - vTaskDelay(5000/portTICK_PERIOD_MS); + vTaskDelay(pdMS_TO_TICKS(5000)); test_bits += 8; - if(test_bits > 32) + if (test_bits > 32) { test_bits = 16; - + } } - } diff --git a/examples/peripherals/i2s/i2s_es8311/README.md b/examples/peripherals/i2s/i2s_es8311/README.md index ba85c38279..fa3a2363ab 100644 --- a/examples/peripherals/i2s/i2s_es8311/README.md +++ b/examples/peripherals/i2s/i2s_es8311/README.md @@ -137,7 +137,7 @@ The example have contained a piece of music in canon.pcm, if you want to play yo 5. Transfer the music format into .pcm. ```ffmpeg -i a_cut.mp3 -f s16ls -ar 16000 -ac -1 -acodec pcm_s16le a.pcm``` 6. Move 'a.pcm' under 'main' directory 7. Replace 'canon.pcm' with 'a.pcm' in 'CMakeLists.txt' under 'main' directory -8. Replace '_binary_canon_pcm_start' and '_binary_canon_pcm_end' with '_binary_a_pcm_start' and '_binary_a_pcm_end' in `i2s_es9311_example.c`(line 46/47) +8. Replace '_binary_canon_pcm_start' and '_binary_canon_pcm_end' with '_binary_a_pcm_start' and '_binary_a_pcm_end' in `i2s_es8311_example.c`(line 46/47) 9. Download the example and enjoy your own music ## Troubleshooting diff --git a/examples/peripherals/i2s/i2s_es8311/main/i2s_es8311_example.c b/examples/peripherals/i2s/i2s_es8311/main/i2s_es8311_example.c index 07afe5b885..be824e3bbe 100644 --- a/examples/peripherals/i2s/i2s_es8311/main/i2s_es8311_example.c +++ b/examples/peripherals/i2s/i2s_es8311/main/i2s_es8311_example.c @@ -8,7 +8,7 @@ #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "driver/i2s.h" +#include "driver/i2s_controller.h" #include "esp_system.h" #include "esp_check.h" #include "es8311.h" @@ -34,7 +34,7 @@ /* Example configurations */ #define EXAMPLE_RECV_BUF_SIZE (2048) #define EXAMPLE_SAMPLE_RATE (16000) -#define EXAMPLE_MCLK_MULTIPLE I2S_MCLK_MULTIPLE_256 +#define EXAMPLE_MCLK_MULTIPLE (256) #define EXAMPLE_VOICE_VOLUME CONFIG_EXAMPLE_VOICE_VOLUME #if CONFIG_EXAMPLE_MODE_ECHO #define EXAMPLE_MIC_GAIN CONFIG_EXAMPLE_MIC_GAIN @@ -44,6 +44,8 @@ static const char *TAG = "i2s_es8311"; static const char err_reason[][30] = {"input param is invalid", "operation timeout" }; +static i2s_chan_handle_t tx_handle = NULL; +static i2s_chan_handle_t rx_handle = NULL; /* Import music file as buffer */ #if CONFIG_EXAMPLE_MODE_MUSIC @@ -73,7 +75,7 @@ static esp_err_t es8311_codec_init(void) .sample_frequency = EXAMPLE_SAMPLE_RATE }; - es8311_init(es_handle, &es_clk, ES8311_RESOLUTION_16, ES8311_RESOLUTION_16); + ESP_ERROR_CHECK(es8311_init(es_handle, &es_clk, ES8311_RESOLUTION_16, ES8311_RESOLUTION_16)); ESP_RETURN_ON_ERROR(es8311_sample_frequency_config(es_handle, EXAMPLE_SAMPLE_RATE * EXAMPLE_MCLK_MULTIPLE, EXAMPLE_SAMPLE_RATE), TAG, "set es8311 sample frequency failed"); ESP_RETURN_ON_ERROR(es8311_voice_volume_set(es_handle, EXAMPLE_VOICE_VOLUME, NULL), TAG, "set es8311 volume failed"); ESP_RETURN_ON_ERROR(es8311_microphone_config(es_handle, false), TAG, "set es8311 microphone failed"); @@ -85,37 +87,23 @@ static esp_err_t es8311_codec_init(void) static esp_err_t i2s_driver_init(void) { - i2s_config_t i2s_cfg = { - .mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_RX, - .sample_rate = EXAMPLE_SAMPLE_RATE, - .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, - .communication_format = I2S_COMM_FORMAT_STAND_I2S, - .tx_desc_auto_clear = true, -#if SOC_I2S_SUPPORTS_TDM - .total_chan = 2, - .chan_mask = I2S_TDM_ACTIVE_CH0 | I2S_TDM_ACTIVE_CH1, - .left_align = false, - .big_edin = false, - .bit_order_msb = false, - .skip_msk = false, -#endif - .dma_desc_num = 8, - .dma_frame_num = 64, - .use_apll = false, - .mclk_multiple = EXAMPLE_MCLK_MULTIPLE, - .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, + i2s_gpio_config_t i2s_pin = { + .mclk = GPIO_NUM_0, + .bclk = GPIO_NUM_4, + .ws = GPIO_NUM_5, + .dout = GPIO_NUM_18, + .din = GPIO_NUM_19 }; - - ESP_RETURN_ON_ERROR(i2s_driver_install(I2S_NUM, &i2s_cfg, 0, NULL), TAG, "install i2s failed"); - i2s_pin_config_t i2s_pin_cfg = { - .mck_io_num = I2S_MCK_IO, - .bck_io_num = I2S_BCK_IO, - .ws_io_num = I2S_WS_IO, - .data_out_num = I2S_DO_IO, - .data_in_num = I2S_DI_IO - }; - ESP_RETURN_ON_ERROR(i2s_set_pin(I2S_NUM, &i2s_pin_cfg), TAG, "set i2s pins failed"); + i2s_chan_config_t chan_cfg = I2S_CHANNEL_CONFIG(I2S_ROLE_MASTER, I2S_COMM_MODE_STD, &i2s_pin); + chan_cfg.id = I2S_NUM; + ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle)); + i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIP_SLOT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO); + slot_cfg.auto_clear = true; + i2s_std_clk_config_t clk_cfg = I2S_STD_CLK_CONFIG(EXAMPLE_SAMPLE_RATE); + ESP_ERROR_CHECK(i2s_init_channel(tx_handle, &clk_cfg, &slot_cfg)); + ESP_ERROR_CHECK(i2s_init_channel(rx_handle, &clk_cfg, &slot_cfg)); + ESP_ERROR_CHECK(i2s_start_channel(tx_handle)); + ESP_ERROR_CHECK(i2s_start_channel(rx_handle)); return ESP_OK; } @@ -124,18 +112,20 @@ static void i2s_music(void *args) { esp_err_t ret = ESP_OK; size_t bytes_write = 0; + if (tx_handle == NULL) { + ESP_LOGE(TAG, "[music] i2s tx channel has not been registered yet"); + abort(); + } while (1) { /* Write music to earphone */ - ret = i2s_write(I2S_NUM, music_pcm_start, music_pcm_end - music_pcm_start, &bytes_write, portMAX_DELAY); + ret = i2s_write_channel(tx_handle, music_pcm_start, music_pcm_end - music_pcm_start, &bytes_write, portMAX_DELAY); if (ret != ESP_OK) { - /* Since we set timeout to 'portMAX_DELAY' in 'i2s_write' + /* Since we set timeout to 'portMAX_DELAY' in 'i2s_write_channel' so you won't reach here unless you set other timeout value, if timeout detected, it means write operation failed. */ ESP_LOGE(TAG, "[music] i2s read failed, %s", err_reason[ret == ESP_ERR_TIMEOUT]); abort(); } - /* Clear DMA buffer to avoid noise from legacy data in buffer */ - i2s_zero_dma_buffer(I2S_NUM); if (bytes_write > 0) { ESP_LOGI(TAG, "[music] i2s music played, %d bytes are written.", bytes_write); } else { @@ -150,6 +140,10 @@ static void i2s_music(void *args) #else static void i2s_echo(void *args) { + if (rx_handle == NULL || tx_handle == NULL) { + ESP_LOGE(TAG, "[echo] i2s rx or tx channel has not been registered yet"); + abort(); + } int *mic_data = malloc(EXAMPLE_RECV_BUF_SIZE); if (!mic_data) { ESP_LOGE(TAG, "[echo] No memory for read data buffer"); @@ -163,13 +157,13 @@ static void i2s_echo(void *args) while (1) { memset(mic_data, 0, EXAMPLE_RECV_BUF_SIZE); /* Read sample data from mic */ - ret = i2s_read(I2S_NUM, mic_data, EXAMPLE_RECV_BUF_SIZE, &bytes_read, 100); + ret = i2s_read_channel(rx_handle, mic_data, EXAMPLE_RECV_BUF_SIZE, &bytes_read, 100); if (ret != ESP_OK) { ESP_LOGE(TAG, "[echo] i2s read failed, %s", err_reason[ret == ESP_ERR_TIMEOUT]); abort(); } /* Write sample data to earphone */ - ret = i2s_write(I2S_NUM, mic_data, EXAMPLE_RECV_BUF_SIZE, &bytes_write, 100); + ret = i2s_write_channel(tx_handle, mic_data, EXAMPLE_RECV_BUF_SIZE, &bytes_write, 100); if (ret != ESP_OK) { ESP_LOGE(TAG, "[echo] i2s write failed, %s", err_reason[ret == ESP_ERR_TIMEOUT]); abort(); diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index e7d5b56ed3..6e3bbe29bd 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -1941,11 +1941,6 @@ examples/peripherals/i2c/i2c_simple/main/i2c_simple_main.c examples/peripherals/i2c/i2c_tools/example_test.py examples/peripherals/i2c/i2c_tools/main/cmd_i2ctools.h examples/peripherals/i2c/i2c_tools/main/i2ctools_example_main.c -examples/peripherals/i2s/i2s_adc_dac/main/app_main.c -examples/peripherals/i2s/i2s_adc_dac/main/audio_example_file.h -examples/peripherals/i2s/i2s_adc_dac/tools/generate_audio_file.py -examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/i2s_recorder_main.c -examples/peripherals/i2s/i2s_basic/main/i2s_example_main.c examples/peripherals/ledc/ledc_basic/main/ledc_basic_example_main.c examples/peripherals/ledc/ledc_fade/main/ledc_fade_example_main.c examples/peripherals/mcpwm/mcpwm_brushed_dc_control/main/cmd_mcpwm_motor.c