Chip-cn-dat/Heroic-dat/HT517-dat/2026-07-25-15-22-41.png
... ...
Binary files /dev/null and b/Chip-cn-dat/Heroic-dat/HT517-dat/2026-07-25-15-22-41.png differ
Chip-cn-dat/Heroic-dat/HT517-dat/2026-07-25-15-23-04.png
... ...
Binary files /dev/null and b/Chip-cn-dat/Heroic-dat/HT517-dat/2026-07-25-15-23-04.png differ
Chip-cn-dat/Heroic-dat/HT517-dat/2026-07-25-15-23-27.png
... ...
Binary files /dev/null and b/Chip-cn-dat/Heroic-dat/HT517-dat/2026-07-25-15-23-27.png differ
Chip-cn-dat/Heroic-dat/HT517-dat/HT517-dat.md
... ...
@@ -0,0 +1,28 @@
1
+
2
+
3
+# HT517-dat
4
+
5
+- [[HT517-dat]] - [[heroic-dat]] - [[speaker-I2S-dat]]
6
+
7
+
8
+
9
+## Info
10
+
11
+
12
+![](2026-07-25-15-23-04.png)
13
+
14
+
15
+![](2026-07-25-15-22-41.png)
16
+
17
+![](2026-07-25-15-23-27.png)
18
+
19
+- DI0 - BCLK
20
+- DI1 - LRCK - WS
21
+- ID2 - DOUT -
22
+- EN
23
+- VDD
24
+
25
+
26
+
27
+## ref
28
+
Chip-cn-dat/Heroic-dat/heroic-dat.md
... ...
@@ -6,3 +6,13 @@
6 6
7 7
- [[HT7181-dat]] - [[dcdc-boost-dat]] - [[heroic-dat]]
8 8
9
+- [[HT517-dat]] - [[heroic-dat]] - [[speaker-I2S-dat]]
10
+
11
+
12
+
13
+
14
+
15
+
16
+## ref
17
+
18
+
Chip-cn-dat/everest-semi-dat/ES8311-dat/ES8311-SDK-dat/ES8311-SDK-dat.md
... ...
@@ -1,6 +1,10 @@
1 1
# ES8311-SDK-dat
2 2
3 3
4
+
5
+- [[I2S-speaker-microphone-dat]] - [[ES8311-dat]] - [[ES8311-SDK-dat]]
6
+
7
+
4 8
- [[oscilloscope-dat]]
5 9
6 10
- [[I2C-dat]]
Chip-cn-dat/everest-semi-dat/ES8311-dat/ES8311-SDK-dat/example-2/es8311.c
... ...
@@ -0,0 +1,749 @@
1
+/*
2
+ * ESPRESSIF MIT License
3
+ *
4
+ * Copyright (c) 2019 <ESPRESSIF SYSTEMS (SHANGHAI) CO., LTD>
5
+ *
6
+ * Permission is hereby granted for use on all ESPRESSIF SYSTEMS products, in which case,
7
+ * it is free of charge, to any person obtaining a copy of this software and associated
8
+ * documentation files (the "Software"), to deal in the Software without restriction, including
9
+ * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the Software is furnished
11
+ * to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in all copies or
14
+ * substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ *
23
+ */
24
+
25
+#include <string.h>
26
+#include "driver/i2c.h"
27
+#include "board.h"
28
+#include "esp_log.h"
29
+#include "es8311.h"
30
+
31
+/* ES8311 address
32
+ * 0x32:CE=1;0x30:CE=0
33
+ */
34
+#define ES8311_ADDR 0x30
35
+
36
+/*
37
+ * to define the clock soure of MCLK
38
+ */
39
+#define FROM_MCLK_PIN 0
40
+#define FROM_SCLK_PIN 1
41
+#define MCLK_SOURCE 0
42
+
43
+/*
44
+ * to define whether to reverse the clock
45
+ */
46
+#define INVERT_MCLK 0 // do not invert
47
+#define INVERT_SCLK 0
48
+
49
+#define IS_DMIC 0 // Is it a digital microphone
50
+
51
+#define MCLK_DIV_FRE 256
52
+
53
+/*
54
+ * i2c default configuration
55
+ */
56
+static i2c_config_t es_i2c_cfg = {
57
+ .mode = I2C_MODE_MASTER,
58
+ .sda_pullup_en = GPIO_PULLUP_ENABLE,
59
+ .scl_pullup_en = GPIO_PULLUP_ENABLE,
60
+ .master.clk_speed = 100000
61
+};
62
+
63
+/*
64
+ * operate function of codec
65
+ */
66
+audio_hal_func_t AUDIO_CODEC_ES8311_DEFAULT_HANDLE = {
67
+ .audio_codec_initialize = es8311_codec_init,
68
+ .audio_codec_deinitialize = es8311_codec_deinit,
69
+ .audio_codec_ctrl = es8311_codec_ctrl_state,
70
+ .audio_codec_config_iface = es8311_codec_config_i2s,
71
+ .audio_codec_set_mute = es8311_set_voice_mute,
72
+ .audio_codec_set_volume = es8311_codec_set_voice_volume,
73
+ .audio_codec_get_volume = es8311_codec_get_voice_volume,
74
+};
75
+
76
+/*
77
+ * Clock coefficient structer
78
+ */
79
+struct _coeff_div {
80
+ uint32_t mclk; /* mclk frequency */
81
+ uint32_t rate; /* sample rate */
82
+ uint8_t pre_div; /* the pre divider with range from 1 to 8 */
83
+ uint8_t pre_multi; /* the pre multiplier with x1, x2, x4 and x8 selection */
84
+ uint8_t adc_div; /* adcclk divider */
85
+ uint8_t dac_div; /* dacclk divider */
86
+ uint8_t fs_mode; /* double speed or single speed, =0, ss, =1, ds */
87
+ uint8_t lrck_h; /* adclrck divider and daclrck divider */
88
+ uint8_t lrck_l;
89
+ uint8_t bclk_div; /* sclk divider */
90
+ uint8_t adc_osr; /* adc osr */
91
+ uint8_t dac_osr; /* dac osr */
92
+};
93
+
94
+/* codec hifi mclk clock divider coefficients */
95
+static const struct _coeff_div coeff_div[] = {
96
+ //mclk rate pre_div mult adc_div dac_div fs_mode lrch lrcl bckdiv osr
97
+ /* 8k */
98
+ {12288000, 8000 , 0x06, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
99
+ {18432000, 8000 , 0x03, 0x02, 0x03, 0x03, 0x00, 0x05, 0xff, 0x18, 0x10, 0x10},
100
+ {16384000, 8000 , 0x08, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
101
+ {8192000 , 8000 , 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
102
+ {6144000 , 8000 , 0x03, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
103
+ {4096000 , 8000 , 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
104
+ {3072000 , 8000 , 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
105
+ {2048000 , 8000 , 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
106
+ {1536000 , 8000 , 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
107
+ {1024000 , 8000 , 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
108
+
109
+ /* 11.025k */
110
+ {11289600, 11025, 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
111
+ {5644800 , 11025, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
112
+ {2822400 , 11025, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
113
+ {1411200 , 11025, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
114
+
115
+ /* 12k */
116
+ {12288000, 12000, 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
117
+ {6144000 , 12000, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
118
+ {3072000 , 12000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
119
+ {1536000 , 12000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
120
+
121
+ /* 16k */
122
+ {12288000, 16000, 0x03, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
123
+ {18432000, 16000, 0x03, 0x02, 0x03, 0x03, 0x00, 0x02, 0xff, 0x0c, 0x10, 0x10},
124
+ {16384000, 16000, 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
125
+ {8192000 , 16000, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
126
+ {6144000 , 16000, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
127
+ {4096000 , 16000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
128
+ {3072000 , 16000, 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
129
+ {2048000 , 16000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
130
+ {1536000 , 16000, 0x03, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
131
+ {1024000 , 16000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
132
+
133
+ /* 22.05k */
134
+ {11289600, 22050, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
135
+ {5644800 , 22050, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
136
+ {2822400 , 22050, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
137
+ {1411200 , 22050, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
138
+
139
+ /* 24k */
140
+ {12288000, 24000, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
141
+ {18432000, 24000, 0x03, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
142
+ {6144000 , 24000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
143
+ {3072000 , 24000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
144
+ {1536000 , 24000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
145
+
146
+ /* 32k */
147
+ {12288000, 32000, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
148
+ {18432000, 32000, 0x03, 0x04, 0x03, 0x03, 0x00, 0x02, 0xff, 0x0c, 0x10, 0x10},
149
+ {16384000, 32000, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
150
+ {8192000 , 32000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
151
+ {6144000 , 32000, 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
152
+ {4096000 , 32000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
153
+ {3072000 , 32000, 0x03, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
154
+ {2048000 , 32000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
155
+ {1536000 , 32000, 0x03, 0x08, 0x01, 0x01, 0x01, 0x00, 0x7f, 0x02, 0x10, 0x10},
156
+ {1024000 , 32000, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
157
+
158
+ /* 44.1k */
159
+ {11289600, 44100, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
160
+ {5644800 , 44100, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
161
+ {2822400 , 44100, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
162
+ {1411200 , 44100, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
163
+
164
+ /* 48k */
165
+ {12288000, 48000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
166
+ {18432000, 48000, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
167
+ {6144000 , 48000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
168
+ {3072000 , 48000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
169
+ {1536000 , 48000, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
170
+
171
+ /* 64k */
172
+ {12288000, 64000, 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
173
+ {18432000, 64000, 0x03, 0x04, 0x03, 0x03, 0x01, 0x01, 0x7f, 0x06, 0x10, 0x10},
174
+ {16384000, 64000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
175
+ {8192000 , 64000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
176
+ {6144000 , 64000, 0x01, 0x04, 0x03, 0x03, 0x01, 0x01, 0x7f, 0x06, 0x10, 0x10},
177
+ {4096000 , 64000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
178
+ {3072000 , 64000, 0x01, 0x08, 0x03, 0x03, 0x01, 0x01, 0x7f, 0x06, 0x10, 0x10},
179
+ {2048000 , 64000, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
180
+ {1536000 , 64000, 0x01, 0x08, 0x01, 0x01, 0x01, 0x00, 0xbf, 0x03, 0x18, 0x18},
181
+ {1024000 , 64000, 0x01, 0x08, 0x01, 0x01, 0x01, 0x00, 0x7f, 0x02, 0x10, 0x10},
182
+
183
+ /* 88.2k */
184
+ {11289600, 88200, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
185
+ {5644800 , 88200, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
186
+ {2822400 , 88200, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
187
+ {1411200 , 88200, 0x01, 0x08, 0x01, 0x01, 0x01, 0x00, 0x7f, 0x02, 0x10, 0x10},
188
+
189
+ /* 96k */
190
+ {12288000, 96000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
191
+ {18432000, 96000, 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
192
+ {6144000 , 96000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
193
+ {3072000 , 96000, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
194
+ {1536000 , 96000, 0x01, 0x08, 0x01, 0x01, 0x01, 0x00, 0x7f, 0x02, 0x10, 0x10},
195
+};
196
+
197
+static char *TAG = "DRV8311";
198
+
199
+#define ES_ASSERT(a, format, b, ...) \
200
+ if ((a) != 0) { \
201
+ ESP_LOGE(TAG, format, ##__VA_ARGS__); \
202
+ return b;\
203
+ }
204
+
205
+static int es8311_write_reg(uint8_t reg_addr, uint8_t data)
206
+{
207
+ int res = 0;
208
+ i2c_cmd_handle_t cmd = i2c_cmd_link_create();
209
+ res |= i2c_master_start(cmd);
210
+ res |= i2c_master_write_byte(cmd, ES8311_ADDR, 1 /*ACK_CHECK_EN*/);
211
+ res |= i2c_master_write_byte(cmd, reg_addr, 1 /*ACK_CHECK_EN*/);
212
+ res |= i2c_master_write_byte(cmd, data, 1 /*ACK_CHECK_EN*/);
213
+ res |= i2c_master_stop(cmd);
214
+ res |= i2c_master_cmd_begin(0, cmd, 1000 / portTICK_RATE_MS);
215
+ i2c_cmd_link_delete(cmd);
216
+ ES_ASSERT(res, "Es8311 Write Reg error", -1);
217
+ return res;
218
+}
219
+
220
+static int es8311_read_reg(uint8_t reg_addr)
221
+{
222
+ uint8_t data;
223
+ int res = 0;
224
+ i2c_cmd_handle_t cmd = i2c_cmd_link_create();
225
+
226
+ res |= i2c_master_start(cmd);
227
+ res |= i2c_master_write_byte(cmd, ES8311_ADDR, 1 /*ACK_CHECK_EN*/);
228
+ res |= i2c_master_write_byte(cmd, reg_addr, 1 /*ACK_CHECK_EN*/);
229
+ res |= i2c_master_stop(cmd);
230
+ res |= i2c_master_cmd_begin(0, cmd, 1000 / portTICK_RATE_MS);
231
+ i2c_cmd_link_delete(cmd);
232
+
233
+ cmd = i2c_cmd_link_create();
234
+ res |= i2c_master_start(cmd);
235
+ res |= i2c_master_write_byte(cmd, ES8311_ADDR | 0x01, 1 /*ACK_CHECK_EN*/);
236
+ res |= i2c_master_read_byte(cmd, &data, 0x01 /*NACK_VAL*/);
237
+ res |= i2c_master_stop(cmd);
238
+ res |= i2c_master_cmd_begin(0, cmd, 1000 / portTICK_RATE_MS);
239
+ i2c_cmd_link_delete(cmd);
240
+
241
+ ES_ASSERT(res, "Es8311 Read Reg error", -1);
242
+ return (int)data;
243
+}
244
+
245
+static int i2c_init()
246
+{
247
+ int res = 0;
248
+ get_i2c_pins(I2C_NUM_0, &es_i2c_cfg);
249
+ res |= i2c_param_config(I2C_NUM_0, &es_i2c_cfg);
250
+ res |= i2c_driver_install(I2C_NUM_0, es_i2c_cfg.mode, 0, 0, 0);
251
+ ES_ASSERT(res, "i2c_init error", -1);
252
+ return res;
253
+}
254
+
255
+/*
256
+* look for the coefficient in coeff_div[] table
257
+*/
258
+static int get_coeff(uint32_t mclk, uint32_t rate)
259
+{
260
+ for (int i = 0; i < (sizeof(coeff_div) / sizeof(coeff_div[0])); i++) {
261
+ if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
262
+ return i;
263
+ }
264
+ return -1;
265
+}
266
+
267
+/*
268
+* set es8311 dac mute or not
269
+* if mute = 0, dac un-mute
270
+* if mute = 1, dac mute
271
+*/
272
+static void es8311_mute(int mute)
273
+{
274
+ uint8_t regv;
275
+ ESP_LOGI(TAG, "Enter into es8311_mute(), mute = %d\n", mute);
276
+ regv = es8311_read_reg(ES8311_DAC_REG31) & 0x9f;
277
+ if (mute) {
278
+ es8311_write_reg(ES8311_SYSTEM_REG12, 0x02);
279
+ es8311_write_reg(ES8311_DAC_REG31, regv | 0x60);
280
+ es8311_write_reg(ES8311_DAC_REG32, 0x00);
281
+ es8311_write_reg(ES8311_DAC_REG37, 0x08);
282
+ } else {
283
+ es8311_write_reg(ES8311_DAC_REG31, regv);
284
+ es8311_write_reg(ES8311_SYSTEM_REG12, 0x00);
285
+ }
286
+}
287
+
288
+/*
289
+* set es8311 into suspend mode
290
+*/
291
+static void es8311_suspend(void)
292
+{
293
+ ESP_LOGI(TAG, "Enter into es8311_suspend()");
294
+ es8311_write_reg(ES8311_DAC_REG32, 0x00);
295
+ es8311_write_reg(ES8311_ADC_REG17, 0x00);
296
+ es8311_write_reg(ES8311_SYSTEM_REG0E, 0xFF);
297
+ es8311_write_reg(ES8311_SYSTEM_REG12, 0x02);
298
+ es8311_write_reg(ES8311_SYSTEM_REG14, 0x00);
299
+ es8311_write_reg(ES8311_SYSTEM_REG0D, 0xFA);
300
+ es8311_write_reg(ES8311_ADC_REG15, 0x00);
301
+ es8311_write_reg(ES8311_DAC_REG37, 0x08);
302
+ es8311_write_reg(ES8311_GP_REG45, 0x01);
303
+}
304
+
305
+/*
306
+* enable pa power
307
+*/
308
+void es8311_pa_power(bool enable)
309
+{
310
+ gpio_config_t io_conf;
311
+ memset(&io_conf, 0, sizeof(io_conf));
312
+ io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
313
+ io_conf.mode = GPIO_MODE_OUTPUT;
314
+ io_conf.pin_bit_mask = BIT(get_pa_enable_gpio());
315
+ io_conf.pull_down_en = 0;
316
+ io_conf.pull_up_en = 0;
317
+ gpio_config(&io_conf);
318
+ if (enable) {
319
+ gpio_set_level(get_pa_enable_gpio(), 1);
320
+ } else {
321
+ gpio_set_level(get_pa_enable_gpio(), 0);
322
+ }
323
+}
324
+
325
+esp_err_t es8311_codec_init(audio_hal_codec_config_t *codec_cfg)
326
+{
327
+ uint8_t datmp, regv;
328
+ int coeff;
329
+ esp_err_t ret = ESP_OK;
330
+ i2c_init(); // ESP32 in master mode
331
+
332
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, 0x30);
333
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG02, 0x00);
334
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG03, 0x10);
335
+ ret |= es8311_write_reg(ES8311_ADC_REG16, 0x24);
336
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG04, 0x10);
337
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG05, 0x00);
338
+ ret |= es8311_write_reg(ES8311_SYSTEM_REG0B, 0x00);
339
+ ret |= es8311_write_reg(ES8311_SYSTEM_REG0C, 0x00);
340
+ ret |= es8311_write_reg(ES8311_SYSTEM_REG10, 0x1F);
341
+ ret |= es8311_write_reg(ES8311_SYSTEM_REG11, 0x7F);
342
+ ret |= es8311_write_reg(ES8311_RESET_REG00, 0x80);
343
+ /*
344
+ * Set Codec into Master or Slave mode
345
+ */
346
+ regv = es8311_read_reg(ES8311_RESET_REG00);
347
+ /*
348
+ * Set master/slave audio interface
349
+ */
350
+ audio_hal_codec_i2s_iface_t *i2s_cfg = &(codec_cfg->i2s_iface);
351
+ switch (i2s_cfg->mode) {
352
+ case AUDIO_HAL_MODE_MASTER: /* MASTER MODE */
353
+ ESP_LOGI(TAG, "ES8311 in Master mode");
354
+ regv |= 0x40;
355
+ break;
356
+ case AUDIO_HAL_MODE_SLAVE: /* SLAVE MODE */
357
+ ESP_LOGI(TAG, "ES8311 in Slave mode");
358
+ regv &= 0xBF;
359
+ break;
360
+ default:
361
+ regv &= 0xBF;
362
+ }
363
+ ret |= es8311_write_reg(ES8311_RESET_REG00, regv);
364
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, 0x3F);
365
+ /*
366
+ * Select clock source for internal mclk
367
+ */
368
+ switch (MCLK_SOURCE) {
369
+ case FROM_MCLK_PIN:
370
+ regv = es8311_read_reg(ES8311_CLK_MANAGER_REG01);
371
+ regv &= 0x7F;
372
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, regv);
373
+ break;
374
+ case FROM_SCLK_PIN:
375
+ regv = es8311_read_reg(ES8311_CLK_MANAGER_REG01);
376
+ regv |= 0x80;
377
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, regv);
378
+ break;
379
+ default:
380
+ regv = es8311_read_reg(ES8311_CLK_MANAGER_REG01);
381
+ regv &= 0x7F;
382
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, regv);
383
+ break;
384
+ }
385
+ int sample_fre = 0;
386
+ int mclk_fre = 0;
387
+ switch (i2s_cfg->samples) {
388
+ case AUDIO_HAL_08K_SAMPLES:
389
+ sample_fre = 8000;
390
+ break;
391
+ case AUDIO_HAL_11K_SAMPLES:
392
+ sample_fre = 11025;
393
+ break;
394
+ case AUDIO_HAL_16K_SAMPLES:
395
+ sample_fre = 16000;
396
+ break;
397
+ case AUDIO_HAL_22K_SAMPLES:
398
+ sample_fre = 22050;
399
+ break;
400
+ case AUDIO_HAL_24K_SAMPLES:
401
+ sample_fre = 24000;
402
+ break;
403
+ case AUDIO_HAL_32K_SAMPLES:
404
+ sample_fre = 32000;
405
+ break;
406
+ case AUDIO_HAL_44K_SAMPLES:
407
+ sample_fre = 44100;
408
+ break;
409
+ case AUDIO_HAL_48K_SAMPLES:
410
+ sample_fre = 48000;
411
+ break;
412
+ default:
413
+ ESP_LOGE(TAG, "Unable to configure sample rate %dHz", sample_fre);
414
+ break;
415
+ }
416
+ mclk_fre = sample_fre * MCLK_DIV_FRE;
417
+ coeff = get_coeff(mclk_fre, sample_fre);
418
+ if (coeff < 0) {
419
+ ESP_LOGE(TAG, "Unable to configure sample rate %dHz with %dHz MCLK", sample_fre, mclk_fre);
420
+ return ESP_FAIL;
421
+ }
422
+ /*
423
+ * Set clock parammeters
424
+ */
425
+ if (coeff >= 0) {
426
+ regv = es8311_read_reg(ES8311_CLK_MANAGER_REG02) & 0x07;
427
+ regv |= (coeff_div[coeff].pre_div - 1) << 5;
428
+ datmp = 0;
429
+ switch (coeff_div[coeff].pre_multi) {
430
+ case 1:
431
+ datmp = 0;
432
+ break;
433
+ case 2:
434
+ datmp = 1;
435
+ break;
436
+ case 4:
437
+ datmp = 2;
438
+ break;
439
+ case 8:
440
+ datmp = 3;
441
+ break;
442
+ default:
443
+ break;
444
+ }
445
+ regv |= (datmp) << 3;
446
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG02, regv);
447
+
448
+ regv = es8311_read_reg(ES8311_CLK_MANAGER_REG05) & 0x00;
449
+ regv |= (coeff_div[coeff].adc_div - 1) << 4;
450
+ regv |= (coeff_div[coeff].dac_div - 1) << 0;
451
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG05, regv);
452
+
453
+ regv = es8311_read_reg(ES8311_CLK_MANAGER_REG03) & 0x80;
454
+ regv |= coeff_div[coeff].fs_mode << 6;
455
+ regv |= coeff_div[coeff].adc_osr << 0;
456
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG03, regv);
457
+
458
+ regv = es8311_read_reg(ES8311_CLK_MANAGER_REG04) & 0x80;
459
+ regv |= coeff_div[coeff].dac_osr << 0;
460
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG04, regv);
461
+
462
+ regv = es8311_read_reg(ES8311_CLK_MANAGER_REG07) & 0xC0;
463
+ regv |= coeff_div[coeff].lrck_h << 0;
464
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG07, regv);
465
+
466
+ regv = es8311_read_reg(ES8311_CLK_MANAGER_REG08) & 0x00;
467
+ regv |= coeff_div[coeff].lrck_l << 0;
468
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG08, regv);
469
+
470
+ regv = es8311_read_reg(ES8311_CLK_MANAGER_REG06) & 0xE0;
471
+ if (coeff_div[coeff].bclk_div < 19) {
472
+ regv |= (coeff_div[coeff].bclk_div - 1) << 0;
473
+ } else {
474
+ regv |= (coeff_div[coeff].bclk_div) << 0;
475
+ }
476
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG06, regv);
477
+ }
478
+
479
+ /*
480
+ * mclk inverted or not
481
+ */
482
+ if (INVERT_MCLK) {
483
+ regv = es8311_read_reg(ES8311_CLK_MANAGER_REG01);
484
+ regv |= 0x40;
485
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, regv);
486
+ } else {
487
+ regv = es8311_read_reg(ES8311_CLK_MANAGER_REG01);
488
+ regv &= ~(0x40);
489
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, regv);
490
+ }
491
+ /*
492
+ * sclk inverted or not
493
+ */
494
+ if (INVERT_SCLK) {
495
+ regv = es8311_read_reg(ES8311_CLK_MANAGER_REG06);
496
+ regv |= 0x20;
497
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG06, regv);
498
+ } else {
499
+ regv = es8311_read_reg(ES8311_CLK_MANAGER_REG06);
500
+ regv &= ~(0x20);
501
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG06, regv);
502
+ }
503
+
504
+ ret |= es8311_write_reg(ES8311_SYSTEM_REG13, 0x10);
505
+ ret |= es8311_write_reg(ES8311_ADC_REG1B, 0x0A);
506
+ ret |= es8311_write_reg(ES8311_ADC_REG1C, 0x6A);
507
+ ret |= es8311_write_reg(ES8311_GPIO_REG44, 0x08);
508
+
509
+ es8311_pa_power(true);
510
+ return ESP_OK;
511
+}
512
+
513
+esp_err_t es8311_codec_deinit()
514
+{
515
+//TODO
516
+ return ESP_OK;
517
+}
518
+
519
+esp_err_t es8311_config_fmt(es_i2s_fmt_t fmt)
520
+{
521
+ esp_err_t ret = ESP_OK;
522
+ uint8_t adc_iface = 0, dac_iface = 0;
523
+ dac_iface = es8311_read_reg(ES8311_SDPIN_REG09);
524
+ adc_iface = es8311_read_reg(ES8311_SDPOUT_REG0A);
525
+ switch (fmt) {
526
+ case AUDIO_HAL_I2S_NORMAL:
527
+ ESP_LOGD(TAG, "ES8311 in I2S Format");
528
+ dac_iface &= 0xFC;
529
+ adc_iface &= 0xFC;
530
+ break;
531
+ case AUDIO_HAL_I2S_LEFT:
532
+ case AUDIO_HAL_I2S_RIGHT:
533
+ ESP_LOGD(TAG, "ES8311 in LJ Format");
534
+ adc_iface &= 0xFC;
535
+ dac_iface &= 0xFC;
536
+ adc_iface |= 0x01;
537
+ dac_iface |= 0x01;
538
+ break;
539
+ case AUDIO_HAL_I2S_DSP:
540
+ ESP_LOGD(TAG, "ES8311 in DSP-A Format");
541
+ adc_iface &= 0xDC;
542
+ dac_iface &= 0xDC;
543
+ adc_iface |= 0x03;
544
+ dac_iface |= 0x03;
545
+ break;
546
+ default:
547
+ dac_iface &= 0xFC;
548
+ adc_iface &= 0xFC;
549
+ break;
550
+ }
551
+ ret |= es8311_write_reg(ES8311_SDPIN_REG09, dac_iface);
552
+ ret |= es8311_write_reg(ES8311_SDPOUT_REG0A, adc_iface);
553
+
554
+ return ret;
555
+}
556
+
557
+esp_err_t es8311_set_bits_per_sample(audio_hal_iface_bits_t bits)
558
+{
559
+ esp_err_t ret = ESP_OK;
560
+ uint8_t adc_iface = 0, dac_iface = 0;
561
+ dac_iface = es8311_read_reg(ES8311_SDPIN_REG09);
562
+ adc_iface = es8311_read_reg(ES8311_SDPOUT_REG0A);
563
+ switch (bits) {
564
+ case AUDIO_HAL_BIT_LENGTH_16BITS:
565
+ dac_iface |= 0x0c;
566
+ adc_iface |= 0x0c;
567
+ break;
568
+ case AUDIO_HAL_BIT_LENGTH_24BITS:
569
+ break;
570
+ case AUDIO_HAL_BIT_LENGTH_32BITS:
571
+ dac_iface |= 0x10;
572
+ adc_iface |= 0x10;
573
+ break;
574
+ default:
575
+ dac_iface |= 0x0c;
576
+ adc_iface |= 0x0c;
577
+ break;
578
+
579
+ }
580
+ ret |= es8311_write_reg(ES8311_SDPIN_REG09, dac_iface);
581
+ ret |= es8311_write_reg(ES8311_SDPOUT_REG0A, adc_iface);
582
+
583
+ return ret;
584
+}
585
+
586
+esp_err_t es8311_codec_config_i2s(audio_hal_codec_mode_t mode, audio_hal_codec_i2s_iface_t *iface)
587
+{
588
+ int ret = ESP_OK;
589
+ ret |= es8311_set_bits_per_sample(iface->bits);
590
+ ret |= es8311_config_fmt(iface->fmt);
591
+ return ret;
592
+}
593
+
594
+esp_err_t es8311_codec_ctrl_state(audio_hal_codec_mode_t mode, audio_hal_ctrl_t ctrl_state)
595
+{
596
+ esp_err_t ret = ESP_OK;
597
+ es_module_t es_mode = ES_MODULE_MIN;
598
+
599
+ switch (mode) {
600
+ case AUDIO_HAL_CODEC_MODE_ENCODE:
601
+ es_mode = ES_MODULE_ADC;
602
+ break;
603
+ case AUDIO_HAL_CODEC_MODE_LINE_IN:
604
+ es_mode = ES_MODULE_LINE;
605
+ break;
606
+ case AUDIO_HAL_CODEC_MODE_DECODE:
607
+ es_mode = ES_MODULE_DAC;
608
+ break;
609
+ case AUDIO_HAL_CODEC_MODE_BOTH:
610
+ es_mode = ES_MODULE_ADC_DAC;
611
+ break;
612
+ default:
613
+ es_mode = ES_MODULE_DAC;
614
+ ESP_LOGW(TAG, "Codec mode not support, default is decode mode");
615
+ break;
616
+ }
617
+
618
+ if (ctrl_state == AUDIO_HAL_CTRL_START) {
619
+ ret |= es8311_start(es_mode);
620
+ } else {
621
+ ESP_LOGW(TAG, "The codec is about to stop");
622
+ ret |= es8311_stop(es_mode);
623
+ }
624
+
625
+ return ret;
626
+}
627
+
628
+esp_err_t es8311_start(es_module_t mode)
629
+{
630
+ esp_err_t ret = ESP_OK;
631
+ uint8_t adc_iface = 0, dac_iface = 0;
632
+
633
+ dac_iface = es8311_read_reg(ES8311_SDPIN_REG09) & 0xBF;
634
+ adc_iface = es8311_read_reg(ES8311_SDPOUT_REG0A) & 0xBF;
635
+ adc_iface |= BIT(6);
636
+ dac_iface |= BIT(6);
637
+
638
+ if (mode == ES_MODULE_LINE) {
639
+ ESP_LOGE(TAG, "The codec es8311 doesn't support ES_MODULE_LINE mode");
640
+ return ESP_FAIL;
641
+ }
642
+ if (mode == ES_MODULE_ADC || mode == ES_MODULE_ADC_DAC) {
643
+ adc_iface &= ~(BIT(6));
644
+ }
645
+ if (mode == ES_MODULE_DAC || mode == ES_MODULE_ADC_DAC) {
646
+ dac_iface &= ~(BIT(6));
647
+ }
648
+
649
+ ret |= es8311_write_reg(ES8311_SDPIN_REG09, dac_iface);
650
+ ret |= es8311_write_reg(ES8311_SDPOUT_REG0A, adc_iface);
651
+
652
+ ret |= es8311_write_reg(ES8311_DAC_REG32, 0xBF);
653
+ ret |= es8311_write_reg(ES8311_ADC_REG17, 0xBF);
654
+ ret |= es8311_write_reg(ES8311_SYSTEM_REG0E, 0x02);
655
+ ret |= es8311_write_reg(ES8311_SYSTEM_REG12, 0x00);
656
+ ret |= es8311_write_reg(ES8311_SYSTEM_REG14, 0x1A);
657
+
658
+ /*
659
+ * pdm dmic enable or disable
660
+ */
661
+ int regv = 0;
662
+ if (IS_DMIC) {
663
+ regv = es8311_read_reg(ES8311_SYSTEM_REG14);
664
+ regv |= 0x40;
665
+ ret |= es8311_write_reg(ES8311_SYSTEM_REG14, regv);
666
+ } else {
667
+ regv = es8311_read_reg(ES8311_SYSTEM_REG14);
668
+ regv &= ~(0x40);
669
+ ret |= es8311_write_reg(ES8311_SYSTEM_REG14, regv);
670
+ }
671
+
672
+ ret |= es8311_write_reg(ES8311_SYSTEM_REG0D, 0x01);
673
+ ret |= es8311_write_reg(ES8311_ADC_REG15, 0x40);
674
+ ret |= es8311_write_reg(ES8311_DAC_REG37, 0x48);
675
+ ret |= es8311_write_reg(ES8311_GP_REG45, 0x00);
676
+
677
+ return ret;
678
+}
679
+
680
+esp_err_t es8311_stop(es_module_t mode)
681
+{
682
+ esp_err_t ret = ESP_OK;
683
+ es8311_suspend();
684
+ return ret;
685
+}
686
+
687
+int es8311_codec_set_voice_volume(int volume)
688
+{
689
+ int res = 0;
690
+ if (volume < 0) {
691
+ volume = 0;
692
+ } else if (volume > 100) {
693
+ volume = 100;
694
+ }
695
+ int vol = (volume) * 2550 / 1000;
696
+ ESP_LOGD(TAG, "SET: volume:%d", vol);
697
+ es8311_write_reg(ES8311_DAC_REG32, vol);
698
+ return res;
699
+}
700
+
701
+int es8311_codec_get_voice_volume(int *volume)
702
+{
703
+ int res = ESP_OK;
704
+ int regv = 0;
705
+ regv = es8311_read_reg(ES8311_DAC_REG32);
706
+ if (regv == ESP_FAIL) {
707
+ *volume = 0;
708
+ res = ESP_FAIL;
709
+ } else {
710
+ *volume = regv * 100 / 256;
711
+ }
712
+ ESP_LOGD(TAG, "GET: res:%d, volume:%d", regv, *volume);
713
+ return res;
714
+}
715
+
716
+esp_err_t es8311_set_voice_mute(bool enable)
717
+{
718
+ int res = 0;
719
+ ESP_LOGD(TAG, "Es8311SetVoiceMute volume:%d", enable);
720
+ es8311_mute(enable);
721
+ return res;
722
+}
723
+
724
+int es8311_get_voice_mute(int *mute)
725
+{
726
+ int res = -1;
727
+ uint8_t reg = 0;
728
+ res = es8311_read_reg(ES8311_DAC_REG31);
729
+ if (res != ESP_FAIL) {
730
+ reg = (res & 0x20) >> 5;
731
+ }
732
+ *mute = reg;
733
+ return res;
734
+}
735
+
736
+esp_err_t es8311_set_mic_gain(es8311_mic_gain_t gain_db)
737
+{
738
+ int res = 0;
739
+ res = es8311_write_reg(ES8311_ADC_REG16, gain_db); // MIC gain scale
740
+ return res;
741
+}
742
+
743
+void es8311_read_all()
744
+{
745
+ for (int i = 0; i < 0x4A; i++) {
746
+ uint8_t reg = es8311_read_reg(i);
747
+ ets_printf("REG:%02x, %02x\n", reg, i);
748
+ }
749
+}
Chip-cn-dat/everest-semi-dat/ES8311-dat/ES8311-SDK-dat/example-2/es8311.h
... ...
@@ -0,0 +1,237 @@
1
+/*
2
+ * ESPRESSIF MIT License
3
+ *
4
+ * Copyright (c) 2019 <ESPRESSIF SYSTEMS (SHANGHAI) CO., LTD>
5
+ *
6
+ * Permission is hereby granted for use on all ESPRESSIF SYSTEMS products, in which case,
7
+ * it is free of charge, to any person obtaining a copy of this software and associated
8
+ * documentation files (the "Software"), to deal in the Software without restriction, including
9
+ * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the Software is furnished
11
+ * to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in all copies or
14
+ * substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ *
23
+ */
24
+
25
+#ifndef _ES8311_H
26
+#define _ES8311_H
27
+
28
+#include "audio_hal.h"
29
+#include "esp_types.h"
30
+#include "esxxx_common.h"
31
+
32
+/*
33
+ * ES8311_REGISTER NAME_REG_REGISTER ADDRESS
34
+ */
35
+#define ES8311_RESET_REG00 0x00 /*reset digital,csm,clock manager etc.*/
36
+
37
+/*
38
+ * Clock Scheme Register definition
39
+ */
40
+#define ES8311_CLK_MANAGER_REG01 0x01 /* select clk src for mclk, enable clock for codec */
41
+#define ES8311_CLK_MANAGER_REG02 0x02 /* clk divider and clk multiplier */
42
+#define ES8311_CLK_MANAGER_REG03 0x03 /* adc fsmode and osr */
43
+#define ES8311_CLK_MANAGER_REG04 0x04 /* dac osr */
44
+#define ES8311_CLK_MANAGER_REG05 0x05 /* clk divier for adc and dac */
45
+#define ES8311_CLK_MANAGER_REG06 0x06 /* bclk inverter and divider */
46
+#define ES8311_CLK_MANAGER_REG07 0x07 /* tri-state, lrck divider */
47
+#define ES8311_CLK_MANAGER_REG08 0x08 /* lrck divider */
48
+/*
49
+ * SDP
50
+ */
51
+#define ES8311_SDPIN_REG09 0x09 /* dac serial digital port */
52
+#define ES8311_SDPOUT_REG0A 0x0A /* adc serial digital port */
53
+/*
54
+ * SYSTEM
55
+ */
56
+#define ES8311_SYSTEM_REG0B 0x0B /* system */
57
+#define ES8311_SYSTEM_REG0C 0x0C /* system */
58
+#define ES8311_SYSTEM_REG0D 0x0D /* system, power up/down */
59
+#define ES8311_SYSTEM_REG0E 0x0E /* system, power up/down */
60
+#define ES8311_SYSTEM_REG0F 0x0F /* system, low power */
61
+#define ES8311_SYSTEM_REG10 0x10 /* system */
62
+#define ES8311_SYSTEM_REG11 0x11 /* system */
63
+#define ES8311_SYSTEM_REG12 0x12 /* system, Enable DAC */
64
+#define ES8311_SYSTEM_REG13 0x13 /* system */
65
+#define ES8311_SYSTEM_REG14 0x14 /* system, select DMIC, select analog pga gain */
66
+/*
67
+ * ADC
68
+ */
69
+#define ES8311_ADC_REG15 0x15 /* ADC, adc ramp rate, dmic sense */
70
+#define ES8311_ADC_REG16 0x16 /* ADC */
71
+#define ES8311_ADC_REG17 0x17 /* ADC, volume */
72
+#define ES8311_ADC_REG18 0x18 /* ADC, alc enable and winsize */
73
+#define ES8311_ADC_REG19 0x19 /* ADC, alc maxlevel */
74
+#define ES8311_ADC_REG1A 0x1A /* ADC, alc automute */
75
+#define ES8311_ADC_REG1B 0x1B /* ADC, alc automute, adc hpf s1 */
76
+#define ES8311_ADC_REG1C 0x1C /* ADC, equalizer, hpf s2 */
77
+/*
78
+ * DAC
79
+ */
80
+#define ES8311_DAC_REG31 0x31 /* DAC, mute */
81
+#define ES8311_DAC_REG32 0x32 /* DAC, volume */
82
+#define ES8311_DAC_REG33 0x33 /* DAC, offset */
83
+#define ES8311_DAC_REG34 0x34 /* DAC, drc enable, drc winsize */
84
+#define ES8311_DAC_REG35 0x35 /* DAC, drc maxlevel, minilevel */
85
+#define ES8311_DAC_REG37 0x37 /* DAC, ramprate */
86
+/*
87
+ *GPIO
88
+ */
89
+#define ES8311_GPIO_REG44 0x44 /* GPIO, dac2adc for test */
90
+#define ES8311_GP_REG45 0x45 /* GP CONTROL */
91
+/*
92
+ * CHIP
93
+ */
94
+#define ES8311_CHD1_REGFD 0xFD /* CHIP ID1 */
95
+#define ES8311_CHD2_REGFE 0xFE /* CHIP ID2 */
96
+#define ES8311_CHVER_REGFF 0xFF /* VERSION */
97
+#define ES8311_CHD1_REGFD 0xFD /* CHIP ID1 */
98
+
99
+#define ES8311_MAX_REGISTER 0xFF
100
+
101
+typedef enum {
102
+ ES8311_MIC_GAIN_MIN = -1,
103
+ ES8311_MIC_GAIN_0DB,
104
+ ES8311_MIC_GAIN_6DB,
105
+ ES8311_MIC_GAIN_12DB,
106
+ ES8311_MIC_GAIN_18DB,
107
+ ES8311_MIC_GAIN_24DB,
108
+ ES8311_MIC_GAIN_30DB,
109
+ ES8311_MIC_GAIN_36DB,
110
+ ES8311_MIC_GAIN_42DB,
111
+ ES8311_MIC_GAIN_MAX
112
+} es8311_mic_gain_t;
113
+
114
+/*
115
+ * @brief Initialize ES8311 codec chip
116
+ *
117
+ * @param codec_cfg configuration of ES8311
118
+ *
119
+ * @return
120
+ * - ESP_OK
121
+ * - ESP_FAIL
122
+ */
123
+esp_err_t es8311_codec_init(audio_hal_codec_config_t *codec_cfg);
124
+
125
+/**
126
+ * @brief Deinitialize ES8311 codec chip
127
+ *
128
+ * @return
129
+ * - ESP_OK
130
+ * - ESP_FAIL
131
+ */
132
+esp_err_t es8311_codec_deinit(void);
133
+
134
+/**
135
+ * @brief Control ES8311 codec chip
136
+ *
137
+ * @param mode codec mode
138
+ * @param ctrl_state start or stop decode or encode progress
139
+ *
140
+ * @return
141
+ * - ESP_FAIL Parameter error
142
+ * - ESP_OK Success
143
+ */
144
+esp_err_t es8311_codec_ctrl_state(audio_hal_codec_mode_t mode, audio_hal_ctrl_t ctrl_state);
145
+
146
+/**
147
+ * @brief Configure ES8311 codec mode and I2S interface
148
+ *
149
+ * @param mode codec mode
150
+ * @param iface I2S config
151
+ *
152
+ * @return
153
+ * - ESP_FAIL Parameter error
154
+ * - ESP_OK Success
155
+ */
156
+esp_err_t es8311_codec_config_i2s(audio_hal_codec_mode_t mode, audio_hal_codec_i2s_iface_t *iface);
157
+
158
+/**
159
+ * @brief Configure ES8311 DAC mute or not. Basically you can use this function to mute the output or unmute
160
+ *
161
+ * @param enable enable(1) or disable(0)
162
+ *
163
+ * @return
164
+ * - ESP_FAIL Parameter error
165
+ * - ESP_OK Success
166
+ */
167
+esp_err_t es8311_set_voice_mute(bool enable);
168
+
169
+/**
170
+ * @brief Set voice volume
171
+ *
172
+ * @param volume: voice volume (0~100)
173
+ *
174
+ * @return
175
+ * - ESP_OK
176
+ * - ESP_FAIL
177
+ */
178
+esp_err_t es8311_codec_set_voice_volume(int volume);
179
+
180
+/**
181
+ * @brief Get voice volume
182
+ *
183
+ * @param[out] *volume: voice volume (0~100)
184
+ *
185
+ * @return
186
+ * - ESP_OK
187
+ * - ESP_FAIL
188
+ */
189
+esp_err_t es8311_codec_get_voice_volume(int *volume);
190
+
191
+/**
192
+ * @brief Configure ES8311 I2S format
193
+ *
194
+ * @param mod: set ADC or DAC or both
195
+ * @param cfg: ES8388 I2S format
196
+ *
197
+ * @return
198
+ * - ESP_OK
199
+ * - ESP_FAIL
200
+ */
201
+esp_err_t es8311_config_fmt(es_i2s_fmt_t fmt);
202
+
203
+/**
204
+ * @brief Configure ES8311 data sample bits
205
+ *
206
+ * @param mode: set ADC or DAC or both
207
+ * @param bit_per_sample: bit number of per sample
208
+ *
209
+ * @return
210
+ * - ESP_OK
211
+ * - ESP_FAIL
212
+ */
213
+esp_err_t es8311_set_bits_per_sample(audio_hal_iface_bits_t bits);
214
+
215
+/**
216
+ * @brief Start ES8311 codec chip
217
+ *
218
+ * @param mode: set ADC or DAC or both
219
+ *
220
+ * @return
221
+ * - ESP_OK
222
+ * - ESP_FAIL
223
+ */
224
+esp_err_t es8311_start(es_module_t mode);
225
+
226
+/**
227
+ * @brief Stop ES8311 codec chip
228
+ *
229
+ * @param mode: set ADC or DAC or both
230
+ *
231
+ * @return
232
+ * - ESP_OK
233
+ * - ESP_FAIL
234
+ */
235
+esp_err_t es8311_stop(es_module_t mode);
236
+
237
+#endif
Chip-cn-dat/everest-semi-dat/ES8311-dat/ES8311-SDK-dat/example/example_config.h
... ...
@@ -0,0 +1,33 @@
1
+/*
2
+ * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
3
+ *
4
+ * SPDX-License-Identifier: CC0-1.0
5
+ */
6
+
7
+#pragma once
8
+
9
+#include "sdkconfig.h"
10
+
11
+/* Example configurations */
12
+#define EXAMPLE_RECV_BUF_SIZE (2400)
13
+#define EXAMPLE_SAMPLE_RATE (16000)
14
+#define EXAMPLE_MCLK_MULTIPLE (384) // If not using 24-bit data width, 256 should be enough
15
+#define EXAMPLE_MCLK_FREQ_HZ (EXAMPLE_SAMPLE_RATE * EXAMPLE_MCLK_MULTIPLE)
16
+#define EXAMPLE_VOICE_VOLUME CONFIG_EXAMPLE_VOICE_VOLUME
17
+#define EXAMPLE_PA_CTRL_IO CONFIG_EXAMPLE_PA_CTRL_IO
18
+#if CONFIG_EXAMPLE_MODE_ECHO
19
+#define EXAMPLE_MIC_GAIN CONFIG_EXAMPLE_MIC_GAIN
20
+#endif
21
+
22
+/* I2C port and GPIOs */
23
+#define I2C_NUM (0)
24
+#define I2C_SCL_IO CONFIG_EXAMPLE_I2C_SCL_IO
25
+#define I2C_SDA_IO CONFIG_EXAMPLE_I2C_SDA_IO
26
+
27
+/* I2S port and GPIOs */
28
+#define I2S_NUM (0)
29
+#define I2S_MCK_IO CONFIG_EXAMPLE_I2S_MCLK_IO
30
+#define I2S_BCK_IO CONFIG_EXAMPLE_I2S_BCLK_IO
31
+#define I2S_WS_IO CONFIG_EXAMPLE_I2S_WS_IO
32
+#define I2S_DO_IO CONFIG_EXAMPLE_I2S_DOUT_IO
33
+#define I2S_DI_IO CONFIG_EXAMPLE_I2S_DIN_IO
Chip-cn-dat/everest-semi-dat/ES8311-dat/ES8311-SDK-dat/example/i2s_es8311_example.c
... ...
@@ -0,0 +1,251 @@
1
+/*
2
+ * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
3
+ *
4
+ * SPDX-License-Identifier: CC0-1.0
5
+ */
6
+
7
+#include <stdio.h>
8
+#include <string.h>
9
+#include "sdkconfig.h"
10
+#include "freertos/FreeRTOS.h"
11
+#include "freertos/task.h"
12
+#include "driver/i2s_std.h"
13
+#include "driver/i2c_master.h"
14
+#include "driver/gpio.h"
15
+#include "esp_system.h"
16
+#include "esp_codec_dev_defaults.h"
17
+#include "esp_codec_dev.h"
18
+#include "esp_codec_dev_vol.h"
19
+#include "esp_check.h"
20
+#include "example_config.h"
21
+
22
+static const char *TAG = "i2s_es8311";
23
+static const char err_reason[][30] = {"input param is invalid",
24
+ "operation timeout"
25
+ };
26
+static i2s_chan_handle_t tx_handle = NULL;
27
+static i2s_chan_handle_t rx_handle = NULL;
28
+
29
+/* Import music file as buffer */
30
+#if CONFIG_EXAMPLE_MODE_MUSIC
31
+extern const uint8_t music_pcm_start[] asm("_binary_canon_pcm_start");
32
+extern const uint8_t music_pcm_end[] asm("_binary_canon_pcm_end");
33
+#endif
34
+
35
+static esp_err_t es8311_codec_init(void)
36
+{
37
+ /* Initialize I2C peripheral */
38
+ i2c_master_bus_handle_t i2c_bus_handle = NULL;
39
+ i2c_master_bus_config_t i2c_mst_cfg = {
40
+ .i2c_port = I2C_NUM,
41
+ .sda_io_num = I2C_SDA_IO,
42
+ .scl_io_num = I2C_SCL_IO,
43
+ .clk_source = I2C_CLK_SRC_DEFAULT,
44
+ .glitch_ignore_cnt = 7,
45
+ /* Pull-up internally for no external pull-up case.
46
+ Suggest to use external pull-up to ensure a strong enough pull-up. */
47
+ .flags.enable_internal_pullup = true,
48
+ };
49
+ ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_mst_cfg, &i2c_bus_handle));
50
+
51
+ /* Create control interface with I2C bus handle */
52
+ audio_codec_i2c_cfg_t i2c_cfg = {
53
+ .port = I2C_NUM,
54
+ .addr = ES8311_CODEC_DEFAULT_ADDR,
55
+ .bus_handle = i2c_bus_handle,
56
+ };
57
+ const audio_codec_ctrl_if_t *ctrl_if = audio_codec_new_i2c_ctrl(&i2c_cfg);
58
+ assert(ctrl_if);
59
+
60
+ /* Create data interface with I2S bus handle */
61
+ audio_codec_i2s_cfg_t i2s_cfg = {
62
+ .port = I2S_NUM,
63
+ .rx_handle = rx_handle,
64
+ .tx_handle = tx_handle,
65
+ };
66
+ const audio_codec_data_if_t *data_if = audio_codec_new_i2s_data(&i2s_cfg);
67
+ assert(data_if);
68
+
69
+ /* Create ES8311 interface handle */
70
+ const audio_codec_gpio_if_t *gpio_if = audio_codec_new_gpio();
71
+ assert(gpio_if);
72
+ es8311_codec_cfg_t es8311_cfg = {
73
+ .ctrl_if = ctrl_if,
74
+ .gpio_if = gpio_if,
75
+ .codec_mode = ESP_CODEC_DEV_WORK_MODE_BOTH,
76
+ .master_mode = false,
77
+ .use_mclk = I2S_MCK_IO >= 0,
78
+ .pa_pin = EXAMPLE_PA_CTRL_IO,
79
+ .pa_reverted = false,
80
+ .hw_gain = {
81
+ .pa_voltage = 5.0,
82
+ .codec_dac_voltage = 3.3,
83
+ },
84
+ .mclk_div = EXAMPLE_MCLK_MULTIPLE,
85
+ };
86
+ const audio_codec_if_t *es8311_if = es8311_codec_new(&es8311_cfg);
87
+ assert(es8311_if);
88
+
89
+ /* Create the top codec handle with ES8311 interface handle and data interface */
90
+ esp_codec_dev_cfg_t dev_cfg = {
91
+ .dev_type = ESP_CODEC_DEV_TYPE_IN_OUT,
92
+ .codec_if = es8311_if,
93
+ .data_if = data_if,
94
+ };
95
+ esp_codec_dev_handle_t codec_handle = esp_codec_dev_new(&dev_cfg);
96
+ assert(codec_handle);
97
+
98
+ /* Specify the sample configurations and open the device */
99
+ esp_codec_dev_sample_info_t sample_cfg = {
100
+ .bits_per_sample = I2S_DATA_BIT_WIDTH_16BIT,
101
+ .channel = 2,
102
+ .channel_mask = 0x03,
103
+ .sample_rate = EXAMPLE_SAMPLE_RATE,
104
+ .mclk_multiple = EXAMPLE_MCLK_MULTIPLE,
105
+ };
106
+ if (esp_codec_dev_open(codec_handle, &sample_cfg) != ESP_CODEC_DEV_OK) {
107
+ ESP_LOGE(TAG, "Open codec device failed");
108
+ return ESP_FAIL;
109
+ }
110
+
111
+ /* Set the initial volume and gain */
112
+ if (esp_codec_dev_set_out_vol(codec_handle, EXAMPLE_VOICE_VOLUME) != ESP_CODEC_DEV_OK) {
113
+ ESP_LOGE(TAG, "set output volume failed");
114
+ return ESP_FAIL;
115
+ }
116
+#if CONFIG_EXAMPLE_MODE_ECHO
117
+ if (esp_codec_dev_set_in_gain(codec_handle, EXAMPLE_MIC_GAIN) != ESP_CODEC_DEV_OK) {
118
+ ESP_LOGE(TAG, "set input gain failed");
119
+ return ESP_FAIL;
120
+ }
121
+#endif
122
+ return ESP_OK;
123
+}
124
+
125
+static esp_err_t i2s_driver_init(void)
126
+{
127
+ i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM, I2S_ROLE_MASTER);
128
+ chan_cfg.auto_clear = true; // Auto clear the legacy data in the DMA buffer
129
+ ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle));
130
+ i2s_std_config_t std_cfg = {
131
+ .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(EXAMPLE_SAMPLE_RATE),
132
+ .slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO),
133
+ .gpio_cfg = {
134
+ .mclk = I2S_MCK_IO,
135
+ .bclk = I2S_BCK_IO,
136
+ .ws = I2S_WS_IO,
137
+ .dout = I2S_DO_IO,
138
+ .din = I2S_DI_IO,
139
+ .invert_flags = {
140
+ .mclk_inv = false,
141
+ .bclk_inv = false,
142
+ .ws_inv = false,
143
+ },
144
+ },
145
+ };
146
+
147
+ ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_handle, &std_cfg));
148
+ ESP_ERROR_CHECK(i2s_channel_init_std_mode(rx_handle, &std_cfg));
149
+ ESP_ERROR_CHECK(i2s_channel_enable(tx_handle));
150
+ ESP_ERROR_CHECK(i2s_channel_enable(rx_handle));
151
+ return ESP_OK;
152
+}
153
+
154
+#if CONFIG_EXAMPLE_MODE_MUSIC
155
+static void i2s_music(void *args)
156
+{
157
+ esp_err_t ret = ESP_OK;
158
+ size_t bytes_write = 0;
159
+ uint8_t *data_ptr = (uint8_t *)music_pcm_start;
160
+
161
+ /* (Optional) Disable TX channel and preload the data before enabling the TX channel,
162
+ * so that the valid data can be transmitted immediately */
163
+ ESP_ERROR_CHECK(i2s_channel_disable(tx_handle));
164
+ ESP_ERROR_CHECK(i2s_channel_preload_data(tx_handle, data_ptr, music_pcm_end - data_ptr, &bytes_write));
165
+ data_ptr += bytes_write; // Move forward the data pointer
166
+
167
+ /* Enable the TX channel */
168
+ ESP_ERROR_CHECK(i2s_channel_enable(tx_handle));
169
+ while (1) {
170
+ /* Write music to earphone */
171
+ ret = i2s_channel_write(tx_handle, data_ptr, music_pcm_end - data_ptr, &bytes_write, portMAX_DELAY);
172
+ if (ret != ESP_OK) {
173
+ /* Since we set timeout to 'portMAX_DELAY' in 'i2s_channel_write'
174
+ so you won't reach here unless you set other timeout value,
175
+ if timeout detected, it means write operation failed. */
176
+ ESP_LOGE(TAG, "[music] i2s write failed, %s", err_reason[ret == ESP_ERR_TIMEOUT]);
177
+ abort();
178
+ }
179
+ if (bytes_write > 0) {
180
+ ESP_LOGI(TAG, "[music] i2s music played, %d bytes are written.", bytes_write);
181
+ } else {
182
+ ESP_LOGE(TAG, "[music] i2s music play failed.");
183
+ abort();
184
+ }
185
+ data_ptr = (uint8_t *)music_pcm_start;
186
+ vTaskDelay(1000 / portTICK_PERIOD_MS);
187
+ }
188
+ vTaskDelete(NULL);
189
+}
190
+
191
+#else
192
+static void i2s_echo(void *args)
193
+{
194
+ int *mic_data = malloc(EXAMPLE_RECV_BUF_SIZE);
195
+ if (!mic_data) {
196
+ ESP_LOGE(TAG, "[echo] No memory for read data buffer");
197
+ abort();
198
+ }
199
+ esp_err_t ret = ESP_OK;
200
+ size_t bytes_read = 0;
201
+ size_t bytes_write = 0;
202
+ ESP_LOGI(TAG, "[echo] Echo start");
203
+
204
+ while (1) {
205
+ memset(mic_data, 0, EXAMPLE_RECV_BUF_SIZE);
206
+ /* Read sample data from mic */
207
+ ret = i2s_channel_read(rx_handle, mic_data, EXAMPLE_RECV_BUF_SIZE, &bytes_read, 1000);
208
+ if (ret != ESP_OK) {
209
+ ESP_LOGE(TAG, "[echo] i2s read failed, %s", err_reason[ret == ESP_ERR_TIMEOUT]);
210
+ abort();
211
+ }
212
+ /* Write sample data to earphone */
213
+ ret = i2s_channel_write(tx_handle, mic_data, EXAMPLE_RECV_BUF_SIZE, &bytes_write, 1000);
214
+ if (ret != ESP_OK) {
215
+ ESP_LOGE(TAG, "[echo] i2s write failed, %s", err_reason[ret == ESP_ERR_TIMEOUT]);
216
+ abort();
217
+ }
218
+ if (bytes_read != bytes_write) {
219
+ ESP_LOGW(TAG, "[echo] %d bytes read but only %d bytes are written", bytes_read, bytes_write);
220
+ }
221
+ }
222
+ vTaskDelete(NULL);
223
+}
224
+#endif
225
+
226
+void app_main(void)
227
+{
228
+ printf("i2s es8311 codec example start\n-----------------------------\n");
229
+ /* Initialize i2s peripheral */
230
+ if (i2s_driver_init() != ESP_OK) {
231
+ ESP_LOGE(TAG, "i2s driver init failed");
232
+ abort();
233
+ } else {
234
+ ESP_LOGI(TAG, "i2s driver init success");
235
+ }
236
+ /* Initialize i2c peripheral and config es8311 codec by i2c */
237
+ if (es8311_codec_init() != ESP_OK) {
238
+ ESP_LOGE(TAG, "es8311 codec init failed");
239
+ abort();
240
+ } else {
241
+ ESP_LOGI(TAG, "es8311 codec init success");
242
+ }
243
+
244
+#if CONFIG_EXAMPLE_MODE_MUSIC
245
+ /* Play a piece of music in music mode */
246
+ xTaskCreate(i2s_music, "i2s_music", 4096, NULL, 5, NULL);
247
+#else
248
+ /* Echo the sound from MIC in echo mode */
249
+ xTaskCreate(i2s_echo, "i2s_echo", 8192, NULL, 5, NULL);
250
+#endif
251
+}
Chip-cn-dat/everest-semi-dat/ES8311-dat/ES8311-SDK-dat/test/ES8311-code-mic2/ES8311-code-mic2.ino
... ...
@@ -1,78 +1,147 @@
1 1
#include <Wire.h>
2
-#include <ESP_I2S.h>
2
+#include <driver/i2s.h>
3 3
4
-// PIN CONFIGURATION
4
+// ========== PIN CONFIGURATION ==========
5 5
#define I2C_SDA 5
6 6
#define I2C_SCL 4
7 7
8 8
#define I2S_BCLK 14
9
-#define I2S_LRCK 12
10
-#define I2S_DOUT 13
11
-#define I2S_DIN 11 // unused (DAC playback only)
12
-#define I2S_MCLK 6
9
+#define I2S_LRCK 13
10
+#define I2S_DOUT 12 // unused (reading from mic)
11
+#define I2S_DIN 15 // ES8311 SDTO (data out)
12
+#define I2S_MCLK 16
13 13
14
-#define ES8311_ADDR 0x18
14
+#define ES8311_ADDR 0x18
15
+#define SAMPLE_RATE 16000
15 16
16
-I2SClass i2s;
17
+// ========== I2C HELPERS ==========
18
+bool writeReg(uint8_t reg, uint8_t val) {
19
+ Wire.beginTransmission(ES8311_ADDR);
20
+ Wire.write(reg);
21
+ Wire.write(val);
22
+ return Wire.endTransmission() == 0;
23
+}
17 24
18
-void writeReg(uint8_t reg, uint8_t value) {
25
+uint8_t readReg(uint8_t reg) {
19 26
Wire.beginTransmission(ES8311_ADDR);
20 27
Wire.write(reg);
21
- Wire.write(value);
22
- Wire.endTransmission();
28
+ Wire.endTransmission(false);
29
+ Wire.requestFrom(ES8311_ADDR, (uint8_t)1);
30
+ return Wire.available() ? Wire.read() : 0xFF;
31
+}
32
+
33
+void dumpRegs() {
34
+ Serial.println("--- ES8311 Registers ---");
35
+ uint8_t regs[] = {0x00,0x01,0x02,0x03,0x0A,0x0B,0x0D,0x0E,
36
+ 0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x45};
37
+ for (int i = 0; i < (int)(sizeof(regs)/sizeof(regs[0])); i++) {
38
+ Serial.printf(" REG[0x%02X] = 0x%02X\n", regs[i], readReg(regs[i]));
39
+ }
23 40
}
24 41
25
-void init_ES8311() {
42
+// ========== ES8311 INIT ==========
43
+bool init_ES8311() {
26 44
// 1. Reset
27
- writeReg(0x00, 0x80); delay(50);
28
- writeReg(0x00, 0x00);
29
-
30
- // 2. Clock Management (Slave Mode)
31
- writeReg(0x01, 0x30); // Enable MCLK and Clocks
32
- writeReg(0x02, 0x10); // ADC Clock
33
- writeReg(0x03, 0x10); // DAC Clock
34
-
35
- // 3. I2S Format (Phillips 16-bit)
36
- writeReg(0x0A, 0x00); // Phillips Mode
37
- writeReg(0x0B, 0x0C); // 16-bit word length (0x0C)
38
-
39
- // 4. Power & Analog Path
40
- writeReg(0x0D, 0x03); // Power up Analog core
41
- writeReg(0x0E, 0x02); // Enable ADC Analog
42
- writeReg(0x13, 0x40); // SELECT MIC1 (MIC_P), Power up MICBIAS
43
- writeReg(0x14, 0x1A); // PGA Gain +24dB
44
- writeReg(0x15, 0x00); // SELECT ANALOG ADC (0x40 was Digital Mic mode)
45
- writeReg(0x16, 0x00); // ALC Off
46
- writeReg(0x17, 0x00); // Volume Max
47
-
48
- // 5. Digital Enable
49
- writeReg(0x45, 0x01);
50
- Serial.println("ES8311 Configured (Phillips, MIC1, +24dB)");
45
+ if (!writeReg(0x00, 0x1F)) { Serial.println("I2C FAIL - check wiring"); return false; }
46
+ delay(10);
47
+ writeReg(0x00, 0x00); delay(10);
48
+
49
+ // 2. Clock: MCLK divider — MCLK=4.096MHz (256 × 16kHz)
50
+ writeReg(0x01, 0x30); // MCLK input enabled, clock divider on
51
+ writeReg(0x02, 0x10); // ADC: fs = MCLK/256
52
+ writeReg(0x03, 0x10); // DAC: fs = MCLK/256
53
+
54
+ // 3. I2S format: Philips, 16-bit
55
+ writeReg(0x0A, 0x00); // I2S Philips mode
56
+ writeReg(0x0B, 0x0C); // bits[4:2]=011 → 16-bit
57
+
58
+ // 4. Power up
59
+ writeReg(0x0D, 0x01); delay(5); // digital core
60
+ writeReg(0x0D, 0x03); delay(5); // analog + digital
61
+
62
+ // 5. Analog path: MIC1
63
+ writeReg(0x0E, 0x06); // ADC + I/O buffer powered
64
+ writeReg(0x13, 0x40); // MIC1 selected, MICBIAS on
65
+ writeReg(0x14, 0x1A); // PGA gain +24 dB
66
+ writeReg(0x15, 0x00); // ADC input = analog PGA
67
+ writeReg(0x1A, 0x00); // MIC1 volume
68
+ writeReg(0x1B, 0x00); // MIC2 volume
69
+
70
+ // 6. ALC off, volume max
71
+ writeReg(0x16, 0x00); // ALC disable
72
+ writeReg(0x17, 0x00); // ADC volume
73
+ writeReg(0x18, 0x00); // DAC volume L
74
+ writeReg(0x19, 0x00); // DAC volume R
75
+
76
+ // 7. Digital enable
77
+ writeReg(0x45, 0x01); delay(10);
78
+
79
+ Serial.println("ES8311 configured");
80
+ dumpRegs();
81
+ return true;
82
+}
83
+
84
+// ========== I2S SETUP (IDF driver — reliable) ==========
85
+void setupI2S() {
86
+ i2s_config_t cfg = {
87
+ .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
88
+ .sample_rate = SAMPLE_RATE,
89
+ .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
90
+ .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
91
+ .communication_format = I2S_COMM_FORMAT_STAND_I2S,
92
+ .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
93
+ .dma_buf_count = 4,
94
+ .dma_buf_len = 128,
95
+ .use_apll = true,
96
+ .tx_desc_auto_clear = false,
97
+ .fixed_mclk = SAMPLE_RATE * 256,
98
+ };
99
+
100
+ i2s_pin_config_t pins = {
101
+ .bck_io_num = I2S_BCLK,
102
+ .ws_io_num = I2S_LRCK,
103
+ .data_out_num = I2S_PIN_NO_CHANGE,
104
+ .data_in_num = I2S_DIN,
105
+ };
106
+
107
+ ESP_ERROR_CHECK(i2s_driver_install(I2S_NUM_0, &cfg, 0, NULL));
108
+ ESP_ERROR_CHECK(i2s_set_pin(I2S_NUM_0, &pins));
109
+ i2s_zero_dma_buffer(I2S_NUM_0);
110
+ Serial.println("I2S RX ready");
51 111
}
52 112
113
+// ========== SETUP ==========
53 114
void setup() {
54 115
Serial.begin(115200);
55
- delay(1000);
116
+ delay(2000);
117
+ Serial.println("\n=== ES8311 Mic Test ===");
118
+
56 119
Wire.begin(I2C_SDA, I2C_SCL);
57
- init_ES8311();
58
-
59
- // STABLE I2S CONFIG
60
- i2s.setPins(I2S_BCLK, I2S_LRCK, I2S_DOUT, I2S_DIN, I2S_MCLK);
61
-
62
- // Use Phillips mode and 16-bit. Read both slots.
63
- if (!i2s.begin(I2S_MODE_STD, 16000, I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO, I2S_STD_SLOT_BOTH)) {
64
- Serial.println("I2S Init Failed");
65
- while (1);
120
+
121
+ // I2C bus scan
122
+ Serial.println("Scanning I2C bus...");
123
+ int found = 0;
124
+ for (uint8_t addr = 1; addr < 127; addr++) {
125
+ Wire.beginTransmission(addr);
126
+ if (Wire.endTransmission() == 0) {
127
+ Serial.printf(" Found 0x%02X\n", addr);
128
+ found++;
129
+ }
66 130
}
67
- Serial.println("I2S Ready (Stereo 16-bit).");
131
+ if (found == 0) { Serial.println("NO I2C devices found!"); while (1); }
132
+
133
+ if (!init_ES8311()) { Serial.println("ES8311 init FAILED"); while (1); }
134
+ setupI2S();
135
+ Serial.println("=== Ready — tap the mic! ===\n");
68 136
}
69 137
138
+// ========== LOOP ==========
70 139
void loop() {
71
- int16_t samples[2]; // [0] = Left, [1] = Right
72
- size_t bytes_read = i2s.readBytes((char*)samples, sizeof(samples));
73
-
74
- if (bytes_read == sizeof(samples)) {
75
- // If you talk into the mic, these numbers should JUMP wildly
76
- Serial.printf("L:%6d R:%6d\n", samples[0], samples[1]);
140
+ int16_t sample;
141
+ size_t bytes_read = 0;
142
+
143
+ esp_err_t err = i2s_read(I2S_NUM_0, &sample, sizeof(sample), &bytes_read, portMAX_DELAY);
144
+ if (err == ESP_OK && bytes_read == sizeof(sample)) {
145
+ Serial.println(sample);
77 146
}
78 147
}
... ...
\ No newline at end of file
Chip-cn-dat/everest-semi-dat/ES8311-dat/ES8311-SDK-dat/test/ES8311-code-spk3-melody/ES8311-code-spk3-melody.ino
... ...
@@ -1,35 +1,44 @@
1
+/*
2
+ * ES8311 Melody Player for ESP32-S3 + ES8311-NS4150B
3
+ *
4
+ * ES8311 init adapted from the official ESP-IDF es8311.c driver.
5
+ *
6
+ * Board wiring (from ES8311-dat):
7
+ * GPIO 4 → SCL GPIO 5 → SDA
8
+ * GPIO 6 → MCLK GPIO 11 → DIN (ESP32 DOUT → ES8311 SDIN)
9
+ * GPIO 12 → LRCK GPIO 13 → DOUT (not used for playback)
10
+ * GPIO 14 → SCLK (BCLK)
11
+ */
12
+
1 13
#include <Wire.h>
2
-#include <ESP_I2S.h> // Uses the standard ESP32 Arduino I2S library
14
+#include <driver/i2s.h>
3 15
4
-// Fallback in case Arduino core doesn't define PI
5 16
#ifndef PI
6 17
#define PI 3.141592653589793f
7 18
#endif
8 19
9
-// Define your board's pin layout (Change these values to match your specific board schematic)
10
-#define I2S_BCLK 14
11
-#define I2S_LRCK 12
12
-#define I2S_DOUT 13
13
-#define I2S_DIN -1 // not used (DAC playback only)
14
-
15
-#define I2S_MCLK 6
16
-
17
-#define I2C_SDA 5
18
-#define I2C_SCL 4
20
+// ==================== PIN MAPPING ====================
21
+#define I2C_SDA 5
22
+#define I2C_SCL 4
19 23
24
+#define I2S_MCLK 6
25
+#define I2S_BCLK 14
26
+#define I2S_LRCK 12
27
+#define I2S_DOUT 11 // ESP32 DOUT → ES8311 SDIN
28
+#define I2S_DIN 13 // unused for playback
20 29
21
-// NS4150 CTRL pin: hardware-pulled HIGH (no GPIO needed)
30
+#define PA_CTRL -1
22 31
23
-#define ES8311_ADDR 0x18 // Default I2C Address for ES8311
32
+#define ES8311_ADDR 0x18
33
+#define SAMPLE_RATE 16000
34
+#define MCLK_HZ (SAMPLE_RATE * 256) // 4.096 MHz
24 35
25
-I2SClass i2s;
26
-
27
-// Helper to write to ES8311 registers over I2C
28
-void writeReg(uint8_t reg, uint8_t value) {
36
+// ==================== I2C Helpers ====================
37
+bool writeReg(uint8_t reg, uint8_t val) {
29 38
Wire.beginTransmission(ES8311_ADDR);
30 39
Wire.write(reg);
31
- Wire.write(value);
32
- Wire.endTransmission();
40
+ Wire.write(val);
41
+ return Wire.endTransmission() == 0;
33 42
}
34 43
35 44
uint8_t readReg(uint8_t reg) {
... ...
@@ -37,152 +46,164 @@ uint8_t readReg(uint8_t reg) {
37 46
Wire.write(reg);
38 47
Wire.endTransmission(false);
39 48
Wire.requestFrom((uint16_t)ES8311_ADDR, (uint8_t)1);
40
- if (Wire.available()) return Wire.read();
41
- return 0;
49
+ return Wire.available() ? Wire.read() : 0xFF;
42 50
}
43 51
44
-void init_ES8311() {
45
- // === ES8311 Register Map (from arduino-audio-driver ES8311.h) ===
46
- // 0x00=RESET, 0x01=CLK_MGR1, 0x02=CLK_MGR2, 0x03=CLK_MGR3(ADC OSR),
47
- // 0x04=CLK_MGR4(DAC OSR), 0x05=CLK_MGR5(ADC/DAC div),
48
- // 0x06=CLK_MGR6(BCLK div), 0x07=CLK_MGR7(LRCK H), 0x08=CLK_MGR8(LRCK L),
49
- // 0x09=SDP_IN(DAC I2S), 0x0A=SDP_OUT(ADC I2S),
50
- // 0x0B-0x0C=SYSTEM, 0x0D=ANALOG_PWR, 0x0E=SYSTEM,
51
- // 0x10-0x11=SYSTEM, 0x12-0x13=SYSTEM,
52
- // 0x14=SYSTEM(PGA/analog), 0x15-0x1C=ADC,
53
- // 0x31-0x35=DAC, 0x37=DAC_CTRL, 0x32=DAC_VOL,
54
- // 0xFD=CHIP_ID1, 0xFE=CHIP_ID2
55
-
56
- // === 1. Initial register setup (before reset) ===
57
- writeReg(0x01, 0x30); // CLK_MGR1: enable main clocks
58
- writeReg(0x02, 0x00); // CLK_MGR2: clear pre-divider
59
- writeReg(0x03, 0x10); // CLK_MGR3: ADC OSR=16x (default)
60
- writeReg(0x16, 0x24); // ADC_REG16: MIC gain initial
61
- writeReg(0x04, 0x10); // CLK_MGR4: DAC OSR=16x
62
- writeReg(0x05, 0x00); // CLK_MGR5: clear ADC/DAC dividers
63
- writeReg(0x0B, 0x00); // SYSTEM_REG0B
64
- writeReg(0x0C, 0x00); // SYSTEM_REG0C
65
- writeReg(0x10, 0x1F); // SYSTEM_REG10
66
- writeReg(0x11, 0x7F); // SYSTEM_REG11
67
-
68
- // === 2. Reset chip ===
69
- writeReg(0x00, 0x80); // RESET: trigger reset
70
- delay(20);
71
-
72
- // === 3. Set Slave Mode (ESP32 is I2S Master) ===
73
- uint8_t regv = readReg(0x00);
74
- regv &= 0xBF; // Clear bit 6 → Slave mode
75
- writeReg(0x00, regv);
76
-
77
- // === 4. Enable all internal clocks, use BCLK as clock source ===
78
- // Using BCLK (SCLK) instead of MCLK pin avoids MCLK frequency mismatch
79
- writeReg(0x01, 0x3F); // CLK_MGR1: all clocks ON
80
- regv = readReg(0x01);
81
- regv |= 0x80; // Set bit 7 → clock source = BCLK (SCLK pin)
82
- writeReg(0x01, regv);
83
-
84
- // === 5. Clock dividers for 16kHz @ 4.096MHz MCLK (256*Fs) ===
85
- // From coefficient table: {4096000, 16000, pre=1, mult=1, adc=1, dac=1,
86
- // fs=0, lrch=0, lrcl=0xFF, bck=4, osr=0x10}
87
- writeReg(0x02, 0x00); // CLK_MGR2: pre_div=1, multi=1
88
- writeReg(0x03, 0x10); // CLK_MGR3: fs_mode=0, adc_osr=0x10
89
- writeReg(0x04, 0x10); // CLK_MGR4: dac_osr=0x10
90
- writeReg(0x05, 0x00); // CLK_MGR5: adc_div=1, dac_div=1
91
- writeReg(0x06, 0x03); // CLK_MGR6: bclk_div=4
92
- writeReg(0x07, 0x00); // CLK_MGR7: lrck_h=0
93
- writeReg(0x08, 0xFF); // CLK_MGR8: lrck_l=0xFF
94
-
95
- // === 6. I2S Format: 16-bit Phillips (standard I2S) ===
96
- writeReg(0x09, 0x0C); // SDP_IN: 16-bit I2S for DAC
97
- writeReg(0x0A, 0x0C); // SDP_OUT: 16-bit I2S for ADC
98
-
99
- // === 7. System init (from official driver) ===
100
- writeReg(0x13, 0x10); // SYSTEM_REG13
101
- writeReg(0x1B, 0x0A); // ADC_REG1B
102
- writeReg(0x1C, 0x6A); // ADC_REG1C
103
-
104
- Serial.println("ES8311 Init done (clock + I2S format).");
105
-
106
- // === Verify chip ID ===
107
- uint8_t chip_id1 = readReg(0xFD);
108
- uint8_t chip_id2 = readReg(0xFE);
109
- Serial.printf("ES8311 Chip ID: 0x%02X%02X (expect 0x8311)\n", chip_id1, chip_id2);
52
+void dumpRegs() {
53
+ Serial.println("--- ES8311 Registers ---");
54
+ uint8_t regs[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
55
+ 0x09,0x0A,0x0D,0x0E,0x12,0x14,0x15,0x31,0x32,0x37,0x44,0x45};
56
+ for (int i = 0; i < (int)(sizeof(regs)/sizeof(regs[0])); i++) {
57
+ Serial.printf(" REG[0x%02X] = 0x%02X\n", regs[i], readReg(regs[i]));
58
+ }
110 59
}
111 60
112
-void start_ES8311_DAC() {
113
- // === START sequence for DAC playback (from official driver) ===
114
- // Powers up DAC, unmutes, routes audio to output
115
-
116
- // 1. Set PGA / analog control (max analog gain)
117
- writeReg(0x14, 0x3B); // SYSTEM_REG14: max PGA gain, no mic bias
118
-
119
- // 2. Unmute DAC on I2S interface (clear bit 6 in SDP_IN)
120
- uint8_t dac_iface = readReg(0x09) & 0xBF;
121
- writeReg(0x09, dac_iface);
122
-
123
- // 3. Unmute ADC on I2S interface (not needed, but harmless)
124
- uint8_t adc_iface = readReg(0x0A) & 0xBF;
125
- writeReg(0x0A, adc_iface);
126
-
127
- // 4. ADC digital volume = max
128
- writeReg(0x17, 0xBF); // ADC_REG17
129
-
130
- // 5. System analog enable
131
- writeReg(0x0E, 0x02); // SYSTEM_REG0E
132
-
133
- // 6. System control
134
- writeReg(0x12, 0x00); // SYSTEM_REG12
135
-
136
- // 7. Power up analog (DAC + ADC + full analog blocks)
137
- writeReg(0x0D, 0x03); // SYSTEM_REG0D: power up DAC + ADC analog
138
-
139
- // 8. ADC control
140
- writeReg(0x15, 0x40); // ADC_REG15
141
-
142
- // 9. DAC control - max output drive
143
- writeReg(0x37, 0x78); // DAC_REG37: max DAC output drive (was 0x68)
144
-
145
- // 10. GPIO / digital
146
- writeReg(0x45, 0x00); // GP_REG45
147
-
148
- // 11. DAC digital volume (0x00=mute, 0xBF=0dB, 0xFF=+6dB max)
149
- writeReg(0x32, 0xFF); // DAC_REG32: MAXIMUM volume
61
+// ==================== ES8311 Init (from es8311.c official driver) ====================
62
+/*
63
+ * Coefficient for 16kHz @ MCLK=4.096MHz (256 × 16kHz):
64
+ * pre_div=1, pre_multi=1, adc_div=1, dac_div=1,
65
+ * fs_mode=0, lrck_h=0, lrck_l=0xFF, bclk_div=4, adc_osr=16, dac_osr=16
66
+ */
67
+bool init_ES8311_DAC() {
68
+ // === 1. Pre-reset writes (es8311_codec_init) ===
69
+ writeReg(0x01, 0x30);
70
+ writeReg(0x02, 0x00);
71
+ writeReg(0x03, 0x10);
72
+ writeReg(0x16, 0x24);
73
+ writeReg(0x04, 0x10);
74
+ writeReg(0x05, 0x00);
75
+ writeReg(0x0B, 0x00);
76
+ writeReg(0x0C, 0x00);
77
+ writeReg(0x10, 0x1F);
78
+ writeReg(0x11, 0x7F);
79
+
80
+ // === 2. Reset ===
81
+ if (!writeReg(0x00, 0x80)) { Serial.println("I2C FAIL"); return false; }
82
+ delay(20);
83
+ writeReg(0x00, 0x00);
84
+
85
+ // === 3. Slave mode (clear bit6) ===
86
+ uint8_t r = readReg(0x00);
87
+ r &= 0xBF;
88
+ writeReg(0x00, r);
89
+
90
+ // === 4. Enable all clocks ===
91
+ writeReg(0x01, 0x3F);
92
+
93
+ // === 5. Select MCLK pin as clock source (clear bit7) ===
94
+ r = readReg(0x01);
95
+ r &= 0x7F;
96
+ writeReg(0x01, r);
97
+
98
+ // === 6. Clock dividers from coefficient table ===
99
+ // pre_div=1, pre_multi=1 → reg02 = 0x00
100
+ writeReg(0x02, 0x00);
101
+ // fs_mode=0, adc_osr=16 → reg03 = 0x10
102
+ writeReg(0x03, 0x10);
103
+ // dac_osr=16 → reg04 = 0x10
104
+ writeReg(0x04, 0x10);
105
+ // adc_div=1, dac_div=1 → reg05 = 0x00
106
+ writeReg(0x05, 0x00);
107
+ // bclk_div=4 → reg06 = 0x03
108
+ writeReg(0x06, 0x03);
109
+ // lrck_h=0 → reg07 = 0x00
110
+ writeReg(0x07, 0x00);
111
+ // lrck_l=0xFF → reg08 = 0xFF
112
+ writeReg(0x08, 0xFF);
113
+
114
+ // === 7. I2S format: Philips 16-bit ===
115
+ writeReg(0x09, 0x0C);
116
+ writeReg(0x0A, 0x0C);
117
+
118
+ // === 8. System init (from official driver) ===
119
+ writeReg(0x13, 0x10);
120
+ writeReg(0x1B, 0x0A);
121
+ writeReg(0x1C, 0x6A);
122
+ writeReg(0x44, 0x08);
123
+
124
+ // === 9. DAC start sequence (es8311_start in DAC mode) ===
125
+ // Unmute DAC (clear bit6 in reg09)
126
+ r = readReg(0x09) & 0xBF;
127
+ writeReg(0x09, r);
128
+ // Unmute ADC (clear bit6 in reg0A) — harmless
129
+ r = readReg(0x0A) & 0xBF;
130
+ writeReg(0x0A, r);
131
+
132
+ writeReg(0x32, 0xBF); // DAC volume = 0dB (official driver value)
133
+ writeReg(0x17, 0xBF); // ADC volume
134
+ writeReg(0x0E, 0x02); // Analog enable
135
+ writeReg(0x12, 0x00); // System
136
+ writeReg(0x14, 0x1A); // PGA + DMIC select (0=analog mic)
137
+ writeReg(0x0D, 0x01); // Power digital only
138
+ delay(5);
139
+ writeReg(0x15, 0x40); // ADC control
140
+ writeReg(0x37, 0x48); // DAC output drive
141
+ writeReg(0x45, 0x00); // GPIO
142
+
143
+ Serial.println("ES8311 DAC configured (es8311.c reference)");
144
+ dumpRegs();
145
+ return true;
146
+}
150 147
151
- Serial.println("ES8311 DAC STARTED (powered, unmuted, routed).");
148
+// ==================== I2S Setup ====================
149
+void setupI2S() {
150
+ i2s_config_t cfg = {
151
+ .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX),
152
+ .sample_rate = SAMPLE_RATE,
153
+ .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
154
+ .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
155
+ .communication_format = I2S_COMM_FORMAT_STAND_I2S,
156
+ .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
157
+ .dma_buf_count = 4,
158
+ .dma_buf_len = 256,
159
+ .use_apll = true,
160
+ .tx_desc_auto_clear = true,
161
+ .fixed_mclk = MCLK_HZ, // 4.096 MHz for ES8311 MCLK pin
162
+ };
163
+
164
+ i2s_pin_config_t pins = {
165
+ .bck_io_num = I2S_BCLK,
166
+ .ws_io_num = I2S_LRCK,
167
+ .data_out_num = I2S_DOUT,
168
+ .data_in_num = I2S_PIN_NO_CHANGE,
169
+ };
170
+
171
+ ESP_ERROR_CHECK(i2s_driver_install(I2S_NUM_0, &cfg, 0, NULL));
172
+ ESP_ERROR_CHECK(i2s_set_pin(I2S_NUM_0, &pins));
173
+ i2s_zero_dma_buffer(I2S_NUM_0);
174
+ Serial.println("I2S TX ready");
152 175
}
153 176
177
+// ==================== Setup ====================
154 178
void setup() {
155 179
Serial.begin(115200);
156
- delay(1000); // Wait for Serial monitor
180
+ delay(1500);
181
+ Serial.println("\n=== ES8311 Melody Player ===");
182
+
183
+ // Enable amplifier if PA_CTRL pin is configured
184
+ if (PA_CTRL >= 0) {
185
+ pinMode(PA_CTRL, OUTPUT);
186
+ digitalWrite(PA_CTRL, HIGH);
187
+ Serial.printf("PA_CTRL GPIO%d = HIGH\n", PA_CTRL);
188
+ }
157 189
158
- // === 1. Fire up I2C Bus ===
159 190
Wire.begin(I2C_SDA, I2C_SCL);
160
- Wire.setClock(100000); // 100kHz standard speed
191
+ Wire.setClock(100000);
161 192
162
- // === 2. Scan I2C to verify ES8311 is reachable ===
163 193
Wire.beginTransmission(ES8311_ADDR);
164 194
if (Wire.endTransmission() == 0) {
165
- Serial.printf("✅ ES8311 found at I2C address 0x%02X\n", ES8311_ADDR);
195
+ Serial.printf("ES8311 found at 0x%02X\n", ES8311_ADDR);
166 196
} else {
167
- Serial.printf("❌ ES8311 NOT found at I2C address 0x%02X! Check wiring.\n", ES8311_ADDR);
168
- }
169
-
170
- init_ES8311();
171
-
172
- // === 2b. Power up DAC and start output path ===
173
- start_ES8311_DAC();
174
-
175
- // === 3. Initialize I2S peripheral (STEREO to match ES8311) ===
176
- i2s.setPins(I2S_BCLK, I2S_LRCK, I2S_DOUT, I2S_DIN, I2S_MCLK);
177
- if (!i2s.begin(I2S_MODE_STD, 16000, I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO, I2S_STD_SLOT_BOTH)) {
178
- Serial.println("❌ Failed to initialize I2S!");
197
+ Serial.printf("ES8311 NOT found at 0x%02X! Check wiring.\n", ES8311_ADDR);
179 198
while (1);
180 199
}
181
- Serial.println("✅ I2S initialized successfully (STEREO).");
200
+
201
+ if (!init_ES8311_DAC()) { while (1); }
202
+ setupI2S();
203
+ Serial.println("=== Playing melody ===\n");
182 204
}
183 205
184
-// === Melody: "Twinkle Twinkle Little Star" ===
185
-// Frequencies in Hz
206
+// ==================== Melody Data ====================
186 207
#define NOTE_C4 262
187 208
#define NOTE_D4 294
188 209
#define NOTE_E4 330
... ...
@@ -193,120 +214,97 @@ void setup() {
193 214
#define NOTE_C5 523
194 215
#define NOTE_REST 0
195 216
196
-struct Note {
197
- uint16_t freq; // Hz, 0 = rest
198
- uint16_t duration; // ms
199
-};
217
+struct Note { uint16_t freq; uint16_t duration; };
200 218
201 219
const Note melody[] = {
202
- // Twinkle twinkle little star
203
- {NOTE_C4, 400}, {NOTE_C4, 400}, {NOTE_G4, 400}, {NOTE_G4, 400},
204
- {NOTE_A4, 400}, {NOTE_A4, 400}, {NOTE_G4, 800},
205
- // How I wonder what you are
206
- {NOTE_F4, 400}, {NOTE_F4, 400}, {NOTE_E4, 400}, {NOTE_E4, 400},
207
- {NOTE_D4, 400}, {NOTE_D4, 400}, {NOTE_C4, 800},
208
- // Up above the world so high
209
- {NOTE_G4, 400}, {NOTE_G4, 400}, {NOTE_F4, 400}, {NOTE_F4, 400},
210
- {NOTE_E4, 400}, {NOTE_E4, 400}, {NOTE_D4, 800},
211
- // Like a diamond in the sky
212
- {NOTE_G4, 400}, {NOTE_G4, 400}, {NOTE_F4, 400}, {NOTE_F4, 400},
213
- {NOTE_E4, 400}, {NOTE_E4, 400}, {NOTE_D4, 800},
214
- // Twinkle twinkle little star
215
- {NOTE_C4, 400}, {NOTE_C4, 400}, {NOTE_G4, 400}, {NOTE_G4, 400},
216
- {NOTE_A4, 400}, {NOTE_A4, 400}, {NOTE_G4, 800},
217
- // How I wonder what you are
218
- {NOTE_F4, 400}, {NOTE_F4, 400}, {NOTE_E4, 400}, {NOTE_E4, 400},
219
- {NOTE_D4, 400}, {NOTE_D4, 400}, {NOTE_C4, 800},
220
- // Pause before repeat
221
- {NOTE_REST, 600},
220
+ {NOTE_C4,400},{NOTE_C4,400},{NOTE_G4,400},{NOTE_G4,400},
221
+ {NOTE_A4,400},{NOTE_A4,400},{NOTE_G4,800},
222
+ {NOTE_F4,400},{NOTE_F4,400},{NOTE_E4,400},{NOTE_E4,400},
223
+ {NOTE_D4,400},{NOTE_D4,400},{NOTE_C4,800},
224
+ {NOTE_G4,400},{NOTE_G4,400},{NOTE_F4,400},{NOTE_F4,400},
225
+ {NOTE_E4,400},{NOTE_E4,400},{NOTE_D4,800},
226
+ {NOTE_G4,400},{NOTE_G4,400},{NOTE_F4,400},{NOTE_F4,400},
227
+ {NOTE_E4,400},{NOTE_E4,400},{NOTE_D4,800},
228
+ {NOTE_C4,400},{NOTE_C4,400},{NOTE_G4,400},{NOTE_G4,400},
229
+ {NOTE_A4,400},{NOTE_A4,400},{NOTE_G4,800},
230
+ {NOTE_F4,400},{NOTE_F4,400},{NOTE_E4,400},{NOTE_E4,400},
231
+ {NOTE_D4,400},{NOTE_D4,400},{NOTE_C4,800},
232
+ {NOTE_REST,600},
222 233
};
223 234
const int melody_len = sizeof(melody) / sizeof(Note);
224 235
225
-const int SAMPLE_RATE = 16000;
226
-const int BUFFER_SAMPLES = 256;
236
+// ==================== Audio Generator ====================
237
+#define BUF_SAMPLES 256
238
+#define ATTACK_MS 12
239
+#define RELEASE_MS 15
240
+#define GAP_MS 4
241
+#define XFADE_MS 10
227 242
228
-// Timing constants (in ms)
229
-const int ATTACK_MS = 12; // note attack ramp
230
-const int RELEASE_MS = 15; // note release ramp
231
-const int GAP_MS = 3; // silence gap between notes
232
-const int XFADE_MS = 8; // frequency crossfade duration
233
-
234
-// State
235
-static float phase = 0.0f;
236
-static uint8_t note_idx = 0;
237
-static uint32_t note_start_ms = 0;
238
-static float prev_freq = melody[0].freq;
239
-static bool first_buffer = true;
243
+static float g_phase = 0.0f;
244
+static uint8_t g_note_idx = 0;
245
+static uint32_t g_note_start = 0;
246
+static float g_prev_freq = melody[0].freq;
247
+static bool g_first = true;
240 248
241 249
void loop() {
242
- int16_t audio_buffer[BUFFER_SAMPLES * 2]; // stereo L,R interleaved
250
+ int16_t buf[BUF_SAMPLES * 2];
243 251
uint32_t now = millis();
244
- uint32_t note_elapsed = now - note_start_ms;
245
- Note current = melody[note_idx];
246
-
247
- // --- Note transition ---
248
- if (note_elapsed >= current.duration + GAP_MS) {
249
- prev_freq = current.freq;
250
- note_idx++;
251
- if (note_idx >= melody_len) note_idx = 0;
252
- note_start_ms = now;
253
- current = melody[note_idx];
254
- Serial.printf("♪ Note %d: freq=%d Hz, dur=%d ms\n",
255
- note_idx, current.freq, current.duration);
256
- }
257
- // Recalculate note_elapsed AFTER possible transition (fixes envelope bug)
258
- note_elapsed = now - note_start_ms;
259
-
260
- // --- Crossfade frequency between old and new note ---
261
- float xfade_k = (note_elapsed < XFADE_MS) ? (note_elapsed / (float)XFADE_MS) : 1.0f;
262
- float freq = prev_freq * (1.0f - xfade_k) + current.freq * xfade_k;
263
-
264
- // --- Generate audio buffer ---
265
- int gap_samples = GAP_MS * SAMPLE_RATE / 1000;
266
- int attack_samples = ATTACK_MS * SAMPLE_RATE / 1000;
267
- int release_samples = RELEASE_MS * SAMPLE_RATE / 1000;
268
- // current elapsed in samples (estimate, tracking from note_start)
269
- uint32_t sample_offset = (uint32_t)((float)note_elapsed * SAMPLE_RATE / 1000.0f);
270
- uint32_t dur_samples = (uint32_t)((float)current.duration * SAMPLE_RATE / 1000.0f);
271
-
272
- for (int i = 0; i < BUFFER_SAMPLES; i++) {
273
- uint32_t s = sample_offset + i;
274
- int16_t sample;
275
-
276
- // Silence during gap between notes
277
- if (s < (uint32_t)gap_samples) {
278
- sample = 0;
279
- }
280
- // Silence during rest (after crossfade)
281
- else if (current.freq == 0 && note_elapsed >= XFADE_MS) {
282
- sample = 0;
283
- }
284
- else {
285
- // Envelope: attack → sustain → release
286
- float envelope = 0.75f;
287
- uint32_t note_s = s - gap_samples; // sample pos relative to note body
288
- if (note_s < (uint32_t)attack_samples) {
289
- envelope *= (float)note_s / attack_samples; // linear attack
290
- } else if (note_s > dur_samples - release_samples && dur_samples > (uint32_t)(attack_samples + release_samples)) {
291
- uint32_t rel = dur_samples - note_s;
292
- envelope *= (float)rel / release_samples; // linear release
293
- }
294
-
295
- sample = (int16_t)(sinf(phase) * envelope * 28000);
296
- phase += 2.0f * PI * freq / SAMPLE_RATE;
297
- if (phase > 2.0f * PI) phase -= 2.0f * PI;
298
- }
299
- audio_buffer[i * 2] = sample; // Left
300
- audio_buffer[i * 2 + 1] = sample; // Right
252
+
253
+ if (g_first) {
254
+ g_note_start = now;
255
+ g_first = false;
256
+ Serial.printf("♪ [0] %d Hz %d ms\n", melody[0].freq, melody[0].duration);
301 257
}
302 258
303
- size_t written = i2s.write((uint8_t*)audio_buffer, sizeof(audio_buffer));
304
- if (written != sizeof(audio_buffer)) {
305
- Serial.printf("⚠ I2S write short: %d / %d bytes\n", written, sizeof(audio_buffer));
259
+ uint32_t elapsed = now - g_note_start;
260
+ Note cur = melody[g_note_idx];
261
+
262
+ // Note transition
263
+ if (elapsed >= cur.duration + GAP_MS) {
264
+ g_prev_freq = cur.freq;
265
+ g_note_idx = (g_note_idx + 1) % melody_len;
266
+ g_note_start = now;
267
+ cur = melody[g_note_idx];
268
+ Serial.printf("♪ [%d] %d Hz %d ms\n", g_note_idx, cur.freq, cur.duration);
269
+ }
270
+ elapsed = now - g_note_start;
271
+
272
+ // Crossfade frequency
273
+ float xf = (elapsed < XFADE_MS) ? (elapsed / (float)XFADE_MS) : 1.0f;
274
+ float freq = g_prev_freq * (1.0f - xf) + cur.freq * xf;
275
+
276
+ // Timing
277
+ int gap_s = GAP_MS * SAMPLE_RATE / 1000;
278
+ int att_s = ATTACK_MS * SAMPLE_RATE / 1000;
279
+ int rel_s = RELEASE_MS * SAMPLE_RATE / 1000;
280
+ uint32_t off = (uint32_t)(elapsed * SAMPLE_RATE / 1000.0f);
281
+ uint32_t dur_s = (uint32_t)(cur.duration * SAMPLE_RATE / 1000.0f);
282
+
283
+ for (int i = 0; i < BUF_SAMPLES; i++) {
284
+ uint32_t s = off + i;
285
+ int16_t smp;
286
+ if (s < (uint32_t)gap_s) {
287
+ smp = 0;
288
+ } else if (cur.freq == 0 && elapsed >= XFADE_MS) {
289
+ smp = 0;
290
+ } else {
291
+ float env = 0.75f;
292
+ uint32_t ns = s - gap_s;
293
+ if (ns < (uint32_t)att_s)
294
+ env *= (float)ns / att_s;
295
+ else if (ns > dur_s - rel_s && dur_s > (uint32_t)(att_s + rel_s))
296
+ env *= (float)(dur_s - ns) / rel_s;
297
+ smp = (int16_t)(sinf(g_phase) * env * 28000);
298
+ g_phase += 2.0f * PI * freq / SAMPLE_RATE;
299
+ if (g_phase > 2.0f * PI) g_phase -= 2.0f * PI;
300
+ }
301
+ buf[i * 2] = smp;
302
+ buf[i * 2 + 1] = smp;
306 303
}
307 304
308
- if (first_buffer) {
309
- Serial.println("▶ Melody started: Twinkle Twinkle Little Star");
310
- first_buffer = false;
305
+ size_t written = 0;
306
+ esp_err_t err = i2s_write(I2S_NUM_0, buf, sizeof(buf), &written, portMAX_DELAY);
307
+ if (err != ESP_OK || written != sizeof(buf)) {
308
+ Serial.printf("I2S err=%d written=%d\n", err, written);
311 309
}
312 310
}
... ...
\ No newline at end of file
Chip-cn-dat/everest-semi-dat/ES8311-dat/ES8311-SDK-dat/test/ES8311-code-spk5/ES8311-code-spk5.ino
... ...
@@ -0,0 +1,218 @@
1
+/*
2
+ * ES8311-code-spk5.ino
3
+ *
4
+ * Minimal Arduino sketch that reuses es8311.c / es8311.h from the
5
+ * official ESP-IDF driver. Both files live in this same folder and
6
+ * are auto-compiled by the Arduino IDE.
7
+ *
8
+ * The init sequence follows es8311.c exactly:
9
+ * es8311_codec_init() → es8311_start(ES_MODULE_DAC)
10
+ *
11
+ * I2C uses Arduino Wire instead of the ESP-IDF i2c_driver.
12
+ *
13
+ * Wiring (from ES8311-dat):
14
+ * GPIO 4 → SCL GPIO 5 → SDA
15
+ * GPIO 6 → MCLK GPIO 11 → DIN (ESP32 DOUT → ES8311 SDIN)
16
+ * GPIO 12 → LRCK GPIO 14 → BCLK
17
+ */
18
+
19
+#include <Wire.h>
20
+#include <driver/i2s.h>
21
+#include "es8311.h" // register constants
22
+
23
+// ==================== Pins ====================
24
+#define I2C_SDA 5
25
+#define I2C_SCL 4
26
+#define I2S_MCLK 6
27
+#define I2S_BCLK 14
28
+#define I2S_LRCK 12
29
+#define I2S_DOUT 11 // → ES8311 SDIN
30
+#define I2S_DIN 13 // unused
31
+
32
+#define PA_CTRL -1
33
+#define SAMPLE_RATE 16000
34
+#define MCLK_HZ (SAMPLE_RATE * 256)
35
+
36
+// ==================== I2C helpers ====================
37
+static bool w(uint8_t r, uint8_t v) {
38
+ Wire.beginTransmission(0x18);
39
+ Wire.write(r); Wire.write(v);
40
+ return Wire.endTransmission() == 0;
41
+}
42
+static uint8_t r(uint8_t r) {
43
+ Wire.beginTransmission(0x18); Wire.write(r);
44
+ Wire.endTransmission(false);
45
+ Wire.requestFrom((uint16_t)0x18, (uint8_t)1);
46
+ return Wire.available() ? Wire.read() : 0xFF;
47
+}
48
+
49
+// ==================== Clock coefficient (16k, MCLK=4.096M) ====================
50
+// From coeff_div[]: {4096000,16000, pre=1,mult=1, adc=1,dac=1,
51
+// fs=0, lrch=0,lrcl=0xFF, bck=4, osr=16}
52
+static void set_coeff() {
53
+ w(ES8311_CLK_MANAGER_REG02, 0x00); // pre_div=1, pre_multi=1
54
+ w(ES8311_CLK_MANAGER_REG03, 0x10); // fs=0, adc_osr=16
55
+ w(ES8311_CLK_MANAGER_REG04, 0x10); // dac_osr=16
56
+ w(ES8311_CLK_MANAGER_REG05, 0x00); // adc=1, dac=1
57
+ w(ES8311_CLK_MANAGER_REG06, 0x03); // bclk_div=4
58
+ w(ES8311_CLK_MANAGER_REG07, 0x00); // lrck_h=0
59
+ w(ES8311_CLK_MANAGER_REG08, 0xFF); // lrck_l=0xFF
60
+}
61
+
62
+// ==================== ES8311 init ====================
63
+// Follows es8311_codec_init() from es8311.c line-for-line
64
+bool es8311_init() {
65
+ // Pre-reset
66
+ w(ES8311_CLK_MANAGER_REG01, 0x30);
67
+ w(ES8311_CLK_MANAGER_REG02, 0x00);
68
+ w(ES8311_CLK_MANAGER_REG03, 0x10);
69
+ w(ES8311_ADC_REG16, 0x24);
70
+ w(ES8311_CLK_MANAGER_REG04, 0x10);
71
+ w(ES8311_CLK_MANAGER_REG05, 0x00);
72
+ w(ES8311_SYSTEM_REG0B, 0x00);
73
+ w(ES8311_SYSTEM_REG0C, 0x00);
74
+ w(ES8311_SYSTEM_REG10, 0x1F);
75
+ w(ES8311_SYSTEM_REG11, 0x7F);
76
+
77
+ if (!w(ES8311_RESET_REG00, 0x80)) return false;
78
+ delay(20);
79
+
80
+ // Slave mode
81
+ w(ES8311_RESET_REG00, r(ES8311_RESET_REG00) & 0xBF);
82
+
83
+ // All clocks ON
84
+ w(ES8311_CLK_MANAGER_REG01, 0x3F);
85
+
86
+ // MCLK pin (clear bit7)
87
+ w(ES8311_CLK_MANAGER_REG01, r(ES8311_CLK_MANAGER_REG01) & 0x7F);
88
+
89
+ set_coeff();
90
+
91
+ // MCLK not inverted, BCLK not inverted
92
+ w(ES8311_CLK_MANAGER_REG01, r(ES8311_CLK_MANAGER_REG01) & ~0x40);
93
+ w(ES8311_CLK_MANAGER_REG06, r(ES8311_CLK_MANAGER_REG06) & ~0x20);
94
+
95
+ w(ES8311_SYSTEM_REG13, 0x10);
96
+ w(ES8311_ADC_REG1B, 0x0A);
97
+ w(ES8311_ADC_REG1C, 0x6A);
98
+ w(ES8311_GPIO_REG44, 0x08);
99
+ return true;
100
+}
101
+
102
+// ==================== DAC start ====================
103
+// Follows es8311_start(ES_MODULE_DAC) from es8311.c
104
+void es8311_start_dac() {
105
+ // Unmute DAC (clear bit6 in reg09)
106
+ w(ES8311_SDPIN_REG09, r(ES8311_SDPIN_REG09) & 0xBF);
107
+ // Unmute ADC (clear bit6 in reg0A)
108
+ w(ES8311_SDPOUT_REG0A, r(ES8311_SDPOUT_REG0A) & 0xBF);
109
+
110
+ w(ES8311_DAC_REG32, 0xBF); // 0 dB
111
+ w(ES8311_ADC_REG17, 0xBF);
112
+ w(ES8311_SYSTEM_REG0E, 0x02);
113
+ w(ES8311_SYSTEM_REG12, 0x00);
114
+ w(ES8311_SYSTEM_REG14, 0x1A); // analog mic, not DMIC
115
+ w(ES8311_SYSTEM_REG0D, 0x01);
116
+ delay(5);
117
+ w(ES8311_ADC_REG15, 0x40);
118
+ w(ES8311_DAC_REG37, 0x48);
119
+ w(ES8311_GP_REG45, 0x00);
120
+}
121
+
122
+// ==================== I2S ====================
123
+void setup_i2s() {
124
+ i2s_config_t c = {
125
+ .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX),
126
+ .sample_rate = SAMPLE_RATE,
127
+ .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
128
+ .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
129
+ .communication_format = I2S_COMM_FORMAT_STAND_I2S,
130
+ .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
131
+ .dma_buf_count = 4,
132
+ .dma_buf_len = 256,
133
+ .use_apll = true,
134
+ .tx_desc_auto_clear = true,
135
+ .fixed_mclk = MCLK_HZ,
136
+ };
137
+ i2s_pin_config_t p = {
138
+ .bck_io_num = I2S_BCLK,
139
+ .ws_io_num = I2S_LRCK,
140
+ .data_out_num = I2S_DOUT,
141
+ .data_in_num = I2S_PIN_NO_CHANGE,
142
+ };
143
+ ESP_ERROR_CHECK(i2s_driver_install(I2S_NUM_0, &c, 0, NULL));
144
+ ESP_ERROR_CHECK(i2s_set_pin(I2S_NUM_0, &p));
145
+ i2s_zero_dma_buffer(I2S_NUM_0);
146
+}
147
+
148
+// ==================== Register dump ====================
149
+void dump() {
150
+ Serial.println("--- ES8311 regs ---");
151
+ uint8_t regs[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
152
+ 0x09,0x0A,0x0D,0x0E,0x12,0x14,0x15,0x31,0x32,0x37,0x44,0x45};
153
+ for (int i = 0; i < (int)(sizeof(regs)/sizeof(regs[0])); i++)
154
+ Serial.printf(" [0x%02X] = 0x%02X\n", regs[i], r(regs[i]));
155
+}
156
+
157
+// ==================== Melody ====================
158
+#define BUF_SZ 256
159
+#define N8(f) {f,800}
160
+#define N4(f) {f,400}
161
+#define RST {0,600}
162
+
163
+static const struct { uint16_t f, d; } mel[] = {
164
+ N4(262),N4(262),N4(392),N4(392),N4(440),N4(440),N8(392),
165
+ N4(349),N4(349),N4(330),N4(330),N4(294),N4(294),N8(262),
166
+ N8(392),N8(349),N8(330),N8(294),
167
+ N4(262),N4(262),N4(392),N4(392),N4(440),N4(440),N8(392),
168
+ N4(349),N4(349),N4(330),N4(330),N4(294),N4(294),N8(262),
169
+ RST,
170
+};
171
+static const int N = sizeof(mel)/sizeof(mel[0]);
172
+
173
+static float ph = 0;
174
+static uint8_t ix = 0;
175
+static uint32_t t0 = 0;
176
+static bool fst = true;
177
+
178
+// ==================== Setup ====================
179
+void setup() {
180
+ Serial.begin(115200); delay(1500);
181
+ Serial.println("\n=== spk5 ===");
182
+
183
+ if (PA_CTRL >= 0) { pinMode(PA_CTRL, OUTPUT); digitalWrite(PA_CTRL, HIGH); }
184
+
185
+ Wire.begin(I2C_SDA, I2C_SCL); Wire.setClock(100000);
186
+ Wire.beginTransmission(0x18);
187
+ if (Wire.endTransmission()) { Serial.println("No ES8311!"); while (1); }
188
+ Serial.println("ES8311 found");
189
+
190
+ if (!es8311_init()) { Serial.println("Init FAIL"); while (1); }
191
+ es8311_start_dac();
192
+ dump();
193
+ setup_i2s();
194
+ Serial.println("=== play ===\n");
195
+}
196
+
197
+// ==================== Loop ====================
198
+void loop() {
199
+ int16_t buf[BUF_SZ * 2];
200
+ uint32_t now = millis();
201
+ if (fst) { t0 = now; fst = false; }
202
+
203
+ uint32_t el = now - t0;
204
+ if (el >= mel[ix].d + 4) {
205
+ ix = (ix + 1) % N;
206
+ t0 = now; el = 0;
207
+ Serial.printf("♪ %d Hz\n", mel[ix].f);
208
+ }
209
+
210
+ for (int i = 0; i < BUF_SZ; i++) {
211
+ int16_t s = mel[ix].f ? (int16_t)(sinf(ph) * 24000) : 0;
212
+ ph += 2 * PI * mel[ix].f / SAMPLE_RATE;
213
+ if (ph > 2 * PI) ph -= 2 * PI;
214
+ buf[i*2] = buf[i*2+1] = s;
215
+ }
216
+ size_t w = 0;
217
+ i2s_write(I2S_NUM_0, buf, sizeof(buf), &w, portMAX_DELAY);
218
+}
Chip-cn-dat/everest-semi-dat/ES8311-dat/ES8311-SDK-dat/test/ES8311-code-spk5/es8311.c
... ...
@@ -0,0 +1,749 @@
1
+/*
2
+ * ESPRESSIF MIT License
3
+ *
4
+ * Copyright (c) 2019 <ESPRESSIF SYSTEMS (SHANGHAI) CO., LTD>
5
+ *
6
+ * Permission is hereby granted for use on all ESPRESSIF SYSTEMS products, in which case,
7
+ * it is free of charge, to any person obtaining a copy of this software and associated
8
+ * documentation files (the "Software"), to deal in the Software without restriction, including
9
+ * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the Software is furnished
11
+ * to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in all copies or
14
+ * substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ *
23
+ */
24
+
25
+#include <string.h>
26
+#include "driver/i2c.h"
27
+#include "board.h"
28
+#include "esp_log.h"
29
+#include "es8311.h"
30
+
31
+/* ES8311 address
32
+ * 0x32:CE=1;0x30:CE=0
33
+ */
34
+#define ES8311_ADDR 0x30
35
+
36
+/*
37
+ * to define the clock soure of MCLK
38
+ */
39
+#define FROM_MCLK_PIN 0
40
+#define FROM_SCLK_PIN 1
41
+#define MCLK_SOURCE 0
42
+
43
+/*
44
+ * to define whether to reverse the clock
45
+ */
46
+#define INVERT_MCLK 0 // do not invert
47
+#define INVERT_SCLK 0
48
+
49
+#define IS_DMIC 0 // Is it a digital microphone
50
+
51
+#define MCLK_DIV_FRE 256
52
+
53
+/*
54
+ * i2c default configuration
55
+ */
56
+static i2c_config_t es_i2c_cfg = {
57
+ .mode = I2C_MODE_MASTER,
58
+ .sda_pullup_en = GPIO_PULLUP_ENABLE,
59
+ .scl_pullup_en = GPIO_PULLUP_ENABLE,
60
+ .master.clk_speed = 100000
61
+};
62
+
63
+/*
64
+ * operate function of codec
65
+ */
66
+audio_hal_func_t AUDIO_CODEC_ES8311_DEFAULT_HANDLE = {
67
+ .audio_codec_initialize = es8311_codec_init,
68
+ .audio_codec_deinitialize = es8311_codec_deinit,
69
+ .audio_codec_ctrl = es8311_codec_ctrl_state,
70
+ .audio_codec_config_iface = es8311_codec_config_i2s,
71
+ .audio_codec_set_mute = es8311_set_voice_mute,
72
+ .audio_codec_set_volume = es8311_codec_set_voice_volume,
73
+ .audio_codec_get_volume = es8311_codec_get_voice_volume,
74
+};
75
+
76
+/*
77
+ * Clock coefficient structer
78
+ */
79
+struct _coeff_div {
80
+ uint32_t mclk; /* mclk frequency */
81
+ uint32_t rate; /* sample rate */
82
+ uint8_t pre_div; /* the pre divider with range from 1 to 8 */
83
+ uint8_t pre_multi; /* the pre multiplier with x1, x2, x4 and x8 selection */
84
+ uint8_t adc_div; /* adcclk divider */
85
+ uint8_t dac_div; /* dacclk divider */
86
+ uint8_t fs_mode; /* double speed or single speed, =0, ss, =1, ds */
87
+ uint8_t lrck_h; /* adclrck divider and daclrck divider */
88
+ uint8_t lrck_l;
89
+ uint8_t bclk_div; /* sclk divider */
90
+ uint8_t adc_osr; /* adc osr */
91
+ uint8_t dac_osr; /* dac osr */
92
+};
93
+
94
+/* codec hifi mclk clock divider coefficients */
95
+static const struct _coeff_div coeff_div[] = {
96
+ //mclk rate pre_div mult adc_div dac_div fs_mode lrch lrcl bckdiv osr
97
+ /* 8k */
98
+ {12288000, 8000 , 0x06, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
99
+ {18432000, 8000 , 0x03, 0x02, 0x03, 0x03, 0x00, 0x05, 0xff, 0x18, 0x10, 0x10},
100
+ {16384000, 8000 , 0x08, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
101
+ {8192000 , 8000 , 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
102
+ {6144000 , 8000 , 0x03, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
103
+ {4096000 , 8000 , 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
104
+ {3072000 , 8000 , 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
105
+ {2048000 , 8000 , 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
106
+ {1536000 , 8000 , 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
107
+ {1024000 , 8000 , 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
108
+
109
+ /* 11.025k */
110
+ {11289600, 11025, 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
111
+ {5644800 , 11025, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
112
+ {2822400 , 11025, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
113
+ {1411200 , 11025, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
114
+
115
+ /* 12k */
116
+ {12288000, 12000, 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
117
+ {6144000 , 12000, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
118
+ {3072000 , 12000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
119
+ {1536000 , 12000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
120
+
121
+ /* 16k */
122
+ {12288000, 16000, 0x03, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
123
+ {18432000, 16000, 0x03, 0x02, 0x03, 0x03, 0x00, 0x02, 0xff, 0x0c, 0x10, 0x10},
124
+ {16384000, 16000, 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
125
+ {8192000 , 16000, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
126
+ {6144000 , 16000, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
127
+ {4096000 , 16000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
128
+ {3072000 , 16000, 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
129
+ {2048000 , 16000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
130
+ {1536000 , 16000, 0x03, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
131
+ {1024000 , 16000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
132
+
133
+ /* 22.05k */
134
+ {11289600, 22050, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
135
+ {5644800 , 22050, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
136
+ {2822400 , 22050, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
137
+ {1411200 , 22050, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
138
+
139
+ /* 24k */
140
+ {12288000, 24000, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
141
+ {18432000, 24000, 0x03, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
142
+ {6144000 , 24000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
143
+ {3072000 , 24000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
144
+ {1536000 , 24000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
145
+
146
+ /* 32k */
147
+ {12288000, 32000, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
148
+ {18432000, 32000, 0x03, 0x04, 0x03, 0x03, 0x00, 0x02, 0xff, 0x0c, 0x10, 0x10},
149
+ {16384000, 32000, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
150
+ {8192000 , 32000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
151
+ {6144000 , 32000, 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
152
+ {4096000 , 32000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
153
+ {3072000 , 32000, 0x03, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
154
+ {2048000 , 32000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
155
+ {1536000 , 32000, 0x03, 0x08, 0x01, 0x01, 0x01, 0x00, 0x7f, 0x02, 0x10, 0x10},
156
+ {1024000 , 32000, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
157
+
158
+ /* 44.1k */
159
+ {11289600, 44100, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
160
+ {5644800 , 44100, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
161
+ {2822400 , 44100, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
162
+ {1411200 , 44100, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
163
+
164
+ /* 48k */
165
+ {12288000, 48000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
166
+ {18432000, 48000, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
167
+ {6144000 , 48000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
168
+ {3072000 , 48000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
169
+ {1536000 , 48000, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
170
+
171
+ /* 64k */
172
+ {12288000, 64000, 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
173
+ {18432000, 64000, 0x03, 0x04, 0x03, 0x03, 0x01, 0x01, 0x7f, 0x06, 0x10, 0x10},
174
+ {16384000, 64000, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
175
+ {8192000 , 64000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
176
+ {6144000 , 64000, 0x01, 0x04, 0x03, 0x03, 0x01, 0x01, 0x7f, 0x06, 0x10, 0x10},
177
+ {4096000 , 64000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
178
+ {3072000 , 64000, 0x01, 0x08, 0x03, 0x03, 0x01, 0x01, 0x7f, 0x06, 0x10, 0x10},
179
+ {2048000 , 64000, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
180
+ {1536000 , 64000, 0x01, 0x08, 0x01, 0x01, 0x01, 0x00, 0xbf, 0x03, 0x18, 0x18},
181
+ {1024000 , 64000, 0x01, 0x08, 0x01, 0x01, 0x01, 0x00, 0x7f, 0x02, 0x10, 0x10},
182
+
183
+ /* 88.2k */
184
+ {11289600, 88200, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
185
+ {5644800 , 88200, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
186
+ {2822400 , 88200, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
187
+ {1411200 , 88200, 0x01, 0x08, 0x01, 0x01, 0x01, 0x00, 0x7f, 0x02, 0x10, 0x10},
188
+
189
+ /* 96k */
190
+ {12288000, 96000, 0x01, 0x02, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
191
+ {18432000, 96000, 0x03, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
192
+ {6144000 , 96000, 0x01, 0x04, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
193
+ {3072000 , 96000, 0x01, 0x08, 0x01, 0x01, 0x00, 0x00, 0xff, 0x04, 0x10, 0x10},
194
+ {1536000 , 96000, 0x01, 0x08, 0x01, 0x01, 0x01, 0x00, 0x7f, 0x02, 0x10, 0x10},
195
+};
196
+
197
+static char *TAG = "DRV8311";
198
+
199
+#define ES_ASSERT(a, format, b, ...) \
200
+ if ((a) != 0) { \
201
+ ESP_LOGE(TAG, format, ##__VA_ARGS__); \
202
+ return b;\
203
+ }
204
+
205
+static int es8311_write_reg(uint8_t reg_addr, uint8_t data)
206
+{
207
+ int res = 0;
208
+ i2c_cmd_handle_t cmd = i2c_cmd_link_create();
209
+ res |= i2c_master_start(cmd);
210
+ res |= i2c_master_write_byte(cmd, ES8311_ADDR, 1 /*ACK_CHECK_EN*/);
211
+ res |= i2c_master_write_byte(cmd, reg_addr, 1 /*ACK_CHECK_EN*/);
212
+ res |= i2c_master_write_byte(cmd, data, 1 /*ACK_CHECK_EN*/);
213
+ res |= i2c_master_stop(cmd);
214
+ res |= i2c_master_cmd_begin(0, cmd, 1000 / portTICK_RATE_MS);
215
+ i2c_cmd_link_delete(cmd);
216
+ ES_ASSERT(res, "Es8311 Write Reg error", -1);
217
+ return res;
218
+}
219
+
220
+static int es8311_read_reg(uint8_t reg_addr)
221
+{
222
+ uint8_t data;
223
+ int res = 0;
224
+ i2c_cmd_handle_t cmd = i2c_cmd_link_create();
225
+
226
+ res |= i2c_master_start(cmd);
227
+ res |= i2c_master_write_byte(cmd, ES8311_ADDR, 1 /*ACK_CHECK_EN*/);
228
+ res |= i2c_master_write_byte(cmd, reg_addr, 1 /*ACK_CHECK_EN*/);
229
+ res |= i2c_master_stop(cmd);
230
+ res |= i2c_master_cmd_begin(0, cmd, 1000 / portTICK_RATE_MS);
231
+ i2c_cmd_link_delete(cmd);
232
+
233
+ cmd = i2c_cmd_link_create();
234
+ res |= i2c_master_start(cmd);
235
+ res |= i2c_master_write_byte(cmd, ES8311_ADDR | 0x01, 1 /*ACK_CHECK_EN*/);
236
+ res |= i2c_master_read_byte(cmd, &data, 0x01 /*NACK_VAL*/);
237
+ res |= i2c_master_stop(cmd);
238
+ res |= i2c_master_cmd_begin(0, cmd, 1000 / portTICK_RATE_MS);
239
+ i2c_cmd_link_delete(cmd);
240
+
241
+ ES_ASSERT(res, "Es8311 Read Reg error", -1);
242
+ return (int)data;
243
+}
244
+
245
+static int i2c_init()
246
+{
247
+ int res = 0;
248
+ get_i2c_pins(I2C_NUM_0, &es_i2c_cfg);
249
+ res |= i2c_param_config(I2C_NUM_0, &es_i2c_cfg);
250
+ res |= i2c_driver_install(I2C_NUM_0, es_i2c_cfg.mode, 0, 0, 0);
251
+ ES_ASSERT(res, "i2c_init error", -1);
252
+ return res;
253
+}
254
+
255
+/*
256
+* look for the coefficient in coeff_div[] table
257
+*/
258
+static int get_coeff(uint32_t mclk, uint32_t rate)
259
+{
260
+ for (int i = 0; i < (sizeof(coeff_div) / sizeof(coeff_div[0])); i++) {
261
+ if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
262
+ return i;
263
+ }
264
+ return -1;
265
+}
266
+
267
+/*
268
+* set es8311 dac mute or not
269
+* if mute = 0, dac un-mute
270
+* if mute = 1, dac mute
271
+*/
272
+static void es8311_mute(int mute)
273
+{
274
+ uint8_t regv;
275
+ ESP_LOGI(TAG, "Enter into es8311_mute(), mute = %d\n", mute);
276
+ regv = es8311_read_reg(ES8311_DAC_REG31) & 0x9f;
277
+ if (mute) {
278
+ es8311_write_reg(ES8311_SYSTEM_REG12, 0x02);
279
+ es8311_write_reg(ES8311_DAC_REG31, regv | 0x60);
280
+ es8311_write_reg(ES8311_DAC_REG32, 0x00);
281
+ es8311_write_reg(ES8311_DAC_REG37, 0x08);
282
+ } else {
283
+ es8311_write_reg(ES8311_DAC_REG31, regv);
284
+ es8311_write_reg(ES8311_SYSTEM_REG12, 0x00);
285
+ }
286
+}
287
+
288
+/*
289
+* set es8311 into suspend mode
290
+*/
291
+static void es8311_suspend(void)
292
+{
293
+ ESP_LOGI(TAG, "Enter into es8311_suspend()");
294
+ es8311_write_reg(ES8311_DAC_REG32, 0x00);
295
+ es8311_write_reg(ES8311_ADC_REG17, 0x00);
296
+ es8311_write_reg(ES8311_SYSTEM_REG0E, 0xFF);
297
+ es8311_write_reg(ES8311_SYSTEM_REG12, 0x02);
298
+ es8311_write_reg(ES8311_SYSTEM_REG14, 0x00);
299
+ es8311_write_reg(ES8311_SYSTEM_REG0D, 0xFA);
300
+ es8311_write_reg(ES8311_ADC_REG15, 0x00);
301
+ es8311_write_reg(ES8311_DAC_REG37, 0x08);
302
+ es8311_write_reg(ES8311_GP_REG45, 0x01);
303
+}
304
+
305
+/*
306
+* enable pa power
307
+*/
308
+void es8311_pa_power(bool enable)
309
+{
310
+ gpio_config_t io_conf;
311
+ memset(&io_conf, 0, sizeof(io_conf));
312
+ io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
313
+ io_conf.mode = GPIO_MODE_OUTPUT;
314
+ io_conf.pin_bit_mask = BIT(get_pa_enable_gpio());
315
+ io_conf.pull_down_en = 0;
316
+ io_conf.pull_up_en = 0;
317
+ gpio_config(&io_conf);
318
+ if (enable) {
319
+ gpio_set_level(get_pa_enable_gpio(), 1);
320
+ } else {
321
+ gpio_set_level(get_pa_enable_gpio(), 0);
322
+ }
323
+}
324
+
325
+esp_err_t es8311_codec_init(audio_hal_codec_config_t *codec_cfg)
326
+{
327
+ uint8_t datmp, regv;
328
+ int coeff;
329
+ esp_err_t ret = ESP_OK;
330
+ i2c_init(); // ESP32 in master mode
331
+
332
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, 0x30);
333
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG02, 0x00);
334
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG03, 0x10);
335
+ ret |= es8311_write_reg(ES8311_ADC_REG16, 0x24);
336
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG04, 0x10);
337
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG05, 0x00);
338
+ ret |= es8311_write_reg(ES8311_SYSTEM_REG0B, 0x00);
339
+ ret |= es8311_write_reg(ES8311_SYSTEM_REG0C, 0x00);
340
+ ret |= es8311_write_reg(ES8311_SYSTEM_REG10, 0x1F);
341
+ ret |= es8311_write_reg(ES8311_SYSTEM_REG11, 0x7F);
342
+ ret |= es8311_write_reg(ES8311_RESET_REG00, 0x80);
343
+ /*
344
+ * Set Codec into Master or Slave mode
345
+ */
346
+ regv = es8311_read_reg(ES8311_RESET_REG00);
347
+ /*
348
+ * Set master/slave audio interface
349
+ */
350
+ audio_hal_codec_i2s_iface_t *i2s_cfg = &(codec_cfg->i2s_iface);
351
+ switch (i2s_cfg->mode) {
352
+ case AUDIO_HAL_MODE_MASTER: /* MASTER MODE */
353
+ ESP_LOGI(TAG, "ES8311 in Master mode");
354
+ regv |= 0x40;
355
+ break;
356
+ case AUDIO_HAL_MODE_SLAVE: /* SLAVE MODE */
357
+ ESP_LOGI(TAG, "ES8311 in Slave mode");
358
+ regv &= 0xBF;
359
+ break;
360
+ default:
361
+ regv &= 0xBF;
362
+ }
363
+ ret |= es8311_write_reg(ES8311_RESET_REG00, regv);
364
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, 0x3F);
365
+ /*
366
+ * Select clock source for internal mclk
367
+ */
368
+ switch (MCLK_SOURCE) {
369
+ case FROM_MCLK_PIN:
370
+ regv = es8311_read_reg(ES8311_CLK_MANAGER_REG01);
371
+ regv &= 0x7F;
372
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, regv);
373
+ break;
374
+ case FROM_SCLK_PIN:
375
+ regv = es8311_read_reg(ES8311_CLK_MANAGER_REG01);
376
+ regv |= 0x80;
377
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, regv);
378
+ break;
379
+ default:
380
+ regv = es8311_read_reg(ES8311_CLK_MANAGER_REG01);
381
+ regv &= 0x7F;
382
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, regv);
383
+ break;
384
+ }
385
+ int sample_fre = 0;
386
+ int mclk_fre = 0;
387
+ switch (i2s_cfg->samples) {
388
+ case AUDIO_HAL_08K_SAMPLES:
389
+ sample_fre = 8000;
390
+ break;
391
+ case AUDIO_HAL_11K_SAMPLES:
392
+ sample_fre = 11025;
393
+ break;
394
+ case AUDIO_HAL_16K_SAMPLES:
395
+ sample_fre = 16000;
396
+ break;
397
+ case AUDIO_HAL_22K_SAMPLES:
398
+ sample_fre = 22050;
399
+ break;
400
+ case AUDIO_HAL_24K_SAMPLES:
401
+ sample_fre = 24000;
402
+ break;
403
+ case AUDIO_HAL_32K_SAMPLES:
404
+ sample_fre = 32000;
405
+ break;
406
+ case AUDIO_HAL_44K_SAMPLES:
407
+ sample_fre = 44100;
408
+ break;
409
+ case AUDIO_HAL_48K_SAMPLES:
410
+ sample_fre = 48000;
411
+ break;
412
+ default:
413
+ ESP_LOGE(TAG, "Unable to configure sample rate %dHz", sample_fre);
414
+ break;
415
+ }
416
+ mclk_fre = sample_fre * MCLK_DIV_FRE;
417
+ coeff = get_coeff(mclk_fre, sample_fre);
418
+ if (coeff < 0) {
419
+ ESP_LOGE(TAG, "Unable to configure sample rate %dHz with %dHz MCLK", sample_fre, mclk_fre);
420
+ return ESP_FAIL;
421
+ }
422
+ /*
423
+ * Set clock parammeters
424
+ */
425
+ if (coeff >= 0) {
426
+ regv = es8311_read_reg(ES8311_CLK_MANAGER_REG02) & 0x07;
427
+ regv |= (coeff_div[coeff].pre_div - 1) << 5;
428
+ datmp = 0;
429
+ switch (coeff_div[coeff].pre_multi) {
430
+ case 1:
431
+ datmp = 0;
432
+ break;
433
+ case 2:
434
+ datmp = 1;
435
+ break;
436
+ case 4:
437
+ datmp = 2;
438
+ break;
439
+ case 8:
440
+ datmp = 3;
441
+ break;
442
+ default:
443
+ break;
444
+ }
445
+ regv |= (datmp) << 3;
446
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG02, regv);
447
+
448
+ regv = es8311_read_reg(ES8311_CLK_MANAGER_REG05) & 0x00;
449
+ regv |= (coeff_div[coeff].adc_div - 1) << 4;
450
+ regv |= (coeff_div[coeff].dac_div - 1) << 0;
451
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG05, regv);
452
+
453
+ regv = es8311_read_reg(ES8311_CLK_MANAGER_REG03) & 0x80;
454
+ regv |= coeff_div[coeff].fs_mode << 6;
455
+ regv |= coeff_div[coeff].adc_osr << 0;
456
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG03, regv);
457
+
458
+ regv = es8311_read_reg(ES8311_CLK_MANAGER_REG04) & 0x80;
459
+ regv |= coeff_div[coeff].dac_osr << 0;
460
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG04, regv);
461
+
462
+ regv = es8311_read_reg(ES8311_CLK_MANAGER_REG07) & 0xC0;
463
+ regv |= coeff_div[coeff].lrck_h << 0;
464
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG07, regv);
465
+
466
+ regv = es8311_read_reg(ES8311_CLK_MANAGER_REG08) & 0x00;
467
+ regv |= coeff_div[coeff].lrck_l << 0;
468
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG08, regv);
469
+
470
+ regv = es8311_read_reg(ES8311_CLK_MANAGER_REG06) & 0xE0;
471
+ if (coeff_div[coeff].bclk_div < 19) {
472
+ regv |= (coeff_div[coeff].bclk_div - 1) << 0;
473
+ } else {
474
+ regv |= (coeff_div[coeff].bclk_div) << 0;
475
+ }
476
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG06, regv);
477
+ }
478
+
479
+ /*
480
+ * mclk inverted or not
481
+ */
482
+ if (INVERT_MCLK) {
483
+ regv = es8311_read_reg(ES8311_CLK_MANAGER_REG01);
484
+ regv |= 0x40;
485
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, regv);
486
+ } else {
487
+ regv = es8311_read_reg(ES8311_CLK_MANAGER_REG01);
488
+ regv &= ~(0x40);
489
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, regv);
490
+ }
491
+ /*
492
+ * sclk inverted or not
493
+ */
494
+ if (INVERT_SCLK) {
495
+ regv = es8311_read_reg(ES8311_CLK_MANAGER_REG06);
496
+ regv |= 0x20;
497
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG06, regv);
498
+ } else {
499
+ regv = es8311_read_reg(ES8311_CLK_MANAGER_REG06);
500
+ regv &= ~(0x20);
501
+ ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG06, regv);
502
+ }
503
+
504
+ ret |= es8311_write_reg(ES8311_SYSTEM_REG13, 0x10);
505
+ ret |= es8311_write_reg(ES8311_ADC_REG1B, 0x0A);
506
+ ret |= es8311_write_reg(ES8311_ADC_REG1C, 0x6A);
507
+ ret |= es8311_write_reg(ES8311_GPIO_REG44, 0x08);
508
+
509
+ es8311_pa_power(true);
510
+ return ESP_OK;
511
+}
512
+
513
+esp_err_t es8311_codec_deinit()
514
+{
515
+//TODO
516
+ return ESP_OK;
517
+}
518
+
519
+esp_err_t es8311_config_fmt(es_i2s_fmt_t fmt)
520
+{
521
+ esp_err_t ret = ESP_OK;
522
+ uint8_t adc_iface = 0, dac_iface = 0;
523
+ dac_iface = es8311_read_reg(ES8311_SDPIN_REG09);
524
+ adc_iface = es8311_read_reg(ES8311_SDPOUT_REG0A);
525
+ switch (fmt) {
526
+ case AUDIO_HAL_I2S_NORMAL:
527
+ ESP_LOGD(TAG, "ES8311 in I2S Format");
528
+ dac_iface &= 0xFC;
529
+ adc_iface &= 0xFC;
530
+ break;
531
+ case AUDIO_HAL_I2S_LEFT:
532
+ case AUDIO_HAL_I2S_RIGHT:
533
+ ESP_LOGD(TAG, "ES8311 in LJ Format");
534
+ adc_iface &= 0xFC;
535
+ dac_iface &= 0xFC;
536
+ adc_iface |= 0x01;
537
+ dac_iface |= 0x01;
538
+ break;
539
+ case AUDIO_HAL_I2S_DSP:
540
+ ESP_LOGD(TAG, "ES8311 in DSP-A Format");
541
+ adc_iface &= 0xDC;
542
+ dac_iface &= 0xDC;
543
+ adc_iface |= 0x03;
544
+ dac_iface |= 0x03;
545
+ break;
546
+ default:
547
+ dac_iface &= 0xFC;
548
+ adc_iface &= 0xFC;
549
+ break;
550
+ }
551
+ ret |= es8311_write_reg(ES8311_SDPIN_REG09, dac_iface);
552
+ ret |= es8311_write_reg(ES8311_SDPOUT_REG0A, adc_iface);
553
+
554
+ return ret;
555
+}
556
+
557
+esp_err_t es8311_set_bits_per_sample(audio_hal_iface_bits_t bits)
558
+{
559
+ esp_err_t ret = ESP_OK;
560
+ uint8_t adc_iface = 0, dac_iface = 0;
561
+ dac_iface = es8311_read_reg(ES8311_SDPIN_REG09);
562
+ adc_iface = es8311_read_reg(ES8311_SDPOUT_REG0A);
563
+ switch (bits) {
564
+ case AUDIO_HAL_BIT_LENGTH_16BITS:
565
+ dac_iface |= 0x0c;
566
+ adc_iface |= 0x0c;
567
+ break;
568
+ case AUDIO_HAL_BIT_LENGTH_24BITS:
569
+ break;
570
+ case AUDIO_HAL_BIT_LENGTH_32BITS:
571
+ dac_iface |= 0x10;
572
+ adc_iface |= 0x10;
573
+ break;
574
+ default:
575
+ dac_iface |= 0x0c;
576
+ adc_iface |= 0x0c;
577
+ break;
578
+
579
+ }
580
+ ret |= es8311_write_reg(ES8311_SDPIN_REG09, dac_iface);
581
+ ret |= es8311_write_reg(ES8311_SDPOUT_REG0A, adc_iface);
582
+
583
+ return ret;
584
+}
585
+
586
+esp_err_t es8311_codec_config_i2s(audio_hal_codec_mode_t mode, audio_hal_codec_i2s_iface_t *iface)
587
+{
588
+ int ret = ESP_OK;
589
+ ret |= es8311_set_bits_per_sample(iface->bits);
590
+ ret |= es8311_config_fmt(iface->fmt);
591
+ return ret;
592
+}
593
+
594
+esp_err_t es8311_codec_ctrl_state(audio_hal_codec_mode_t mode, audio_hal_ctrl_t ctrl_state)
595
+{
596
+ esp_err_t ret = ESP_OK;
597
+ es_module_t es_mode = ES_MODULE_MIN;
598
+
599
+ switch (mode) {
600
+ case AUDIO_HAL_CODEC_MODE_ENCODE:
601
+ es_mode = ES_MODULE_ADC;
602
+ break;
603
+ case AUDIO_HAL_CODEC_MODE_LINE_IN:
604
+ es_mode = ES_MODULE_LINE;
605
+ break;
606
+ case AUDIO_HAL_CODEC_MODE_DECODE:
607
+ es_mode = ES_MODULE_DAC;
608
+ break;
609
+ case AUDIO_HAL_CODEC_MODE_BOTH:
610
+ es_mode = ES_MODULE_ADC_DAC;
611
+ break;
612
+ default:
613
+ es_mode = ES_MODULE_DAC;
614
+ ESP_LOGW(TAG, "Codec mode not support, default is decode mode");
615
+ break;
616
+ }
617
+
618
+ if (ctrl_state == AUDIO_HAL_CTRL_START) {
619
+ ret |= es8311_start(es_mode);
620
+ } else {
621
+ ESP_LOGW(TAG, "The codec is about to stop");
622
+ ret |= es8311_stop(es_mode);
623
+ }
624
+
625
+ return ret;
626
+}
627
+
628
+esp_err_t es8311_start(es_module_t mode)
629
+{
630
+ esp_err_t ret = ESP_OK;
631
+ uint8_t adc_iface = 0, dac_iface = 0;
632
+
633
+ dac_iface = es8311_read_reg(ES8311_SDPIN_REG09) & 0xBF;
634
+ adc_iface = es8311_read_reg(ES8311_SDPOUT_REG0A) & 0xBF;
635
+ adc_iface |= BIT(6);
636
+ dac_iface |= BIT(6);
637
+
638
+ if (mode == ES_MODULE_LINE) {
639
+ ESP_LOGE(TAG, "The codec es8311 doesn't support ES_MODULE_LINE mode");
640
+ return ESP_FAIL;
641
+ }
642
+ if (mode == ES_MODULE_ADC || mode == ES_MODULE_ADC_DAC) {
643
+ adc_iface &= ~(BIT(6));
644
+ }
645
+ if (mode == ES_MODULE_DAC || mode == ES_MODULE_ADC_DAC) {
646
+ dac_iface &= ~(BIT(6));
647
+ }
648
+
649
+ ret |= es8311_write_reg(ES8311_SDPIN_REG09, dac_iface);
650
+ ret |= es8311_write_reg(ES8311_SDPOUT_REG0A, adc_iface);
651
+
652
+ ret |= es8311_write_reg(ES8311_DAC_REG32, 0xBF);
653
+ ret |= es8311_write_reg(ES8311_ADC_REG17, 0xBF);
654
+ ret |= es8311_write_reg(ES8311_SYSTEM_REG0E, 0x02);
655
+ ret |= es8311_write_reg(ES8311_SYSTEM_REG12, 0x00);
656
+ ret |= es8311_write_reg(ES8311_SYSTEM_REG14, 0x1A);
657
+
658
+ /*
659
+ * pdm dmic enable or disable
660
+ */
661
+ int regv = 0;
662
+ if (IS_DMIC) {
663
+ regv = es8311_read_reg(ES8311_SYSTEM_REG14);
664
+ regv |= 0x40;
665
+ ret |= es8311_write_reg(ES8311_SYSTEM_REG14, regv);
666
+ } else {
667
+ regv = es8311_read_reg(ES8311_SYSTEM_REG14);
668
+ regv &= ~(0x40);
669
+ ret |= es8311_write_reg(ES8311_SYSTEM_REG14, regv);
670
+ }
671
+
672
+ ret |= es8311_write_reg(ES8311_SYSTEM_REG0D, 0x01);
673
+ ret |= es8311_write_reg(ES8311_ADC_REG15, 0x40);
674
+ ret |= es8311_write_reg(ES8311_DAC_REG37, 0x48);
675
+ ret |= es8311_write_reg(ES8311_GP_REG45, 0x00);
676
+
677
+ return ret;
678
+}
679
+
680
+esp_err_t es8311_stop(es_module_t mode)
681
+{
682
+ esp_err_t ret = ESP_OK;
683
+ es8311_suspend();
684
+ return ret;
685
+}
686
+
687
+int es8311_codec_set_voice_volume(int volume)
688
+{
689
+ int res = 0;
690
+ if (volume < 0) {
691
+ volume = 0;
692
+ } else if (volume > 100) {
693
+ volume = 100;
694
+ }
695
+ int vol = (volume) * 2550 / 1000;
696
+ ESP_LOGD(TAG, "SET: volume:%d", vol);
697
+ es8311_write_reg(ES8311_DAC_REG32, vol);
698
+ return res;
699
+}
700
+
701
+int es8311_codec_get_voice_volume(int *volume)
702
+{
703
+ int res = ESP_OK;
704
+ int regv = 0;
705
+ regv = es8311_read_reg(ES8311_DAC_REG32);
706
+ if (regv == ESP_FAIL) {
707
+ *volume = 0;
708
+ res = ESP_FAIL;
709
+ } else {
710
+ *volume = regv * 100 / 256;
711
+ }
712
+ ESP_LOGD(TAG, "GET: res:%d, volume:%d", regv, *volume);
713
+ return res;
714
+}
715
+
716
+esp_err_t es8311_set_voice_mute(bool enable)
717
+{
718
+ int res = 0;
719
+ ESP_LOGD(TAG, "Es8311SetVoiceMute volume:%d", enable);
720
+ es8311_mute(enable);
721
+ return res;
722
+}
723
+
724
+int es8311_get_voice_mute(int *mute)
725
+{
726
+ int res = -1;
727
+ uint8_t reg = 0;
728
+ res = es8311_read_reg(ES8311_DAC_REG31);
729
+ if (res != ESP_FAIL) {
730
+ reg = (res & 0x20) >> 5;
731
+ }
732
+ *mute = reg;
733
+ return res;
734
+}
735
+
736
+esp_err_t es8311_set_mic_gain(es8311_mic_gain_t gain_db)
737
+{
738
+ int res = 0;
739
+ res = es8311_write_reg(ES8311_ADC_REG16, gain_db); // MIC gain scale
740
+ return res;
741
+}
742
+
743
+void es8311_read_all()
744
+{
745
+ for (int i = 0; i < 0x4A; i++) {
746
+ uint8_t reg = es8311_read_reg(i);
747
+ ets_printf("REG:%02x, %02x\n", reg, i);
748
+ }
749
+}
Chip-cn-dat/everest-semi-dat/ES8311-dat/ES8311-SDK-dat/test/ES8311-code-spk5/es8311.h
... ...
@@ -0,0 +1,237 @@
1
+/*
2
+ * ESPRESSIF MIT License
3
+ *
4
+ * Copyright (c) 2019 <ESPRESSIF SYSTEMS (SHANGHAI) CO., LTD>
5
+ *
6
+ * Permission is hereby granted for use on all ESPRESSIF SYSTEMS products, in which case,
7
+ * it is free of charge, to any person obtaining a copy of this software and associated
8
+ * documentation files (the "Software"), to deal in the Software without restriction, including
9
+ * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the Software is furnished
11
+ * to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in all copies or
14
+ * substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ *
23
+ */
24
+
25
+#ifndef _ES8311_H
26
+#define _ES8311_H
27
+
28
+#include "audio_hal.h"
29
+#include "esp_types.h"
30
+#include "esxxx_common.h"
31
+
32
+/*
33
+ * ES8311_REGISTER NAME_REG_REGISTER ADDRESS
34
+ */
35
+#define ES8311_RESET_REG00 0x00 /*reset digital,csm,clock manager etc.*/
36
+
37
+/*
38
+ * Clock Scheme Register definition
39
+ */
40
+#define ES8311_CLK_MANAGER_REG01 0x01 /* select clk src for mclk, enable clock for codec */
41
+#define ES8311_CLK_MANAGER_REG02 0x02 /* clk divider and clk multiplier */
42
+#define ES8311_CLK_MANAGER_REG03 0x03 /* adc fsmode and osr */
43
+#define ES8311_CLK_MANAGER_REG04 0x04 /* dac osr */
44
+#define ES8311_CLK_MANAGER_REG05 0x05 /* clk divier for adc and dac */
45
+#define ES8311_CLK_MANAGER_REG06 0x06 /* bclk inverter and divider */
46
+#define ES8311_CLK_MANAGER_REG07 0x07 /* tri-state, lrck divider */
47
+#define ES8311_CLK_MANAGER_REG08 0x08 /* lrck divider */
48
+/*
49
+ * SDP
50
+ */
51
+#define ES8311_SDPIN_REG09 0x09 /* dac serial digital port */
52
+#define ES8311_SDPOUT_REG0A 0x0A /* adc serial digital port */
53
+/*
54
+ * SYSTEM
55
+ */
56
+#define ES8311_SYSTEM_REG0B 0x0B /* system */
57
+#define ES8311_SYSTEM_REG0C 0x0C /* system */
58
+#define ES8311_SYSTEM_REG0D 0x0D /* system, power up/down */
59
+#define ES8311_SYSTEM_REG0E 0x0E /* system, power up/down */
60
+#define ES8311_SYSTEM_REG0F 0x0F /* system, low power */
61
+#define ES8311_SYSTEM_REG10 0x10 /* system */
62
+#define ES8311_SYSTEM_REG11 0x11 /* system */
63
+#define ES8311_SYSTEM_REG12 0x12 /* system, Enable DAC */
64
+#define ES8311_SYSTEM_REG13 0x13 /* system */
65
+#define ES8311_SYSTEM_REG14 0x14 /* system, select DMIC, select analog pga gain */
66
+/*
67
+ * ADC
68
+ */
69
+#define ES8311_ADC_REG15 0x15 /* ADC, adc ramp rate, dmic sense */
70
+#define ES8311_ADC_REG16 0x16 /* ADC */
71
+#define ES8311_ADC_REG17 0x17 /* ADC, volume */
72
+#define ES8311_ADC_REG18 0x18 /* ADC, alc enable and winsize */
73
+#define ES8311_ADC_REG19 0x19 /* ADC, alc maxlevel */
74
+#define ES8311_ADC_REG1A 0x1A /* ADC, alc automute */
75
+#define ES8311_ADC_REG1B 0x1B /* ADC, alc automute, adc hpf s1 */
76
+#define ES8311_ADC_REG1C 0x1C /* ADC, equalizer, hpf s2 */
77
+/*
78
+ * DAC
79
+ */
80
+#define ES8311_DAC_REG31 0x31 /* DAC, mute */
81
+#define ES8311_DAC_REG32 0x32 /* DAC, volume */
82
+#define ES8311_DAC_REG33 0x33 /* DAC, offset */
83
+#define ES8311_DAC_REG34 0x34 /* DAC, drc enable, drc winsize */
84
+#define ES8311_DAC_REG35 0x35 /* DAC, drc maxlevel, minilevel */
85
+#define ES8311_DAC_REG37 0x37 /* DAC, ramprate */
86
+/*
87
+ *GPIO
88
+ */
89
+#define ES8311_GPIO_REG44 0x44 /* GPIO, dac2adc for test */
90
+#define ES8311_GP_REG45 0x45 /* GP CONTROL */
91
+/*
92
+ * CHIP
93
+ */
94
+#define ES8311_CHD1_REGFD 0xFD /* CHIP ID1 */
95
+#define ES8311_CHD2_REGFE 0xFE /* CHIP ID2 */
96
+#define ES8311_CHVER_REGFF 0xFF /* VERSION */
97
+#define ES8311_CHD1_REGFD 0xFD /* CHIP ID1 */
98
+
99
+#define ES8311_MAX_REGISTER 0xFF
100
+
101
+typedef enum {
102
+ ES8311_MIC_GAIN_MIN = -1,
103
+ ES8311_MIC_GAIN_0DB,
104
+ ES8311_MIC_GAIN_6DB,
105
+ ES8311_MIC_GAIN_12DB,
106
+ ES8311_MIC_GAIN_18DB,
107
+ ES8311_MIC_GAIN_24DB,
108
+ ES8311_MIC_GAIN_30DB,
109
+ ES8311_MIC_GAIN_36DB,
110
+ ES8311_MIC_GAIN_42DB,
111
+ ES8311_MIC_GAIN_MAX
112
+} es8311_mic_gain_t;
113
+
114
+/*
115
+ * @brief Initialize ES8311 codec chip
116
+ *
117
+ * @param codec_cfg configuration of ES8311
118
+ *
119
+ * @return
120
+ * - ESP_OK
121
+ * - ESP_FAIL
122
+ */
123
+esp_err_t es8311_codec_init(audio_hal_codec_config_t *codec_cfg);
124
+
125
+/**
126
+ * @brief Deinitialize ES8311 codec chip
127
+ *
128
+ * @return
129
+ * - ESP_OK
130
+ * - ESP_FAIL
131
+ */
132
+esp_err_t es8311_codec_deinit(void);
133
+
134
+/**
135
+ * @brief Control ES8311 codec chip
136
+ *
137
+ * @param mode codec mode
138
+ * @param ctrl_state start or stop decode or encode progress
139
+ *
140
+ * @return
141
+ * - ESP_FAIL Parameter error
142
+ * - ESP_OK Success
143
+ */
144
+esp_err_t es8311_codec_ctrl_state(audio_hal_codec_mode_t mode, audio_hal_ctrl_t ctrl_state);
145
+
146
+/**
147
+ * @brief Configure ES8311 codec mode and I2S interface
148
+ *
149
+ * @param mode codec mode
150
+ * @param iface I2S config
151
+ *
152
+ * @return
153
+ * - ESP_FAIL Parameter error
154
+ * - ESP_OK Success
155
+ */
156
+esp_err_t es8311_codec_config_i2s(audio_hal_codec_mode_t mode, audio_hal_codec_i2s_iface_t *iface);
157
+
158
+/**
159
+ * @brief Configure ES8311 DAC mute or not. Basically you can use this function to mute the output or unmute
160
+ *
161
+ * @param enable enable(1) or disable(0)
162
+ *
163
+ * @return
164
+ * - ESP_FAIL Parameter error
165
+ * - ESP_OK Success
166
+ */
167
+esp_err_t es8311_set_voice_mute(bool enable);
168
+
169
+/**
170
+ * @brief Set voice volume
171
+ *
172
+ * @param volume: voice volume (0~100)
173
+ *
174
+ * @return
175
+ * - ESP_OK
176
+ * - ESP_FAIL
177
+ */
178
+esp_err_t es8311_codec_set_voice_volume(int volume);
179
+
180
+/**
181
+ * @brief Get voice volume
182
+ *
183
+ * @param[out] *volume: voice volume (0~100)
184
+ *
185
+ * @return
186
+ * - ESP_OK
187
+ * - ESP_FAIL
188
+ */
189
+esp_err_t es8311_codec_get_voice_volume(int *volume);
190
+
191
+/**
192
+ * @brief Configure ES8311 I2S format
193
+ *
194
+ * @param mod: set ADC or DAC or both
195
+ * @param cfg: ES8388 I2S format
196
+ *
197
+ * @return
198
+ * - ESP_OK
199
+ * - ESP_FAIL
200
+ */
201
+esp_err_t es8311_config_fmt(es_i2s_fmt_t fmt);
202
+
203
+/**
204
+ * @brief Configure ES8311 data sample bits
205
+ *
206
+ * @param mode: set ADC or DAC or both
207
+ * @param bit_per_sample: bit number of per sample
208
+ *
209
+ * @return
210
+ * - ESP_OK
211
+ * - ESP_FAIL
212
+ */
213
+esp_err_t es8311_set_bits_per_sample(audio_hal_iface_bits_t bits);
214
+
215
+/**
216
+ * @brief Start ES8311 codec chip
217
+ *
218
+ * @param mode: set ADC or DAC or both
219
+ *
220
+ * @return
221
+ * - ESP_OK
222
+ * - ESP_FAIL
223
+ */
224
+esp_err_t es8311_start(es_module_t mode);
225
+
226
+/**
227
+ * @brief Stop ES8311 codec chip
228
+ *
229
+ * @param mode: set ADC or DAC or both
230
+ *
231
+ * @return
232
+ * - ESP_OK
233
+ * - ESP_FAIL
234
+ */
235
+esp_err_t es8311_stop(es_module_t mode);
236
+
237
+#endif
Tech-dat/Interface-dat/I2S-dat/I2S-dat.md
... ...
@@ -24,6 +24,8 @@
24 24
25 25
- [[sensor-microphone-dat]] - [[sensor-microphone-I2S-dat]]
26 26
27
+- [[I2S-speaker-microphone-dat]] - [[ES8311-dat]]
28
+
27 29
## info
28 30
29 31
An I2S (Interactive Two-Way Serial) interface is a type of serial communication protocol used for transferring data between devices.
Tech-dat/Interface-dat/I2S-dat/I2S-speaker-microphone-dat/I2S-speaker-microphone-dat.md
... ...
@@ -0,0 +1,11 @@
1
+
2
+
3
+# I2S-speaker-microphone-dat
4
+
5
+- [[I2S-speaker-microphone-dat]] - [[ES8311-dat]] - [[ES8311-SDK-dat]]
6
+
7
+
8
+
9
+
10
+## ref
11
+
Tech-dat/acturator-dat/speaker-dat/speaker-I2S-dat/I2S-speaker-general-1/I2S-speaker-general-1.ino
... ...
@@ -0,0 +1,126 @@
1
+/**
2
+ * HT517-test-1.ino
3
+ *
4
+ * Simple I2S audio output demo for ESP32-S3 → I2S amplifier (MAX98357 / PCM5102 / etc.)
5
+ *
6
+ * Hardware connection (ESP32-S3 → I2S amplifier):
7
+ * I2S_BCK (Bit Clock) → GPIO 4 -> BCK / BCLK / SCK
8
+ * I2S_WS (Word Select) → GPIO 5 -> WS / LRCK / FS
9
+ * I2S_DATA (Data) → GPIO 6 -> DIN / DATA / SD
10
+ * (Optional) I2S_MCLK (Master Clock) → GPIO 7 -> MCLK (not required by MAX98357)
11
+ *
12
+ * Tested amplifiers: MAX98357, PCM5102, I2S DAC, etc.
13
+ * Output: 16-bit 44100 Hz mono sine wave (left+right same data).
14
+ */
15
+
16
+#include <driver/i2s.h>
17
+#include <math.h>
18
+
19
+// ============ CONFIGURATION ============
20
+#define SAMPLE_RATE 44100
21
+#define BITS_PER_SAMPLE 16
22
+#define I2S_PORT I2S_NUM_0
23
+
24
+// GPIO pins (adjust to your wiring)
25
+#define I2S_BCK 4 // Bit Clock
26
+#define I2S_WS 5 // Word Select (LRCK)
27
+#define I2S_DATA 6 // Data out (DIN)
28
+#define I2S_MCLK -1 // -1 = disable Master Clock (not needed for MAX98357)
29
+
30
+// ============ BUFFER ============
31
+#define BUF_LEN 256 // samples per channel per buffer
32
+int16_t buf[BUF_LEN * 2]; // stereo interleaved
33
+
34
+// ============ I2S CONFIG ============
35
+
36
+void setupI2S() {
37
+ i2s_config_t i2s_config = {
38
+ .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX),
39
+ .sample_rate = SAMPLE_RATE,
40
+ .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
41
+ .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
42
+ .communication_format = I2S_COMM_FORMAT_STAND_I2S,
43
+ .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
44
+ .dma_buf_count = 8,
45
+ .dma_buf_len = BUF_LEN,
46
+ .use_apll = true,
47
+ .tx_desc_auto_clear = true,
48
+ .fixed_mclk = 0,
49
+ };
50
+
51
+ i2s_pin_config_t pin_config = {
52
+ .bck_io_num = I2S_BCK,
53
+ .ws_io_num = I2S_WS,
54
+ .data_out_num = I2S_DATA,
55
+ .data_in_num = I2S_PIN_NO_CHANGE,
56
+ };
57
+
58
+ // Install and start I2S driver
59
+ esp_err_t err = i2s_driver_install(I2S_PORT, &i2s_config, 0, NULL);
60
+ if (err != ESP_OK) {
61
+ Serial.printf("FAIL: i2s_driver_install returned %d\n", err);
62
+ while (1) delay(100);
63
+ }
64
+
65
+ // Set pins (only if MCLK is not used)
66
+ err = i2s_set_pin(I2S_PORT, &pin_config);
67
+ if (err != ESP_OK) {
68
+ Serial.printf("FAIL: i2s_set_pin returned %d\n", err);
69
+ while (1) delay(100);
70
+ }
71
+
72
+ // Set MCLK if enabled
73
+ if (I2S_MCLK > 0) {
74
+ i2s_set_clk(I2S_PORT, SAMPLE_RATE, I2S_BITS_PER_SAMPLE_16BIT, I2S_CHANNEL_STEREO);
75
+ }
76
+
77
+ Serial.println("I2S initialized OK");
78
+}
79
+
80
+// ============ GENERATE AUDIO ============
81
+void generateSine(int16_t *buf, int len, float freq, float amplitude, uint32_t &phase_acc) {
82
+ float phase_step = freq / SAMPLE_RATE; // fractional phase increment per sample
83
+ for (int i = 0; i < len; i++) {
84
+ float phase = (phase_acc & 0xFFFF) / 65536.0f; // 0.0 ~ 1.0
85
+ int16_t sample = (int16_t)(amplitude * sinf(phase * 2.0f * M_PI));
86
+ // stereo: left = right
87
+ buf[i * 2 + 0] = sample; // left
88
+ buf[i * 2 + 1] = sample; // right
89
+ phase_acc = (uint32_t)(phase_acc + phase_step * 65536);
90
+ }
91
+}
92
+
93
+// ============ SETUP ============
94
+void setup() {
95
+ Serial.begin(115200);
96
+ delay(500);
97
+ Serial.println("\n--- I2S Audio Demo for ESP32-S3 ---");
98
+
99
+ setupI2S();
100
+}
101
+
102
+// ============ LOOP ============
103
+void loop() {
104
+ static uint32_t phase_acc = 0;
105
+ static float freq = 440.0f; // A4 note
106
+ static float amplitude = 16000; // 0 ~ 32767
107
+
108
+ generateSine(buf, BUF_LEN, freq, amplitude, phase_acc);
109
+
110
+ size_t bytes_written = 0;
111
+ esp_err_t err = i2s_write(I2S_PORT, buf, sizeof(buf), &bytes_written, portMAX_DELAY);
112
+ if (err != ESP_OK) {
113
+ Serial.printf("I2S write error: %d\n", err);
114
+ }
115
+
116
+ // Optional: cycle through notes every 2 seconds
117
+ static unsigned long last_note_change = 0;
118
+ if (millis() - last_note_change > 2000) {
119
+ last_note_change = millis();
120
+ static float notes[] = {262, 294, 330, 349, 392, 440, 494, 523}; // C4 ~ C5
121
+ static int note_idx = 0;
122
+ freq = notes[note_idx];
123
+ note_idx = (note_idx + 1) % 8;
124
+ Serial.printf("Playing: %.0f Hz\n", freq);
125
+ }
126
+}
Tech-dat/acturator-dat/speaker-dat/speaker-I2S-dat/speaker-I2S-dat.md
... ...
@@ -1,7 +1,6 @@
1
-
2 1
# speaker-I2S-dat
3 2
4
-- [[speaker-dat]] - [[speaker-I2S-dat]]
3
+- [[speaker-dat]] - [[speaker-I2S-dat]] - [[I2S-dat]]
5 4
6 5
- [[amplifier-dat]]
7 6
... ...
@@ -24,7 +23,7 @@ I2S DAC Decoder speaker
24 23
25 24
- [[UDA1334-dat]] - [[AMP1013-dat]] - [[NXP-dat]]
26 25
27
-- [[HT517-dat]]
26
+- [[HT517-dat]] - [[heroic-dat]] - [[speaker-I2S-dat]]
28 27
29 28
30 29
## Common Microphone, Speaker Wiring
... ...
@@ -62,4 +61,84 @@ I2S Circuit:
62 61
- ESP32-S2 has DAC on GPIO pins 17 and 18.
63 62
- Connect speaker(s) or headphones.
64 63
65
-- [[MAX98357-dat]]
... ...
\ No newline at end of file
0
+- [[MAX98357-dat]]
1
+
2
+
3
+## general test code
4
+
5
+- [[I2S-speaker-general-1.ino]]
6
+
7
+### I2S Demo Code for ESP32-S3 (I2S-speaker-general-1.ino)
8
+
9
+Simple I2S audio output demo for ESP32-S3 → I2S amplifier (MAX98357 / PCM5102 / etc.).
10
+
11
+#### Pinout (ESP32-S3 → I2S Amplifier)
12
+
13
+| Signal | GPIO | Amplifier Pin |
14
+| -------------------- | ------------------------- | ---------------- |
15
+| I2S_BCK (Bit Clock) | GPIO 4 | BCK / BCLK / SCK |
16
+| I2S_WS (Word Select) | GPIO 5 | WS / LRCK / FS |
17
+| I2S_DATA | GPIO 6 | DIN / DATA / SD |
18
+| I2S_MCLK (Optional) | GPIO 7 (or -1 to disable) | MCLK |
19
+
20
+#### Features
21
+
22
+| Parameter | Value |
23
+| ------------- | -------------------------------------------------------- |
24
+| Protocol | Standard Philips I2S |
25
+| Sample Rate | 44100 Hz |
26
+| Bit Depth | 16-bit |
27
+| Channels | Stereo (left = right) |
28
+| Audio Source | Sine wave generator (no external file needed) |
29
+| Note Sequence | C4 → D4 → E4 → F4 → G4 → A4 → B4 → C5, changing every 2s |
30
+
31
+#### Code Structure
32
+
33
+| Function | Description |
34
+| ---------------- | ------------------------------------------------------- |
35
+| `setupI2S()` | Initializes I2S driver with DMA, configures pins |
36
+| `generateSine()` | Fills buffer with sine wave samples at given frequency |
37
+| `setup()` | Serial init + I2S setup |
38
+| `loop()` | Generates audio and writes to I2S, cycles through notes |
39
+
40
+#### Configuration Macros
41
+
42
+| Macro | Default | Description |
43
+| ----------------- | ----------- | ---------------------------------- |
44
+| `SAMPLE_RATE` | 44100 | Audio sample rate in Hz |
45
+| `BITS_PER_SAMPLE` | 16 | Audio bit depth |
46
+| `I2S_PORT` | `I2S_NUM_0` | I2S controller number |
47
+| `I2S_BCK` | 4 | Bit Clock GPIO |
48
+| `I2S_WS` | 5 | Word Select GPIO |
49
+| `I2S_DATA` | 6 | Data out GPIO |
50
+| `I2S_MCLK` | -1 | Master Clock GPIO (-1 = disabled) |
51
+| `BUF_LEN` | 256 | Samples per channel per DMA buffer |
52
+
53
+#### Compatible Amplifiers
54
+
55
+- [[MAX98357-dat]] - no MCLK required
56
+- [[PCM5102-dat]]
57
+- [[NS4168-dat]]
58
+- [[UDA1334-dat]]
59
+- Any I2S DAC with standard Philips I2S input
60
+
61
+#### Usage
62
+
63
+1. Wire ESP32-S3 to amplifier per pinout table above
64
+2. Upload `I2S-speaker-general-1.ino` to ESP32-S3 (select board: ESP32S3 Dev Module)
65
+3. Open Serial Monitor at **115200 baud** to see note change logs
66
+4. Connect speaker to amplifier output — you should hear a repeating scale
67
+
68
+#### Customization
69
+
70
+- Change pins by editing `I2S_BCK`, `I2S_WS`, `I2S_DATA` macros
71
+- Enable MCLK by setting `I2S_MCLK` to a GPIO number (required by some DACs)
72
+- Adjust sample rate / bit depth via `SAMPLE_RATE` / `BITS_PER_SAMPLE`
73
+- Replace sine wave with WAV data by filling buffer directly
74
+
75
+
76
+
77
+
78
+
79
+
80
+## ref
... ...
\ No newline at end of file
Tech-dat/tech-dat.md
... ...
@@ -216,6 +216,8 @@
216 216
217 217
- [[codec-audio-dat]] - [[codec-dat]] - [[audio-dat]] - [[I2S-dat]] - [[arduino-audio-dat]] - [[media-dat]] - [[MP3-dat]]
218 218
219
+- [[I2S-dat]] - [[speaker-I2S-dat]] - [[sensor-microphone-I2S-dat]]
220
+
219 221
- [[filter-dat]]
220 222
221 223
- [[transmitter-current-dat]]