#include #include #include "sdkconfig.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_chip_info.h" // #include "esp_flash.h" #include "esp_system.h" #include "esp_idf_version.h" // #include "unity.h" #include "esp_codec_dev.h" #include "esp_codec_dev_defaults.h" #include "ES7243E.h" #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) #include "driver/i2s_std.h" #include "driver/i2s_tdm.h" #include "soc/soc_caps.h" #else #include "driver/i2s.h" #endif #include "driver/i2c_master.h" //esp_codec_dev_handle_t codec_dev = NULL; #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0) && !CONFIG_CODEC_I2C_BACKWARD_COMPATIBLE #define USE_IDF_I2C_MASTER #include "driver/i2c_master.h" #else #include "driver/i2c.h" #endif #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) #define I2S_MAX_KEEP SOC_I2S_NUM typedef struct { i2s_chan_handle_t tx_handle; i2s_chan_handle_t rx_handle; } i2s_keep_t; static i2s_comm_mode_t i2s_in_mode = I2S_COMM_MODE_STD; static i2s_comm_mode_t i2s_out_mode = I2S_COMM_MODE_STD; static i2s_keep_t *i2s_keep[I2S_MAX_KEEP]; #endif static void codec_max_sample(uint8_t *data, int size, int *max_value, int *min_value) { int16_t *s = (int16_t *) data; size >>= 1; int i = 1, max, min; max = min = s[0]; while (i < size) { if (s[i] > max) { max = s[i]; } else if (s[i] < min) { min = s[i]; } i++; } *max_value = max; *min_value = min; } #ifdef USE_IDF_I2C_MASTER // 定义为全局变量,供BMI270使用 i2c_master_bus_handle_t i2c_bus_handle = NULL; #endif int ut_i2c_init(uint8_t port) { #ifdef USE_IDF_I2C_MASTER i2c_master_bus_config_t i2c_bus_config = {0}; i2c_bus_config.clk_source = I2C_CLK_SRC_DEFAULT; i2c_bus_config.i2c_port = port; i2c_bus_config.scl_io_num = TEST_BOARD_I2C_SCL_PIN; i2c_bus_config.sda_io_num = TEST_BOARD_I2C_SDA_PIN; i2c_bus_config.glitch_ignore_cnt = 7; i2c_bus_config.flags.enable_internal_pullup = true; return i2c_new_master_bus(&i2c_bus_config, &i2c_bus_handle); #else i2c_config_t i2c_cfg = { .mode = I2C_MODE_MASTER, .sda_pullup_en = GPIO_PULLUP_ENABLE, .scl_pullup_en = GPIO_PULLUP_ENABLE, .master.clk_speed = 100000, }; i2c_cfg.sda_io_num = GPIO_NUM_0; i2c_cfg.scl_io_num = GPIO_NUM_1; esp_err_t ret = i2c_param_config(port, &i2c_cfg); if (ret != ESP_OK) { return -1; } return i2c_driver_install(port, i2c_cfg.mode, 0, 0, 0); #endif } static int ut_i2s_init(uint8_t port) { #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) if (port >= I2S_MAX_KEEP) { return -1; } // Already installed if (i2s_keep[port]) { return 0; } i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); i2s_std_config_t std_cfg = { .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(16000), .slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(16, I2S_SLOT_MODE_STEREO), .gpio_cfg ={ .mclk = TEST_BOARD_I2S_MCK_PIN, .bclk = TEST_BOARD_I2S_BCK_PIN, .ws = TEST_BOARD_I2S_DATA_WS_PIN, .dout = -1, .din = TEST_BOARD_I2S_DATA_IN_PIN, }, }; i2s_keep[port] = (i2s_keep_t *) calloc(1, sizeof(i2s_keep_t)); if (i2s_keep[port] == NULL) { return -1; } #if SOC_I2S_SUPPORTS_TDM i2s_tdm_slot_mask_t slot_mask = I2S_TDM_SLOT0 | I2S_TDM_SLOT1 | I2S_TDM_SLOT2 | I2S_TDM_SLOT3; i2s_tdm_config_t tdm_cfg = { .slot_cfg = I2S_TDM_PHILIPS_SLOT_DEFAULT_CONFIG(16, I2S_SLOT_MODE_MONO, slot_mask), .clk_cfg = I2S_TDM_CLK_DEFAULT_CONFIG(16000), .gpio_cfg = { .mclk = TEST_BOARD_I2S_MCK_PIN, .bclk = TEST_BOARD_I2S_BCK_PIN, .ws = TEST_BOARD_I2S_DATA_WS_PIN, .dout = -1, .din = TEST_BOARD_I2S_DATA_IN_PIN, }, }; tdm_cfg.slot_cfg.total_slot = 4; #endif int ret = i2s_new_channel(&chan_cfg, &i2s_keep[port]->tx_handle, &i2s_keep[port]->rx_handle); if(ret == ESP_OK) printf("i2s_new_channel success.\n"); else printf("i2s_new_channel failed.\n"); if (i2s_out_mode == I2S_COMM_MODE_STD) { ret = i2s_channel_init_std_mode(i2s_keep[port]->tx_handle, &std_cfg); } #if SOC_I2S_SUPPORTS_TDM else if (i2s_out_mode == I2S_COMM_MODE_TDM) { ret = i2s_channel_init_tdm_mode(i2s_keep[port]->tx_handle, &tdm_cfg); } #endif if(ret == ESP_OK) printf("2 success.\n"); else printf("2 failed.\n"); if (i2s_in_mode == I2S_COMM_MODE_STD) { ret = i2s_channel_init_std_mode(i2s_keep[port]->rx_handle, &std_cfg); } #if SOC_I2S_SUPPORTS_TDM else if (i2s_in_mode == I2S_COMM_MODE_TDM) { ret = i2s_channel_init_tdm_mode(i2s_keep[port]->rx_handle, &tdm_cfg); } #endif if(ret == ESP_OK) printf("3 success.\n"); else printf("3 failed.\n"); // For tx master using duplex mode ret=i2s_channel_enable(i2s_keep[port]->tx_handle); if(ret == ESP_OK) printf("i2s_channel_enable tx success.\n"); ret=i2s_channel_enable(i2s_keep[port]->rx_handle); if(ret == ESP_OK) printf("i2s_channel_enable rx success.\n"); #else i2s_config_t i2s_config = { .mode = (i2s_mode_t) (I2S_MODE_TX | I2S_MODE_RX | I2S_MODE_MASTER), .sample_rate = 16000, .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, .communication_format = I2S_COMM_FORMAT_STAND_I2S, .intr_alloc_flags = ESP_INTR_FLAG_LEVEL2 | ESP_INTR_FLAG_IRAM, .dma_buf_count = 2, .dma_buf_len = 128, .use_apll = true, .tx_desc_auto_clear = true, }; int ret = i2s_driver_install(port, &i2s_config, 0, NULL); i2s_pin_config_t i2s_pin_cfg = { .mck_io_num = TEST_BOARD_I2S_MCK_PIN, .bck_io_num = TEST_BOARD_I2S_BCK_PIN, .ws_io_num = TEST_BOARD_I2S_DATA_WS_PIN, .data_out_num = TEST_BOARD_I2S_DATA_OUT_PIN, .data_in_num = TEST_BOARD_I2S_DATA_IN_PIN, }; i2s_set_pin(port, &i2s_pin_cfg); #endif return ret; } extern void i2c_scan_devices(void); extern i2c_master_bus_handle_t s_i2c_bus; extern i2c_master_bus_handle_t touch_bus_handle_BMI; //*****************外部方法*************************** */ esp_codec_dev_handle_t ES7243E_Init(void) { //为编解码器设备的控制和数据总线安装驱动 int ret; ret = ut_i2c_init(0);// 初始化I2C总线0 if(ret == ESP_OK) printf("ut_i2c_init success.\n"); else printf("ut_i2c_init failed.\n"); ret = ut_i2s_init(0); // 初始化I2S总线0 if(ret == ESP_OK) printf("ut_i2s_init success.\n"); else printf("ut_i2s_init failed.\n"); s_i2c_bus = i2c_bus_handle; i2c_scan_devices(); // 扫描I2C总线上的设备 vTaskDelay(pdMS_TO_TICKS(100)); //初始化与音频编解码器相关的接口,包括数据接口(I2S)、控制接口(I2C)和GPIO接口 audio_codec_i2s_cfg_t i2s_cfg = { #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) .rx_handle = i2s_keep[0]->rx_handle, // 接收句柄 .tx_handle = i2s_keep[0]->tx_handle, // 发送句柄 #endif }; const audio_codec_data_if_t *data_if = audio_codec_new_i2s_data(&i2s_cfg); // 创建I2S数据接口 audio_codec_i2c_cfg_t i2c_cfg = {.addr = ES7243E_CODEC_DEFAULT_ADDR};// 设置编解码器的默认地址 printf("sign1\n"); #ifdef USE_IDF_I2C_MASTER i2c_cfg.bus_handle = i2c_bus_handle; // 如果定义了USE_IDF_I2C_MASTER宏,则设置I2C总线句柄i2c_bus_handle touch_bus_handle_BMI #endif const audio_codec_ctrl_if_t *in_ctrl_if = audio_codec_new_i2c_ctrl(&i2c_cfg); printf("sign2\n"); const audio_codec_gpio_if_t *gpio_if = audio_codec_new_gpio(); // 创建GPIO接口 es7243e_codec_cfg_t es7243e_cfg = { .ctrl_if = in_ctrl_if, }; const audio_codec_if_t *in_codec_if = es7243e_codec_new(&es7243e_cfg);//wenti printf("sign3\n"); esp_codec_dev_cfg_t dev_cfg = { .codec_if = in_codec_if, .data_if = data_if, .dev_type = ESP_CODEC_DEV_TYPE_IN, }; esp_codec_dev_handle_t record_dev = esp_codec_dev_new(&dev_cfg); printf("sign4\n"); ret = esp_codec_dev_set_in_gain(record_dev, 30); esp_codec_dev_sample_info_t fs = { .sample_rate = 16000, // 采样率 .channel = 2, .bits_per_sample = 16, // 每个样本的位数 }; ret = esp_codec_dev_open(record_dev, &fs); printf("sign5\n"); return record_dev; } void ES7243E_Record(esp_codec_dev_handle_t codec_dev, int16_t* audio_data, size_t buffer_size) { // printf("开始录音.\n"); esp_codec_dev_read(codec_dev, audio_data, buffer_size); // 读取音频数据(录音) } // 获取ES7243E的I2C总线句柄,供BMI270使用 i2c_master_bus_handle_t ES7243E_get_i2c_bus_handle(void) { #ifdef USE_IDF_I2C_MASTER return i2c_bus_handle; #else return NULL; #endif }