關於基於WinCE下的聲音系統調試的一些經驗總結之驱动程式部分(二)
/
//Author:Mercury Xu
//Date:2008-12-08
//Descrption:聲音作為WinCE系統中一個比較基礎的配置大家已經都不會陌生。
// 本文主要是總結下作者在調試WM9715聲卡驅動芯片
// 過程中遇到的一些問題
//OS:WinCE5.0
/
正文
好了。以下是Segment II,跳过来的朋友和读过来的朋友都要准备好了。我们要开始耍WM9715了。
首先我们还是来热身下,热身我们要准备以下两个东西
1.应用层的一些小知识。
2.WM9715 datasheet。
我们先来看第一个,做流式驱动调用的时候我们知道,有一个XXX_IOCONTROL之类的函数一般在最后,我们再WM9715的WAV驱动的地方也有个。 WAV_IOControl。我们在应用层怎么去调用他呢?
其实很简单。大家先看看MSDN的这个文档:
http://msdn.microsoft.com/en-us/library/aa363216(VS.85).aspx
BOOL WINAPI DeviceIoControl( __in HANDLE hDevice, //句柄一个,定义一个HANDLE的句柄,在初始化的时候就好了 __in DWORD dwIoControlCode,//这个一般无关痛痒,Null掉了 __in_opt LPVOID lpInBuffer,//这个就比较重要了,输入数据的接口,要和你定义好的case数值匹配好哦! __in DWORD nInBufferSize,//这个长度一般都直接用sizeof处理掉了。 __out_opt LPVOID lpOutBuffer,//这个也是比较重要的,返回值,在上一篇文章里面case最后有个比较精彩的程序段, //给了这个变量值,大家可以回头过去看看。 __in DWORD nOutBufferSize,//这个也直接sizeof了。 __out_opt LPDWORD lpBytesReturned,//这个我们都Null __inout_opt LPOVERLAPPED lpOverlapped ///这个也NULL了);
好了。不多说了,看懂了吧。这里再提醒下,case的值一定不能搞错了,搞错了怎么样都是出不了的。
接下来还有个难度稍微大一点点的。我们再上一篇文章应该有看到在try的里面有个很长的结构体,叫PMMDRV_MESSAGE_PARAMS
这个结构体再APP不管你用EVC还是VS2005都是没有给出初始化定义的。所以,接下来我们给出他的定义
- BOOL WAV_IOControl(DWORD dwOpenData,
- DWORD dwCode,
- PBYTE pBufIn,
- DWORD dwLenIn,
- PBYTE pBufOut,
- DWORD dwLenOut,
- PDWORD pdwActualOut)
- You can use pBufIn pass its parameter, and pBufIn is defined with
- typedef struct {
- UINT uDeviceId;
- UINT uMsg;
- DWORD dwUser;
- DWORD dwParam1;
- DWORD dwParam2;
- } MMDRV_MESSAGE_PARAMS, *PMMDRV_MESSAGE_PARAMS;
- and you can use pBufOut to get return value, it is definded with
- (DWORD *)
- (PMMDRV_MESSAGE_PARAMS)pBufIn, (DWORD *)pBufOut
- WRITE REGISTER
- dwCode: IOCTL_WAV_MESSAGE
- uMsg: WODM_WRITE_AC97
- dwParam1: AC97 register's ID, it should be even, please read AC'97 specification
- dwParam2: pass value(write), the value shoud be an 16-bits
- number.
- READ REGISTER
- dwCode: IOCTL_WAV_MESSAGE
- uMsg: WIDM_READ_AC97
- dwParam1: AC97 register's ID, it should be even, please read AC'97 specification
- pBufOut: RETURN VALUE
这下眼前一亮了吧。我顺带将9715的两个东东也带出来了。关于9715的操作我们接下来就开始给大家说说,刺激的地方要开始了。
下面我们开始比较刺激的地方了。看看WM9715的结构以及驱动的地方怎么去处理。
对于芯片的操作,无非就是两个,读寄存器,写寄存器,首先我们看看WM9715的datasheet
http://www.wolfsonmicro.jp/uploads/documents/cn/WM9715L_Rev3.9.pdf
我们先看下他的功能
rel="File-List" href="file:///C:%5CDOCUME%7E1%5CMERCUR%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml">
AC’97 Rev 2.2 compatible stereo codec
AC’97 Rev2.2 兼容立体声解码
- DAC SNR 90dB, THD –86dB
- ADC SNR 88dB, THD –88dB
- Variable Rate Audio, supports all WinCE sample rates
多频率音频,支持所有WinCE采样率
- Tone Control, Bass Boost and 3D Enhancement
音调控制,重音控制以及3D环绕控制
• On-chip 45mW headphone driver
片载45毫瓦耳机驱动
• On-chip 400mW mono speaker driver
片载400毫瓦单声道喇叭驱动
• Stereo, mono or differential microphone input
立体声,单声道或者混合麦克风输入
- Automatic Level Control (ALC)
自动等级控制
• Auxiliary mono DAC (ring tone or DC level generation)
辅助单DAC
• Seamless interface to wireless chipset
无线连接接口
• Resistive touchpanel interface
电阻丝触摸板接口
- Supports 4-wire and 5-wire panels
支持4线和5线触摸板
- 12-bit resolution, INL ±3 LSBs (<0.5 pixels)
12位协议,INL ±LSBs (<0.5 pixels)
- X, Y and touch-pressure (Z) measurement
X,Y以及触摸压力测量
- Pen-down detection supported in Sleep Mode
休眠模式下触摸笔下压侦测
• 2 comparator inputs for battery monitoring
2个电源侦测比较输入端口
• Up to 4 auxiliary ADC inputs
4个辅助ADC输入
• 1.8V to 3.6V supplies
1.8V 到 3.6v 电压支持
• 7x7mm QFN
7* 7mm QFN封装
好了,如果你还是不放心,看到
- Variable Rate Audio, supports all WinCE sample rates
多频率音频,支持所有WinCE采样率
这句话你应该可以放心大胆的来玩这颗芯片了。
首先,我们需要知道,系统的声音是一个数据音频,所有,系统走的方式是通过I2S来的。这一块一般再BSP包中都会有写好了。大家都不用去修改。直接用就好了
其次,其他的声音输入采用的方式基本上是通过9715的几个音频输入口,比如MIC LINEIN这几个来实现的。首先你要检查下硬件上都是OK,输入一些音频的模拟信号进去,确认已经进入到了芯片里。
最后我们开始来看这个DATASHEET里面的最神奇的图。Audio paths overview。。。大概在14页图片1
这个图太神奇了。。想起了小时玩红白机三国志里面选角色的情景,走线路判断后选人。怀念啊。。。。
这里我们就拿LINEINL这一路来看PIN23蓝色的线走下去。
1.我们先碰到了10H这个寄存器他是控制输入音量的,我们先要使能,然后选择最大音量,这里有个小尝试,+的dB是音量最大啊!!!(众人,地球人都知道。。。)
2.接下来我们看到了个MIXER.不鸟他
3.然后我们看到我们要使能的寄存位了10H:15我们很开心的把它做成1,使能了。
4.headphone mix是个大关,混合了下音以后送出来
5.接下来有个选择器,我们直接过去,上面有个转向器,我们也不用鸟他了02H的转向器
6.最后一个BOSS来了02H首先你要他处于可以放的状态,也就是非MUTE状态,我们仔细一看,02H:7.好了。我们很开心的把它弄成了1.
7.最后的最后我们来弄个音量,也弄个最大音量就好了。
以上就是一套路线打通的方法,其他路线打通的方法大同小异。大家一路跟下去就OK了。
至于如可写寄存器如何读寄存器,下面我们简单说下,因为不同的ARM可能对这个处理的方式不太一样。但是总体上是类似。
上面我们很开心的将一些寄存器位设计为高,我们通过写寄存器的方式实现。下面我给一个参考给大家
- BOOL WriteAC97Reg(USHORT RegIndex, USHORT RegValue)
- {
- ULONG timeout = 0;
- GRABMUTEX();
- IOW_REG_SET(struct ac97Ctrl1Bits, &v_pCodecReg->ac97ctrl1, (RegValue << 16) | ((RegIndex & 0x7f) << 8)); // CODEC_AC97_CMD = (RegValue << 16) | RegIndex;
- IOW_REG_OR(struct ac97Ctrl0Bits, &v_pCodecReg->ac97ctrl0, 0xe000); // CODEC_AC97_CTRL |= 0xe000;
- while ((v_pCodecReg->ac97ctrl0.ac97_write_tagh & AC97_WRITE_SLOT1_VALID) && (timeout++ < TIMEOUT_LOOPS));
- if(timeout >= TIMEOUT_LOOPS)
- {
- RETAILMSG(1, (TEXT("Timeout in write ac97")));
- }
- usWait(5);
- RELEASEMUTEX();
- return (timeout < TIMEOUT_LOOPS);
- }
- // AC97_CONTROL_0 -0X01C R/W
- struct ac97Ctrl0Bits {
- unsigned da_channel :2;// da channel enable, bit1 left channel, bit0 right channel; 1= channel enable;0=channel disable
- unsigned ad_channel :2;// ad channel enable
- unsigned warm_wake :1;// Warm wake codec 1= warm wake 0= exit warm wake-up mode.
- unsigned ac97_start :1;// ac97 interface start 1= ac97 interface start 0= stop
- unsigned rsvd0 :5;// reserved
- unsigned ac97_write_tagh :5;// AC-link output frame tag setting
- unsigned rsvd1 :16;// reserved
- };
- // AC97_STATUS_0 -0X024 R
- struct ac97Status0Bits {
- unsigned ac97_slot_rq :8; // ac97 slot request
- unsigned ac97_read_tagh :8; // ac97 input frame status bit15 codec ready, bit14 solt1 valid, bit13 slot2....
- unsigned rsvd0 :16;
- };
1.IOW_REG_SET和 IOW_REG_OR这两个函数大家根据自己的芯片进行定义就好了,其他都是很常用的。在这里就不多说了。
2. ac97Ctrl1Bits和0是对WM9715你自身ARM控制的一些操作。这个你按照你自己的来就好了。
3.最后两个是赋值了。
基本的思路是上面的。大家还是要根据不同的芯片来不同处理。
那今天驱动部分我们就介绍完了。关于应用层,明天我们再聊。
關於基於WinCE下的聲音系統調試的一些經驗總結之驱动程式部分(二)相关推荐
- java 修改wav文件头_使用Java聲音API從WAV文件中修剪開頭和結尾
我有製作的基礎知識.但是,輸出文件一遍又一遍地重複WAV標頭字節.生成的文件大小合適,但是它與垃圾一起提交.使用Java聲音API從WAV文件中修剪開頭和結尾 我想使用一個擴展AudioInputSt ...
- 关于wince 下LCD 控制器设置成RGB888 24bit 的相关问题
在论坛找了一个topic ,自己也来分析一下. http://bbs.csdn.net/topics/350122995?page=1#post-392888121 -- 100分:开帖讨论WINCE ...
- linux下复制catalog信息指令,基於Linux下catalog方式的 Oracle 備份策略(RMAN)
--********************************** --基於Linux下 Oracle備份策略(RMAN) --********************************* ...
- mt7601的linux驱动下载,mt7601u,基於 Linux mac80211 MT7601U USB bgn無線dongle驅動程序,下載mt7601u的源碼_GitHub_開發99...
這是一款用於 MT7601U USB dongle的Linux驅動程序. 它是基於供應商gpl驅動程序從頭開始編寫的. 供應商驅動程序不同,這個驅動程序使用現代的Linux WiFi基礎設施,並且應該 ...
- 基於IIS的WCF的分布式多層架構開發實現
曾用.NET Remoting,基於IIS,為公司實現過分布式多層架構,客戶端采用Web Browser瀏覽,當時,公司領導告訴我可能會有多臺中間服務器用於系統,又不想每臺電腦的去安裝程序,所以,我最 ...
- 基於tiny4412的Linux內核移植--- 中斷和GPIO學習(2)
作者 彭東林 pengdonglin137@163.com 平臺 tiny4412 ADK Linux-4.4.4 u-boot使用的U-Boot 2010.12,是友善自帶的,爲支持設備樹和uIma ...
- python笑傲江湖统计字数_基於Python的tf-idf算法实现:以《笑傲江湖》为例
连结Jasonnor/tf-idf-pythongithub.com 简介 tf-idf(term frequency-inverse document frequency)是一种用於信息检索与文字 ...
- php complex,PHP復雜的基於角色的訪問控制列表
I have already made the database and the php code needed to implement this customized ACL system. No ...
- OpenCV學習筆記(6)基於 VC+OpenCV+DirectShow 的多個攝像頭同步工作
http://blog.csdn.net/chenyusiyuan/article/details/4643313 因項目需要采集2個攝像頭的數據進行雙目檢測,一開始采用以下代碼來測試: #inclu ...
最新文章
- Spring cloud 微服务docker容器化最佳实践
- 为何 Windows 10X 无法延续 Windows 的成功?
- php ecos,php
- poj1192 最优连通子集(树形dp)
- 自己动手用C扩展PHP(三)
- python做excel表格代码_[宜配屋]听图阁
- ANDROID笔记:Activity之间的传值
- 3. LAMP 安装与配置
- python策略模式包含角色_Python 之策略模式
- dosbox使用教程创建masm5
- Ipsec phase1 and phase2
- python怎么让矩阵内所有元素自己平方_python numpy库中矩阵用法指南
- 实验一:交换机和路由器的基本配置
- Spring Boot学习笔记(二十一)Spring boot 数据校验 @Validated、@Valid用法详解
- SDOI2019R2翻车记
- 手机内存卡照片删了怎么恢复
- 使用Adobe Acrobat XI Pro进行pdf裁剪
- org.quartz.JobPersistenceException:Couldn‘t retrieve job because a required class was not found
- 金海佳学C++primer 练习9.4/9.5
- Facebook等使用苹果源生分享
热门文章
- php 系统平均负载,深入理解liunx平均负载
- Google DFP广告管理系统简介:下订单
- #ifndef、#define、#endif作用
- 【微信小程序】小程序自定义随机分享图片
- php实现数组值遍历连接成一串字符串
- “声”来震撼 乐在途中·飞利浦汽车音响震撼上市
- 糯米团—重制“iPhone团购信息客户端”(二)
- 阿里国际站买家取消金标蓝标–上线优质买家(L1+)
- frp内网穿透服务器搭建及免费frp服务器提供
- 从0开始学c语言-终篇41-练习、学习分享