九鼎创展论坛中文版English
登录 | 立即注册 设为首页收藏本站 切换到宽版
查看: 10895|回复: 7
打印 上一主题 下一主题

音频芯片WM8976基于Windows CE6.0的驱动调试笔记[原创]

[复制链接]
跳转到指定楼层
楼主
发表于 2012-2-21 10:11:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
音频芯片WM8976基于Windows CE6.0的驱动调试笔记
--------基于X210开发板
   2011107
有一年多没有写过代码了,最近因朋友要求,移植X210-S5PV210开发板中音频驱动.这款开发板选用的CODEC芯片是wolfson WM8976.因以前在三星的S3C2450.S3C6410上都移过这款芯片的驱动.本以为可以很快移完.想不到是的花了我整个5天国庆假期.由于以前没有记笔记的习惯,现在记性也不好了.所以今天特记录下来.写音频驱动架构的资料网上比较多,有些介绍比较完善,所以在此本人只从调试过程做些记录.
音频驱动是典型的流驱动.三星原厂开发板的BSP包有示例代码.由于X210-S5PV210开发板采用的CODEC芯片不同,所以移植从以下几方面入手,
1.       先保证调试I2S通道的频率正常.
2.       保证有音频数据输出
3.       保证I2C正常通信.
4.       修改CODEC WM8976相关控制代码.
一.  I2S通道的频率
I2S音频正常工作需要以下几路信号
IISSCLK   -------------------  采样时钟
IISLRCLK  ------------------  左右声道的时钟
IISCDCLK  ------------------  主时钟
IISSDO    -------------------  IIS格式音频数据输出
IISSDI     -------------------  IIS格式音频数据输入
S5PV210IIS通道做master,WM8976作为slave.所以IISSCLK IISLRCLK,IISCDCLK三个时钟都由S5PV210产生,提供给音频WM8976芯片.
IISSCLK   采用44.1Khz的采样率.
IISLRCLK  根据210芯片手册采用32fs,1.4112Mhz.(:fs就是采样频率44.1Khz.)
IISCDCLK  根据210芯片手册采用256fs ,11.289Mhz
经以上分析,正式开始移植, X210开发板音频所采用的IIS1通道与三星原厂的IIS0不同,所以把所有通道改为I2S1.示波器抓IISSCLK IISLRCLK,IISCDCLK引脚的波形,发现时钟频率不对.有时钟输出,说明IIS通道已从IIS0改到IIS1通道.
接下来就是查找为何时钟频率不对的原因.仔细查看S5PV210芯片手册,主要时钟配置在IISMOD寄存器,按手册配置后,时钟频率一直不对.多次配置后,要么
IISCDCLK  11.289Mhz.
IISSCLK    470.4khz
IISLRCLK  14.7hz
要么
当把IISCDLK 66.7MHZ
IISSCLK    1.4112Mhz
IISLRCLK  44.1Khz
以为手册上有寄存器没有配置到位,所以反复看了几遍,一下无果.这问题一直持续了好几天.就卡在正确的频率出不来.郁闷之极啊.
后来发现IISLRCLK引脚上的波形很规则,是有规律的被拉成高高低低的台阶,怀疑CODEC芯片也输出波形,从而造成正常的波形被影响.查看WM8976寄存器初始化值,发现是被配成SLAVE模式,原理上应该不会有数据输出.为了进一步验证这个结果,屏蔽掉IIS寄存器的初始化代码.也就是不让主控芯片输出IIS的相关时钟,来检测WM8976上是否有时钟输出.结果测量IISLRCLK,发现时钟信号并不存在.证明WM8976并没有输出时钟信号.到此时,似乎没有任何思路了.
绝望中寻找希望.在后来的调试中,屏蔽掉I2CWM8976的代码后,时钟频率奇迹般正确分频了.看来问题出在I2CWM8976的配置通信中,原因后面会分析.
IISCDCLK  11.289Mhz.
IISSCLK    1.4112Mhz
IISLRCLK   44.1Khz
呵呵,接下来的工作比较好办了.
二.  保证有数据输出
有音频数据输出时, IISLRCLK会输出44.1Khz的采样频率时钟,同时IISSDO会在频率输出.如果没有,则查DMA通道是否有数据送出.通过加打印信息跟踪即可.在有了时钟和数据输出后,接下来就是控制音频芯片工作了.
三.  保证I2C的正常通信
音频芯片WM8976的控制通信接口是采用I2C接口,由于CODEC 芯片WM8976无法读取内置寄存器值.所以不能通过I2C读取CODEC ID来验证是否读操作是否正常.自然也不能通过读写进去的值来验证I2C写操作是否正常.
因为在上面的步骤当中,设置频率时出现的问题,可判定I2C操作是对CODEC有影响的,认为是正常通信.只是写进去的值不对而导致影响到主控芯片S5PV210提供的时钟频率.仔细查看读写寄存器的函数,发现的问题所在.
在此不得不说下WM8976芯片寄存器的特点.WM8976的寄存器值有9.通常我们对I2C器件写数据时,都是8bit数据.为此,在往WM8976芯片中写数据时,需按以下规格处理
7位寄存器地址

9b

8位数据位

7b

6b

5b

4b

3b

2b

1b

0b

7b

6b

5b

4b

3b

2b

1b

0b

CODEC寄存器地址左移一位,D0位用于存放数据寄存器的最高位D8.函数实现如下,见蓝色字体部分:
Void HardwareContext::WriteCodecRegister(WORD wReg, WORD wVal)
{
    BYTE btWriteBuffer[2];
    btWriteBuffer[0] = (BYTE)(wReg<<1)|(BYTE)((wVal>>8)&1);
    btWriteBuffer[1] = (BYTE)(wVal&0xFF);
    WriteI2C_CODEC(m_hI2CCodec, btWriteBuffer, 2);
    DBGMSG(WAVE_CODEC, (L"[WAV] WRITE ADDR : 0x%04X, DATA : 0x%04X\r\n", wReg, wVal));
}
WM8976寄存器数值的数组如下
// WM8976 Codec-chip Initialization Value
unsigned int WM8580_Codec_Init_Table[][2] =\
{
       {0x00,0x00},//R0 software reset
      {0x03,0xed},//R1 power management 1--PLL 0ff
       {0x05,0x80},//R2 power management 2
……
};
数组WM8580_Codec_Init_Tabl[][2]中的寄存器地址和数据已经做了移位处理, WriteCodecRegister()再进行移位处理,造成了数据全部错位.所以解决办法是只保留一次移位操作.即可.改之.声音出来了
四.  修改WM8976的控制代码
参考以前的WM8976的初始化代码和WM8976的数据手册,完成相关的控制.
总结:
       此时调试时间主要花在配置时钟频率.原因就是CODEC音频芯片的影响,由于对三星S5PV210芯片不熟悉,一直怀疑S5PV210寄存器配置有问题.
虽然分析过CODEC对时间频率的影响,正确的排除法是去除I2CCODEC的初始化代码或根本就不给CODEC上电.但这款X210开发板是直接上电,没有GPIO控制.
回复

使用道具 举报

沙发
 楼主| 发表于 2012-2-23 10:24:19 | 只看该作者
自己顶一下!
回复 支持 反对

使用道具 举报

板凳
发表于 2012-3-24 22:45:25 | 只看该作者
300050300050300050300050300050
回复 支持 反对

使用道具 举报

地板
 楼主| 发表于 2012-5-4 09:04:06 | 只看该作者
tjCFeng 发表于 2012-5-3 16:58
学习了,没看懂,呵呵。

呵呵,自己调试一次就知道了啊,就是个流驱动。涉及到I2S协议、I2C协议。
回复 支持 反对

使用道具 举报

5#
发表于 2012-5-31 20:50:29 | 只看该作者
最近在看android音频的驱动,感觉好复杂啊。
回复 支持 反对

使用道具 举报

6#
发表于 2012-5-31 20:57:38 | 只看该作者
买了x210ii开发板,开发板用wm8976,听启明星说有两个wm8888和wm8976 。就是不懂为什么一个驱动有两个驱动文件?
回复 支持 反对

使用道具 举报

7#
发表于 2013-8-6 15:16:43 | 只看该作者
不错,,还可以,,,
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳市九鼎创展科技官方论坛 ( 粤ICP备11028681号-2  

GMT+8, 2024-5-8 03:41 , Processed in 0.023910 second(s), 16 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表