Just refine code.

This commit is contained in:
Colin 2026-01-02 14:35:26 +08:00
parent 157336a955
commit 29c08f655b
1 changed files with 64 additions and 116 deletions

View File

@ -27,10 +27,12 @@
#define I2C_SDA_IO (1)
#define I2C_SCL_IO (2)
#define BSP_I2C_SDA (GPIO_NUM_1) // SDA引脚
#define BSP_I2C_SCL (GPIO_NUM_2) // SCL引脚
#define BSP_I2C_NUM (0) // I2C外设
#define BSP_I2C_FREQ_HZ 100000 // 100kHz
/* ES7210 configurations */
#define ES7210_I2C_ADDR (0x41)
#define ES7210_I2C_CLK (100000)
#define ES7210_MIC_GAIN (ES7210_MIC_GAIN_30DB)
#define ES7210_MIC_BIAS (ES7210_MIC_BIAS_2V87)
#define ES7210_ADC_VOLUME (0)
/* I2S port and GPIOs */
#define I2S_NUM (0)
@ -79,8 +81,6 @@
// 全局变量
static const char* TAG = "I2S_DMA_ISR";
static i2s_chan_handle_t rx_chan = NULL;
static QueueHandle_t i2s_event_queue = NULL;
static SemaphoreHandle_t data_ready_sem = NULL;
// 中断服务程序的数据处理任务句柄
static TaskHandle_t rx_task_handle = NULL;
@ -91,34 +91,37 @@ typedef struct {
size_t size;
} i2s_queue_data_t;
// static i2s_chan_handle_t es7210_i2s_init(void) {
// i2s_chan_handle_t i2s_rx_chan = NULL; // 定义接收通道句柄
// ESP_LOGI(TAG, "Create I2S receive channel");
// i2s_chan_config_t i2s_rx_conf = I2S_CHANNEL_DEFAULT_CONFIG(
// I2S_NUM_AUTO, I2S_ROLE_MASTER); // 配置接收通道
// ESP_ERROR_CHECK(
// i2s_new_channel(&i2s_rx_conf, NULL, &i2s_rx_chan)); // 创建i2s通道
static i2s_chan_handle_t es7210_i2s_init(void) {
ESP_LOGI(TAG, "Create I2S receive channel");
i2s_chan_config_t i2s_rx_conf = I2S_CHANNEL_DEFAULT_CONFIG(
I2S_NUM_AUTO, I2S_ROLE_MASTER); // 配置接收通道
i2s_rx_conf.dma_desc_num = DMA_BUF_COUNT;
i2s_rx_conf.dma_frame_num = DMA_BUF_LEN;
i2s_rx_conf.auto_clear = true;
ESP_ERROR_CHECK(
i2s_new_channel(&i2s_rx_conf, NULL, &rx_chan)); // 创建i2s通道
// ESP_LOGI(TAG, "Configure I2S receive channel to TDM mode");
// // 定义接收通道为I2S TDM模式 并配置
// i2s_tdm_config_t i2s_tdm_rx_conf = {
// .slot_cfg = I2S_TDM_PHILIPS_SLOT_DEFAULT_CONFIG(
// I2S_SAMPLE_BITS, I2S_SLOT_MODE_STEREO, I2S_TDM_SLOT_MASK),
// .clk_cfg = {.clk_src = I2S_CLK_SRC_DEFAULT,
// .sample_rate_hz = I2S_SAMPLE_RATE,
// .mclk_multiple = I2S_MCLK_MULTIPLE},
// .gpio_cfg = {.mclk = I2S_MCK_IO,
// .bclk = I2S_BCK_IO,
// .ws = I2S_WS_IO,
// .dout = -1, // ES7210 only has ADC capability
// .din = I2S_DI_IO},
// };
ESP_LOGI(TAG, "Configure I2S receive channel to TDM mode");
// 定义接收通道为I2S TDM模式 并配置
i2s_tdm_config_t i2s_tdm_rx_conf = {
.slot_cfg = I2S_TDM_PHILIPS_SLOT_DEFAULT_CONFIG(
I2S_SAMPLE_BITS, I2S_SLOT_MODE_STEREO, I2S_TDM_SLOT_MASK),
.clk_cfg = {.clk_src = I2S_CLK_SRC_DEFAULT,
.sample_rate_hz = I2S_SAMPLE_RATE,
.mclk_multiple = I2S_MCLK_MULTIPLE},
.gpio_cfg = {.mclk = I2S_MCK_IO,
.bclk = I2S_BCK_IO,
.ws = I2S_WS_IO,
.dout = -1, // ES7210 only has ADC capability
.din = I2S_DI_IO},
};
// ESP_ERROR_CHECK(i2s_channel_init_tdm_mode(
// i2s_rx_chan, &i2s_tdm_rx_conf)); // 初始化I2S通道为TDM模式
ESP_ERROR_CHECK(i2s_channel_init_tdm_mode(
rx_chan, &i2s_tdm_rx_conf)); // 初始化I2S通道为TDM模式
// return i2s_rx_chan;
// }
ESP_ERROR_CHECK(i2s_channel_enable(rx_chan));
return rx_chan;
}
sdmmc_card_t* mount_sdcard(void) {
sdmmc_card_t* sdmmc_card = NULL;
@ -167,19 +170,20 @@ sdmmc_card_t* mount_sdcard(void) {
return sdmmc_card;
}
esp_err_t i2c_init(void) {
i2c_config_t i2c_conf = {.mode = I2C_MODE_MASTER,
.sda_io_num = BSP_I2C_SDA,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_io_num = BSP_I2C_SCL,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = BSP_I2C_FREQ_HZ};
i2c_param_config(BSP_I2C_NUM, &i2c_conf);
return i2c_driver_install(BSP_I2C_NUM, i2c_conf.mode, 0, 0, 0);
}
static void es7210_codec_init(void) {
// 初始化I2C接口
ESP_LOGI(TAG, "Init I2C used to configure ES7210");
i2c_config_t i2c_conf = {
.sda_io_num = I2C_SDA_IO,
.scl_io_num = I2C_SCL_IO,
.mode = I2C_MODE_MASTER,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = ES7210_I2C_CLK,
};
ESP_ERROR_CHECK(i2c_param_config(I2C_NUM, &i2c_conf));
ESP_ERROR_CHECK(i2c_driver_install(I2C_NUM, i2c_conf.mode, 0, 0, 0));
// 创建es7210器件句柄
es7210_dev_handle_t es7210_handle = NULL;
es7210_i2c_config_t es7210_i2c_conf = {.i2c_port = I2C_NUM,
@ -200,7 +204,6 @@ static void es7210_codec_init(void) {
ESP_ERROR_CHECK(es7210_config_volume(es7210_handle, ES7210_ADC_VOLUME));
}
// I2S数据接收任务 - 从DMA缓冲区读取数据并放入队列
static void i2s_rx_task(void* arg) {
size_t bytes_read = 0;
int16_t* data_buffer = NULL;
@ -263,38 +266,6 @@ static void i2s_rx_task(void* arg) {
vTaskDelete(NULL);
}
// I2S数据处理任务 - 仅处理队列中的数据不主动读取I2S
static void i2s_process_task(void* arg) {
i2s_queue_data_t queue_data;
ESP_LOGI(TAG, "I2S数据处理任务开始运行");
while (1) {
// 等待数据就绪信号,使用超时避免无限等待
if (xSemaphoreTake(data_ready_sem, pdMS_TO_TICKS(1000)) == pdTRUE) {
// 从队列中获取数据
while (xQueueReceive(i2s_event_queue, &queue_data, 0) == pdTRUE) {
// 处理接收到的数据
ESP_LOGI(TAG, "处理 %d 字节的I2S数据", queue_data.size);
// 在这里可以添加对音频数据的处理逻辑
// 例如:音频分析、滤波、存储等
// 释放数据缓冲区
// if (queue_data.buffer) {
// free(queue_data.buffer);
// }
}
esp_light_sleep_start();
} else {
// 超时未收到信号,可以执行其他操作或简单地继续循环
// 这样可以避免任务无限期阻塞
// 可以在这里添加其他处理逻辑 if needed
}
}
}
// I2S事件回调函数 - 当DMA完成数据传输时被调用 (由DMA中断触发)
static bool IRAM_ATTR i2s_evt_callback(i2s_chan_handle_t handle,
i2s_event_data_t* event,
@ -311,18 +282,18 @@ static bool IRAM_ATTR i2s_evt_callback(i2s_chan_handle_t handle,
// 创建要发送到队列的事件数据
i2s_queue_data_t queue_event = {.buffer = NULL, .size = event->size};
// 发送数据到队列,供处理任务使用
if (xQueueSendFromISR(i2s_event_queue, &queue_event, &need_yield) !=
pdTRUE) {
// 队列满,丢弃数据并释放缓冲区
// free(data_buffer);
} else {
// 通知数据处理任务
if (data_ready_sem) {
xSemaphoreGiveFromISR(data_ready_sem, &need_yield);
}
// }
}
// // 发送数据到队列,供处理任务使用
// if (xQueueSendFromISR(i2s_event_queue, &queue_event, &need_yield) !=
// pdTRUE) {
// // 队列满,丢弃数据并释放缓冲区
// // free(data_buffer);
// } else {
// // 通知数据处理任务
// if (data_ready_sem) {
// xSemaphoreGiveFromISR(data_ready_sem, &need_yield);
// }
// // }
// }
// ESP_LOGI(TAG, "处理 %d 字节的I2S数据", event->size);
// vTaskDelay(1000 / portTICK_PERIOD_MS);
@ -333,22 +304,7 @@ static bool IRAM_ATTR i2s_evt_callback(i2s_chan_handle_t handle,
return (need_yield == pdTRUE);
}
// 初始化I2S
static esp_err_t i2s_init(void) {
// 创建I2S事件队列
i2s_event_queue = xQueueCreate(DMA_BUF_COUNT, sizeof(i2s_queue_data_t));
if (!i2s_event_queue) {
ESP_LOGE(TAG, "创建I2S事件队列失败");
return ESP_FAIL;
}
// 创建数据就绪信号量
data_ready_sem = xSemaphoreCreateBinary();
if (!data_ready_sem) {
ESP_LOGE(TAG, "创建数据就绪信号量失败");
return ESP_FAIL;
}
// 配置I2S通道
i2s_chan_config_t chan_cfg =
I2S_CHANNEL_DEFAULT_CONFIG(I2S_PORT, I2S_ROLE_MASTER);
@ -390,7 +346,6 @@ static esp_err_t i2s_init(void) {
// .bclk_inv = false,
// .ws_inv = false,
// }}};
// ESP_ERROR_CHECK(i2s_channel_init_std_mode(rx_chan, &std_cfg));
// 注册事件回调 - 这是DMA中断触发的回调
@ -408,8 +363,6 @@ static esp_err_t i2s_init(void) {
return ESP_OK;
}
// 主处理任务 - 从队列中获取并处理数据
void config_power_manager() {
// 自动降频至8MHz 双核都空闲时进入 Light Sleep
esp_err_t ret;
@ -444,14 +397,12 @@ void app_main(void) {
sdmmc_card_t* sdmmc_card = mount_sdcard();
i2c_init();
// if (i2s_init() != ESP_OK) {
// ESP_LOGE(TAG, "I2S初始化失败");
// return;
// }
es7210_i2s_init();
if (i2s_init() != ESP_OK) {
ESP_LOGE(TAG, "I2S初始化失败");
return;
}
// i2s_chan_handle_t i2s_rx_chan = es7210_i2s_init();
es7210_codec_init();
ESP_LOGI(TAG, "启动I2S DMA接收示例");
@ -464,9 +415,6 @@ void app_main(void) {
BaseType_t task_ret = xTaskCreate(i2s_rx_task, "i2s_rx_task", 4096, NULL,
tskIDLE_PRIORITY + 2, &rx_task_handle);
// BaseType_t task_ret =
// xTaskCreate(i2s_process_task, "i2s_process_task", 4096, NULL,
// tskIDLE_PRIORITY + 1, &rx_task_handle);
if (task_ret != pdTRUE) {
ESP_LOGE(TAG, "创建I2S数据处理任务失败");