接前一篇文章:ESP32-S3模组上跑通ES8388(10)
二、利用ESP-ADF操作ES8388
2. 详细解析
上一回解析了es8388_init函数中的第4段代码,本回继续往下解析。为了便于理解和回顾,再次贴出es8388_init函数源码,在components\audio_hal\driver\es8388\es8388.c中,如下:
/*** @return* - (-1) Error* - (0) Success*/
esp_err_t es8388_init(audio_hal_codec_config_t *cfg)
{int res = 0;
#ifdef CONFIG_ESP_LYRAT_V4_3_BOARDheadphone_detect_init(get_headphone_detect_gpio());
#endifres = i2c_init(); // ESP32 in master moderes |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL3, 0x04); // 0x04 mute/0x00 unmute&ramp;DAC unmute and disabled digital volume control soft ramp/* Chip Control and Power Management */res |= es_write_reg(ES8388_ADDR, ES8388_CONTROL2, 0x50);res |= es_write_reg(ES8388_ADDR, ES8388_CHIPPOWER, 0x00); //normal all and power up all// Disable the internal DLL to improve 8K sample rateres |= es_write_reg(ES8388_ADDR, 0x35, 0xA0);res |= es_write_reg(ES8388_ADDR, 0x37, 0xD0);res |= es_write_reg(ES8388_ADDR, 0x39, 0xD0);res |= es_write_reg(ES8388_ADDR, ES8388_MASTERMODE, cfg->i2s_iface.mode); //CODEC IN I2S SLAVE MODE/* dac */res |= es_write_reg(ES8388_ADDR, ES8388_DACPOWER, 0xC0); //disable DAC and disable Lout/Rout/1/2res |= es_write_reg(ES8388_ADDR, ES8388_CONTROL1, 0x12); //Enfr=0,Play&Record Mode,(0x17-both of mic&paly)
// res |= es_write_reg(ES8388_ADDR, ES8388_CONTROL2, 0); //LPVrefBuf=0,Pdn_ana=0res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL1, 0x18);//1a 0x18:16bit iis , 0x00:24res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL2, 0x02); //DACFsMode,SINGLE SPEED; DACFsRatio,256res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL16, 0x00); // 0x00 audio on LIN1&RIN1, 0x09 LIN2&RIN2res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL17, 0x90); // only left DAC to left mixer enable 0dbres |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL20, 0x90); // only right DAC to right mixer enable 0dbres |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL21, 0x80); // set internal ADC and DAC use the same LRCK clock, ADC LRCK as internal LRCKres |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL23, 0x00); // vroi=0res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL24, 0x1E); // Set L1 R1 L2 R2 volume. 0x00: -30dB, 0x1E: 0dB, 0x21: 3dBres |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL25, 0x1E);res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL26, 0);res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL27, 0);// res |= es8388_set_adc_dac_volume(ES_MODULE_DAC, 0, 0); // 0dbint tmp = 0;if (AUDIO_HAL_DAC_OUTPUT_LINE2 == cfg->dac_output) {tmp = DAC_OUTPUT_LOUT1 | DAC_OUTPUT_ROUT1;} else if (AUDIO_HAL_DAC_OUTPUT_LINE1 == cfg->dac_output) {tmp = DAC_OUTPUT_LOUT2 | DAC_OUTPUT_ROUT2;} else {tmp = DAC_OUTPUT_LOUT1 | DAC_OUTPUT_LOUT2 | DAC_OUTPUT_ROUT1 | DAC_OUTPUT_ROUT2;}res |= es_write_reg(ES8388_ADDR, ES8388_DACPOWER, tmp); //0x3c Enable DAC and Enable Lout/Rout/1/2/* adc */res |= es_write_reg(ES8388_ADDR, ES8388_ADCPOWER, 0xFF);res |= es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL1, 0xbb); // MIC Left and Right channel PGA gaintmp = 0;if (AUDIO_HAL_ADC_INPUT_LINE1 == cfg->adc_input) {tmp = ADC_INPUT_LINPUT1_RINPUT1;} else if (AUDIO_HAL_ADC_INPUT_LINE2 == cfg->adc_input) {tmp = ADC_INPUT_LINPUT2_RINPUT2;} else {tmp = ADC_INPUT_DIFFERENCE;}res |= es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL2, tmp); //0x00 LINSEL & RINSEL, LIN1/RIN1 as ADC Input; DSSEL,use one DS Reg11; DSR, LINPUT1-RINPUT1res |= es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL3, 0x02);res |= es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL4, 0x0c); // 16 Bits length and I2S serial audio data formatres |= es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL5, 0x02); //ADCFsMode,singel SPEED,RATIO=256//ALC for Microphoneres |= es8388_set_adc_dac_volume(ES_MODULE_ADC, 0, 0); // 0dbres |= es_write_reg(ES8388_ADDR, ES8388_ADCPOWER, 0x09); // Power on ADC, enable LIN&RIN, power off MICBIAS, and set int1lp to low power mode/* es8388 PA gpio_config */gpio_config_t io_conf;memset(&io_conf, 0, sizeof(io_conf));io_conf.mode = GPIO_MODE_OUTPUT;io_conf.pin_bit_mask = BIT64(get_pa_enable_gpio());io_conf.pull_down_en = 0;io_conf.pull_up_en = 0;gpio_config(&io_conf);/* enable es8388 PA */es8388_pa_power(true);codec_dac_volume_config_t vol_cfg = ES8388_DAC_VOL_CFG_DEFAULT();dac_vol_handle = audio_codec_volume_init(&vol_cfg);ESP_LOGI(ES_TAG, "init,out:%02x, in:%02x", cfg->dac_output, cfg->adc_input);return res;
}
接下来是第5段代码:
// Disable the internal DLL to improve 8K sample rateres |= es_write_reg(ES8388_ADDR, 0x35, 0xA0);res |= es_write_reg(ES8388_ADDR, 0x37, 0xD0);res |= es_write_reg(ES8388_ADDR, 0x39, 0xD0);
0x35、0x37、0x39寄存器
这3个寄存器手册中并未给出,手册中最多就是到Reg 52,而0x35正好是Reg53,0x37(Reg 55)、0x39(Reg 57)就更没有了。
这是怎么回事?难道乐鑫的官方代码给错了?
笔者为此特意咨询过乐鑫的技术支持,他们(音频组的项目经理)给出的答复是:“看着是为了修复些啥,而这些顺芯手册里没有写,应该是工程师和顺芯对的结果。直接参考着用吧”。同时给出了内部历史提交记录:
笔者又专门问了顺芯(Everest Semiconductor)的人,他们给出的答复是这样:“这个是内部的pll设置不对外开放。就按照他设置的写就行,不需要调整”。
既然没有寄存器的具体说明,那么只能根据代码注释来理解了,这三行代码是禁止ES8388内部PLL以提高8K采样率。
至此,es8388_init函数中的第5段代码就解析完了,下一回继续解析该函数后续内容。