当前位置: 首页 > article >正文

ESP32-S3模组上跑通ES8388(13)

接前一篇文章:ESP32-S3模组上跑通ES8388(12)

 

二、利用ESP-ADF操作ES8388

2. 详细解析

上一回解析了es8388_init函数中的第6段代码,本回继续往下解析。为了便于理解和回顾,再次贴出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_BOARD
    headphone_detect_init(get_headphone_detect_gpio());
#endif
 
    res = i2c_init(); // ESP32 in master mode
 
    res |= 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 rate
    res |= 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/2
    res |= 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=0
    res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL1, 0x18);//1a 0x18:16bit iis , 0x00:24
    res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL2, 0x02);  //DACFsMode,SINGLE SPEED; DACFsRatio,256
    res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL16, 0x00); // 0x00 audio on LIN1&RIN1,  0x09 LIN2&RIN2
    res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL17, 0x90); // only left DAC to left mixer enable 0db
    res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL20, 0x90); // only right DAC to right mixer enable 0db
    res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL21, 0x80); // set internal ADC and DAC use the same LRCK clock, ADC LRCK as internal LRCK
    res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL23, 0x00); // vroi=0
 
    res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL24, 0x1E); // Set L1 R1 L2 R2 volume. 0x00: -30dB, 0x1E: 0dB, 0x21: 3dB
    res |= 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);       // 0db
    int 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 gain
    tmp = 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-RINPUT1
    res |= 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 format
    res |= es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL5, 0x02);  //ADCFsMode,singel SPEED,RATIO=256
    //ALC for Microphone
    res |= es8388_set_adc_dac_volume(ES_MODULE_ADC, 0, 0);      // 0db
    res |= 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;
}

接下来是第7段代码:

    /* dac */
    res |= es_write_reg(ES8388_ADDR, ES8388_DACPOWER, 0xC0);  //disable DAC and disable Lout/Rout/1/2
    res |= 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=0
    res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL1, 0x18);//1a 0x18:16bit iis , 0x00:24
    res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL2, 0x02);  //DACFsMode,SINGLE SPEED; DACFsRatio,256
    res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL16, 0x00); // 0x00 audio on LIN1&RIN1,  0x09 LIN2&RIN2
    res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL17, 0x90); // only left DAC to left mixer enable 0db
    res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL20, 0x90); // only right DAC to right mixer enable 0db
    res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL21, 0x80); // set internal ADC and DAC use the same LRCK clock, ADC LRCK as internal LRCK
    res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL23, 0x00); // vroi=0
 
    res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL24, 0x1E); // Set L1 R1 L2 R2 volume. 0x00: -30dB, 0x1E: 0dB, 0x21: 3dB
    res |= 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);       // 0db
    int 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

由注释可知,这一段代码都是与ES8388的DAC相关的。这一段也比较长,即使是代码片段,也得分段(大部分是一行一行)来看。

1)ES8388_DACPOWER

    res |= es_write_reg(ES8388_ADDR, ES8388_DACPOWER, 0xC0);  //disable DAC and disable Lout/Rout/1/2

ES8388_DACPOWER宏也在components\audio_hal\driver\es8388\es8388.h中定义,如下:

#define ES8388_DACPOWER         0x04

其代表了ES8388的DAC Power Management寄存器。参见ES8388数据手册中的以下部分:

f63f40e3b2ec458d8a098d0c1fafe531.png

代码中将该寄存器的值设置为了0xC0,也就是0b11000000,意义如下:

  • PdnDACL(bit 7)

1:left DAC power down (default)。左通道DAC断电(默认)。

  • PdnDACR(bit 6)

1:right DAC power down (default)。右通道DAC断电(默认)。

  • LOUT1(bit 5)

0:LOUT1 disabled (default)。LOUT1禁用(默认)。

  • ROUT1(bit 4)

0:ROUT1 disabled (default)。ROUT1禁用(默认)。

  • LOUT2(bit 3)

0:LOUT2 disabled (default)。LOUT2禁用(默认)。

  • ROUT2(bit 2)

0:ROUT2 disabled (default)。ROUT2禁用(默认)。

这一行代码的作用正如注释所讲:禁用DAC和LOUT1、ROUT1、LOUT2、ROUT2。

1723fb32f89542b887542ef5a8a50553.png

2)ES8388_CONTROL1

    res |= es_write_reg(ES8388_ADDR, ES8388_CONTROL1, 0x12);  //Enfr=0,Play&Record Mode,(0x17-both of mic&paly)

ES8388_CONTROL1宏也在components\audio_hal\driver\es8388\es8388.h中定义,如下:

#define ES8388_CONTROL1         0x00

其代表了ES8388的Chip Control 1寄存器。参见ES8388数据手册中的以下部分:

b699a546874d42eaa6f7180eec688151.png

代码中将该寄存器的值设置为了0x12,也就是0b00010010,意义如下:

  • SCPReset(bit 7)

0:normal (default)。正常(默认)。

  • LRCM(bit 6)

0:ALRCK disabled when both ADC disabled; DLRCK disabled when both DAC disabled (default)。当两个ADC都禁用时,ALRCK禁用;当两个DAC都禁用时,DLRCK禁用(默认)。

  • DACMCLK(bit 5)

0:when SameFs=1, ADCMCLK is the chip master clock source (default)。当SameFs=1时,ADCMCLK是芯片主时钟源(默认)。

  • SameFs(bit 4)

1:ADC Fs is the same as DAC Fs。ADC的采样频率与DAC的采样频率相同。

  • SeqEn(bit 3)

0:internal power up/down sequence disable (default)。内部加电/断电顺序禁用(默认)。

  • EnRef(bit 2)

0:disable reference。reference(参考)禁用。

  • VMIDSEL(bit 1:0)

0b10:500 kΩ divider enabled (default)。启用500 kΩ divider(默认)。

 

下一回继续解析es8388_init函数第7段代码的后续内容。

 


http://www.kler.cn/a/421528.html

相关文章:

  • 机器学习概述,特征工程简述2.1——2.3
  • 快充协议IC支持全协议,内部集成LDO支持输出电压3.3V,支持宽电压范围3.3~30V
  • FolderMove 3.0 |文件夹安全转移,释放C盘空间
  • WPF+LibVLC开发播放器-LibVLC在C#中的使用
  • 深度学习常用训练命令解释
  • Github提交Pull Request教程 Git基础扫盲(零基础易懂)
  • Scala的模式匹配(6)
  • 【C++】LeetCode:LCR 026. 重排链表
  • Android 使用OpenGLES + MediaPlayer 获取视频截图
  • 华为服务器使用U盘重装系统
  • JavaScript(一)
  • 【开发语言】层次状态机(HSM)介绍
  • 【学习Go编程】
  • 数据结构有哪些?
  • Redis+Caffeine 多级缓存数据一致性解决方案
  • 杂七杂八的网络安全知识
  • 【iOS】设计模式的六大原则
  • qt QGraphicsRotation详解
  • 分层架构 IM 系统之 Router 架构分析
  • Elastic Cloud Serverless:深入探讨大规模自动扩展和性能压力测试
  • 重学设计模式-工厂模式(简单工厂模式,工厂方法模式,抽象工厂模式)
  • 数据结构—队列
  • 顶刊算法 | 鱼鹰算法OOA-BiTCN-BiGRU-Attention多输入单输出回归预测(Maltab)
  • Zabbix添加防火墙温度监控值实战
  • Macos用brew安装Nodejs亲手教程
  • LLM与动态符号执行生成测试用例的比较