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

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

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

 

二、利用ESP-ADF操作ES8388

2. 详细解析

上一回解析到es8388_init函数中的第3段代码,本回继续。为了便于理解和回顾,再次贴出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;
}

当前仍然在第3段代码:

    res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL3, 0x04);  // 0x04 mute/0x00 unmute&ramp;DAC unmute and  disabled digital volume control soft ramp

上一回解析了es_write_reg函数,也可以说是扫清了与ES8388寄存器设置无关的代码,从此开始就专注于ES8388各个寄存器的设置了。

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

/* ES8388 address */
#define ES8388_ADDR 0x20  /*!< 0x22:CE=1;0x20:CE=0*/

ES8388的I2C地址为:0b0010000x。其中,x根据引脚AD0的状态而定。见ES8388数据手册中的以下部分:

ab1c739db207407695abec0e43e05749.png

747b181fe9c2413e9264203a3c29a5af.png

有人可能会问了,不是AD0引脚么,怎么圈出来的是CE引脚?这要参见手册中的以下内容:

162d61089d0d4b439c374899570e4a2b.png

这也就和上边ES8388_ADDR宏定义的注释一致了。

/* ES8388 address */
#define ES8388_ADDR 0x20  /*!< 0x22:CE=1;0x20:CE=0*/

接下来回到主线代码中:

​
    res |= es_write_reg(ES8388_ADDR, ES8388_DACCONTROL3, 0x04);  // 0x04 mute/0x00 unmute&ramp;DAC unmute and  disabled digital volume control soft ramp

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

#define ES8388_DACCONTROL3      0x19

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

4a6ee0ac837a4bd79e41c1eab990027b.png

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

  • DACRampRate(bit 7:6)

0b00:0.5 dB per 4 LRCK digital volume control ramp rate (default)。每4个LRCK,数字音量控制斜坡率0.5 dB(默认)。

  • DACSoftRamp(bit 5)。

0:disabled digital volume control soft ramp。禁用数字音量控制软斜面。

  • DACLeR(bit 3)

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

  • DACMute(bit 2)

1:mute analog outputs for both channels。将两个通道的模拟输出静音。

 

至此,es8388_init函数中的第3段代码就解析完了,下一回继续解析该函数后续内容。

 


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

相关文章:

  • 深度学习中的生成对抗网络(GAN)原理与应用
  • Matlab 绘制雷达图像完全案例和官方教程(亲测)
  • 如何使用Spring Boot进行Web开发?
  • Springboot——SseEmitter流式输出
  • 爬取boss直聘上海市人工智能招聘信息+LDA主题建模
  • Linux系统编程——进程替换
  • 完全二叉树的应用--堆
  • RocketMQ负载均衡机制解析
  • spring boot整合ArtemisMQ进行手动消息确认
  • 了解哈希并用线性探测和链地址法解决哈希冲突
  • Asio2网络库
  • 微信小程序首页实现轮廓图及动态渲染的高级教程
  • USBasp给arduino nano烧写bootloader
  • 使用lumerical脚本语言创建定向耦合器并进行数据分析(纯代码实现)
  • 【c++篇】:探索哈希表--数据结构中的独特存在,打开数据组织与查找的新视界
  • 深入解析 Kubernetes 节点操作:Cordon、Uncordon 和 Drain 的使用与最佳实践
  • Leecode刷题C语言之N皇后
  • 若依框架保姆级入门使用
  • IREE AI编译器关键模块分析
  • TypeScript核心语法(3)——类型系统
  • vue3中是如何实现双向数据绑定的
  • 实测数据处理(BP算法处理)——SAR成像算法系列(十)
  • Rsa加解密 + 签名验签
  • 鸿蒙面试 --- 性能优化
  • 【梦幻工厂的探索】亚马逊——基础设施的打造者
  • 游戏引擎学习第29天