wm8960驱动:裸机代码研读
2017-01-08 21:26
411 查看
网上已经有基本的wm8960驱动的demo。可以播放特定频率的wav文件。这个程序很具有参考性。
我们知道,初始化wm8960,需要大概的步骤如下:
1.初始化I2C总线,通过I2C接口给wm8960下配置命令。
2.将声音文件加载到memory中
3.初始化I2S,并把内存中的数据通过I2S总线送给wm8960,从而wm8960通过解码播放出声音
我们大概来看一下,这个代码的实现过程:
其中 wm8960_init()用来初始化wm8960.具体代码:
I2S的初始化:
I2S的初始化,主要完成时钟的初始化.
MPLL_FOUT=67.7Mhz
Codec clock=11.289Mhz—–也称作MCLK=256*fs
I2S SerialCLK(I2SSLK)=1.4122Mhz =2* fs *采样位数
I2S LRCLK ==44.1KHZ
不同采样位数的wav文件,对应的时钟信号有所不同~
这里详细展开下wm8960和s5pv210的时钟配置.
选择s5pv210为主设备,wm8960为从设备。
1. wm8960的时钟
scaler作为Master, codec作为从设备,scaler要向codec提供IIS root clock (codec clock)
还有Bit clock.
2. 产生这些clk需要时钟源,使用三星S5PV210的话,具体的时钟路由如下:
![](http://img.blog.csdn.net/20170111104248871?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hhbmdsaWFuZzc3MzE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![](http://img.blog.csdn.net/20170111104334147?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hhbmdsaWFuZzc3MzE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![](http://img.blog.csdn.net/20170111104430918?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hhbmdsaWFuZzc3MzE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![](http://img.blog.csdn.net/20170111104443180?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hhbmdsaWFuZzc3MzE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
1) 获得FOUTEPLL ,XXTI是外部晶振,从外部晶振获得FINPLL,由FINPLL经过EPLL模块倍频后,产生
2) 获得IISSCLK,先通过CLKMUX_ASS选择FOUTEPLL时钟为Main CLK,再通过MUXIISA选择MAIN clk为IISCLKSRC,然后通过预分频设定分频,最后产生IISCLK
3) 最终痛过RCLKSRC选择 IIS CLK为 RCLKSRC,再通过分频器分出RCLK,也成为Root clk,或者codec clk.
4) 同时root clk再次通过分频器分出BCLK ,也称作bit clock/serial clk
到此为止,scaler产生MCLK和BCLK给codec.scaler端的时钟设置完毕.
Codec端设置:
同理,codec端也需要配置:
1) 设置SYSCLK由MCLK分频1产生
2) 设置DAC/ADC 频率由SYSCLK分频256产生
频率44100hz 16bit的wav文件
LRCLK =音频本身的频率(44.1Khz)
BCLK =2*fs*采样位数(1.411Mhz)
MCLK=256*fs(11.289Mhz)
s5pv210寄存器配置:
![](http://img.blog.csdn.net/20170111105044671?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hhbmdsaWFuZzc3MzE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
Fout = (0x43+0.7)*24M / (3*2^3) = 80*24M/24 = 67.7Mhz
EPLL_CON0 = 0xa8430303;
EPLL_CON1 = 0xbcee;
到此为止:FOUTEPLL已经配置完成,此时FOUTEPLL=67.7Mhz
![](http://img.blog.csdn.net/20170111105118593?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hhbmdsaWFuZzc3MzE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
这边通过配置 AUDIO SUBSYSTEMCLK SRC REG(AUDIO_CLK)
AUDIO_CLK =0x01;
Main clk由 CLKMUX_ASS选择器选择源时钟为上面得到的FOUTEPLL时钟,同时MUXI2S_A选择器设置为00,选择得到的main clk为I2SCLK的源时钟.
寄存器AUDIO_SUBSYSTEMCLK DIV中 I2S_A_RATIO 默认为0,也就是说I2SCLK=上面得到的I2SCLK的时钟源分频1
![](http://img.blog.csdn.net/20170111105149187?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hhbmdsaWFuZzc3MzE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![](http://img.blog.csdn.net/20170111105212500?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hhbmdsaWFuZzc3MzE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![](http://img.blog.csdn.net/20170111105227723?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hhbmdsaWFuZzc3MzE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
上面是I2SCON寄存器
I2SCON =1<<0 | (unsigned)1<<31;
![](http://img.blog.csdn.net/20170111105305407?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hhbmdsaWFuZzc3MzE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![](http://img.blog.csdn.net/20170111105317282?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hhbmdsaWFuZzc3MzE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
这是IISMOD寄存器,其中bit0无意义,所以不列出
我们已经得到了I2SCLK,那么用它干啥?
![](http://img.blog.csdn.net/20170111105439117?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hhbmdsaWFuZzc3MzE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
在获得RCLKSRC时我们需要配置IISMOD[10],选择I2SCLK为时钟源,所以
IISMOD[10]=1 //use I2SCLK
这边的配置基本上就差不多了:RCLKSRC经过一个分频器获得RCLK,RCLK在经过一个分频器获得BCLKmaster.
1) 我们设置scaler为Master模式.codec为slave模式,所以有IISMOD[11]=0
2) SDF描述了IIS信号的传输格式,IIS,左对齐,右对齐,这边选择IIS模式,所以有IISMOD[6:5]=0
3) TXR描述传输方向,选择同时支持发送和接收,所以有IISMOD[9:8]=10
4) CDCLKCON选择codec的时钟,我们是IC内部提供CDCLK给codec.这里的CDCLK指的就是RCLK(root clk),所以有IISMOD[12]=0
5) BLC 描述了每个声道传送的bit数,我们配置为16bits per channel,这里有IISMOD[14:13]=00
6) CDD1,CDD2描述发送端是否丢弃数据,我们选择不丢弃,IISMOD[21:20]=0.IISMOD[19:18]=0
7) BLC_S, BLC_P描述second,primary fifo的每个通道的bit数,16bit,所以有IISMOD[27:26]=0,IISMOD[25:24]=0
8) OP_MUX_SEL描述了数据获取方式是从寄存器还是内部的DMA,我们选择前者,所以有IISMOD[20]=0
9) OP_CLK 描述了时钟输出的方向,scaler向外部codec输出时钟,所以有IISMOD[31:30]=0
继续前面的例子,音频44.1Khz.—–Codec的clk=256*fs =11.2896Mhz
所以此时的N+1=67.738/11.2896=6
![](http://img.blog.csdn.net/20170111105547618?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hhbmdsaWFuZzc3MzE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
这里设置所谓的预分频RCLK= RCLKSRC/(N+1)=11.2896Mhz
所以IISPSR= 1<<15 | 5<<8;
到此为止,codec的时钟已经产生,但还需要其他几个时钟,一个是SCLK/bit clk,另一个是LRSCLK:
![](http://img.blog.csdn.net/20170111105617143?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hhbmdsaWFuZzc3MzE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
这两个时钟配置在IISMOD寄存器厘米那设置:
一个是RFS(IIS Root clk freq select),一个是BFS(bit clock freq select )
![](http://img.blog.csdn.net/20170111105717292?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hhbmdsaWFuZzc3MzE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![](http://img.blog.csdn.net/20170111105729808?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hhbmdsaWFuZzc3MzE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
所以RFS=256,也就是说Rootclk是 fs的256倍数
BFS选择为32*fs,也就是说Bit clk是fs的32倍数
这边的设置还是有些疑问的,首先我们的所有频率都是根据输入的*.wav的rate和bit决定的。所以我们才有了最开始的前提:44100Khz 16bit的wav文件。16bit的音频,BFS可以选择32或者48,这里我们选择32.
确定BFS 分频系数后,RFS可以选择256FS,384FS,512FS,768FS。这里我们选择256FS
所以最开始的FOUTepll我们是根据RFS,BFS确定之后才得到的频率。
我们确定BFS,RFS后,开始反向推导
BFS :bit clock frequency select
我们设置BFS=32,所以BCLK/SCLK =32*fs=1.4112MHZ
RFS:root clock frequency select
我们设置RFS=256,所以 RCLK/MCLK =256*fs =11.2896MHZ
所以我们的fs是最先获得的参数,只有根据fs,才能获得BCLK,MCLK,LRCLK等频率
fs参数包含在*.wav文件描述中,通过一定的格式展开获得.
这样就清晰起来了。RCLK获得方式上面已经讲过,不再赘述。
Codec端时钟设置:
![](http://img.blog.csdn.net/20170111111513870?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hhbmdsaWFuZzc3MzE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![](http://img.blog.csdn.net/20170111111535614?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hhbmdsaWFuZzc3MzE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
SYSCLK SRC选择为MCLK的时钟,也就是11.2896Mhz
SYSCLK的CLKDIV选择1,SYSCLK=MCLK=11.2896Mhz
DACDIV=ADCDIV=SYSCLK/256=44.1Khz
0x4=0;
![](http://img.blog.csdn.net/20170111111602365?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hhbmdsaWFuZzc3MzE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
0x5=0
![](http://img.blog.csdn.net/20170111111626975?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hhbmdsaWFuZzc3MzE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
选择I2S format,word length 16 bit
0x7=2;
![](http://img.blog.csdn.net/20170111112339779?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hhbmdsaWFuZzc3MzE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
我们知道,初始化wm8960,需要大概的步骤如下:
1.初始化I2C总线,通过I2C接口给wm8960下配置命令。
2.将声音文件加载到memory中
3.初始化I2S,并把内存中的数据通过I2S总线送给wm8960,从而wm8960通过解码播放出声音
我们大概来看一下,这个代码的实现过程:
void main(void) { printf("Audio Test\r\n"); int offset = 0x2E; // 音频数据开始的地方 short * p = (short *)0x22000000; // 音频文件应该位于的位置 iic_init(); // 初始化i2c wm8960_init(); // 初始化wm8960 iis_init(); // 初始化iis // 循环播放音频文件 while (1) { // polling Primary Tx FIFO0 full status indication. while((IISCON & (1<<8)) == (1<<8)); IISTXD = *(p+offset); // 每次发送2byte offset++; if (offset > (WAV_SIZE2-0x2e) /2) // 有多少个2byte = (文件大小-偏移)/2 offset = 0x2E; } }
其中 wm8960_init()用来初始化wm8960.具体代码:
void wm8960_init(void) { // bit[7:1]: 0x1a // bit[0]:0: write #define WM8960_DEVICE_ADDR 0x34 // 重置 iic_write(WM8960_DEVICE_ADDR, 0xf, 0x0); // 设置电源 iic_write(WM8960_DEVICE_ADDR, 0x19, 1<<8 | 1<<7 | 1<<6); iic_write(WM8960_DEVICE_ADDR, 0x1a, 1<<8 | 1<<7 | 1<<6 | 1<<5 | 1<<4 | 1<<3); iic_write(WM8960_DEVICE_ADDR, 0x2F, 1<<3 | 1<<2); // 设置时钟 //Mclk--div1-->SYSCLK---DIV256--->DAC/ADC sample Freq=11.289(MCLK)/256=44.1KHZ iic_write(WM8960_DEVICE_ADDR, 0x4, 0x0); // 设置ADC-DAC iic_write(WM8960_DEVICE_ADDR, 0x5, 0x0); // 设置audio interface //I2S format 16 bits word length iic_write(WM8960_DEVICE_ADDR, 0x7, 0x2); // 设置OUTPUTS iic_write(WM8960_DEVICE_ADDR, 0x2, 0xFF | 0x100); iic_write(WM8960_DEVICE_ADDR, 0x3, 0xFF | 0x100); // 设置DAC VOLUME iic_write(WM8960_DEVICE_ADDR, 0xa, 0xFF | 0x100); iic_write(WM8960_DEVICE_ADDR, 0xb, 0xFF | 0x100); // 设置mixer iic_write(WM8960_DEVICE_ADDR, 0x22, 1<<8 | 1<<7); iic_write(WM8960_DEVICE_ADDR, 0x25, 1<<8 | 1<<7); return; }
I2S的初始化:
void iis_init(void) { int N; // 配置引脚用于i2s功能 GPICON = 0x22222222; // 设置i2s相关时钟 // step 1: EPLL output 67.7Mhz (see p361 of s5pv210.pdf) // EPLL_CON0/ EPLL_CON1, R/W, Address = 0xE010_0110/0xE010_0114) // FOUT = (MDIV+K/65536) X FIN / (PDIV X 2SDIV) // Fout = (0x43+0.7)*24M / (3*2^3) = 80*24M/24 = 67.7Mhz #define EPLL_CON0 (*(volatile unsigned int *)0xe0100110) #define EPLL_CON1 (*(volatile unsigned int *)0xe0100114) EPLL_CON0 = 0xa8430303; // MPLL_FOUT = 67.7Mhz EPLL_CON1 = 0xbcee; // from linux kernel setting // step 2: Mux_I2S AUDIO subsystem clock selection (see P1868 P1875 of s5pv210.pdf) #define CLK_CON (*(volatile unsigned int *)0xEEE10000) CLK_CON = 0x1; // 1 = FOUT_EPLL MUXI2S_A 00 = Main CLK // 设置i2s控制器 // step 3: Divider of IIS (67.7 -> 11.289Mhz) // N + 1 = (67.7Mhz) / (256 * 44.1Khz) = 5.99 // IISCDCLK 11.289Mhz = 44.1K * 256fs // IISSCLK 1.4112Mhz = 44.1K * 32fs // IISLRCLK 44.1Khz N = 5; IISPSR = 1<<15 | N<<8; // IIS interface active (start operation). 1 = Active IISCON |= 1<<0 | (unsigned)1<<31; // [9:8] 10 = Transmit and receive simultaneous mode // 1 = Using I2SCLK (use EPLL) IISMOD = 1<<9 | 0<<8 | 1<<10; }
I2S的初始化,主要完成时钟的初始化.
MPLL_FOUT=67.7Mhz
Codec clock=11.289Mhz—–也称作MCLK=256*fs
I2S SerialCLK(I2SSLK)=1.4122Mhz =2* fs *采样位数
I2S LRCLK ==44.1KHZ
不同采样位数的wav文件,对应的时钟信号有所不同~
这里详细展开下wm8960和s5pv210的时钟配置.
选择s5pv210为主设备,wm8960为从设备。
1. wm8960的时钟
scaler作为Master, codec作为从设备,scaler要向codec提供IIS root clock (codec clock)
还有Bit clock.
2. 产生这些clk需要时钟源,使用三星S5PV210的话,具体的时钟路由如下:
1) 获得FOUTEPLL ,XXTI是外部晶振,从外部晶振获得FINPLL,由FINPLL经过EPLL模块倍频后,产生
2) 获得IISSCLK,先通过CLKMUX_ASS选择FOUTEPLL时钟为Main CLK,再通过MUXIISA选择MAIN clk为IISCLKSRC,然后通过预分频设定分频,最后产生IISCLK
3) 最终痛过RCLKSRC选择 IIS CLK为 RCLKSRC,再通过分频器分出RCLK,也成为Root clk,或者codec clk.
4) 同时root clk再次通过分频器分出BCLK ,也称作bit clock/serial clk
到此为止,scaler产生MCLK和BCLK给codec.scaler端的时钟设置完毕.
Codec端设置:
同理,codec端也需要配置:
1) 设置SYSCLK由MCLK分频1产生
2) 设置DAC/ADC 频率由SYSCLK分频256产生
频率44100hz 16bit的wav文件
LRCLK =音频本身的频率(44.1Khz)
BCLK =2*fs*采样位数(1.411Mhz)
MCLK=256*fs(11.289Mhz)
s5pv210寄存器配置:
Fout = (0x43+0.7)*24M / (3*2^3) = 80*24M/24 = 67.7Mhz
EPLL_CON0 = 0xa8430303;
EPLL_CON1 = 0xbcee;
到此为止:FOUTEPLL已经配置完成,此时FOUTEPLL=67.7Mhz
这边通过配置 AUDIO SUBSYSTEMCLK SRC REG(AUDIO_CLK)
AUDIO_CLK =0x01;
Main clk由 CLKMUX_ASS选择器选择源时钟为上面得到的FOUTEPLL时钟,同时MUXI2S_A选择器设置为00,选择得到的main clk为I2SCLK的源时钟.
寄存器AUDIO_SUBSYSTEMCLK DIV中 I2S_A_RATIO 默认为0,也就是说I2SCLK=上面得到的I2SCLK的时钟源分频1
上面是I2SCON寄存器
I2SCON =1<<0 | (unsigned)1<<31;
这是IISMOD寄存器,其中bit0无意义,所以不列出
我们已经得到了I2SCLK,那么用它干啥?
在获得RCLKSRC时我们需要配置IISMOD[10],选择I2SCLK为时钟源,所以
IISMOD[10]=1 //use I2SCLK
这边的配置基本上就差不多了:RCLKSRC经过一个分频器获得RCLK,RCLK在经过一个分频器获得BCLKmaster.
1) 我们设置scaler为Master模式.codec为slave模式,所以有IISMOD[11]=0
2) SDF描述了IIS信号的传输格式,IIS,左对齐,右对齐,这边选择IIS模式,所以有IISMOD[6:5]=0
3) TXR描述传输方向,选择同时支持发送和接收,所以有IISMOD[9:8]=10
4) CDCLKCON选择codec的时钟,我们是IC内部提供CDCLK给codec.这里的CDCLK指的就是RCLK(root clk),所以有IISMOD[12]=0
5) BLC 描述了每个声道传送的bit数,我们配置为16bits per channel,这里有IISMOD[14:13]=00
6) CDD1,CDD2描述发送端是否丢弃数据,我们选择不丢弃,IISMOD[21:20]=0.IISMOD[19:18]=0
7) BLC_S, BLC_P描述second,primary fifo的每个通道的bit数,16bit,所以有IISMOD[27:26]=0,IISMOD[25:24]=0
8) OP_MUX_SEL描述了数据获取方式是从寄存器还是内部的DMA,我们选择前者,所以有IISMOD[20]=0
9) OP_CLK 描述了时钟输出的方向,scaler向外部codec输出时钟,所以有IISMOD[31:30]=0
继续前面的例子,音频44.1Khz.—–Codec的clk=256*fs =11.2896Mhz
所以此时的N+1=67.738/11.2896=6
这里设置所谓的预分频RCLK= RCLKSRC/(N+1)=11.2896Mhz
所以IISPSR= 1<<15 | 5<<8;
到此为止,codec的时钟已经产生,但还需要其他几个时钟,一个是SCLK/bit clk,另一个是LRSCLK:
这两个时钟配置在IISMOD寄存器厘米那设置:
一个是RFS(IIS Root clk freq select),一个是BFS(bit clock freq select )
所以RFS=256,也就是说Rootclk是 fs的256倍数
BFS选择为32*fs,也就是说Bit clk是fs的32倍数
这边的设置还是有些疑问的,首先我们的所有频率都是根据输入的*.wav的rate和bit决定的。所以我们才有了最开始的前提:44100Khz 16bit的wav文件。16bit的音频,BFS可以选择32或者48,这里我们选择32.
确定BFS 分频系数后,RFS可以选择256FS,384FS,512FS,768FS。这里我们选择256FS
所以最开始的FOUTepll我们是根据RFS,BFS确定之后才得到的频率。
我们确定BFS,RFS后,开始反向推导
BFS :bit clock frequency select
我们设置BFS=32,所以BCLK/SCLK =32*fs=1.4112MHZ
RFS:root clock frequency select
我们设置RFS=256,所以 RCLK/MCLK =256*fs =11.2896MHZ
所以我们的fs是最先获得的参数,只有根据fs,才能获得BCLK,MCLK,LRCLK等频率
fs参数包含在*.wav文件描述中,通过一定的格式展开获得.
这样就清晰起来了。RCLK获得方式上面已经讲过,不再赘述。
Codec端时钟设置:
SYSCLK SRC选择为MCLK的时钟,也就是11.2896Mhz
SYSCLK的CLKDIV选择1,SYSCLK=MCLK=11.2896Mhz
DACDIV=ADCDIV=SYSCLK/256=44.1Khz
0x4=0;
0x5=0
选择I2S format,word length 16 bit
0x7=2;
相关文章推荐
- wm8960驱动:裸机代码研读
- WM/WINCE代码研读系列之Power Management(5)
- WM/WINCE代码研读系列之 Power Management(2)
- S3C2440裸机学习[2] - LCD驱动原理及代码分析[一]
- WM/WINCE代码研读系列之 Power Management(1)
- [转]WM/WINCE代码研读系列之Power Management(5)
- [转]WM/WINCE代码研读系列之Power Management(4)
- WM/WINCE代码研读系列之Power Management(6)
- WM/WINCE代码研读系列之Power Management(4)
- WM/WINCE代码研读系列之Power Management(5)
- [转]WM/WINCE代码研读系列之Power Management(6)
- [转]WM/WINCE代码研读系列之 Power Management(1)
- WM/WINCE代码研读系列之Power Management(4)
- WM/WINCE代码研读系列之 Power Management(3)
- android下调试声卡驱动之wm8960介绍一
- [转]WM/WINCE代码研读系列之 Power Management(2)
- WM/WINCE代码研读系列之Power Management(6)
- WM/WINCE代码研读系列之 Power Management(1)
- WM/WINCE代码研读系列之 Power Management(2)
- S3C2440裸机学习- LCD驱动原理及代码分析[二]