I'm having problems with getting any data out of the ES7210 ADC in 4-channel TDM mode. I'm using an official Espressif's example(https://github.com/espressif/esp-idf/tr ... es7210_tdm) with ESP32-S3, just removed the SD related things.
Code: Select all
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <string.h>
#include "sdkconfig.h"
#include "esp_check.h"
#include "esp_vfs_fat.h"
#include "driver/i2s_tdm.h"
#include "driver/i2c.h"
#include "es7210.h"
#include "format_wav.h"
/* I2C port and GPIOs */
#define EXAMPLE_I2C_NUM (0)
#define EXAMPLE_I2C_SDA_IO (47)
#define EXAMPLE_I2C_SCL_IO (21)
/* I2S port and GPIOs */
#define EXAMPLE_I2S_NUM (0)
#define EXAMPLE_I2S_MCK_IO (14)
#define EXAMPLE_I2S_BCK_IO (12)
#define EXAMPLE_I2S_WS_IO (13)
#define EXAMPLE_I2S_DI_IO (11)
/* I2S configurations */
#define EXAMPLE_I2S_TDM_FORMAT (ES7210_I2S_FMT_I2S)
#define EXAMPLE_I2S_CHAN_NUM (4)
#define EXAMPLE_I2S_SAMPLE_RATE (48000)
#define EXAMPLE_I2S_MCLK_MULTIPLE (I2S_MCLK_MULTIPLE_256)
#define EXAMPLE_I2S_SAMPLE_BITS (I2S_DATA_BIT_WIDTH_16BIT)
#define EXAMPLE_I2S_TDM_SLOT_MASK (I2S_TDM_SLOT0 | I2S_TDM_SLOT1 | I2S_TDM_SLOT2 | I2S_TDM_SLOT3)
/* ES7210 configurations */
#define EXAMPLE_ES7210_I2C_ADDR (0x40)
#define EXAMPLE_ES7210_I2C_CLK (100000)
#define EXAMPLE_ES7210_MIC_GAIN (ES7210_MIC_GAIN_30DB)
#define EXAMPLE_ES7210_MIC_BIAS (ES7210_MIC_BIAS_2V87)
#define EXAMPLE_ES7210_ADC_VOLUME (0)
/* SD card & recording configurations */
#define EXAMPLE_RECORD_TIME_SEC (10)
static const char *TAG = "example";
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));
ESP_LOGI(TAG, "Configure I2S receive channel to TDM mode");
i2s_tdm_config_t i2s_tdm_rx_conf = {
.slot_cfg = I2S_TDM_PHILIPS_SLOT_DEFAULT_CONFIG(EXAMPLE_I2S_SAMPLE_BITS, I2S_SLOT_MODE_STEREO, EXAMPLE_I2S_TDM_SLOT_MASK),
.clk_cfg = {
.clk_src = I2S_CLK_SRC_DEFAULT,
.sample_rate_hz = EXAMPLE_I2S_SAMPLE_RATE,
.mclk_multiple = EXAMPLE_I2S_MCLK_MULTIPLE
},
.gpio_cfg = {
.mclk = EXAMPLE_I2S_MCK_IO,
.bclk = EXAMPLE_I2S_BCK_IO,
.ws = EXAMPLE_I2S_WS_IO,
.dout = -1, // ES7210 only has ADC capability
.din = EXAMPLE_I2S_DI_IO
},
};
ESP_ERROR_CHECK(i2s_channel_init_tdm_mode(i2s_rx_chan, &i2s_tdm_rx_conf));
return i2s_rx_chan;
}
static void es7210_codec_init(void)
{
ESP_LOGI(TAG, "Init I2C used to configure ES7210");
i2c_config_t i2c_conf = {
.sda_io_num = EXAMPLE_I2C_SDA_IO,
.scl_io_num = EXAMPLE_I2C_SCL_IO,
.mode = I2C_MODE_MASTER,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = EXAMPLE_ES7210_I2C_CLK,
};
ESP_ERROR_CHECK(i2c_param_config(EXAMPLE_I2C_NUM, &i2c_conf));
ESP_ERROR_CHECK(i2c_driver_install(EXAMPLE_I2C_NUM, i2c_conf.mode, 0, 0, 0));
/* Create ES7210 device handle */
es7210_dev_handle_t es7210_handle = NULL;
es7210_i2c_config_t es7210_i2c_conf = {
.i2c_port = EXAMPLE_I2C_NUM,
.i2c_addr = EXAMPLE_ES7210_I2C_ADDR
};
ESP_ERROR_CHECK(es7210_new_codec(&es7210_i2c_conf, &es7210_handle));
ESP_LOGI(TAG, "Configure ES7210 codec parameters");
es7210_codec_config_t codec_conf = {
.i2s_format = EXAMPLE_I2S_TDM_FORMAT,
.mclk_ratio = EXAMPLE_I2S_MCLK_MULTIPLE,
.sample_rate_hz = EXAMPLE_I2S_SAMPLE_RATE,
.bit_width = (es7210_i2s_bits_t)EXAMPLE_I2S_SAMPLE_BITS,
.mic_bias = EXAMPLE_ES7210_MIC_BIAS,
.mic_gain = EXAMPLE_ES7210_MIC_GAIN,
.flags.tdm_enable = true
};
ESP_ERROR_CHECK(es7210_config_codec(es7210_handle, &codec_conf));
ESP_ERROR_CHECK(es7210_config_volume(es7210_handle, EXAMPLE_ES7210_ADC_VOLUME));
}
static esp_err_t record_wav(i2s_chan_handle_t i2s_rx_chan)
{
ESP_RETURN_ON_FALSE(i2s_rx_chan, ESP_FAIL, TAG, "invalid i2s channel handle pointer");
esp_err_t ret = ESP_OK;
uint32_t byte_rate = EXAMPLE_I2S_SAMPLE_RATE * EXAMPLE_I2S_CHAN_NUM * EXAMPLE_I2S_SAMPLE_BITS / 8;
uint32_t wav_size = byte_rate * EXAMPLE_RECORD_TIME_SEC;
/* Start recording */
size_t wav_written = 0;
static int16_t i2s_readraw_buff[4096];
ESP_GOTO_ON_ERROR(i2s_channel_enable(i2s_rx_chan), err, TAG, "error while starting i2s rx channel");
while (wav_written < wav_size) {
if (wav_written % byte_rate < sizeof(i2s_readraw_buff)) {
ESP_LOGI(TAG, "Recording: %"PRIu32"/%ds", wav_written / byte_rate + 1, (int)EXAMPLE_RECORD_TIME_SEC);
}
size_t bytes_read = 0;
/* Read RAW samples from ES7210 */
ESP_GOTO_ON_ERROR(i2s_channel_read(i2s_rx_chan, i2s_readraw_buff, sizeof(i2s_readraw_buff), &bytes_read,
pdMS_TO_TICKS(1000)), err, TAG, "error while reading samples from i2s");
//calculate an average value in i2s_readraw_buff
int16_t sum = 0;
for (int i = 0; i < bytes_read / 2; i++) {
sum += i2s_readraw_buff[i];
}
int16_t avg = sum / (bytes_read / 2);
ESP_LOGI(TAG, "Average value: %d", avg);
wav_written += bytes_read;
}
err:
i2s_channel_disable(i2s_rx_chan);
ESP_LOGI(TAG, "Recording done! Flushing file buffer");
return ret;
}
void app_main(void)
{
/* Init I2C bus to configure ES7210 and I2S bus to receive audio data from ES7210 */
i2s_chan_handle_t i2s_rx_chan = es7210_i2s_init();
/* Create ES7210 device handle and configure codec parameters */
es7210_codec_init();
esp_err_t err = record_wav(i2s_rx_chan);
}
Thank you in advance.