1. 项目概述与I2S/McASP核心价值
在嵌入式音频系统开发中,无论是智能音箱、车载娱乐系统还是专业音频设备,数字音频数据的可靠、高效传输都是基石。I2S(Inter-IC Sound)总线标准,正是为此而生的“行业通用语言”。它不像I2C或SPI那样需要复杂的协议开销,而是专为音频设计,通过分离的时钟(SCK)、数据(SD)和帧同步(WS/LRCLK)信号,实现了纯净、实时的音频流传输。其核心思想简单而优雅:一个时钟对应一个数据位,一个帧同步信号标志一个声道(左或右)数据的开始,从而将复杂的音频数据流简化为精准的时序关系。
然而,仅仅理解I2S的物理层时序是远远不够的。当我们需要处理多通道、高采样率、低延迟的音频应用时,如何高效地管理数据流、避免缓冲区上溢或下溢、精确控制时钟与帧同步,就成了摆在嵌入式工程师面前的现实挑战。这时,像德州仪器(TI)的McASP(Multi-channel Audio Serial Port)这类高度集成的音频串行端口控制器,其价值就凸显出来了。它不仅仅是一个I2S收发器,更是一个配备了深度FIFO、灵活数据格式化单元、独立收发控制以及强大DMA集成能力的音频协处理器。
理解McASP,关键在于吃透其寄存器配置。官方数据手册虽然详尽,但往往过于碎片化,缺乏从系统角度串联各个寄存器作用的实战视角。比如,RFIFOCTL(接收FIFO控制寄存器)和GBLCTL(全局控制寄存器)的配置顺序为何如此重要?RNUMEVT和RNUMDMA这两个数值该如何根据实际音频流计算?RFMT寄存器中那些看似神秘的位域(如RDATDLY,RRVRS)究竟如何影响最终听到的声音?这些问题,手册不会直接告诉你答案,需要结合音频系统的工作原理和实际调试经验来解答。
本文将从一个资深嵌入式音频开发者的视角,深入拆解McASP关键寄存器组的工作原理与配置逻辑。我不会仅仅罗列寄存器位域描述,而是会聚焦于**“为什么”要这样配置,以及配置不当会导致的“什么”**问题。我们将围绕数据流路径,从时钟初始化、格式配置、FIFO与DMA协同,到状态监控与错误处理,构建一套完整、可落地的McASP驱动配置框架。无论你是在调试音频播放时的“噼啪”杂音,还是在优化多通道采集时的CPU占用率,相信这些从实际项目中沉淀下来的细节与心得,都能为你提供直接的参考。
2. McASP整体架构与数据流解析
在深入每个寄存器之前,我们必须先建立起对McASP整体架构和数据流的宏观认知。你可以把McASP想象成一个功能强大的“音频交通枢纽”,它负责协调外部音频编解码器(Codec)与内部处理器(CPU/DMA)之间的所有数据往来。
2.1 核心功能模块划分
McASP的逻辑结构可以清晰地划分为以下几个关键部分,理解它们有助于我们后续定位配置问题:
时钟与帧同步生成模块:这是整个音频系统的“心跳”。它包含高频主时钟分频器(AHCLKX/R)和位时钟分频器(ACLKX/R),用于产生驱动数据传输的位时钟(BCLK)和主时钟(MCLK)。帧同步发生器则产生标志音频帧(通常是一对左右声道数据)开始的WS信号。
GBLCTL寄存器中的X(H)CLKRST和R(H)CLKRST位,就是控制这些时钟分频器是否运行的开关。串行器与数据格式化模块:这是数据的“翻译官”和“搬运工”。发送端,它将CPU/DMA写入的并行数据,按照
XFMT寄存器配置的格式(位序、对齐方式、时延)转换成串行比特流,通过AXR引脚发送出去。接收端则相反,它将从AXR引脚收到的串行比特流,按照RFMT寄存器的配置,转换成并行数据存入缓冲区。XSRCLR和RSRCLR位控制着串行器的复位与清零。FIFO与DMA接口模块:这是系统的“缓冲池”和“自动化物流系统”。以接收方向为例,数据从串行器转换后,首先进入接收FIFO。
RFIFOCTL寄存器控制着这个FIFO的使能(RENA)和深度管理策略(RNUMEVT,RNUMDMA)。当FIFO中的数据达到一定水位(RNUMEVT),便会触发一个DMA事件(AREVT),通知DMA控制器来批量搬运数据(RNUMDMA个字)到系统内存。这套机制极大地减轻了CPU的负担,并避免了因处理不及时导致的数据丢失(上溢)或重复(下溢)。状态机与控制逻辑:这是整个操作的“指挥中心”。发送和接收各有独立的状态机(由
XSMRST和RSMRST控制),它们严格按照帧同步和位时钟的节奏,指挥数据的移入移出。RSTAT和XSTAT寄存器则实时反映着这个指挥中心的运行状态,比如数据是否就绪(RDATA)、是否发生错误(ROVRN,RSYNCERR)。
2.2 数据流路径与寄存器映射
让我们追踪一个典型的音频接收流程,看看数据是如何流经上述模块,以及对应的寄存器在何处发挥作用:
步骤一:时钟启动与同步(GBLCTL,AHCLKXCTL,ACLKXCTL)系统上电后,首先需要配置时钟源和分频系数,产生正确的ACLK(位时钟)和AHCLK(主时钟)。关键一步:在向GBLCTL的RCLKRST和RHCLKRST位写1(释放时钟分频器复位)之前,必须确保相应的时钟源已经在运行。如果使用外部时钟,需确认其稳定;如果使用内部时钟源,则需要先配置AHCLKRCTL和ACLKRCTL寄存器。这是一个常见的坑点:时钟未启动就使能模块,会导致状态机“卡死”。
步骤二:FIFO与DMA参数预配置(RFIFOCTL)在使能接收FIFO(RENA=1)和释放接收状态机复位(RSMRST=1)之前,必须预先设置好RNUMEVT和RNUMDMA。这是手册中明确强调的硬性规定。RNUMDMA必须等于使能的接收串行器数量。例如,你配置了2个串行器用于立体声接收,那么RNUMDMA必须设为2。RNUMEVT则决定了FIFO的水位线,当FIFO中空闲空间大于等于RNUMEVT个字时,就触发DMA请求。它必须是RNUMDMA的整数倍,通常设置为RNUMDMA的2-4倍,以平衡响应速度和中断频率。
步骤三:数据格式与帧结构配置(RFMT,AFSRCTL,RTDM)接下来,告诉McASP如何解读到来的数据流。RFMT寄存器至关重要:
RSSZ:设置时隙大小,即每个声道数据的位数。对于16位音频,设为7h;24位音频,设为Bh。RDATDLY:设置数据相对于帧同步信号的延迟。对于I2S格式,通常设置为1(即2位延迟),因为I2S标准规定数据在帧同步边沿后的第二个时钟沿有效。RRVRS:设置位序。大多数情况下,I2S是MSB(最高位)先传,所以此位通常设为1。AFSRCTL寄存器用于配置帧同步信号本身,例如是内部生成(FSRM=1)还是外部输入(FSRM=0),以及极性(FSRP)。在I2S模式下,帧同步宽度(FRWID)通常为单字(1),模式(RMOD)设置为2(2-slot TDM)。RTDM寄存器是一个位图,用于在TDM多时隙流中,指定McASP在哪些时隙里是激活的(接收数据)。对于简单的立体声I2S,通常只需要使能时隙0和时隙1(对应左右声道)。
步骤四:使能与启动(GBLCTL/RGBLCTL)所有静态参数配置完毕后,按照严格的顺序使能模块:
- 确保时钟运行。
- 设置
RFIFOCTL中的RNUMEVT和RNUMDMA。 - 使能接收FIFO(
RFIFOCTL.RENA = 1)。 - 释放接收时钟分频器复位(
GBLCTL.RCLKRST = 1,RHCLKRST = 1)。 - 释放接收帧同步发生器复位(
GBLCTL.RFRST = 1)。 - 释放接收串行器复位(
GBLCTL.RSRCLR = 1)。 - 最后,释放接收状态机复位(
GBLCTL.RSMRST = 1)。状态机一旦释放,就会立即开始等待帧同步信号并准备接收数据。
步骤五:数据搬运与状态监控(RSTAT, 中断/DMA)状态机运行后,数据开始流入FIFO。当达到RNUMEVT条件,会触发DMA事件。同时,RSTAT寄存器中的RDATA位会被置起。如果使能了中断(通过RINTCTL),CPU也会收到通知。DMA或CPU随后从RBUF寄存器(实际上是FIFO的访问端口)读取数据。必须及时读取,否则下一个时隙的数据准备覆盖RBUF时,就会发生上溢错误(ROVRN位置1),导致音频数据丢失并可能产生刺耳的噪声。
核心经验:配置顺序就是生命线McASP的配置必须遵循一个基本原则:先静态,后动态;先下级,后上级。静态参数(如格式、FIFO深度)必须在模块使能前设定好。使能顺序通常是从“基础设施”(时钟)开始,到“数据通道”(串行器),最后是“控制核心”(状态机)。错误的顺序轻则导致功能异常,重则引起总线锁死。在调试任何McASP问题时,第一个检查点就应该是你的初始化序列是否与数据手册推荐的流程一致。
3. 关键寄存器深度解析与配置实战
理解了整体框架,我们现在可以深入几个最核心、也最容易出错的寄存器,看看它们的每一个比特位在实际工程中扮演什么角色。
3.1 RFIFOCTL:接收FIFO的流量控制阀
RFIFOCTL寄存器是协调低速系统内存访问与高速串行数据流的关键。配置不当是造成音频断断续续或杂音的常见元凶。
RENA (Bit 16): 接收FIFO使能位。这是一个硬开关。关键点:该位必须在McASP退出复位(即
RSMRST置1)之前被使能。如果你在数据已经开始传输后才尝试打开FIFO,行为是未定义的。通常的做法是在初始化序列的早期就设置好它。RNUMEVT (Bits 15-8): 每个DMA事件的读取字数。这个参数定义了FIFO的“告警水位线”。当FIFO中的空闲空间大于等于
RNUMEVT个字时,硬件就会产生一个接收DMA事件(AREVT)。如何计算?它必须是激活的接收串行器数量的整数倍。假设我们使用立体声(2个串行器),每个音频样本是32位(24位音频数据通常存放在32位字中)。那么,RNUMEVT可以设置为4、8、12等。设置得太小(如等于RNUMDMA),会导致DMA事件过于频繁,增加系统开销;设置得太大,则可能因DMA响应延迟导致FIFO被填满,引发上溢。一个经验值是RNUMDMA的2到4倍。RNUMDMA (Bits 7-0): 每次传输的读取字数。这是DMA控制器每次被触发时,从FIFO中搬走的数据量。黄金法则:
RNUMDMA必须严格等于激活的接收串行器数量。在上述立体声例子中,RNUMDMA必须设为2。如果设置错误,例如设为1,那么DMA每次只搬走一个声道的数据,另一个声道的数据会滞留在FIFO中,迅速导致上溢和混乱。
配置示例与验证: 假设一个48kHz采样率、24位、立体声的I2S输入流。我们使用DMA进行搬运。
- 激活的接收串行器数量 = 2 (左、右声道)。
- 设置
RNUMDMA = 2(每次DMA传输搬2个字,即一个完整的立体声样本对)。 - 设置
RNUMEVT = 4(DMA事件水位线为4个字,即两对立体声样本的空闲空间)。这意味着当FIFO有空间容纳至少4个新字时,就请求DMA来搬走2个字。 - 在初始化早期,先写入
RFIFOCTL = 0x00001004(RENA=1, RNUMEVT=0x10即16?不对,注意计算!0x10是十进制16,我们需要的是4)。实际上,对于值4,应写入RNUMEVT字段为0x04。因此,正确的32位值需要计算:RENA在bit16,值为1<<16 = 0x10000。RNUMEVT在bit8-15,值4对应4<<8 = 0x400。RNUMDMA在bit0-7,值2对应2。所以最终RFIFOCTL = 0x10000 | 0x400 | 0x2 = 0x10402。但手册显示复位值是1004h,即RNUMEVT=10h(16), RNUMDMA=4。我们需要覆盖它。所以应写入0x10402。 - 之后,再配置其他寄存器并最终释放状态机复位。
3.2 GBLCTL与它的别名寄存器:模块的复位与启动控制器
GBLCTL是一个全局控制寄存器,但它同时拥有两个别名寄存器:RGBLCTL(仅控制接收部分)和XGBLCTL(仅控制发送部分)。这种设计提供了极大的灵活性,允许你独立复位和启动发送与接收通道,这在半双工或调试场景下非常有用。
复位与使能序列的重要性:
GBLCTL中的位(如RCLKRST,RFRST,RSRCLR,RSMRST)不是简单的“功能开关”,而是严格的“状态机控制点”。以接收部分为例,标准的启动序列是:RCLKRST = 1(释放接收位时钟分频器复位)RFRST = 1(释放接收帧同步发生器复位)RSRCLR = 1(释放接收串行器清零,使其进入活动状态)RSMRST = 1(最后,释放接收状态机复位,开始工作) 这个顺序不能乱。特别是RSMRST,必须在其他部分都准备就绪后才能释放。
别名寄存器的妙用:假设你的系统只需要接收音频,而不需要发送。你可以只配置接收相关的时钟、格式寄存器,然后通过写入
RGBLCTL寄存器(例如,写入0x1F来一次性设置RFRST,RSMRST,RSRCLR,RHCLKRST,RCLKRST为1),来独立启动接收通道。而发送相关的位(XFRST等)由于在RGBLCTL中是只读的,不会被意外修改。这避免了操作GBLCTL时可能对发送端产生的干扰。同样,XGBLCTL用于独立控制发送端。读写回验证:手册特别强调,在对
GBLCTL(或它的别名)进行写操作后,必须进行读回验证,确认位已被正确锁存。这是因为这些控制位是与对应的音频时钟(ACLKX/R)同步的。在低速的系统总线时钟下写完后,需要等待几个音频时钟周期,位才能真正生效。通过读回检查,可以确保在执行下一步操作前,硬件已进入预期状态。这是一个非常重要的稳健性设计习惯。
3.3 RFMT:数据格式的翻译规则手册
RFMT寄存器定义了接收端如何解释串行比特流,任何错误都会导致数据完全错乱。
RSSZ (Bits 7-4): 时隙大小。这是最基础的设置,必须与音频编解码器发送的数据宽度严格匹配。常见值:
3h: 8位7h: 16位 (I2S常见)Bh: 24位 (高保真音频常见)Fh: 32位注意:这个设置的是“时隙”大小,即每个声道数据占用的位数。对于24位数据存放在32位字中的情况,时隙大小仍然是32位,但有效数据是24位,剩余位可能补零或进行其他处理(与RMASK寄存器配合)。
RDATDLY (Bits 17-16): 接收数据延迟。这决定了第一个数据位在帧同步信号出现后,第几个位时钟沿开始采样。I2S标准格式要求是2个位时钟的延迟(即
RDATDLY = 1)。左对齐格式通常是0延迟(RDATDLY = 0),右对齐格式则可能是1位延迟。配置错误的表现:音频能响,但声音完全失真、充满噪声,因为采样点完全错位。RRVRS (Bit 15): 位反转使能。设置为1时,硬件会自动将接收到的比特流顺序反转(MSB<->LSB)。大多数I2S设备是MSB先传,所以通常需要使能此位(
RRVRS=1)。如果发现音频数据的高低字节反了,可以检查此位。RPBIT 与 RMASK 寄存器:这对寄存器用于处理数据对齐和位填充。例如,当接收24位有效数据,但时隙大小设置为32位时,多出的8位如何处理?
RFMT.RPAD(图中未截全,但在完整RFMT寄存器中)字段可以设置填充方式(如补0、符号扩展等)。RPBIT则指定当使用特定填充模式时,用哪个源位来填充。RMASK寄存器是一个32位的掩码,位值为0的对应位置,数据在存入RBUF前会被屏蔽掉,并用RPBIT指定的策略填充。这在处理非标准位宽数据时非常有用。
配置示例(24位I2S): 假设接收24位I2S格式数据,MSB先传,2位数据延迟。
RSSZ = Bh(24位时隙)RDATDLY = 1(2位延迟,I2S标准)RRVRS = 1(MSB先传,使能位反转)- 假设我们将24位数据存放在32位字的低24位,高8位补零。那么可能需要配置
RPAD为0(补零),并且RMASK寄存器可以设置为0x00FFFFFF,这样高8位在读回时总是0。 - 最终,
RFMT寄存器的值可能需要设置为0x0001800B(这里是一个示意,需要根据实际寄存器位域偏移精确计算)。
3.4 AFSRCTL 与 RTDM:帧结构与时隙管理
AFSRCTL:这个寄存器控制帧同步信号。
FSRM:决定帧同步是内部生成(Master模式)还是外部输入(Slave模式)。作为接收方,如果音频源提供WS信号,则应设置为0(外部)。FSRP:帧同步极性。I2S标准中,帧同步信号在左声道时为低电平,右声道时为高电平,且数据在帧同步边沿变化后的第二个BCLK沿开始。通常,我们需要根据编解码器数据手册来设置此极性,以确保采样点对齐。设置错误会导致左右声道颠倒。FRWID:帧同步脉冲宽度。I2S模式下,通常是一个字长(即FRWID=1)。RMOD:接收帧模式。对于标准I2S(2时隙TDM),应设置为2h。
RTDM:在TDM模式下,一个帧同步周期内包含多个时隙(slot),
RTDM寄存器就是一个位图,用来指定McASP在哪些时隙里是“监听”状态。对于最简单的立体声I2S,只有时隙0和时隙1有效,所以通常设置RTDMS0=1且RTDMS1=1。在更复杂的多通道TDM系统中,例如8通道音频,你需要根据编解码器输出的时隙映射,来使能对应的RTDMSx位。一个坑:如果你使能了某个时隙,但DMA配置没有为这个时隙准备足够的数据缓冲区,就会导致DMA错误(RDMAERR)。
4. 中断、状态与错误处理机制
一个健壮的音频驱动,不仅要能正常工作,还要能及时发现和处理异常。McASP提供了一套细致的中断和状态标志机制。
4.1 RINTCTL:中断源的门卫
RINTCTL寄存器允许你精细地控制哪些事件可以触发接收中断(RINT)。在DMA主导数据传输的场景下,你可能不需要数据就绪(RDATA)中断,但错误中断至关重要。
ROVRNIE (ROVRN interrupt enable): 接收上溢中断使能。强烈建议使能。当CPU/DMA来不及读取数据,而新数据已经到来并准备覆盖缓冲区时,此标志置位。这是音频出现“爆音”、断断续续的最常见原因。使能中断后,可以在中断服务程序(ISR)中及时处理(如重置FIFO、记录错误计数)。
RSYNCERRIE: 非预期帧同步中断使能。当在预期之外的时间点检测到帧同步信号时,此标志置位。这通常意味着主从设备之间的时钟或帧同步失去了同步,可能是硬件连接问题或时钟配置错误。这也是一个需要使能的关键错误指示。
RSTAFRMIE, RLASTIE, RDATAIE: 这些是正常流程中断。
RSTAFRM标志一个新帧的开始,RLAST标志一个帧的最后一个时隙,RDATA标志有新数据就绪。在纯DMA模式,这些可以禁用以减少CPU中断开销。在轮询或中断驱动模式,RDATAIE是触发数据搬运的关键。
配置策略:对于高可靠性应用,我的习惯是使能所有错误中断(ROVRN,RSYNCERR,RDMAERR),而禁用流程中断,让DMA安静地工作。这样既不会错过错误,又最大限度地降低了中断延迟对音频流的影响。
4.2 RSTAT:系统的健康仪表盘
RSTAT寄存器是只读的状态集合。在调试时,读取这个寄存器是诊断问题的第一步。
ROVRN (Bit 0): 上溢标志。如果置位,立刻检查:1) DMA是否配置正确且正在运行?2) CPU负载是否过高导致DMA响应不及时?3)
RNUMEVT和RNUMDMA设置是否合理?4) 音频时钟频率是否过高,超过了系统总线的搬运能力?RSYNCERR (Bit 1): 同步错误。如果置位,检查:1) 帧同步信号(WS)的极性和模式(
AFSRCTL)设置是否正确?2) 主从设备的时钟(MCLK, BCLK)是否稳定且同源?3) 物理连接是否有干扰?RDATA (Bit 5): 数据就绪。在轮询模式下,程序需要不断查询此位,为1时读取
RBUF。在DMA模式下,此位仍会置位,并触发DMA事件(AREVT),但通常不需要软件干预。RERR (Bit 8): 这是一个“总错误”标志,它是
ROVRN | RSYNCERR | RCKFAIL | RDMAERR的逻辑或。在ISR中,可以先读RERR快速判断是否有错,然后再读具体错误位定位问题。
调试技巧:当出现音频问题时,编写一个简单的诊断函数,定期(或在错误中断中)打印RSTAT、RFIFOSTS.RLVL(FIFO当前水位)等关键寄存器的值。通过观察FIFO水位的变化,可以直观判断数据流是否平衡。如果水位持续增长直至上溢,说明消费端(DMA/CPU)太慢;如果水位经常为0,说明生产端(串行接收)可能有问题。
4.3 REVTCTL与DMA集成
REVTCTL寄存器通常只有一个有效位RDATDMA,用于控制接收数据就绪事件(RDATA)是否触发DMA请求。在绝大多数使用DMA的应用中,此位应保持为0(使能DMA请求)。这样,一旦RDATA置位,硬件就会自动向DMA控制器发出请求信号,启动一次RNUMDMA字的数据传输。
DMA的配置需要与McASP的寄存器设置紧密匹配:
- DMA源地址:固定为McASP的
RBUF寄存器地址。 - DMA传输宽度:必须与McASP的数据总线宽度一致(通常是32位)。
- DMA传输数量(Burst):应等于
RNUMDMA。每次DMA请求,就搬运这么多字。 - DMA目标地址:系统内存中的音频缓冲区。地址需要根据
RNUMDMA和音频通道数进行递增。 - DMA工作模式:通常配置为自动重载的Ping-Pong模式,以实现不间断的音频流。一个缓冲区正在被DMA写入时,另一个缓冲区可以被CPU处理(如音频算法处理、写入文件等)。
5. 完整配置流程示例与避坑指南
结合以上所有内容,我们可以勾勒出一个典型的McASP接收初始化序列(以从模式、24位I2S、立体声、使用DMA为例):
- 关闭模块,置于已知状态:向
GBLCTL写入0,将发送和接收的所有状态机、串行器、时钟分频器、帧同步发生器全部复位。 - 配置引脚复用:将所用AXR引脚配置为McASP功能,而非GPIO。
- 配置时钟源与分频器:根据所需的采样率(如48kHz)和位时钟频率,计算并设置
AHCLKRCTL和ACLKRCTL寄存器,选择时钟源和分频系数。注意:此时时钟分频器仍在复位状态(RCLKRST=0),不会输出时钟。 - 配置数据格式与帧结构:
- 设置
RFMT:RSSZ=Bh(24位),RDATDLY=1(I2S 2位延迟),RRVRS=1(MSB先传)。 - 设置
AFSRCTL:FSRM=0(外部帧同步),FSRP=1(根据编解码器规格定),FRWID=1(单字宽),RMOD=2(I2S模式)。 - 设置
RTDM:使能时隙0和时隙1(例如,写入0x3)。
- 设置
- 配置FIFO与DMA参数:
- 计算并设置
RFIFOCTL:RNUMDMA=2,RNUMEVT=4或8。先不要使能RENA。
- 计算并设置
- 配置中断(如果需要):设置
RINTCTL,使能ROVRN和RSYNCERR错误中断。 - 启动时钟:向
GBLCTL的RCLKRST和RHCLKRST位写1,释放时钟分频器复位。此时,如果使用内部时钟源,ACLK和AHCLK应该开始输出。可以用示波器验证。 - 使能FIFO:向
RFIFOCTL的RENA位写1,使能接收FIFO。 - 启动帧同步与串行器:向
GBLCTL的RFRST和RSRCLR位写1。 - 配置并启动DMA:根据
RNUMDMA等参数,配置DMA控制器的源、目标、传输量等。启动DMA。 - 最终启动状态机:向
GBLCTL的RSMRST位写1。此时,McASP接收端开始等待帧同步信号,一旦检测到,立即开始接收数据。
常见问题与排查清单:
问题:完全没有声音,或数据全为0。
- 检查:时钟是否有输出?用示波器测量ACLK和AFSR引脚。
- 检查:
RSMRST是否已置1?状态机是否已启动? - 检查:
RTDM寄存器是否使能了正确的时隙? - 检查:DMA是否配置正确并已启动?尝试改用CPU轮询
RDATA位并读取RBUF,看是否有数据。
问题:有声音但严重失真、全是噪声。
- 检查:
RFMT寄存器配置,特别是RSSZ(位宽)和RDATDLY(数据延迟)是否与发送端匹配。 - 检查:
AFSRCTL中的FSRP(帧同步极性)是否正确。 - 检查:
RRVRS(位序)是否正确。
- 检查:
问题:声音断断续续,伴有“噼啪”声。
- 检查:
RSTAT寄存器,是否发生了ROVRN(上溢)或RUNDRN(下溢,发送方向)? - 检查:
RFIFOCTL中的RNUMEVT和RNUMDMA设置是否合理?DMA响应是否足够快? - 检查:系统内存带宽是否足够?是否存在其他高优先级中断长时间关闭了全局中断,导致DMA响应延迟?
- 使用调试器或打印
RFIFOSTS.RLVL,观察FIFO水位是否在剧烈波动或持续满/空。
- 检查:
问题:左右声道相反。
- 检查:
AFSRCTL.FSRP极性。尝试翻转此位。 - 检查:
RTDM的时隙映射。在TDM模式下,可能需要调整使能的时隙顺序。
- 检查:
最后一点心得:McASP的寄存器配置就像一套精密的机械齿轮,每个齿轮都必须严丝合缝。最好的调试方法就是“分步验证,隔离问题”。先确保时钟和帧同步信号在物理层面是正确的,然后在不启动DMA的情况下,用CPU轮询的方式读取数据,验证数据格式是否正确。最后再引入DMA,并监控错误标志。手册是你的地图,但示波器和逻辑分析仪才是你在调试音频硬件时最可靠的眼睛。