Merge branch 'feature/support_legacy_i2s_driver_on_p4' into 'master'

feat(i2s): support i2s legacy driver on p4

Closes IDF-8194

See merge request espressif/esp-idf!28474
This commit is contained in:
Kevin (Lao Kaiyao) 2024-01-22 19:35:49 +08:00
commit 2e037b8ab5
29 changed files with 259 additions and 135 deletions

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -29,6 +29,11 @@
#include "hal/clk_tree_ll.h"
#endif
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
#include "hal/cache_hal.h"
#include "hal/cache_ll.h"
#endif
#if SOC_I2S_SUPPORTS_DAC
#include "hal/dac_ll.h"
#include "hal/dac_types.h"
@ -56,6 +61,12 @@
#include "esp_pm.h"
#include "esp_efuse.h"
#include "esp_rom_gpio.h"
#include "esp_dma_utils.h"
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
#include "esp_cache.h"
#endif
#include "esp_private/i2s_platform.h"
#include "esp_private/periph_ctrl.h"
#include "esp_private/esp_clk.h"
@ -178,11 +189,14 @@ static bool IRAM_ATTR i2s_dma_rx_callback(gdma_channel_handle_t dma_chan, gdma_e
BaseType_t tmp = 0;
int dummy;
i2s_event_t i2s_event;
uint32_t finish_desc;
lldesc_t *finish_desc;
if (p_i2s->rx) {
finish_desc = event_data->rx_eof_desc_addr;
i2s_event.size = ((lldesc_t *)finish_desc)->size;
finish_desc = (lldesc_t *)event_data->rx_eof_desc_addr;
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
esp_cache_msync((void *)finish_desc->buf, p_i2s->rx->buf_size, ESP_CACHE_MSYNC_FLAG_INVALIDATE);
#endif
i2s_event.size = finish_desc->size;
if (xQueueIsQueueFullFromISR(p_i2s->rx->queue)) {
xQueueReceiveFromISR(p_i2s->rx->queue, &dummy, &tmp);
need_awoke |= tmp;
@ -192,7 +206,7 @@ static bool IRAM_ATTR i2s_dma_rx_callback(gdma_channel_handle_t dma_chan, gdma_e
need_awoke |= tmp;
}
}
xQueueSendFromISR(p_i2s->rx->queue, &(((lldesc_t *)finish_desc)->buf), &tmp);
xQueueSendFromISR(p_i2s->rx->queue, &finish_desc->buf, &tmp);
need_awoke |= tmp;
if (p_i2s->i2s_queue) {
i2s_event.type = I2S_EVENT_RX_DONE;
@ -210,10 +224,10 @@ static bool IRAM_ATTR i2s_dma_tx_callback(gdma_channel_handle_t dma_chan, gdma_e
BaseType_t tmp = 0;
int dummy;
i2s_event_t i2s_event;
uint32_t finish_desc;
lldesc_t *finish_desc;
if (p_i2s->tx) {
finish_desc = event_data->tx_eof_desc_addr;
i2s_event.size = ((lldesc_t *)finish_desc)->size;
finish_desc = (lldesc_t *)event_data->tx_eof_desc_addr;
i2s_event.size = finish_desc->size;
if (xQueueIsQueueFullFromISR(p_i2s->tx->queue)) {
xQueueReceiveFromISR(p_i2s->tx->queue, &dummy, &tmp);
need_awoke |= tmp;
@ -225,9 +239,13 @@ static bool IRAM_ATTR i2s_dma_tx_callback(gdma_channel_handle_t dma_chan, gdma_e
}
}
if (p_i2s->tx_desc_auto_clear) {
memset((void *) (((lldesc_t *)finish_desc)->buf), 0, p_i2s->tx->buf_size);
uint8_t *sent_buf = (uint8_t *)finish_desc->buf;
memset(sent_buf, 0, p_i2s->tx->buf_size);
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
esp_cache_msync(sent_buf, p_i2s->tx->buf_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M);
#endif
}
xQueueSendFromISR(p_i2s->tx->queue, &(((lldesc_t *)finish_desc)->buf), &tmp);
xQueueSendFromISR(p_i2s->tx->queue, &finish_desc->buf, &tmp);
need_awoke |= tmp;
if (p_i2s->i2s_queue) {
i2s_event.type = I2S_EVENT_TX_DONE;
@ -499,7 +517,35 @@ static inline uint32_t i2s_get_buf_size(i2s_port_t i2s_num)
uint32_t bytes_per_frame = bytes_per_sample * p_i2s[i2s_num]->active_slot;
p_i2s[i2s_num]->dma_frame_num = (p_i2s[i2s_num]->dma_frame_num * bytes_per_frame > I2S_DMA_BUFFER_MAX_SIZE) ?
I2S_DMA_BUFFER_MAX_SIZE / bytes_per_frame : p_i2s[i2s_num]->dma_frame_num;
return p_i2s[i2s_num]->dma_frame_num * bytes_per_frame;
uint32_t bufsize = p_i2s[i2s_num]->dma_frame_num * bytes_per_frame;
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
/* bufsize need to align with cache line size */
uint32_t alignment = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA);
uint32_t aligned_frame_num = p_i2s[i2s_num]->dma_frame_num;
/* To make the buffer aligned with the cache line size, search for the ceil aligned size first,
If the buffer size exceed the max DMA buffer size, toggle the sign to search for the floor aligned size */
for (int sign = 1; bufsize % alignment != 0; aligned_frame_num += sign) {
bufsize = aligned_frame_num * bytes_per_frame;
/* If the buffer size exceed the max dma size */
if (bufsize > I2S_DMA_BUFFER_MAX_SIZE) {
sign = -1; // toggle the search sign
aligned_frame_num = p_i2s[i2s_num]->dma_frame_num; // Reset the frame num
bufsize = aligned_frame_num * bytes_per_frame; // Reset the bufsize
}
}
if (bufsize / bytes_per_frame != p_i2s[i2s_num]->dma_frame_num) {
ESP_LOGW(TAG, "dma frame num is adjusted to %"PRIu32" to algin the dma buffer with %"PRIu32
", bufsize = %"PRIu32, bufsize / bytes_per_frame, alignment, bufsize);
}
#else
/* 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 %"PRIu32, frame_num);
}
#endif
return bufsize;
}
static esp_err_t i2s_delete_dma_buffer(i2s_port_t i2s_num, i2s_dma_t *dma_obj)
@ -526,15 +572,17 @@ static esp_err_t i2s_alloc_dma_buffer(i2s_port_t i2s_num, i2s_dma_t *dma_obj)
ESP_GOTO_ON_FALSE(dma_obj, ESP_ERR_INVALID_ARG, err, TAG, "I2S DMA object can't be NULL");
uint32_t buf_cnt = p_i2s[i2s_num]->dma_desc_num;
size_t desc_size = 0;
for (int cnt = 0; cnt < buf_cnt; cnt++) {
/* Allocate DMA buffer */
dma_obj->buf[cnt] = (char *) heap_caps_calloc(dma_obj->buf_size, sizeof(char), MALLOC_CAP_DMA);
esp_dma_calloc(1, sizeof(char) * dma_obj->buf_size, (MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA), (void **)&dma_obj->buf[cnt], NULL);
ESP_GOTO_ON_FALSE(dma_obj->buf[cnt], ESP_ERR_NO_MEM, err, TAG, "Error malloc dma buffer");
/* Initialize DMA buffer to 0 */
memset(dma_obj->buf[cnt], 0, dma_obj->buf_size);
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
esp_cache_msync(dma_obj->buf[cnt], dma_obj->buf_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M);
#endif
/* Allocate DMA descpriptor */
dma_obj->desc[cnt] = (lldesc_t *) heap_caps_calloc(1, sizeof(lldesc_t), MALLOC_CAP_DMA);
/* Allocate DMA descriptor */
esp_dma_calloc(1, sizeof(lldesc_t), MALLOC_CAP_DEFAULT, (void **)&dma_obj->desc[cnt], &desc_size);
ESP_GOTO_ON_FALSE(dma_obj->desc[cnt], ESP_ERR_NO_MEM, err, TAG, "Error malloc dma description entry");
}
/* DMA descriptor must be initialize after all descriptor has been created, otherwise they can't be linked together as a chain */
@ -549,6 +597,9 @@ static esp_err_t i2s_alloc_dma_buffer(i2s_port_t i2s_num, i2s_dma_t *dma_obj)
dma_obj->desc[cnt]->offset = 0;
/* Link to the next descriptor */
dma_obj->desc[cnt]->empty = (uint32_t)((cnt < (buf_cnt - 1)) ? (dma_obj->desc[cnt + 1]) : dma_obj->desc[0]);
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
esp_cache_msync(dma_obj->desc[cnt], desc_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M);
#endif
}
if (p_i2s[i2s_num]->dir & I2S_DIR_RX) {
i2s_ll_rx_set_eof_num(p_i2s[i2s_num]->hal.dev, dma_obj->buf_size);
@ -1659,7 +1710,7 @@ esp_err_t i2s_write(i2s_port_t i2s_num, const void *src, size_t size, size_t *by
}
p_i2s[i2s_num]->tx->rw_pos = 0;
}
ESP_LOGD(TAG, "size: %d, rw_pos: %d, buf_size: %d, curr_ptr: %d", size, p_i2s[i2s_num]->tx->rw_pos, p_i2s[i2s_num]->tx->buf_size, (int)p_i2s[i2s_num]->tx->curr_ptr);
ESP_LOGD(TAG, "size: %d, rw_pos: %d, buf_size: %d, curr_ptr: %p", size, p_i2s[i2s_num]->tx->rw_pos, p_i2s[i2s_num]->tx->buf_size, p_i2s[i2s_num]->tx->curr_ptr);
data_ptr = (char *)p_i2s[i2s_num]->tx->curr_ptr;
data_ptr += p_i2s[i2s_num]->tx->rw_pos;
bytes_can_write = p_i2s[i2s_num]->tx->buf_size - p_i2s[i2s_num]->tx->rw_pos;
@ -1667,6 +1718,9 @@ esp_err_t i2s_write(i2s_port_t i2s_num, const void *src, size_t size, size_t *by
bytes_can_write = size;
}
memcpy(data_ptr, src_byte, bytes_can_write);
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
esp_cache_msync((void *)(p_i2s[i2s_num]->tx->curr_ptr), p_i2s[i2s_num]->tx->buf_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M);
#endif
size -= bytes_can_write;
src_byte += bytes_can_write;
p_i2s[i2s_num]->tx->rw_pos += bytes_can_write;
@ -1737,6 +1791,9 @@ esp_err_t i2s_write_expand(i2s_port_t i2s_num, const void *src, size_t size, siz
memcpy(&data_ptr[j], (const char *)(src + *bytes_written), aim_bytes - zero_bytes);
(*bytes_written) += (aim_bytes - zero_bytes);
}
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
esp_cache_msync((void *)p_i2s[i2s_num]->tx->curr_ptr, p_i2s[i2s_num]->tx->buf_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M);
#endif
size -= bytes_can_write;
p_i2s[i2s_num]->tx->rw_pos += bytes_can_write;
}

View File

@ -13,10 +13,6 @@ components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac:
components/driver/test_apps/i2s_test_apps/legacy_i2s_driver:
disable:
- if: SOC_I2S_SUPPORTED != 1
disable_test:
- if: IDF_TARGET == "esp32p4"
temporary: true
reason: lack of runners
components/driver/test_apps/legacy_adc_driver:
disable:

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -447,11 +447,11 @@ TEST_CASE("I2S_TDM_loopback_test_with_master_tx_and_rx", "[i2s_legacy]")
i2s_test_io_config(I2S_TEST_MODE_LOOPBACK);
printf("\r\nheap size: %"PRIu32"\n", esp_get_free_heap_size());
uint8_t *data_wr = (uint8_t *)malloc(sizeof(uint8_t) * 400);
uint8_t *data_wr = (uint8_t *)calloc(1, sizeof(uint8_t) * 400);
size_t i2s_bytes_write = 0;
size_t bytes_read = 0;
int length = 0;
uint8_t *i2s_read_buff = (uint8_t *)malloc(sizeof(uint8_t) * 10000);
uint8_t *i2s_read_buff = (uint8_t *)calloc(1, sizeof(uint8_t) * 10000);
for (int i = 0; i < 100; i++) {
data_wr[i] = i + 1;
@ -880,7 +880,7 @@ static void i2s_test_common_sample_rate(i2s_port_t id)
96000, 128000, 144000, 196000
};
int real_pulse = 0;
#if CONFIG_IDF_ENV_FPGA
#if CONFIG_IDF_ENV_FPGA || CONFIG_IDF_TARGET_ESP32P4
// Limit the test sample rate on FPGA platform due to the low frequency it supports.
int case_cnt = 10;
#else

View File

@ -1,6 +1,5 @@
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import pytest
from pytest_embedded import Dut
@ -11,6 +10,7 @@ from pytest_embedded import Dut
@pytest.mark.esp32s3
@pytest.mark.esp32c6
@pytest.mark.esp32h2
@pytest.mark.esp32p4
@pytest.mark.generic
@pytest.mark.parametrize(
'config',

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -45,13 +45,13 @@ extern "C" {
#define DATA_IN_IO 19
#define DATA_OUT_IO 18
#elif CONFIG_IDF_TARGET_ESP32P4
#define MASTER_MCK_IO 34
#define MASTER_BCK_IO 35
#define MASTER_WS_IO 48
#define SLAVE_BCK_IO 10
#define SLAVE_WS_IO 11
#define DATA_IN_IO 12
#define DATA_OUT_IO 49
#define MASTER_MCK_IO 51
#define MASTER_BCK_IO 45
#define MASTER_WS_IO 46
#define SLAVE_BCK_IO 22
#define SLAVE_WS_IO 23
#define DATA_IN_IO 47
#define DATA_OUT_IO 48
#else
#define MASTER_MCK_IO 0
#define MASTER_BCK_IO 4

View File

@ -432,6 +432,9 @@ esp_err_t i2s_alloc_dma_desc(i2s_chan_handle_t handle, uint32_t num, uint32_t bu
handle->dma.desc[i]->offset = 0;
handle->dma.bufs[i] = (uint8_t *) i2s_dma_calloc(1, bufsize * sizeof(uint8_t), I2S_DMA_ALLOC_CAPS, NULL);
ESP_GOTO_ON_FALSE(handle->dma.bufs[i], ESP_ERR_NO_MEM, err, TAG, "allocate DMA buffer failed");
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
esp_cache_msync(handle->dma.bufs[i], bufsize * sizeof(uint8_t), ESP_CACHE_MSYNC_FLAG_DIR_C2M);
#endif
handle->dma.desc[i]->buf = handle->dma.bufs[i];
ESP_LOGV(TAG, "desc addr: %8p\tbuffer addr:%8p", handle->dma.desc[i], handle->dma.bufs[i]);
}

View File

@ -3,13 +3,8 @@
components/esp_driver_i2s/test_apps/i2s:
disable:
- if: SOC_I2S_SUPPORTED != 1
disable_test:
- if: IDF_TARGET == "esp32p4"
temporary: true
reason: lack of runners
depends_components:
- esp_driver_i2s
- esp_driver_gpio
- esp_driver_pcnt
components/esp_driver_i2s/test_apps/i2s_multi_dev:
@ -22,4 +17,3 @@ components/esp_driver_i2s/test_apps/i2s_multi_dev:
reason: lack of runners
depends_components:
- esp_driver_i2s
- esp_driver_gpio

View File

@ -1,6 +1,5 @@
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import pytest
from pytest_embedded import Dut
@ -11,6 +10,7 @@ from pytest_embedded import Dut
@pytest.mark.esp32c6
@pytest.mark.esp32s3
@pytest.mark.esp32h2
@pytest.mark.esp32p4
@pytest.mark.generic
@pytest.mark.parametrize(
'config',

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -47,13 +47,13 @@ extern "C" {
#define DATA_IN_IO 19
#define DATA_OUT_IO 18
#elif CONFIG_IDF_TARGET_ESP32P4
#define MASTER_MCK_IO 34
#define MASTER_BCK_IO 35
#define MASTER_WS_IO 48
#define SLAVE_BCK_IO 10
#define SLAVE_WS_IO 11
#define DATA_IN_IO 12
#define DATA_OUT_IO 49
#define MASTER_MCK_IO 51
#define MASTER_BCK_IO 45
#define MASTER_WS_IO 46
#define SLAVE_BCK_IO 22
#define SLAVE_WS_IO 23
#define DATA_IN_IO 47
#define DATA_OUT_IO 48
#else
#define MASTER_MCK_IO 0
#define MASTER_BCK_IO 4

View File

@ -70,31 +70,19 @@ examples/peripherals/i2c/i2c_tools:
examples/peripherals/i2s/i2s_basic/i2s_pdm:
disable:
- if: SOC_I2S_SUPPORTS_PDM != 1 or IDF_TARGET == "esp32p4"
disable_test:
- if: IDF_TARGET == "esp32p4"
temporary: true
reason: lack of runners
- if: SOC_I2S_SUPPORTS_PDM != 1
depends_components:
- esp_driver_i2s
examples/peripherals/i2s/i2s_basic/i2s_std:
disable:
- if: SOC_I2S_SUPPORTED != 1 or IDF_TARGET == "esp32p4"
disable_test:
- if: IDF_TARGET == "esp32p4"
temporary: true
reason: lack of runners
- if: SOC_I2S_SUPPORTED != 1
depends_components:
- esp_driver_i2s
examples/peripherals/i2s/i2s_basic/i2s_tdm:
disable:
- if: SOC_I2S_SUPPORTS_TDM != 1 or IDF_TARGET == "esp32p4"
disable_test:
- if: IDF_TARGET == "esp32p4"
temporary: true
reason: lack of runners
- if: SOC_I2S_SUPPORTS_TDM != 1
depends_components:
- esp_driver_i2s
@ -108,26 +96,20 @@ examples/peripherals/i2s/i2s_codec/i2s_es7210_tdm:
reason: lack of runners
depends_components:
- esp_driver_i2s
- esp_driver_i2c
- esp_driver_spi
depends_filepatterns:
- components/driver/i2c/**/*
examples/peripherals/i2s/i2s_codec/i2s_es8311:
disable:
- if: (SOC_I2S_SUPPORTED != 1 or SOC_I2C_SUPPORTED != 1)
reason: rely on I2S STD mode and I2C to config es7210
disable_test:
- if: IDF_TARGET == "esp32p4"
temporary: true
reason: lack of runners
depends_components:
- esp_driver_i2s
depends_filepatterns:
- components/driver/i2c/**/*
- esp_driver_i2c
examples/peripherals/i2s/i2s_recorder:
disable:
- if: SOC_SDMMC_HOST_SUPPORTED != 1 or IDF_TARGET == "esp32p4"
- if: SOC_SDMMC_HOST_SUPPORTED != 1 or SOC_I2S_SUPPORTED != 1
enable:
- if: SOC_I2S_SUPPORTS_PDM_RX > 0
depends_components:

View File

@ -0,0 +1,71 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#pragma once
#include "sdkconfig.h"
#ifdef __cplusplus
extern "C" {
#endif
#if CONFIG_IDF_TARGET_ESP32
#define EXAMPLE_I2S_BCLK_IO1 GPIO_NUM_4 // I2S bit clock io number
#define EXAMPLE_I2S_WS_IO1 GPIO_NUM_5 // I2S word select io number
#define EXAMPLE_I2S_DOUT_IO1 GPIO_NUM_18 // I2S data out io number
#define EXAMPLE_I2S_DIN_IO1 GPIO_NUM_19 // I2S data in io number
// STD simplex pins
#define EXAMPLE_I2S_BCLK_IO2 GPIO_NUM_22 // I2S bit clock io number
#define EXAMPLE_I2S_WS_IO2 GPIO_NUM_23 // I2S word select io number
#define EXAMPLE_I2S_DOUT_IO2 GPIO_NUM_25 // I2S data out io number
#define EXAMPLE_I2S_DIN_IO2 GPIO_NUM_26 // I2S data in io number
#elif CONFIG_IDF_TARGET_ESP32P4
#define EXAMPLE_I2S_BCLK_IO1 GPIO_NUM_45 // I2S bit clock io number
#define EXAMPLE_I2S_WS_IO1 GPIO_NUM_46 // I2S word select io number
#define EXAMPLE_I2S_DOUT_IO1 GPIO_NUM_47 // I2S data out io number
#define EXAMPLE_I2S_DIN_IO1 GPIO_NUM_48 // I2S data in io number
// PDM RX 4 line IO
#define EXAMPLE_I2S_DIN1_IO1 GPIO_NUM_20 // I2S data in io number
#define EXAMPLE_I2S_DIN2_IO1 GPIO_NUM_21 // I2S data in io number
#define EXAMPLE_I2S_DIN3_IO1 GPIO_NUM_22 // I2S data in io number
// STD/TDM simplex pins
#define EXAMPLE_I2S_BCLK_IO2 GPIO_NUM_20 // I2S bit clock io number
#define EXAMPLE_I2S_WS_IO2 GPIO_NUM_21 // I2S word select io number
#define EXAMPLE_I2S_DOUT_IO2 GPIO_NUM_22 // I2S data out io number
#define EXAMPLE_I2S_DIN_IO2 GPIO_NUM_23 // I2S data in io number
#elif CONFIG_IDF_TARGET_ESP32S3
#define EXAMPLE_I2S_BCLK_IO1 GPIO_NUM_2 // I2S bit clock io number
#define EXAMPLE_I2S_WS_IO1 GPIO_NUM_3 // I2S word select io number
#define EXAMPLE_I2S_DOUT_IO1 GPIO_NUM_4 // I2S data out io number
#define EXAMPLE_I2S_DIN_IO1 GPIO_NUM_5 // I2S data in io number
// PDM RX 4 line IO
#define EXAMPLE_I2S_DIN1_IO1 GPIO_NUM_6 // I2S data in io number
#define EXAMPLE_I2S_DIN2_IO1 GPIO_NUM_7 // I2S data in io number
#define EXAMPLE_I2S_DIN3_IO1 GPIO_NUM_8 // I2S data in io number
// STD/TDM simplex pins
#define EXAMPLE_I2S_BCLK_IO2 GPIO_NUM_6 // I2S bit clock io number
#define EXAMPLE_I2S_WS_IO2 GPIO_NUM_7 // I2S word select io number
#define EXAMPLE_I2S_DOUT_IO2 GPIO_NUM_8 // I2S data out io number
#define EXAMPLE_I2S_DIN_IO2 GPIO_NUM_9 // I2S data in io number
#else
#define EXAMPLE_I2S_BCLK_IO1 GPIO_NUM_2 // I2S bit clock io number
#define EXAMPLE_I2S_WS_IO1 GPIO_NUM_3 // I2S word select io number
#define EXAMPLE_I2S_DOUT_IO1 GPIO_NUM_4 // I2S data out io number
#define EXAMPLE_I2S_DIN_IO1 GPIO_NUM_5 // I2S data in io number
#define EXAMPLE_I2S_BCLK_IO2 GPIO_NUM_6 // I2S bit clock io number
#define EXAMPLE_I2S_WS_IO2 GPIO_NUM_7 // I2S word select io number
#define EXAMPLE_I2S_DOUT_IO2 GPIO_NUM_8 // I2S data out io number
#define EXAMPLE_I2S_DIN_IO2 GPIO_NUM_9 // I2S data in io number
#endif
#ifdef __cplusplus
}
#endif

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
# I2S Basic PDM Mode Example

View File

@ -10,4 +10,4 @@ endif()
idf_component_register(SRCS "${srcs}"
PRIV_REQUIRES esp_driver_i2s esp_driver_gpio
INCLUDE_DIRS ".")
INCLUDE_DIRS "." "$ENV{IDF_PATH}/examples/peripherals/i2s/common")

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@ -8,18 +8,20 @@
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "soc/soc_caps.h"
#include "driver/i2s_pdm.h"
#include "driver/gpio.h"
#include "esp_err.h"
#include "sdkconfig.h"
#include "i2s_pdm_example.h"
#include "i2s_example_pins.h"
#define EXAMPLE_PDM_RX_CLK_IO GPIO_NUM_0 // I2S PDM RX clock io number
#define EXAMPLE_PDM_RX_DIN_IO GPIO_NUM_4 // I2S PDM RX data in io number
#if CONFIG_IDF_TARGET_ESP32S3
#define EXAMPLE_PDM_RX_DIN1_IO GPIO_NUM_5 // I2S PDM RX data line1 in io number
#define EXAMPLE_PDM_RX_DIN2_IO GPIO_NUM_6 // I2S PDM RX data line2 in io number
#define EXAMPLE_PDM_RX_DIN3_IO GPIO_NUM_7 // I2S PDM RX data line3 in io number
#define EXAMPLE_PDM_RX_CLK_IO EXAMPLE_I2S_BCLK_IO1 // I2S PDM RX clock io number
#define EXAMPLE_PDM_RX_DIN_IO EXAMPLE_I2S_DIN_IO1 // I2S PDM RX data in io number
#if SOC_I2S_PDM_MAX_RX_LINES == 4
#define EXAMPLE_PDM_RX_DIN1_IO EXAMPLE_I2S_DIN1_IO1 // I2S PDM RX data line1 in io number
#define EXAMPLE_PDM_RX_DIN2_IO EXAMPLE_I2S_DIN2_IO1 // I2S PDM RX data line2 in io number
#define EXAMPLE_PDM_RX_DIN3_IO EXAMPLE_I2S_DIN3_IO1 // I2S PDM RX data line3 in io number
#endif
#define EXAMPLE_PDM_RX_FREQ_HZ 16000 // I2S PDM RX frequency
@ -43,8 +45,7 @@ static i2s_chan_handle_t i2s_example_init_pdm_rx(void)
.slot_cfg = I2S_PDM_RX_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO),
.gpio_cfg = {
.clk = EXAMPLE_PDM_RX_CLK_IO,
#if CONFIG_IDF_TARGET_ESP32S3
// Only ESP32-S3 can support 4-line PDM RX
#if SOC_I2S_PDM_MAX_RX_LINES == 4
.dins = {
EXAMPLE_PDM_RX_DIN_IO,
EXAMPLE_PDM_RX_DIN1_IO,

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@ -13,11 +13,12 @@
#include "esp_check.h"
#include "sdkconfig.h"
#include "i2s_pdm_example.h"
#include "i2s_example_pins.h"
#define EXAMPLE_PDM_TX_CLK_IO GPIO_NUM_4 // I2S PDM TX clock io number
#define EXAMPLE_PDM_TX_DOUT_IO GPIO_NUM_5 // I2S PDM TX data out io number
#define EXAMPLE_PDM_TX_CLK_IO EXAMPLE_I2S_BCLK_IO1 // I2S PDM TX clock io number
#define EXAMPLE_PDM_TX_DOUT_IO EXAMPLE_I2S_DOUT_IO1 // I2S PDM TX data out io number
#define EXAMPLE_PDM_TX_FREQ_HZ 44100 // I2S PDM TX frequency
#define EXAMPLE_PDM_TX_FREQ_HZ 16000 // I2S PDM TX frequency
#define EXAMPLE_WAVE_AMPLITUDE (1000.0) // 1~32767
#define CONST_PI (3.1416f)
#define EXAMPLE_SINE_WAVE_LEN(tone) (uint32_t)((EXAMPLE_PDM_TX_FREQ_HZ / (float)tone) + 0.5) // The sample point number per sine wave to generate the tone

View File

@ -1,6 +1,5 @@
# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import pytest
from pytest_embedded import Dut
@ -10,6 +9,7 @@ from pytest_embedded import Dut
@pytest.mark.esp32c3
@pytest.mark.esp32c6
@pytest.mark.esp32h2
@pytest.mark.esp32p4
@pytest.mark.generic
@pytest.mark.parametrize(
'config',
@ -31,6 +31,7 @@ def test_i2s_pdm_tx_example(dut: Dut) -> None:
@pytest.mark.esp32
@pytest.mark.esp32s3
@pytest.mark.esp32p4
@pytest.mark.generic
@pytest.mark.parametrize(
'config',

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
# I2S Basic Standard Mode Example

View File

@ -1,3 +1,3 @@
idf_component_register(SRCS "i2s_std_example_main.c"
PRIV_REQUIRES esp_driver_i2s esp_driver_gpio
INCLUDE_DIRS ".")
INCLUDE_DIRS "." "$ENV{IDF_PATH}/examples/peripherals/i2s/common")

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@ -12,6 +12,7 @@
#include "driver/gpio.h"
#include "esp_check.h"
#include "sdkconfig.h"
#include "i2s_example_pins.h"
/* Set 1 to allocate rx & tx channels in duplex mode on a same I2S controller, they will share the BCLK and WS signal
* Set 0 to allocate rx & tx channels in simplex mode, these two channels will be totally separated,
@ -19,28 +20,15 @@
* and ESP32-S2 has only one I2S controller, so it can't allocate two simplex channels */
#define EXAMPLE_I2S_DUPLEX_MODE CONFIG_USE_DUPLEX
#if CONFIG_IDF_TARGET_ESP32
#define EXAMPLE_STD_BCLK_IO1 GPIO_NUM_4 // I2S bit clock io number
#define EXAMPLE_STD_WS_IO1 GPIO_NUM_5 // I2S word select io number
#define EXAMPLE_STD_DOUT_IO1 GPIO_NUM_18 // I2S data out io number
#define EXAMPLE_STD_DIN_IO1 GPIO_NUM_19 // I2S data in io number
#define EXAMPLE_STD_BCLK_IO1 EXAMPLE_I2S_BCLK_IO1 // I2S bit clock io number
#define EXAMPLE_STD_WS_IO1 EXAMPLE_I2S_WS_IO1 // I2S word select io number
#define EXAMPLE_STD_DOUT_IO1 EXAMPLE_I2S_DOUT_IO1 // I2S data out io number
#define EXAMPLE_STD_DIN_IO1 EXAMPLE_I2S_DIN_IO1 // I2S data in io number
#if !EXAMPLE_I2S_DUPLEX_MODE
#define EXAMPLE_STD_BCLK_IO2 GPIO_NUM_22 // I2S bit clock io number
#define EXAMPLE_STD_WS_IO2 GPIO_NUM_23 // I2S word select io number
#define EXAMPLE_STD_DOUT_IO2 GPIO_NUM_25 // I2S data out io number
#define EXAMPLE_STD_DIN_IO2 GPIO_NUM_26 // I2S data in io number
#endif
#else
#define EXAMPLE_STD_BCLK_IO1 GPIO_NUM_2 // I2S bit clock io number
#define EXAMPLE_STD_WS_IO1 GPIO_NUM_3 // I2S word select io number
#define EXAMPLE_STD_DOUT_IO1 GPIO_NUM_4 // I2S data out io number
#define EXAMPLE_STD_DIN_IO1 GPIO_NUM_5 // I2S data in io number
#if !EXAMPLE_I2S_DUPLEX_MODE
#define EXAMPLE_STD_BCLK_IO2 GPIO_NUM_6 // I2S bit clock io number
#define EXAMPLE_STD_WS_IO2 GPIO_NUM_7 // I2S word select io number
#define EXAMPLE_STD_DOUT_IO2 GPIO_NUM_8 // I2S data out io number
#define EXAMPLE_STD_DIN_IO2 GPIO_NUM_9 // I2S data in io number
#endif
#define EXAMPLE_STD_BCLK_IO2 EXAMPLE_I2S_BCLK_IO2 // I2S bit clock io number
#define EXAMPLE_STD_WS_IO2 EXAMPLE_I2S_WS_IO2 // I2S word select io number
#define EXAMPLE_STD_DOUT_IO2 EXAMPLE_I2S_DOUT_IO2 // I2S data out io number
#define EXAMPLE_STD_DIN_IO2 EXAMPLE_I2S_DIN_IO2 // I2S data in io number
#endif
#define EXAMPLE_BUFF_SIZE 2048

View File

@ -1,6 +1,5 @@
# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import pytest
from pytest_embedded import Dut
@ -11,6 +10,7 @@ from pytest_embedded import Dut
@pytest.mark.esp32c3
@pytest.mark.esp32c6
@pytest.mark.esp32h2
@pytest.mark.esp32p4
@pytest.mark.generic
def test_i2s_basic_example(dut: Dut) -> None:

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 |
| ----------------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S3 |
| ----------------- | -------- | -------- | -------- | -------- | -------- |
# I2S Basic TDM Mode Example

View File

@ -1,3 +1,3 @@
idf_component_register(SRCS "i2s_tdm_example_main.c"
PRIV_REQUIRES esp_driver_i2s esp_driver_gpio
INCLUDE_DIRS ".")
INCLUDE_DIRS "." "$ENV{IDF_PATH}/examples/peripherals/i2s/common")

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@ -12,21 +12,22 @@
#include "driver/gpio.h"
#include "esp_check.h"
#include "sdkconfig.h"
#include "i2s_example_pins.h"
/* Set 1 to allocate rx & tx channels in duplex mode on a same I2S controller, they will share the BCLK and WS signal
* Set 0 to allocate rx & tx channels in simplex mode, these two channels will be totally separated */
#define EXAMPLE_I2S_DUPLEX_MODE 1
#define EXAMPLE_TDM_BCLK_IO1 GPIO_NUM_2 // I2S bit clock io number
#define EXAMPLE_TDM_WS_IO1 GPIO_NUM_3 // I2S word select io number
#define EXAMPLE_TDM_DOUT_IO1 GPIO_NUM_4 // I2S data out io number
#define EXAMPLE_TDM_DIN_IO1 GPIO_NUM_5 // I2S data in io number
#define EXAMPLE_TDM_BCLK_IO1 EXAMPLE_I2S_BCLK_IO1 // I2S bit clock io number
#define EXAMPLE_TDM_WS_IO1 EXAMPLE_I2S_WS_IO1 // I2S word select io number
#define EXAMPLE_TDM_DOUT_IO1 EXAMPLE_I2S_DOUT_IO1 // I2S data out io number
#define EXAMPLE_TDM_DIN_IO1 EXAMPLE_I2S_DIN_IO1 // I2S data in io number
#if !EXAMPLE_I2S_DUPLEX_MODE
#define EXAMPLE_TDM_BCLK_IO2 GPIO_NUM_6 // I2S bit clock io number
#define EXAMPLE_TDM_WS_IO2 GPIO_NUM_7 // I2S word select io number
#define EXAMPLE_TDM_DOUT_IO2 GPIO_NUM_8 // I2S data out io number
#define EXAMPLE_TDM_DIN_IO2 GPIO_NUM_9 // I2S data in io number
#endif
#define EXAMPLE_TDM_BCLK_IO2 EXAMPLE_I2S_BCLK_IO2 // I2S bit clock io number
#define EXAMPLE_TDM_WS_IO2 EXAMPLE_I2S_WS_IO2 // I2S word select io number
#define EXAMPLE_TDM_DOUT_IO2 EXAMPLE_I2S_DOUT_IO2 // I2S data out io number
#define EXAMPLE_TDM_DIN_IO2 EXAMPLE_I2S_DIN_IO2 // I2S data in io number
#endif // !EXAMPLE_I2S_DUPLEX_MODE
#define EXAMPLE_BUFF_SIZE 2048

View File

@ -1,6 +1,5 @@
# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import pytest
from pytest_embedded import Dut
@ -9,6 +8,7 @@ from pytest_embedded import Dut
@pytest.mark.esp32c3
@pytest.mark.esp32c6
@pytest.mark.esp32h2
@pytest.mark.esp32p4
@pytest.mark.generic
def test_i2s_tdm_example(dut: Dut) -> None:

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@ -30,6 +30,23 @@
#define EXAMPLE_SD_SPI_MOSI_IO (17)
#define EXAMPLE_SD_SPI_MISO_IO (16)
#define EXAMPLE_SD_SPI_CS_IO (15)
#elif CONFIG_IDF_TARGET_ESP32P4
#define EXAMPLE_I2C_NUM (0)
#define EXAMPLE_I2C_SDA_IO (3)
#define EXAMPLE_I2C_SCL_IO (2)
/* I2S port and GPIOs */
#define EXAMPLE_I2S_NUM (0)
#define EXAMPLE_I2S_MCK_IO (4)
#define EXAMPLE_I2S_BCK_IO (5)
#define EXAMPLE_I2S_WS_IO (6)
#define EXAMPLE_I2S_DI_IO (7)
/* SD card SPI GPIOs */
#define EXAMPLE_SD_SPI_CLK_IO (18)
#define EXAMPLE_SD_SPI_MOSI_IO (19)
#define EXAMPLE_SD_SPI_MISO_IO (14)
#define EXAMPLE_SD_SPI_CS_IO (17)
#else
#define EXAMPLE_I2C_NUM (0)
#define EXAMPLE_I2C_SDA_IO (3)

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/
@ -28,6 +28,9 @@
#elif CONFIG_IDF_TARGET_ESP32H2
#define I2C_SCL_IO (GPIO_NUM_8)
#define I2C_SDA_IO (GPIO_NUM_9)
#elif CONFIG_IDF_TARGET_ESP32P4
#define I2C_SCL_IO (GPIO_NUM_8)
#define I2C_SDA_IO (GPIO_NUM_7)
#else
#define I2C_SCL_IO (GPIO_NUM_6)
#define I2C_SDA_IO (GPIO_NUM_7)
@ -35,6 +38,13 @@
/* I2S port and GPIOs */
#define I2S_NUM (0)
#if CONFIG_IDF_TARGET_ESP32P4
#define I2S_MCK_IO (GPIO_NUM_13)
#define I2S_BCK_IO (GPIO_NUM_12)
#define I2S_WS_IO (GPIO_NUM_10)
#define I2S_DO_IO (GPIO_NUM_11)
#define I2S_DI_IO (GPIO_NUM_9)
#else
#define I2S_MCK_IO (GPIO_NUM_0)
#define I2S_BCK_IO (GPIO_NUM_4)
#define I2S_WS_IO (GPIO_NUM_5)
@ -45,6 +55,7 @@
#define I2S_DO_IO (GPIO_NUM_2)
#define I2S_DI_IO (GPIO_NUM_3)
#endif
#endif
#else // CONFIG_EXAMPLE_BSP
#include "bsp/esp-bsp.h"

View File

@ -1,6 +1,5 @@
# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import pytest
from pytest_embedded import Dut
@ -11,6 +10,7 @@ from pytest_embedded import Dut
@pytest.mark.esp32c3
@pytest.mark.esp32c6
@pytest.mark.esp32h2
@pytest.mark.esp32p4
@pytest.mark.generic
def test_i2s_es8311_example_generic(dut: Dut) -> None:
dut.expect('i2s es8311 codec example start')

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-S3 |
| ----------------- | ----- | -------- |
| Supported Targets | ESP32 | ESP32-P4 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- |
# I2S Digital Microphone Recording Example

View File

@ -6,6 +6,7 @@ from pytest_embedded import Dut
@pytest.mark.esp32
@pytest.mark.esp32s3
@pytest.mark.esp32p4
@pytest.mark.generic
def test_i2s_recorder_generic(dut: Dut) -> None:
dut.expect('PDM microphone recording example start')