ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

全志T527音频子系统BSP调试实战:从I2S到Codec的完整链路

全志T527音频子系统BSP调试实战:从I2S到Codec的完整链路 音频子系统在BSP调试里属于那种看起来简单、调起来要命的模块。全志T527这颗SoC的音频通路比很多人想象的复杂——它内部集成了多个I2S/PCM控制器、一个独立的Audio Codec、SPDIF收发器还有DMIC接口信号从SoC内部一路走到外部Codec芯片中间要经过I2S总线、I2C控制总线、时钟树、电源域、PinMux配置任何一个环节出问题你看到的症状可能都是没声音三个字。这篇内容适合正在做T527 BSP bring-up的嵌入式工程师也适合刚接触全志平台音频调试的同行参考。我会把整个调试链路拆开从硬件信号链到驱动配置到用户态验证把每个环节容易踩的坑讲清楚。1. T527音频子系统的硬件拓扑与信号链路1.1 SoC内部音频控制器分布T527的音频子系统不是单一模块而是一组控制器的集合。根据全志T527的datasheet和BSP源码中的设备树描述主要包含以下几类I2S/PCM控制器T527有多个I2S接口通常标注为I2S0、I2S1、I2S2等每个控制器支持标准的I2S、左对齐、右对齐、DSP模式等多种时序格式。这些控制器负责数字音频数据的串行传输是SoC与外部Codec之间的数据通道。Audio Codec内部T527内部集成了一个Audio Codec支持耳机输出、线路输入等模拟接口。如果你的板子用的是内部Codec那就不需要外挂Codec芯片直接配置内部Codec的通路即可。SPDIF支持Sony/Philips Digital Interface格式的数字音频输入输出用于连接外部数字音频设备。DMIC数字麦克风接口直接接收PDM格式的数字麦克风信号不需要外部ADC。在实际项目中最常见的配置是SoC通过I2S总线连接一颗外部Codec芯片比如ES8323、AC107、WM8960等同时可能用内部Codec做耳机输出。具体用哪条通路取决于你的原理图设计。1.2 I2S总线的四线制与时钟关系I2S总线在硬件上至少需要四根信号线信号线全称方向作用BCLKBit ClockSoC→Codec主模式位时钟每个bit一个脉冲LRCLKLeft/Right ClockSoC→Codec主模式帧时钟区分左右声道DINData InCodec→SoC从Codec到SoC的录音数据DOUTData OutSoC→Codec从SoC到Codec的播放数据如果SoC工作在I2S主模式绝大多数情况BCLK和LRCLK由SoC产生Codec作为从设备跟随。BCLK的频率 采样率 × 位宽 × 声道数。比如48kHz采样率、16bit位宽、立体声BCLK 48000 × 16 × 2 1.536MHz。LRCLK的频率就等于采样率48kHz。这里有个容易搞混的点MCLK主时钟不是I2S标准四线的一部分但很多Codec需要一路独立的MCLK作为内部PLL的参考时钟。MCLK的频率通常是采样率的256倍或384倍即48kHz采样率对应12.288MHz或18.432MHz。如果你的Codec不出声先确认MCLK有没有输出、频率对不对。1.3 外部Codec的I2C控制通道外部Codec芯片除了I2S数据接口还需要I2C来控制内部寄存器——设置音量、选择输入输出通路、配置时钟模式等。I2C地址由Codec芯片的ADDR引脚决定常见的有0x10、0x18、0x1A等。调试时第一件事就是用i2cdetect确认Codec在I2C总线上能被识别到。注意有些Codec的I2C地址是7位格式Linux的i2cdetect显示的是7位地址。如果你在设备树里写的地址和i2cdetect显示的不一致先确认是7位还是8位格式。2. 设备树配置从PinMux到Sound Card注册2.1 PinMux配置的常见遗漏T527的引脚复用非常灵活同一个物理引脚可以配置成GPIO、I2S、SPDIF、DMIC等不同功能。在设备树中你需要为I2S信号线配置正确的function和pin group。以I2S1为例典型的pinctrl配置长这样pio { i2s1_pins_a: i2s10 { pins PB4, PB5, PB6, PB7; function i2s1; drive-strength 20; bias-disable; }; i2s1_pins_b: i2s11 { pins PB4, PB5, PB6, PB7; function i2s1; drive-strength 20; bias-disable; }; };这里i2s1_pins_a和i2s1_pins_b分别对应I2S的两种状态比如播放和录音时的不同引脚方向配置。很多人在设备树里只配了一组pins结果播放正常但录音不行或者反过来。原因是I2S的DIN和DOUT方向不同有些SoC的pinctrl驱动需要根据数据方向切换pin的输入输出属性。另一个常见问题是drive-strength设置。I2S的BCLK和LRCLK频率较高如果drive-strength太小比如默认的10mA信号边沿可能不够陡峭导致Codec端采样出错表现为有杂音或断断续续。实测中20mA到30mA是比较稳妥的范围。2.2 dai-link与sound card的绑定逻辑Linux ASoC框架中音频通路由machine driver把CPU DAI和Codec DAI绑定成一个sound card。设备树里的simple-audio-card或者全志自己的sunxi-soundcard节点就是做这件事的。一个典型的配置sound: sound { compatible simple-audio-card; simple-audio-card,name t527-audio; simple-audio-card,format i2s; simple-audio-card,bitclock-master dailink0_master; simple-audio-card,frame-master dailink0_master; simple-audio-card,cpu { sound-dai i2s1; }; simple-audio-card,codec { sound-dai es8323; system-clock-frequency 12288000; }; };关键字段解释bitclock-master和frame-master指定谁产生BCLK和LRCLK。如果SoC做主就指向cpu节点如果Codec做主少见就指向codec节点。system-clock-frequencyCodec的MCLK频率。这个值必须和实际硬件上MCLK的时钟源频率一致否则Codec内部PLL锁不住表现为完全没声音或采样率错误。formatI2S时序格式必须和Codec datasheet中配置的格式一致。常见的有i2s、right_j、left_j、dsp_a、dsp_b。我遇到过一种情况设备树里format写的i2s但Codec寄存器默认是左对齐模式结果播放出来的声音音调不对像是快放或慢放。后来把Codec的寄存器0x08改成I2S模式才正常。这种问题不会报错只能靠听感判断。2.3 时钟树的配置要点T527的音频时钟来自PLL_AUDIO经过分频后分配给各个I2S控制器和Codec。在设备树中你需要确保I2S控制器的时钟源正确使能。MCLK的输出频率与Codec要求匹配。采样率切换时时钟能正确重新计算分频比。全志的CCUClock Control Unit驱动通常会自动处理这些但如果你发现切换采样率后声音异常可以检查/sys/kernel/debug/clk/clk_summary中相关时钟的频率是否正确。3. 驱动层的调试手段与常见故障定位3.1 用aplay/arecord做基础验证驱动加载成功后第一件事是用aplay -l和arecord -l确认声卡是否注册成功。正常输出应该能看到类似card 0: t527audio [t527-audio], device 0: I2S1 es8323-0 [] Subdevices: 1/1 Subdevice #0: subdevice #0如果看不到声卡说明machine driver没有probe成功。这时候用dmesg | grep -i audio或dmesg | grep -i asoc查看内核日志通常会有no codec found、failed to get mclk之类的错误提示。播放测试aplay -D hw:0,0 -f S16_LE -r 48000 -c 2 test.wav录音测试arecord -D hw:0,0 -f S16_LE -r 48000 -c 2 -d 5 record.wav如果aplay报Device or resource busy检查是不是有别的进程占用了声卡比如PulseAudio或PipeWire。在嵌入式系统里通常没有这些但如果你跑的是完整发行版可能需要先停掉音频服务。3.2 用amixer检查通路和音量Codec的很多问题其实是通路没打开或音量被静音了。用amixer -c 0 controls列出所有控件然后用amixer -c 0 sset Playback 80% unmute之类的命令逐个检查。以ES8323为例关键的控件包括Playback播放音量Capture录音音量Left Output Mixer/Right Output Mixer输出混音器开关Output 1 Playback Switch/Output 2 Playback Switch输出通道使能我踩过的一个坑Codec的某个输出通道默认是关闭的amixer里显示为[off]但aplay不报任何错误就是没声音。后来把Output 2 Playback Switch打开才正常。这种问题在第一次调试新板子时特别常见。3.3 用示波器/逻辑分析仪抓I2S波形如果软件层面都正常但就是没声音下一步就是抓波形。用示波器或逻辑分析仪接BCLK、LRCLK、DOUT三根线播放一个单频测试音比如1kHz正弦波观察BCLK是否有输出频率是否等于采样率×位宽×2LRCLK频率是否等于采样率DOUT上是否有数据翻转如果BCLK和LRCLK正常但DOUT没数据说明SoC的I2S控制器没有正确发送数据可能是DMA配置问题或控制器没使能。如果三根线都没信号检查PinMux和时钟使能。提示抓波形时建议用持续播放的测试音频而不是短促的提示音否则触发不好设置。4. 典型故障场景与排查路径4.1 场景一声卡注册失败dmesg报no codec这是最常见的入门级问题。排查路径确认I2C通信正常i2cdetect -y bus看Codec地址是否出现。如果没出现检查I2C的SDA/SCL上拉电阻、电源、地址引脚配置。确认设备树中Codec节点正确compatible字符串必须和驱动中的of_match_table一致。比如ES8323的compatible是everest,es8323写错了驱动就匹配不上。确认Codec驱动已编译进内核zcat /proc/config.gz | grep ES8323或检查.config文件。确认dai-link的sound-dai指向正确cpu节点指向I2S控制器codec节点指向Codec设备。4.2 场景二声卡注册成功但播放无声排查路径amixer检查通路逐个确认输出通道开关和音量。检查MCLK用示波器测Codec的MCLK引脚确认频率正确。检查I2S格式匹配设备树format与Codec寄存器配置是否一致。检查DAPM路由有些Codec的DAPM widget需要正确的路径才能把数据从I2S传到DAC。用cat /sys/kernel/debug/asoc/card/dapm查看当前激活的路径。4.3 场景三播放有杂音或断断续续这类问题通常和时钟或DMA有关BCLK频率偏差如果SoC的PLL分频算出来的BCLK和标称值有偏差Codec可能偶尔采样错误。检查时钟树配置。DMA buffer underrun如果系统负载高DMA来不及填充数据会听到咔咔声。可以增大period size或buffer size。电源噪声Codec的模拟电源如果纹波大会有底噪。检查LDO或DC-DC的滤波电容。4.4 场景四录音无声或录音有回声录音通路的调试和播放类似但方向相反确认DIN引脚PinMux配置为输入。确认Codec的ADC通路和录音增益。确认I2S控制器的capture DMA通道使能。回声问题通常是LRCLK或BCLK相位不对尝试调整I2S的时钟相位配置。5. 几个容易被忽略的细节5.1 电源域与上电时序T527的音频模块有独立的电源域。如果Codec的供电AVDD、DVDD上电时序不对可能导致I2C能通信但I2S不出声。检查原理图中Codec的电源是否受某个GPIO控制设备树里有没有对应的regulator节点。5.2 GPIO复位引脚很多Codec有一个RESET引脚低电平复位。如果这个引脚在设备树里没有正确配置为输出并拉高Codec会一直处于复位状态I2C也通信不了。检查原理图确认RESET引脚连接然后在设备树里加一个gpio-hog或者regulator-fixed来拉高它。5.3 采样率切换时的pop音播放开始和停止时的啪声通常是Codec的DAC在使能/关闭瞬间产生的。解决方法是在驱动里加一个短暂的静音延迟或者配置Codec的soft-ramp功能。ES8323有内置的pop suppression需要在寄存器里使能。5.4 多声卡场景下的默认声卡设置如果系统里有多个声卡比如HDMI音频模拟音频aplay默认可能选错。可以用/etc/asound.conf指定默认设备或者在aplay命令里明确指定-D hw:0,0。6. 调试工具链与实用命令汇总工具/命令用途备注aplay -l列出播放设备确认声卡注册arecord -l列出录音设备确认capture设备amixer -c 0 controls列出所有控件检查通路和音量i2cdetect -y 1扫描I2C设备确认Codec在线dmesggrep asoc查看ASoC日志cat /sys/kernel/debug/asoc/*/dapm查看DAPM路径确认数据通路cat /sys/kernel/debug/clk/clk_summary查看时钟频率确认MCLK/BCLKspeaker-test -D hw:0,0 -c 2 -t sine播放测试音快速验证这些命令我在T527的板子上反复用过基本覆盖了从驱动加载到用户态验证的完整链路。实际调试中问题往往不是单一原因而是多个环节叠加——比如PinMux配错导致I2S没信号同时amixer里通路又是关的。所以排查时要有耐心一个环节一个环节确认不要跳步。最后分享一个个人习惯每次调试新板子的音频我会先准备一个已知能用的WAV文件48kHz/16bit/立体声然后用aplay直接播放。如果没声音先查amixer再查dmesg最后才动示波器。这个顺序能解决80%的问题剩下20%才需要深入硬件层面。
返回列表