1 #include <string.h>
2 #include "esp_log.h"
3 #include "driver/gpio.h"
4 #include "es8388.h"
5
6 #define ES8388_TAG "ES8388"
7
8 #define ES_ASSERT(a, format, b, ...) \
9 if ((a) != 0) { \
10 ESP_LOGE(ES8388_TAG, format, ##__VA_ARGS__); \
11 return b;\
12 }
13
14 #define LOG_8388(fmt, ...) ESP_LOGW(ES8388_TAG, fmt, ##__VA_ARGS__)
15
es_write_reg(uint8_t slave_addr,uint8_t reg_addr,uint8_t data)16 static int es_write_reg(uint8_t slave_addr, uint8_t reg_addr, uint8_t data)
17 {
18 int res = 0;
19 i2c_cmd_handle_t cmd = i2c_cmd_link_create();
20 res |= i2c_master_start(cmd);
21 res |= i2c_master_write_byte(cmd, slave_addr, 1 /*ACK_CHECK_EN*/);
22 res |= i2c_master_write_byte(cmd, reg_addr, 1 /*ACK_CHECK_EN*/);
23 res |= i2c_master_write_byte(cmd, data, 1 /*ACK_CHECK_EN*/);
24 res |= i2c_master_stop(cmd);
25 res |= i2c_master_cmd_begin(0, cmd, 1000 / portTICK_PERIOD_MS);
26 i2c_cmd_link_delete(cmd);
27 ES_ASSERT(res, "es8388_write_reg error", -1);
28 return res;
29 }
30
es8388_read_reg(uint8_t reg_addr,uint8_t * pdata)31 static int es8388_read_reg(uint8_t reg_addr, uint8_t *pdata)
32 {
33 uint8_t data;
34 int res = 0;
35 i2c_cmd_handle_t cmd = i2c_cmd_link_create();
36
37 res |= i2c_master_start(cmd);
38 res |= i2c_master_write_byte(cmd, ES8388_ADDR, 1 /*ACK_CHECK_EN*/);
39 res |= i2c_master_write_byte(cmd, reg_addr, 1 /*ACK_CHECK_EN*/);
40 res |= i2c_master_stop(cmd);
41 res |= i2c_master_cmd_begin(0, cmd, 1000 / portTICK_PERIOD_MS);
42 i2c_cmd_link_delete(cmd);
43
44 cmd = i2c_cmd_link_create();
45 res |= i2c_master_start(cmd);
46 res |= i2c_master_write_byte(cmd, ES8388_ADDR | 0x01, 1 /*ACK_CHECK_EN*/);
47 res |= i2c_master_read_byte(cmd, &data, 0x01/*NACK_VAL*/);
48 res |= i2c_master_stop(cmd);
49 res |= i2c_master_cmd_begin(0, cmd, 1000 / portTICK_PERIOD_MS);
50 i2c_cmd_link_delete(cmd);
51
52 ES_ASSERT(res, "es8388_read_reg error", -1);
53 *pdata = data;
54 return res;
55 }
56
57
i2c_init(i2c_config_t * conf,int port)58 static int i2c_init(i2c_config_t *conf, int port)
59 {
60 int res;
61
62 res = i2c_param_config(port, conf);
63 res |= i2c_driver_install(port, conf->mode, 0, 0, 0);
64 ES_ASSERT(res, "I2cInit error", -1);
65 return res;
66 }
67
68
es8388_read_all_regs()69 void es8388_read_all_regs()
70 {
71 for (int i = 0; i < 50; i++) {
72 uint8_t reg = 0;
73 es8388_read_reg(i, ®);
74 printf("%x: %x\n", i, reg);
75 }
76 }
77
es8388_write_reg(uint8_t regAdd,uint8_t data)78 int es8388_write_reg(uint8_t regAdd, uint8_t data)
79 {
80 return es_write_reg(ES8388_ADDR, regAdd, data);
81 }
82
83
es8388_set_adc_dac_volume(int mode,int volume,int dot)84 static int es8388_set_adc_dac_volume(int mode, int volume, int dot)
85 {
86 int res = 0;
87 if ( volume < -96 || volume > 0 ) {
88 LOG_8388("Warning: volume < -96! or > 0!\n");
89 if (volume < -96)
90 volume = -96;
91 else
92 volume = 0;
93 }
94 dot = (dot >= 5 ? 1 : 0);
95 volume = (-volume << 1) + dot;
96 if (mode == ES_MODULE_ADC || mode == ES_MODULE_ADC_DAC) {
97 res |= es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL8, volume);
98 res |= es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL9, volume); //ADC Right Volume=0db
99 }
100 if (mode == ES_MODULE_DAC || mode == ES_MODULE_ADC_DAC) {
101 res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL5, volume);
102 res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL4, volume);
103 }
104 return res;
105 }
106
es8388_start(es_codec_module_t mode)107 int es8388_start(es_codec_module_t mode)
108 {
109 int res = 0;
110 uint8_t prev_data = 0, data = 0;
111 es8388_read_reg(ES8388_DACCONTROL21, &prev_data);
112 if (mode == ES_MODULE_LINE) {
113 res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL16, 0x09); // 0x00 audio on LIN1&RIN1, 0x09 LIN2&RIN2 by pass enable
114 res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL17, 0x50); // left DAC to left mixer enable and LIN signal to left mixer enable 0db : bupass enable
115 res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL20, 0x50); // right DAC to right mixer enable and LIN signal to right mixer enable 0db : bupass enable
116 res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL21, 0xC0); //enable adc
117 } else {
118 res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL21, 0x80); //enable dac
119 }
120 es8388_read_reg(ES8388_DACCONTROL21, &data);
121 if (prev_data != data) {
122 res |= es_write_reg(ES8388_ADDR, ES8388_CHIPPOWER, 0xF0); //start state machine
123 // res |= es8388_write_reg(ES8388_ADDR, ES8388_CONTROL1, 0x16);
124 // res |= es8388_write_reg(ES8388_ADDR, ES8388_CONTROL2, 0x50);
125 res |= es_write_reg(ES8388_ADDR, ES8388_CHIPPOWER, 0x00); //start state machine
126 }
127 if (mode == ES_MODULE_ADC || mode == ES_MODULE_ADC_DAC || mode == ES_MODULE_LINE)
128 res |= es_write_reg(ES8388_ADDR, ES8388_ADCPOWER, 0x00); //power up adc and line in
129 //res |= es8388_set_adc_dac_volume(ES_MODULE_ADC, 0, 0); // 0db
130 if (mode == ES_MODULE_DAC || mode == ES_MODULE_ADC_DAC || mode == ES_MODULE_LINE) {
131 res |= es_write_reg(ES8388_ADDR, ES8388_DACPOWER, 0x3c); //power up dac and line out
132 res |= es8388_set_mute(false);
133 //res |= es8388_set_adc_dac_volume(ES_MODULE_DAC, 0, 0); // 0db
134 }
135
136 return res;
137 }
138
es8388_stop(es_codec_module_t mode)139 int es8388_stop(es_codec_module_t mode)
140 {
141 int res = 0;
142 if (mode == ES_MODULE_LINE) {
143 res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL21, 0x80); //enable dac
144 res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL16, 0x00); // 0x00 audio on LIN1&RIN1, 0x09 LIN2&RIN2
145 res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL17, 0x90); // only left DAC to left mixer enable 0db
146 res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL20, 0x90); // only right DAC to right mixer enable 0db
147 return res;
148 }
149 if (mode == ES_MODULE_DAC || mode == ES_MODULE_ADC_DAC) {
150 res |= es_write_reg(ES8388_ADDR, ES8388_DACPOWER, 0x00);
151 res |= es8388_set_mute(true);
152 //res |= es8388_set_adc_dac_volume(ES_MODULE_DAC, -96, 5); // 0db
153 //res |= es8388_write_reg(ES8388_ADDR, ES8388_DACPOWER, 0xC0); //power down dac and line out
154 }
155 if (mode == ES_MODULE_ADC || mode == ES_MODULE_ADC_DAC) {
156 //res |= es8388_set_adc_dac_volume(ES_MODULE_ADC, -96, 5); // 0db
157 res |= es_write_reg(ES8388_ADDR, ES8388_ADCPOWER, 0xFF); //power down adc and line in
158 }
159 if (mode == ES_MODULE_ADC_DAC) {
160 res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL21, 0x9C); //disable mclk
161 // res |= es8388_write_reg(ES8388_ADDR, ES8388_CONTROL1, 0x00);
162 // res |= es8388_write_reg(ES8388_ADDR, ES8388_CONTROL2, 0x58);
163 // res |= es8388_write_reg(ES8388_ADDR, ES8388_CHIPPOWER, 0xF3); //stop state machine
164 }
165
166 return res;
167 }
168
169
es8388_i2s_config_clock(es_codec_i2s_clock_t cfg)170 int es8388_i2s_config_clock(es_codec_i2s_clock_t cfg)
171 {
172 int res = 0;
173
174 res |= es_write_reg(ES8388_ADDR, ES8388_MASTERMODE, cfg.sclk_div);
175 res |= es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL5, cfg.lclk_div); //ADCFsMode,singel SPEED,RATIO=256
176 res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL2, cfg.lclk_div); //ADCFsMode,singel SPEED,RATIO=256
177
178 return res;
179 }
180
es8388_uninit()181 void es8388_uninit()
182 {
183 es_write_reg(ES8388_ADDR, ES8388_CHIPPOWER, 0xFF); //reset and stop es8388
184 // i2c_driver_delete(cfg->i2c_port_num);
185 }
186
es8388_init(es8388_config_t * cfg)187 int es8388_init(es8388_config_t *cfg)
188 {
189 int res = 0;
190 res = i2c_init(&cfg->i2c_cfg, cfg->i2c_port_num); // ESP32 in master mode
191 res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL3, 0x04); // 0x04 mute/0x00 unmute&ramp;DAC unmute and disabled digital volume control soft ramp
192 /* Chip Control and Power Management */
193 res |= es_write_reg(ES8388_ADDR, ES8388_CONTROL2, 0x50);
194 res |= es_write_reg(ES8388_ADDR, ES8388_CHIPPOWER, 0x00); //normal all and power up all
195 res |= es_write_reg(ES8388_ADDR, ES8388_MASTERMODE, cfg->es_mode); //CODEC IN I2S SLAVE MODE
196
197 /* dac */
198 res |= es_write_reg(ES8388_ADDR, ES8388_DACPOWER, 0xC0); //disable DAC and disable Lout/Rout/1/2
199 res |= es_write_reg(ES8388_ADDR, ES8388_CONTROL1, 0x12); //Enfr=0,Play&Record Mode,(0x17-both of mic&paly)
200 // res |= es8388_write_reg(ES8388_ADDR, ES8388_CONTROL2, 0); //LPVrefBuf=0,Pdn_ana=0
201 res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL1, 0x18);//1a 0x18:16bit iis , 0x00:24
202 res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL2, 0x02); //DACFsMode,SINGLE SPEED; DACFsRatio,256
203 res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL16, 0x00); // 0x00 audio on LIN1&RIN1, 0x09 LIN2&RIN2
204 res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL17, 0x90); // only left DAC to left mixer enable 0db
205 res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL20, 0x90); // only right DAC to right mixer enable 0db
206 res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL21, 0x80); //set internal ADC and DAC use the same LRCK clock, ADC LRCK as internal LRCK
207 res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL23, 0x00); //vroi=0
208 res |= es8388_set_adc_dac_volume(ES_MODULE_DAC, 0, 0); // 0db
209 res |= es_write_reg(ES8388_ADDR, ES8388_DACPOWER, cfg->dac_output); //0x3c Enable DAC and Enable Lout/Rout/1/2
210 /* adc */
211 res |= es_write_reg(ES8388_ADDR, ES8388_ADCPOWER, 0xFF);
212 res |= es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL1, 0x88); //0x88 MIC PGA =24DB
213 res |= es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL2, cfg->adc_input); //0x00 LINSEL & RINSEL, LIN1/RIN1 as ADC Input; DSSEL,use one DS Reg11; DSR, LINPUT1-RINPUT1
214 res |= es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL3, 0x02);
215 res |= es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL4, 0x0c); //0d 0x0c I2S-16BIT, LEFT ADC DATA = LIN1 , RIGHT ADC DATA =RIN1
216 res |= es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL5, 0x02); //ADCFsMode,singel SPEED,RATIO=256
217 //ALC for Microphone
218 res |= es8388_set_adc_dac_volume(ES_MODULE_ADC, 0, 0); // 0db
219 res |= es_write_reg(ES8388_ADDR, ES8388_ADCPOWER, 0x09); //Power up ADC, Enable LIN&RIN, Power down MICBIAS, set int1lp to low power mode
220
221 es8388_pa_power(true);
222 ESP_LOGD(ES8388_TAG, "init, out:%02x, in:%02x -> %d", cfg->dac_output, cfg->adc_input, res);
223 return res;
224 }
225
es8388_config_fmt(es_codec_module_t mode,es_codec_i2s_fmt_t fmt)226 int es8388_config_fmt(es_codec_module_t mode, es_codec_i2s_fmt_t fmt)
227 {
228 int res = 0;
229 uint8_t reg = 0;
230 if (mode == ES_MODULE_ADC || mode == ES_MODULE_ADC_DAC) {
231 res = es8388_read_reg(ES8388_ADCCONTROL4, ®);
232 reg = reg & 0xfc;
233 res |= es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL4, reg | fmt);
234 }
235 if (mode == ES_MODULE_DAC || mode == ES_MODULE_ADC_DAC) {
236 res = es8388_read_reg(ES8388_DACCONTROL1, ®);
237 reg = reg & 0xf9;
238 res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL1, reg | (fmt << 1));
239 }
240 return res;
241 }
242
es8388_set_volume(int volume)243 int es8388_set_volume(int volume)
244 {
245 int res;
246 if (volume < 0)
247 volume = 0;
248 else if (volume > 100)
249 volume = 100;
250 volume /= 3;
251 res = es_write_reg(ES8388_ADDR, ES8388_DACCONTROL24, volume);
252 res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL25, volume); //ADC Right Volume=0db
253 res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL26, 0);
254 res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL27, 0);
255 return res;
256 }
257
es8388_get_volume(int * volume)258 int es8388_get_volume(int *volume)
259 {
260 int res;
261 uint8_t reg = 0;
262 res = es8388_read_reg(ES8388_DACCONTROL24, ®);
263 if (res == ESP_FAIL) {
264 *volume = 0;
265 } else {
266 *volume = reg;
267 *volume *= 3;
268 if (*volume == 99)
269 *volume = 100;
270 }
271 return res;
272 }
273
es8388_set_bits_per_sample(es_codec_module_t mode,es_codec_bits_len_t bitPerSample)274 int es8388_set_bits_per_sample(es_codec_module_t mode, es_codec_bits_len_t bitPerSample)
275 {
276 int res = 0;
277 uint8_t reg = 0;
278 int bits = (int)bitPerSample;
279
280 if (mode == ES_MODULE_ADC || mode == ES_MODULE_ADC_DAC) {
281 res = es8388_read_reg(ES8388_ADCCONTROL4, ®);
282 reg = reg & 0xe3;
283 res |= es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL4, reg | (bits << 2));
284 }
285 if (mode == ES_MODULE_DAC || mode == ES_MODULE_ADC_DAC) {
286 res = es8388_read_reg(ES8388_DACCONTROL1, ®);
287 reg = reg & 0xc7;
288 res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL1, reg | (bits << 3));
289 }
290 return res;
291 }
292
es8388_set_mute(int enable)293 int es8388_set_mute(int enable)
294 {
295 int res;
296 uint8_t reg = 0;
297 res = es8388_read_reg(ES8388_DACCONTROL3, ®);
298 reg = reg & 0xFB;
299 res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL3, reg | (((int)enable) << 2));
300 return res;
301 }
302
es8388_get_mute(int * mute)303 int es8388_get_mute(int *mute)
304 {
305 int res = -1;
306 uint8_t reg = 0;
307 res = es8388_read_reg(ES8388_DACCONTROL3, ®);
308 if (res == ESP_OK) {
309 reg = (reg & 0x04) >> 2;
310 }
311 *mute = reg;
312 return res;
313 }
314
es8388_set_dac_ouput(es_codec_dac_output_t output)315 int es8388_set_dac_ouput(es_codec_dac_output_t output)
316 {
317 int res;
318 uint8_t reg = 0;
319 res = es8388_read_reg(ES8388_DACPOWER, ®);
320 reg = reg & 0xc3;
321 res |= es_write_reg(ES8388_ADDR, ES8388_DACPOWER, reg | output);
322 return res;
323 }
324
es8388_set_adc_input(es_codec_adc_input_t input)325 int es8388_set_adc_input(es_codec_adc_input_t input)
326 {
327 int res;
328 uint8_t reg = 0;
329 res = es8388_read_reg(ES8388_ADCCONTROL2, ®);
330 reg = reg & 0x0f;
331 res |= es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL2, reg | input);
332 return res;
333 }
334
es8388_set_mic_gain(es_codec_mic_gain_t gain)335 int es8388_set_mic_gain(es_codec_mic_gain_t gain)
336 {
337 if (gain == MIC_GAIN_MIN){
338 gain = MIC_GAIN_0DB;
339 }
340 if (gain == MIC_GAIN_MAX){
341 gain = MIC_GAIN_24DB;
342 }
343 int res, gain_n;
344 gain_n = (int)gain / 3;
345 res = es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL1, (gain_n << 4) | gain_n); //MIC PGA
346 return res;
347 }
348
es8388_pa_power(bool enable)349 void es8388_pa_power(bool enable)
350 {
351 gpio_config_t io_conf;
352 memset(&io_conf, 0, sizeof(io_conf));
353 // v4.4 - io_conf.intr_type = GPIO_PIN_INTR_DISABLE == 0
354 // v5 - io_conf.intr_type = GPIO_INTR_DISABLE == 0
355 io_conf.mode = GPIO_MODE_OUTPUT;
356 io_conf.pin_bit_mask = 1UL << GPIO_NUM_21;
357 io_conf.pull_down_en = 0;
358 io_conf.pull_up_en = 0;
359 gpio_config(&io_conf);
360 if (enable) {
361 gpio_set_level(GPIO_NUM_21, 1);
362 } else {
363 gpio_set_level(GPIO_NUM_21, 0);
364 }
365 }
366