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_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;
}

接下来是第7段代码:

    /* 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

由注释可知,这一段代码都是与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.mzph.cn/web/61810.shtml

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

相关文章

openEuler 22.03 使用cephadm安装部署ceph集群

目录 目的步骤规格步骤ceph部署前准备工作安装部署ceph集群ceph集群添加node与osdceph集群一些操作组件服务操作集群进程操作 目的 使用ceph官网的cephadm无法正常安装,会报错ERROR: Distro openeuler version 22.03 not supported 在openEuler上实现以cephadm安装部…

DevOps工程技术价值流:GitLab源码管理与提交流水线实践

在当今快速迭代的软件开发环境中,DevOps(开发运维一体化)已经成为提升软件交付效率和质量的关键。而GitLab,作为一个全面的开源DevOps平台,不仅提供了强大的版本控制功能,还集成了持续集成/持续交付(CI/CD)…

Spring 邮件发送

Spring 邮件发送 1. 主要内容(了解) 2. JavaMail 概述(了解) JavaMail,顾名思义,提供给开发者处理电⼦邮件相关的编程接⼝。JavaMail 是由 Sun 定义的⼀套收发电⼦邮件的 API,它可以⽅便地执⾏⼀…

VSCode如何关闭Vite项目本地自启动

某些情况下VSCode打开Vite项目不需要自动启动,那么如何关闭该功能 文件>首选项>设置 搜索vite 将Vite:Auto Start 勾选取消即可

一种多功能调试工具设计方案开源

一种多功能调试工具设计方案开源 设计初衷设计方案具体实现HUB芯片采用沁恒微CH339W。TF卡功能网口功能SPI功能IIC功能JTAG功能下行USB接口 安路FPGA烧录器功能Xilinx FPGA烧录器功能Jlink OB功能串口功能RS232串口RS485和RS422串口自适应接口 CAN功能烧录器功能 目前进度后续计…

Spark和MapReduce场景应用和区别

文章目录 Spark和MapReduce场景应用和区别一、引言二、MapReduce和Spark的应用场景1. MapReduce的应用场景2. Spark的应用场景 三、MapReduce和Spark的区别1. 内存使用和性能2. 编程模型和易用性3. 实时计算支持 四、使用示例1. MapReduce代码示例2. Spark代码示例 五、总结 Sp…

Python办公——openpyxl处理Excel每个sheet每行 修改为软雅黑9号剧中+边框线

目录 专栏导读背景1、库的介绍①:openpyxl 2、库的安装3、核心代码4、完整代码5、最快的方法(50万行44秒)——表头其余单元格都修改样式总结 专栏导读 🌸 欢迎来到Python办公自动化专栏—Python处理办公问题,解放您的双手 🏳️‍…

【C#】书籍信息的添加、修改、查询、删除

文章目录 一、简介二、程序功能2.1 Book类属性:方法: 2.2 Program 类 三、方法:四、用户界面流程:五、程序代码六、运行效果 一、简介 简单的C#控制台应用程序,用于管理书籍信息。这个程序将允许用户添加、编辑、查看…

01-树莓派基本配置-基础配置配置

树莓派基本配置 文章目录 树莓派基本配置前言硬件准备树莓派刷机串口方式登录树莓派接入网络ssh方式登录树莓派更换国内源xrdp界面登录树莓派远程文件传输FileZilla 前言 树莓派是一款功能强大且价格实惠的小型计算机,非常适合作为学习编程、物联网项目、家庭自动化…

无人机探测:光电侦测技术详解

一、基本原理 光电识别技术是无人机追踪设备的核心,其原理主要基于光电转换和信号处理技术。光电识别设备通过光学系统收集目标的光学信息,如可见光、红外光等,并将其转换为电信号。这些电信号随后被处理和分析,以实现对目标的识…

106.【C语言】数据结构之二叉树的三种递归遍历方式

目录 1.知识回顾 2.分析二叉树的三种遍历方式 1.总览 2.前序遍历 3.中序遍历 4.后序遍历 5.层序遍历 3.代码实现 1.准备工作 2.前序遍历函数PreOrder 测试结果 3.中序遍历函数InOrder 测试结果 4.后序遍历函数PostOrder 测试结果 4.底层分析 1.知识回顾 在99.…

go并发设计模式runner模式

go并发设计模式runner模式 真正运行的程序不可能是单线程运行的,go语言中最值得骄傲的就是CSP模型了,可以说go语言是CSP模型的实现。 假设现在有一个程序需要实现,这个程序有以下要求: 程序可以在分配的时间内完成工作&#xff0…

03-13、SpringCloud Alibaba第十三章,升级篇,服务降级、熔断和限流Sentinel

SpringCloud Alibaba第十三章,升级篇,服务降级、熔断和限流Sentinel 一、Sentinel概述 1、Sentinel是什么 随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保…

【服务器问题】xshell 登录远程服务器卡住( 而 vscode 直接登录不上)

打开 xshell ssh 登录远程服务器:卡在下面这里,迟迟不继续 当 SSH 连接卡在 Connection established. 之后,但没有显示远程终端提示符时,这通常意味着连接已经成功建立,说明不是网络连接和服务器连接问题,…

图片预处理技术介绍4——降噪

图片预处理 大家好,我是阿赵。   这一篇将两种基础的降噪算法。   之前介绍过均值模糊和高斯模糊。如果从降噪的角度来说,模糊算法也算是降噪的一类,所以之前介绍的两种模糊可以称呼为均值降噪和高斯降噪。不过模糊算法对原来的图像特征的…

Linux 网络编程之TCP套接字

前言 上一期我们对UDP套接字进行了介绍并实现了简单的UDP网络程序,本期我们来介绍TCP套接字,以及实现简单的TCP网络程序! 🎉目录 前言 1、TCP 套接字API详解 1.1 socket 1.2 bind 1.3 listen 1.4 accept 1.5 connect 2、…

AI/ML 基础知识与常用术语全解析

目录 一.引言 二.AI/ML 基础知识 1.人工智能(Artificial Intelligence,AI) (1).定义 (2).发展历程 (3).应用领域 2.机器学习(Machine Learning,ML) (1).定义 (2).学习方式 ①.监督学习 ②.无监督…

计算机网络常见面试题总结(上)

计算机网络基础 网络分层模型 OSI 七层模型是什么?每一层的作用是什么? OSI 七层模型 是国际标准化组织提出的一个网络分层模型,其大体结构以及每一层提供的功能如下图所示: 每一层都专注做一件事情,并且每一层都需…

蓝桥杯准备训练(lesson1,c++方向)

前言 报名参加了蓝桥杯(c)方向的宝子们,今天我将与大家一起努力参赛,后序会与大家分享我的学习情况,我将从最基础的内容开始学习,带大家打好基础,在每节课后都会有练习题,刚开始的练…

Unity类银河战士恶魔城学习总结(P156 Audio Settings音频设置)

【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili 教程源地址:https://www.udemy.com/course/2d-rpg-alexdev/ 本章节实现了音频的大小设置与保存加载 音频管理器 UI_VolumeSlider.cs 定义了 UI_VolumeSlider 类,用于处理与音频设置相关的…