1
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
23
24
25
26
27
28
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
93
94
95
96
97
98
99
100
109
110
111
112
113
114
115
116
117
118
119
120
122
123
124
125
126
127
128
129
130
131
138
144
145
146
147
148
149
150
151
152
153
154
158
159
160
161
162
163
164
165
166
167
171
172
173
177
180
181
182
183
184
185
186
187
188
189
195
196
202
203
204
211
212
213
214
216
217
219
220
/* ... */
#include <stdio.h>
#include <string.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/i2s_std.h"
#include "driver/gpio.h"
#include "esp_system.h"
#include "esp_check.h"
#include "es8311.h"
#include "example_config.h"11 includes
static const char *TAG = "i2s_es8311";
static const char err_reason[][30] = {"input param is invalid",
"operation timeout"
}{...};
static i2s_chan_handle_t tx_handle = NULL;
static i2s_chan_handle_t rx_handle = NULL;
#if CONFIG_EXAMPLE_MODE_MUSIC
extern const uint8_t music_pcm_start[] asm("_binary_canon_pcm_start");
extern const uint8_t music_pcm_end[] asm("_binary_canon_pcm_end");/* ... */
#endif
static esp_err_t es8311_codec_init(void)
{
#if !defined(CONFIG_EXAMPLE_BSP)
const i2c_config_t es_i2c_cfg = {
.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 = 100000,
}{...};
ESP_RETURN_ON_ERROR(i2c_param_config(I2C_NUM, &es_i2c_cfg), TAG, "config i2c failed");
ESP_RETURN_ON_ERROR(i2c_driver_install(I2C_NUM, I2C_MODE_MASTER, 0, 0, 0), TAG, "install i2c driver failed");/* ... */
#else
ESP_ERROR_CHECK(bsp_i2c_init());
#endif
es8311_handle_t es_handle = es8311_create(I2C_NUM, ES8311_ADDRRES_0);
ESP_RETURN_ON_FALSE(es_handle, ESP_FAIL, TAG, "es8311 create failed");
const es8311_clock_config_t es_clk = {
.mclk_inverted = false,
.sclk_inverted = false,
.mclk_from_mclk_pin = true,
.mclk_frequency = EXAMPLE_MCLK_FREQ_HZ,
.sample_frequency = EXAMPLE_SAMPLE_RATE
}{...};
ESP_ERROR_CHECK(es8311_init(es_handle, &es_clk, ES8311_RESOLUTION_16, ES8311_RESOLUTION_16));
ESP_RETURN_ON_ERROR(es8311_sample_frequency_config(es_handle, EXAMPLE_SAMPLE_RATE * EXAMPLE_MCLK_MULTIPLE, EXAMPLE_SAMPLE_RATE), TAG, "set es8311 sample frequency failed");
ESP_RETURN_ON_ERROR(es8311_voice_volume_set(es_handle, EXAMPLE_VOICE_VOLUME, NULL), TAG, "set es8311 volume failed");
ESP_RETURN_ON_ERROR(es8311_microphone_config(es_handle, false), TAG, "set es8311 microphone failed");
#if CONFIG_EXAMPLE_MODE_ECHO
ESP_RETURN_ON_ERROR(es8311_microphone_gain_set(es_handle, EXAMPLE_MIC_GAIN), TAG, "set es8311 microphone gain failed");
#endif
return ESP_OK;
}{ ... }
static esp_err_t i2s_driver_init(void)
{
#if !defined(CONFIG_EXAMPLE_BSP)
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM, I2S_ROLE_MASTER);
chan_cfg.auto_clear = true;
ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle));
i2s_std_config_t std_cfg = {
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(EXAMPLE_SAMPLE_RATE),
.slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO),
.gpio_cfg = {
.mclk = I2S_MCK_IO,
.bclk = I2S_BCK_IO,
.ws = I2S_WS_IO,
.dout = I2S_DO_IO,
.din = I2S_DI_IO,
.invert_flags = {
.mclk_inv = false,
.bclk_inv = false,
.ws_inv = false,
}{...},
}{...},
}{...};
std_cfg.clk_cfg.mclk_multiple = EXAMPLE_MCLK_MULTIPLE;
ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_handle, &std_cfg));
ESP_ERROR_CHECK(i2s_channel_init_std_mode(rx_handle, &std_cfg));
ESP_ERROR_CHECK(i2s_channel_enable(tx_handle));
ESP_ERROR_CHECK(i2s_channel_enable(rx_handle));/* ... */
#else
ESP_LOGI(TAG, "Using BSP for HW configuration");
i2s_std_config_t std_cfg = {
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(EXAMPLE_SAMPLE_RATE),
.slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO),
.gpio_cfg = BSP_I2S_GPIO_CFG,
}{...};
std_cfg.clk_cfg.mclk_multiple = EXAMPLE_MCLK_MULTIPLE;
ESP_ERROR_CHECK(bsp_audio_init(&std_cfg, &tx_handle, &rx_handle));
ESP_ERROR_CHECK(bsp_audio_poweramp_enable(true));/* ... */
#endif
return ESP_OK;
}{ ... }
#if CONFIG_EXAMPLE_MODE_MUSIC
static void i2s_music(void *args)
{
esp_err_t ret = ESP_OK;
size_t bytes_write = 0;
uint8_t *data_ptr = (uint8_t *)music_pcm_start;
/* ... */
ESP_ERROR_CHECK(i2s_channel_disable(tx_handle));
ESP_ERROR_CHECK(i2s_channel_preload_data(tx_handle, data_ptr, music_pcm_end - data_ptr, &bytes_write));
data_ptr += bytes_write;
ESP_ERROR_CHECK(i2s_channel_enable(tx_handle));
while (1) {
ret = i2s_channel_write(tx_handle, data_ptr, music_pcm_end - data_ptr, &bytes_write, portMAX_DELAY);
if (ret != ESP_OK) {
/* ... */
ESP_LOGE(TAG, "[music] i2s write failed, %s", err_reason[ret == ESP_ERR_TIMEOUT]);
abort();
}{...}
if (bytes_write > 0) {
ESP_LOGI(TAG, "[music] i2s music played, %d bytes are written.", bytes_write);
}{...} else {
ESP_LOGE(TAG, "[music] i2s music play failed.");
abort();
}{...}
data_ptr = (uint8_t *)music_pcm_start;
vTaskDelay(1000 / portTICK_PERIOD_MS);
}{...}
vTaskDelete(NULL);
}{ ... }
/* ... */#else
static void i2s_echo(void *args)
{
int *mic_data = malloc(EXAMPLE_RECV_BUF_SIZE);
if (!mic_data) {
ESP_LOGE(TAG, "[echo] No memory for read data buffer");
abort();
}{...}
esp_err_t ret = ESP_OK;
size_t bytes_read = 0;
size_t bytes_write = 0;
ESP_LOGI(TAG, "[echo] Echo start");
while (1) {
memset(mic_data, 0, EXAMPLE_RECV_BUF_SIZE);
ret = i2s_channel_read(rx_handle, mic_data, EXAMPLE_RECV_BUF_SIZE, &bytes_read, 1000);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "[echo] i2s read failed, %s", err_reason[ret == ESP_ERR_TIMEOUT]);
abort();
}{...}
ret = i2s_channel_write(tx_handle, mic_data, EXAMPLE_RECV_BUF_SIZE, &bytes_write, 1000);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "[echo] i2s write failed, %s", err_reason[ret == ESP_ERR_TIMEOUT]);
abort();
}{...}
if (bytes_read != bytes_write) {
ESP_LOGW(TAG, "[echo] %d bytes read but only %d bytes are written", bytes_read, bytes_write);
}{...}
}{...}
vTaskDelete(NULL);
}{...}
/* ... */#endif
void app_main(void)
{
printf("i2s es8311 codec example start\n-----------------------------\n");
if (i2s_driver_init() != ESP_OK) {
ESP_LOGE(TAG, "i2s driver init failed");
abort();
}{...} else {
ESP_LOGI(TAG, "i2s driver init success");
}{...}
if (es8311_codec_init() != ESP_OK) {
ESP_LOGE(TAG, "es8311 codec init failed");
abort();
}{...} else {
ESP_LOGI(TAG, "es8311 codec init success");
}{...}
#if EXAMPLE_PA_CTRL_IO >= 0
gpio_config_t gpio_cfg = {
.pin_bit_mask = (1ULL << EXAMPLE_PA_CTRL_IO),
.mode = GPIO_MODE_OUTPUT,
}{...};
ESP_ERROR_CHECK(gpio_config(&gpio_cfg));
ESP_ERROR_CHECK(gpio_set_level(EXAMPLE_PA_CTRL_IO, 1));/* ... */
#endif
#if CONFIG_EXAMPLE_MODE_MUSIC
xTaskCreate(i2s_music, "i2s_music", 4096, NULL, 5, NULL);/* ... */
#else
xTaskCreate(i2s_echo, "i2s_echo", 8192, NULL, 5, NULL);/* ... */
#endif
}{ ... }