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

news2024/12/4 16:41:52

接前一篇文章: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.coloradmin.cn/o/2253146.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Mac】安装Gradle

1、说明 Gradle 运行依赖 JVM,需要先安装JDK,Gradle 与 JDK的版本对应参见:Java Compatibility IDEA的版本也是有要求Gradle版本的,二者版本对应关系参见:Third-Party Software and Licenses 本次 Gradle 安装版本为…

根据YAML文件创建Conda环境

YAML(全称为YAML Ain’t Markup Language)是一种轻量级的标记语言。在Python中,YAML文件包含conda环境名和依赖,如图所示。 根据yaml文件创建Conda环境 1.切换路径 找到miniAnaconda或Anaconda,打开Anaconda Powersh…

【分组去重】.NET开源 ORM 框架 SqlSugar 系列

💥 .NET开源 ORM 框架 SqlSugar 系列 🎉🎉🎉 【开篇】.NET开源 ORM 框架 SqlSugar 系列【入门必看】.NET开源 ORM 框架 SqlSugar 系列【实体配置】.NET开源 ORM 框架 SqlSugar 系列【Db First】.NET开源 ORM 框架 SqlSugar 系列…

故障诊断 | Transformer-LSTM组合模型的故障诊断(Matlab)

效果一览 文章概述 故障诊断 | Transformer-LSTM组合模型的故障诊断(Matlab) 源码设计 %% 初始化 clear close all clc disp(此程序务必用2023b及其以上版本的MATLAB!否则会报错!) warning off %

亚马逊云(AWS)使用root用户登录

最近在AWS新开了服务器(EC2),用于学习,遇到一个问题就是默认是用ec2-user用户登录,也需要密钥对。 既然是学习用的服务器,还是想直接用root登录,下面开始修改: 操作系统是&#xff1…

Android笔记【12】脚手架Scaffold和导航Navigation

一、前言 学习课程时,对于自己不懂的点的记录。 对于cy老师第二节课总结。 二、内容 1、PPT介绍scaffold 2、开始代码实操 先新建一个screen包,写一个Homescreen函数,包括四个页面。 再新建一个compenent包,写一个displayText…

HookVip4.0.3 | 可解锁各大应用会员

HookVip是一款可以解锁会员的模块工具,需要搭配相应框架结合使用。这款插件工具支持多种框架如LSPosed、LSPatch、太极、应用转生等,并且完全免费,占用内存小。支持的软件包括now要想、神奇脑波、塔罗牌占卜、爱剪辑、人人视频、咪萌桌面宠物…

猎板 PCB特殊工艺:铸就电子行业核心竞争力新高度

在当今竞争激烈且技术驱动的电子制造领域,印制电路板(PCB)作为电子产品的关键基石,其特殊工艺的发展水平直接影响着整个行业的创新步伐与产品品质。猎板 PCB 凭借在厚铜板、孔口铺铜、HDI 板、大尺寸板以及高频高速板等特殊工艺方…

【教学类-43-25】20241203 数独3宫格的所有可能-使用模版替换(12套样式,空1格-空8格,每套510张,共6120小图)

前期做数独惨宫格的所有排列,共有12套样式,空1格-空8格,每套510张,共6120小图) 【教学类-43-24】20241127 数独3宫格的所有可能(12套样式,空1格-空8格,每套510张,共6120…

Redis+Caffeine 多级缓存数据一致性解决方案

RedisCaffeine 多级缓存数据一致性解决方案 背景 之前写过一篇文章RedisCaffeine 实现两级缓存实战,文章提到了两级缓存RedisCaffeine可以解决缓存雪等问题也可以提高接口的性能,但是可能会出现缓存一致性问题。如果数据频繁的变更,可能会导…

echarts地图立体效果,echarts地图点击事件,echarts地图自定义自定义tooltip

一.地图立体效果 方法1:两层地图叠加 实现原理:geo数组中放入两个地图对象,通过修改zlevel属性以及top,left,right,bottom形成视觉差 配置项参考如下代码: geo: [{zlevel: 2,top: 96,map: map,itemStyle: {color: #091A51ee,opacity: 1,borderWidth: 2,borderColor: #16BAFA…

D87【python 接口自动化学习】- pytest基础用法

day87 pytest运行参数 -m -k 学习日期:20241203 学习目标:pytest基础用法 -- pytest运行参数-m -k 学习笔记: 常用运行参数 pytest运行参数-m -k pytest -m 执行特定的测试用例,markers最好使用英文 [pytest] testpaths./te…

总结拓展十七:特殊采购业务——委外业务

SAP中委外采购业务,又称供应商分包(或外协、转包、、外包、托外等),是企业将部分生产任务委托给外部供应商/集团其他分子公司完成的一种特殊采购业务模式。 委外业务主要有2大类型,分别是标准委外(委外采购…

ESP8266作为TCP客户端或者服务器使用

ESP8266模块,STA模式(与手机搭建TCP通讯,EPS8266为服务端)_esp8266作为station-CSDN博客 ESP8266模块,STA模式(与电脑搭建TCP通讯,ESP8266 为客户端)_esp8266 sta 连接tcp-CSDN博客…

ATTCK红队评估实战靶场(四)

靶机链接:http://vulnstack.qiyuanxuetang.net/vuln/detail/6/ 环境搭建 新建两张仅主机网卡,一张192.168.183.0网段(内网网卡),一张192.168.157.0网段(模拟外网网段),然后按照拓补…

C 语言 “神秘魔杖”—— 指针初相识,解锁编程魔法大门(一)

文章目录 一、概念1、取地址操作符(&)2、解引用操作符(*)3、指针变量1、 声明和初始化2、 用途 二、内存和地址三、指针变量类型的意义1、 指针变量类型的基本含义2、 举例说明不同类型指针变量的意义 四、const修饰指针1、co…

封装loding加载动画的请求

图片 /*** Loading 状态管理类*/ export class Loading {constructor(timer300) {this.value falsethis.timer timer}/*** 执行异步操作并自动管理 loading 状态* param {Promise|Function|any} target - Promise、函数或其他值* returns {Promise} - 返回请求结果*/async r…

人形机器人训练、机器臂远程操控、VR游戏交互、影视动画制作,一副手套全部解决!

广州虚拟动力基于自研技术推出了多节点mHand Pro动捕数据手套,其最大的特点就是功能集成与高精度捕捉,可以用于人形机器人训练、机器臂远程操控、VR游戏交互、影视动画制作等多种场景。 一、人形机器人训练 mHand Pro动捕数据手套双手共装配16个9轴惯性…

Nginx Web服务器管理、均衡负载、访问控制与跨域问题

Nginx Web 服务器的均衡负载、访问控制与跨域问题 Nginx 的配置 1. 安装Nginx 首先安装Nginx apt install nginx -ycaccpurgatory-v:~$ sudo apt install nginx [sudo] password for cacc: Reading package lists... Done Building dependency tree... Done Reading state i…

Bert+CRF的NER实战

CRF(条件随机场-Conditional Random Field) 原始本文:我在北京吃炸酱面 标注示例(采用BIO标注方式): 我O在O北B-PLA京I-PLA吃O炸B-FOOD酱I-FOOD面I-FOOD CRF: 目的:提出一些不可能…