mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-06 14:14:33 +02:00
i2s: support esp32h2
This commit is contained in:
@@ -116,7 +116,7 @@ else()
|
|||||||
idf_component_register(SRCS "${srcs}"
|
idf_component_register(SRCS "${srcs}"
|
||||||
INCLUDE_DIRS ${includes}
|
INCLUDE_DIRS ${includes}
|
||||||
PRIV_INCLUDE_DIRS "include/driver"
|
PRIV_INCLUDE_DIRS "include/driver"
|
||||||
PRIV_REQUIRES efuse esp_timer esp_adc
|
PRIV_REQUIRES efuse esp_timer esp_adc esp_psram
|
||||||
REQUIRES esp_pm esp_ringbuf freertos soc hal esp_hw_support
|
REQUIRES esp_pm esp_ringbuf freertos soc hal esp_hw_support
|
||||||
LDFRAGMENTS linker.lf)
|
LDFRAGMENTS linker.lf)
|
||||||
endif()
|
endif()
|
||||||
|
@@ -46,6 +46,9 @@
|
|||||||
#include "esp_attr.h"
|
#include "esp_attr.h"
|
||||||
|
|
||||||
#include "esp_rom_gpio.h"
|
#include "esp_rom_gpio.h"
|
||||||
|
#if CONFIG_SPIRAM && !CONFIG_IDF_TARGET_ESP32
|
||||||
|
#include "esp_psram.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define I2S_DMA_BUFFER_MAX_SIZE (4092)
|
#define I2S_DMA_BUFFER_MAX_SIZE (4092)
|
||||||
|
|
||||||
@@ -59,6 +62,7 @@
|
|||||||
#define I2S_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT
|
#define I2S_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT
|
||||||
#endif //CONFIG_I2S_ISR_IRAM_SAFE
|
#endif //CONFIG_I2S_ISR_IRAM_SAFE
|
||||||
#define I2S_DMA_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA)
|
#define I2S_DMA_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA)
|
||||||
|
#define I2S_PSRAM_ALLOC_CAPS (MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Global i2s platform object
|
* @brief Global i2s platform object
|
||||||
@@ -204,7 +208,6 @@ static i2s_controller_t *i2s_acquire_controller_obj(int id)
|
|||||||
portENTER_CRITICAL(&g_i2s.spinlock);
|
portENTER_CRITICAL(&g_i2s.spinlock);
|
||||||
if (g_i2s.controller[id]) {
|
if (g_i2s.controller[id]) {
|
||||||
i2s_obj = g_i2s.controller[id];
|
i2s_obj = g_i2s.controller[id];
|
||||||
} else {
|
|
||||||
}
|
}
|
||||||
portEXIT_CRITICAL(&g_i2s.spinlock);
|
portEXIT_CRITICAL(&g_i2s.spinlock);
|
||||||
if (i2s_obj == NULL) {
|
if (i2s_obj == NULL) {
|
||||||
@@ -407,12 +410,22 @@ esp_err_t i2s_alloc_dma_desc(i2s_chan_handle_t handle, uint32_t num, uint32_t bu
|
|||||||
handle->dma.desc_num = num;
|
handle->dma.desc_num = num;
|
||||||
handle->dma.buf_size = bufsize;
|
handle->dma.buf_size = bufsize;
|
||||||
|
|
||||||
handle->dma.desc = (lldesc_t **)heap_caps_calloc(num, sizeof(lldesc_t *), I2S_MEM_ALLOC_CAPS);
|
uint32_t dma_alloc_caps = I2S_DMA_ALLOC_CAPS;
|
||||||
|
uint32_t mem_alloc_caps = I2S_MEM_ALLOC_CAPS;
|
||||||
|
|
||||||
|
#if (CONFIG_SPIRAM_USE_MALLOC || CONFIG_SPIRAM_USE_CAPS_ALLOC) && !CONFIG_IDF_TARGET_ESP32
|
||||||
|
if (handle->dma.psram_en && esp_psram_is_initialized()) {
|
||||||
|
ESP_LOGD(TAG, "DMA buffer will be allocate in the psram");
|
||||||
|
dma_alloc_caps = I2S_PSRAM_ALLOC_CAPS;
|
||||||
|
mem_alloc_caps = I2S_PSRAM_ALLOC_CAPS;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
handle->dma.desc = (lldesc_t **)heap_caps_aligned_calloc(4, num, sizeof(lldesc_t *), mem_alloc_caps);
|
||||||
ESP_GOTO_ON_FALSE(handle->dma.desc, ESP_ERR_NO_MEM, err, TAG, "create I2S DMA decriptor array failed");
|
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);
|
handle->dma.bufs = (uint8_t **)heap_caps_aligned_calloc(4, num, sizeof(uint8_t *), mem_alloc_caps);
|
||||||
for (int i = 0; i < num; i++) {
|
for (int i = 0; i < num; i++) {
|
||||||
/* Allocate DMA descriptor */
|
/* Allocate DMA descriptor */
|
||||||
handle->dma.desc[i] = (lldesc_t *) heap_caps_calloc(1, sizeof(lldesc_t), I2S_DMA_ALLOC_CAPS);
|
handle->dma.desc[i] = (lldesc_t *) heap_caps_aligned_calloc(4, 1, sizeof(lldesc_t), dma_alloc_caps);
|
||||||
ESP_GOTO_ON_FALSE(handle->dma.desc[i], ESP_ERR_NO_MEM, err, TAG, "allocate DMA description failed");
|
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]->owner = 1;
|
||||||
handle->dma.desc[i]->eof = 1;
|
handle->dma.desc[i]->eof = 1;
|
||||||
@@ -420,7 +433,7 @@ esp_err_t i2s_alloc_dma_desc(i2s_chan_handle_t handle, uint32_t num, uint32_t bu
|
|||||||
handle->dma.desc[i]->length = bufsize;
|
handle->dma.desc[i]->length = bufsize;
|
||||||
handle->dma.desc[i]->size = bufsize;
|
handle->dma.desc[i]->size = bufsize;
|
||||||
handle->dma.desc[i]->offset = 0;
|
handle->dma.desc[i]->offset = 0;
|
||||||
handle->dma.bufs[i] = (uint8_t *) heap_caps_calloc(1, bufsize * sizeof(uint8_t), I2S_DMA_ALLOC_CAPS);
|
handle->dma.bufs[i] = (uint8_t *) heap_caps_aligned_calloc(4, 1, bufsize * sizeof(uint8_t), dma_alloc_caps);
|
||||||
handle->dma.desc[i]->buf = handle->dma.bufs[i];
|
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");
|
ESP_GOTO_ON_FALSE(handle->dma.desc[i]->buf, ESP_ERR_NO_MEM, err, TAG, "allocate DMA buffer failed");
|
||||||
}
|
}
|
||||||
@@ -782,6 +795,7 @@ esp_err_t i2s_new_channel(const i2s_chan_config_t *chan_cfg, i2s_chan_handle_t *
|
|||||||
err, TAG, "register I2S tx channel failed");
|
err, TAG, "register I2S tx channel failed");
|
||||||
i2s_obj->tx_chan->role = chan_cfg->role;
|
i2s_obj->tx_chan->role = chan_cfg->role;
|
||||||
i2s_obj->tx_chan->dma.auto_clear = chan_cfg->auto_clear;
|
i2s_obj->tx_chan->dma.auto_clear = chan_cfg->auto_clear;
|
||||||
|
i2s_obj->tx_chan->dma.psram_en = chan_cfg->dma_buf_in_psram;
|
||||||
i2s_obj->tx_chan->dma.desc_num = chan_cfg->dma_desc_num;
|
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->dma.frame_num = chan_cfg->dma_frame_num;
|
||||||
i2s_obj->tx_chan->start = i2s_tx_channel_start;
|
i2s_obj->tx_chan->start = i2s_tx_channel_start;
|
||||||
@@ -794,6 +808,7 @@ esp_err_t i2s_new_channel(const i2s_chan_config_t *chan_cfg, i2s_chan_handle_t *
|
|||||||
ESP_GOTO_ON_ERROR(i2s_register_channel(i2s_obj, I2S_DIR_RX, chan_cfg->dma_desc_num),
|
ESP_GOTO_ON_ERROR(i2s_register_channel(i2s_obj, I2S_DIR_RX, chan_cfg->dma_desc_num),
|
||||||
err, TAG, "register I2S rx channel failed");
|
err, TAG, "register I2S rx channel failed");
|
||||||
i2s_obj->rx_chan->role = chan_cfg->role;
|
i2s_obj->rx_chan->role = chan_cfg->role;
|
||||||
|
i2s_obj->rx_chan->dma.psram_en = chan_cfg->dma_buf_in_psram;
|
||||||
i2s_obj->rx_chan->dma.desc_num = chan_cfg->dma_desc_num;
|
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->dma.frame_num = chan_cfg->dma_frame_num;
|
||||||
i2s_obj->rx_chan->start = i2s_rx_channel_start;
|
i2s_obj->rx_chan->start = i2s_rx_channel_start;
|
||||||
|
@@ -67,8 +67,10 @@ static esp_err_t i2s_pdm_tx_set_clock(i2s_chan_handle_t handle, const i2s_pdm_tx
|
|||||||
portENTER_CRITICAL(&g_i2s.spinlock);
|
portENTER_CRITICAL(&g_i2s.spinlock);
|
||||||
/* Set clock configurations in HAL*/
|
/* Set clock configurations in HAL*/
|
||||||
i2s_hal_set_tx_clock(&handle->controller->hal, &clk_info, clk_cfg->clk_src);
|
i2s_hal_set_tx_clock(&handle->controller->hal, &clk_info, clk_cfg->clk_src);
|
||||||
|
#if SOC_I2S_HW_VERSION_2
|
||||||
/* Work aroud for PDM TX clock, set the raw division directly to reduce the noise */
|
/* Work aroud for PDM TX clock, set the raw division directly to reduce the noise */
|
||||||
i2s_ll_tx_set_raw_clk_div(handle->controller->hal.dev, 1, 1, 0, 0);
|
i2s_ll_tx_set_raw_clk_div(handle->controller->hal.dev, 1, 1, 0, 0);
|
||||||
|
#endif
|
||||||
portEXIT_CRITICAL(&g_i2s.spinlock);
|
portEXIT_CRITICAL(&g_i2s.spinlock);
|
||||||
|
|
||||||
/* Update the mode info: clock configuration */
|
/* Update the mode info: clock configuration */
|
||||||
|
@@ -47,6 +47,7 @@ typedef struct {
|
|||||||
uint32_t desc_num; /*!< I2S DMA buffer number, it is also the number of DMA descriptor */
|
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 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 */
|
uint32_t buf_size; /*!< dma buffer size */
|
||||||
|
bool psram_en; /*!< Whether prefer to allocate the DMA buffers in the psram */
|
||||||
bool auto_clear; /*!< Set to auto clear DMA TX descriptor, i2s will always send zero automatically if no data to send */
|
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 */
|
uint32_t rw_pos; /*!< reading/writing pointer position */
|
||||||
void *curr_ptr; /*!< Pointer to current dma buffer */
|
void *curr_ptr; /*!< Pointer to current dma buffer */
|
||||||
|
@@ -24,6 +24,7 @@ extern "C" {
|
|||||||
.role = i2s_role, \
|
.role = i2s_role, \
|
||||||
.dma_desc_num = 6, \
|
.dma_desc_num = 6, \
|
||||||
.dma_frame_num = 250, \
|
.dma_frame_num = 250, \
|
||||||
|
.dma_buf_in_psram = false, \
|
||||||
.auto_clear = false, \
|
.auto_clear = false, \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,43 +37,45 @@ extern "C" {
|
|||||||
* The variables used in the function should be in the SRAM as well.
|
* The variables used in the function should be in the SRAM as well.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
i2s_isr_callback_t on_recv; /**< Callback of data received event, only for rx channel
|
i2s_isr_callback_t on_recv; /**< Callback of data received event, only for rx channel
|
||||||
* The event data includes DMA buffer address and size that just finished receiving data
|
* The event data includes DMA buffer address and size that just finished receiving data
|
||||||
*/
|
*/
|
||||||
i2s_isr_callback_t on_recv_q_ovf; /**< Callback of receiving queue overflowed event, only for rx channel
|
i2s_isr_callback_t on_recv_q_ovf; /**< Callback of receiving queue overflowed event, only for rx channel
|
||||||
* The event data includes buffer size that has been overwritten
|
* The event data includes buffer size that has been overwritten
|
||||||
*/
|
*/
|
||||||
i2s_isr_callback_t on_sent; /**< Callback of data sent event, only for tx channel
|
i2s_isr_callback_t on_sent; /**< Callback of data sent event, only for tx channel
|
||||||
* The event data includes DMA buffer address and size that just finished sending data
|
* The event data includes DMA buffer address and size that just finished sending data
|
||||||
*/
|
*/
|
||||||
i2s_isr_callback_t on_send_q_ovf; /**< Callback of sending queue overflowed evnet, only for tx channel
|
i2s_isr_callback_t on_send_q_ovf; /**< Callback of sending queue overflowed evnet, only for tx channel
|
||||||
* The event data includes buffer size that has been overwritten
|
* The event data includes buffer size that has been overwritten
|
||||||
*/
|
*/
|
||||||
} i2s_event_callbacks_t;
|
} i2s_event_callbacks_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief I2S controller channel configuration
|
* @brief I2S controller channel configuration
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
i2s_port_t id; /*!< I2S port id */
|
i2s_port_t id; /*!< I2S port id */
|
||||||
i2s_role_t role; /*!< I2S role, I2S_ROLE_MASTER or I2S_ROLE_SLAVE */
|
i2s_role_t role; /*!< I2S role, I2S_ROLE_MASTER or I2S_ROLE_SLAVE */
|
||||||
|
|
||||||
/* DMA configurations */
|
/* DMA configurations */
|
||||||
uint32_t dma_desc_num; /*!< I2S DMA buffer number, it is also the number of DMA descriptor */
|
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 */
|
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 buffer, i2s will always send zero automatically if no data to send */
|
bool dma_buf_in_psram; /*!< Prefer to allocate the DMA buffers in the psram (not supported on ESP32)
|
||||||
|
* To allocate the DMA buffers in the psram, SPIRAM should be enabled in menuconfig
|
||||||
|
*/
|
||||||
|
bool auto_clear; /*!< Set to auto clear DMA TX buffer, i2s will always send zero automatically if no data to send */
|
||||||
} i2s_chan_config_t;
|
} i2s_chan_config_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief I2S channel information
|
* @brief I2S channel information
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
i2s_port_t id; /*!< I2S port id */
|
i2s_port_t id; /*!< I2S port id */
|
||||||
i2s_role_t role; /*!< I2S role, I2S_ROLE_MASTER or I2S_ROLE_SLAVE */
|
i2s_role_t role; /*!< I2S role, I2S_ROLE_MASTER or I2S_ROLE_SLAVE */
|
||||||
i2s_dir_t dir; /*!< I2S channel direction */
|
i2s_dir_t dir; /*!< I2S channel direction */
|
||||||
i2s_comm_mode_t mode; /*!< I2S channel communication mode */
|
i2s_comm_mode_t mode; /*!< I2S channel communication mode */
|
||||||
i2s_chan_handle_t pair_chan; /*!< I2S pair channel handle in duplex mode, always NULL in simplex mode */
|
i2s_chan_handle_t pair_chan; /*!< I2S pair channel handle in duplex mode, always NULL in simplex mode */
|
||||||
} i2s_chan_info_t;
|
} i2s_chan_info_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1,2 +1,2 @@
|
|||||||
| Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
|
| Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 | ESP32-H2 |
|
||||||
| ----------------- | ----- | -------- | -------- | -------- |
|
| ----------------- | ----- | -------- | -------- | -------- | -------- |
|
||||||
|
@@ -1,2 +1,2 @@
|
|||||||
| Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
|
| Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 | ESP32-H2 |
|
||||||
| ----------------- | ----- | -------- | -------- | -------- |
|
| ----------------- | ----- | -------- | -------- | -------- | -------- |
|
||||||
|
@@ -44,6 +44,14 @@ extern "C" {
|
|||||||
#define SLAVE_WS_IO 15
|
#define SLAVE_WS_IO 15
|
||||||
#define DATA_IN_IO 19
|
#define DATA_IN_IO 19
|
||||||
#define DATA_OUT_IO 18
|
#define DATA_OUT_IO 18
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
#define MASTER_MCK_IO 0
|
||||||
|
#define MASTER_BCK_IO 4
|
||||||
|
#define MASTER_WS_IO 5
|
||||||
|
#define SLAVE_BCK_IO 2
|
||||||
|
#define SLAVE_WS_IO 3
|
||||||
|
#define DATA_IN_IO 6
|
||||||
|
#define DATA_OUT_IO 7
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
| Supported Targets | ESP32 | ESP32-C3 | ESP32-S3 |
|
| Supported Targets | ESP32 | ESP32-C3 | ESP32-S3 | ESP32-H2 |
|
||||||
| ----------------- | ----- | -------- | -------- |
|
| ----------------- | ----- | -------- | -------- | -------- |
|
||||||
|
|
||||||
# I2S Basic Standard Mode Example
|
# I2S Basic Standard Mode Example
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
| Supported Targets | ESP32 | ESP32-S2 | ESP32-C3 | ESP32-S3 |
|
| Supported Targets | ESP32 | ESP32-S2 | ESP32-C3 | ESP32-S3 | ESP32-H2 |
|
||||||
| ----------------- | ----- | -------- | -------- | -------- |
|
| ----------------- | ----- | -------- | -------- | -------- | -------- |
|
||||||
|
|
||||||
# I2S Basic Standard Mode Example
|
# I2S Basic Standard Mode Example
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
| Supported Targets | ESP32-C3 | ESP32-S3 |
|
| Supported Targets | ESP32-C3 | ESP32-S3 | ESP32-H2 |
|
||||||
| ----------------- | -------- | -------- |
|
| ----------------- | -------- | -------- | -------- |
|
||||||
|
|
||||||
# I2S Basic TDM Mode Example
|
# I2S Basic TDM Mode Example
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
| Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
|
| Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 | ESP32-H2 |
|
||||||
| ----------------- | ----- | -------- | -------- | -------- |
|
| ----------------- | ----- | -------- | -------- | -------- | -------- |
|
||||||
|
|
||||||
# I2S ES8311 Example
|
# I2S ES8311 Example
|
||||||
|
|
||||||
@@ -41,20 +41,20 @@ For more details, see [ES8311 datasheet](http://www.everest-semi.com/pdf/ES8311%
|
|||||||
│ WS-GPIO 5 ├──────────►│PIN8-LRCK PIN13-OUTN├───────────┤ │
|
│ WS-GPIO 5 ├──────────►│PIN8-LRCK PIN13-OUTN├───────────┤ │
|
||||||
│ │ │ │ └─────────┘
|
│ │ │ │ └─────────┘
|
||||||
│ SDOUT-GPIO 18├──────────►│PIN9-SDIN │
|
│ SDOUT-GPIO 18├──────────►│PIN9-SDIN │
|
||||||
│ │ │ │
|
│ (GPIO 2)│ │ │
|
||||||
│ SDIN-GPIO 19│◄──────────┤PIN7-SDOUT │
|
│ SDIN-GPIO 19│◄──────────┤PIN7-SDOUT │
|
||||||
│ │ │ │ ┌─────────┐
|
│ (GPIO 3)│ │ │ ┌─────────┐
|
||||||
│ │ │ PIN18-MIC1P├───────────┤ │
|
│ │ │ PIN18-MIC1P├───────────┤ │
|
||||||
│ SCL-GPIO 16├──────────►│PIN1 -CCLK │ │ MIC │
|
│ SCL-GPIO 16├──────────►│PIN1 -CCLK │ │ MIC │
|
||||||
│ (GPIO 7)│ │ PIN17-MIC1N├───────────┤ │
|
│ (GPIO 6)│ │ PIN17-MIC1N├───────────┤ │
|
||||||
│ SDA-GPIO 17│◄─────────►│PIN19-CDATA │ └─────────┘
|
│ SDA-GPIO 17│◄─────────►│PIN19-CDATA │ └─────────┘
|
||||||
│ (GPIO 8)│ │ │
|
│ (GPIO 7)│ │ │
|
||||||
│ VCC 3.3├───────────┤VCC │
|
│ VCC 3.3├───────────┤VCC │
|
||||||
│ │ │ │
|
│ │ │ │
|
||||||
│ GND├───────────┤GND │
|
│ GND├───────────┤GND │
|
||||||
└─────────────────┘ └──────────────────────────┘
|
└─────────────────┘ └──────────────────────────┘
|
||||||
```
|
```
|
||||||
Note: Since ESP32-C3 board does not have GPIO 16/17, you can use other available GPIOs instead. In this example, we set GPIO 7/8 as I2C pins for ESP32-C3 and GPIO 16/17 for other chips.
|
Note: Since ESP32-C3 & ESP32-H2 board does not have GPIO 16/17, you can use other available GPIOs instead. In this example, we set GPIO 6/7 as I2C pins for ESP32-C3 & ESP32-H2 and GPIO 16/17 for other chips, same as GPIO 18/19, we use GPIO 2/3 instead.
|
||||||
|
|
||||||
### Dependency
|
### Dependency
|
||||||
|
|
||||||
@@ -123,8 +123,8 @@ If you have a logic analyzer, you can use a logic analyzer to grab GPIO signal d
|
|||||||
| MCLK |module clock | GPIO_NUM_0|
|
| MCLK |module clock | GPIO_NUM_0|
|
||||||
| BCLK |bit clock | GPIO_NUM_4 |
|
| BCLK |bit clock | GPIO_NUM_4 |
|
||||||
| WS |word select | GPIO_NUM_5 |
|
| WS |word select | GPIO_NUM_5 |
|
||||||
| SDOUT |serial data out| GPIO_NUM_18 |
|
| SDOUT |serial data out| GPIO_NUM_18/2 |
|
||||||
| SDIN |serial data in | GPIO_NUM_19 |
|
| SDIN |serial data in | GPIO_NUM_19/3 |
|
||||||
|
|
||||||
### Customize your own music
|
### Customize your own music
|
||||||
|
|
||||||
|
@@ -15,12 +15,12 @@
|
|||||||
|
|
||||||
/* I2C port and GPIOs */
|
/* I2C port and GPIOs */
|
||||||
#define I2C_NUM (0)
|
#define I2C_NUM (0)
|
||||||
#ifdef CONFIG_IDF_TARGET_ESP32C3
|
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2
|
||||||
#define I2C_SDA_IO (GPIO_NUM_17)
|
#define I2C_SCL_IO (GPIO_NUM_6)
|
||||||
#define I2C_SCL_IO (GPIO_NUM_16)
|
#define I2C_SDA_IO (GPIO_NUM_7)
|
||||||
#else
|
#else
|
||||||
#define I2C_SDA_IO (GPIO_NUM_15)
|
#define I2C_SCL_IO (GPIO_NUM_16)
|
||||||
#define I2C_SCL_IO (GPIO_NUM_14)
|
#define I2C_SDA_IO (GPIO_NUM_17)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* I2S port and GPIOs */
|
/* I2S port and GPIOs */
|
||||||
@@ -28,13 +28,18 @@
|
|||||||
#define I2S_MCK_IO (GPIO_NUM_0)
|
#define I2S_MCK_IO (GPIO_NUM_0)
|
||||||
#define I2S_BCK_IO (GPIO_NUM_4)
|
#define I2S_BCK_IO (GPIO_NUM_4)
|
||||||
#define I2S_WS_IO (GPIO_NUM_5)
|
#define I2S_WS_IO (GPIO_NUM_5)
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
#define I2S_DO_IO (GPIO_NUM_2)
|
||||||
|
#define I2S_DI_IO (GPIO_NUM_3)
|
||||||
|
#else
|
||||||
#define I2S_DO_IO (GPIO_NUM_18)
|
#define I2S_DO_IO (GPIO_NUM_18)
|
||||||
#define I2S_DI_IO (GPIO_NUM_19)
|
#define I2S_DI_IO (GPIO_NUM_19)
|
||||||
|
#endif
|
||||||
/* Example configurations */
|
/* Example configurations */
|
||||||
#define EXAMPLE_RECV_BUF_SIZE (2048)
|
#define EXAMPLE_RECV_BUF_SIZE (2048)
|
||||||
#define EXAMPLE_SAMPLE_RATE (16000)
|
#define EXAMPLE_SAMPLE_RATE (16000)
|
||||||
#define EXAMPLE_MCLK_MULTIPLE (256)
|
#define EXAMPLE_MCLK_MULTIPLE (256)
|
||||||
|
#define EXAMPLE_MCLK_FREQ_HZ (EXAMPLE_SAMPLE_RATE * EXAMPLE_MCLK_MULTIPLE)
|
||||||
#define EXAMPLE_VOICE_VOLUME CONFIG_EXAMPLE_VOICE_VOLUME
|
#define EXAMPLE_VOICE_VOLUME CONFIG_EXAMPLE_VOICE_VOLUME
|
||||||
#if CONFIG_EXAMPLE_MODE_ECHO
|
#if CONFIG_EXAMPLE_MODE_ECHO
|
||||||
#define EXAMPLE_MIC_GAIN CONFIG_EXAMPLE_MIC_GAIN
|
#define EXAMPLE_MIC_GAIN CONFIG_EXAMPLE_MIC_GAIN
|
||||||
@@ -71,7 +76,10 @@ static esp_err_t es8311_codec_init(void)
|
|||||||
es8311_handle_t es_handle = es8311_create(I2C_NUM, ES8311_ADDRRES_0);
|
es8311_handle_t es_handle = es8311_create(I2C_NUM, ES8311_ADDRRES_0);
|
||||||
ESP_RETURN_ON_FALSE(es_handle, ESP_FAIL, TAG, "es8311 create failed");
|
ESP_RETURN_ON_FALSE(es_handle, ESP_FAIL, TAG, "es8311 create failed");
|
||||||
es8311_clock_config_t es_clk = {
|
es8311_clock_config_t es_clk = {
|
||||||
|
.mclk_inverted = false,
|
||||||
|
.sclk_inverted = false,
|
||||||
.mclk_from_mclk_pin = true,
|
.mclk_from_mclk_pin = true,
|
||||||
|
.mclk_frequency = EXAMPLE_MCLK_FREQ_HZ,
|
||||||
.sample_frequency = EXAMPLE_SAMPLE_RATE
|
.sample_frequency = EXAMPLE_SAMPLE_RATE
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -88,16 +96,17 @@ static esp_err_t es8311_codec_init(void)
|
|||||||
static esp_err_t i2s_driver_init(void)
|
static esp_err_t i2s_driver_init(void)
|
||||||
{
|
{
|
||||||
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM, I2S_ROLE_MASTER);
|
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM, I2S_ROLE_MASTER);
|
||||||
|
chan_cfg.auto_clear = true; // Auto clear the legacy data in the DMA buffer
|
||||||
ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle));
|
ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle));
|
||||||
i2s_std_config_t std_cfg = {
|
i2s_std_config_t std_cfg = {
|
||||||
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(EXAMPLE_SAMPLE_RATE),
|
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(EXAMPLE_SAMPLE_RATE),
|
||||||
.slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO),
|
.slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO),
|
||||||
.gpio_cfg = {
|
.gpio_cfg = {
|
||||||
.mclk = GPIO_NUM_0,
|
.mclk = I2S_MCK_IO,
|
||||||
.bclk = GPIO_NUM_4,
|
.bclk = I2S_BCK_IO,
|
||||||
.ws = GPIO_NUM_5,
|
.ws = I2S_WS_IO,
|
||||||
.dout = GPIO_NUM_18,
|
.dout = I2S_DO_IO,
|
||||||
.din = GPIO_NUM_19,
|
.din = I2S_DI_IO,
|
||||||
.invert_flags = {
|
.invert_flags = {
|
||||||
.mclk_inv = false,
|
.mclk_inv = false,
|
||||||
.bclk_inv = false,
|
.bclk_inv = false,
|
||||||
|
@@ -1,16 +1,17 @@
|
|||||||
## IDF Component Manager Manifest File
|
## IDF Component Manager Manifest File
|
||||||
## Version of your project. Should conform Semantic Versioning 2.0 rules https://semver.org/
|
|
||||||
version: "1.0.0"
|
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
espressif/es8311: ">=0.0.2"
|
espressif/es8311: "==1.0.0"
|
||||||
## Required IDF version
|
## Required IDF version
|
||||||
idf:
|
idf:
|
||||||
version: "^5.0"
|
version: ">=4.1.0"
|
||||||
# # Put list of dependencies here
|
# # Put list of dependencies here
|
||||||
# # For components maintained by Espressif:
|
# # For components maintained by Espressif:
|
||||||
# component:
|
# component: "~1.0.0"
|
||||||
# version: "~1.0.0"
|
|
||||||
# # For 3rd party components:
|
# # For 3rd party components:
|
||||||
# username/component:
|
# username/component: ">=1.0.0,<2.0.0"
|
||||||
|
# username2/component2:
|
||||||
# version: "~1.0.0"
|
# version: "~1.0.0"
|
||||||
|
# # For transient dependencies `public` flag can be set.
|
||||||
|
# # `public` flag doesn't have an effect dependencies of the `main` component.
|
||||||
|
# # All dependencies of `main` are public by default.
|
||||||
|
# public: true
|
||||||
|
Reference in New Issue
Block a user