S3C2410通过IIS(Inter-IC Sound)总线与音频控制芯片UDA1380进行通信。放音时发送数据到UDA1380的DATAI管脚,录音时从UDA1380的DATAO管脚接收数据,其数据传输方式为DMA方式。
IIS用于传输音频数据,IIC用于控制1380芯片。
IIS有pclk,sclk,lrclk,sdi,sdo。
PCLK(通俗来说就是声音的采样频率如:44.1K,它的产生是有2410系统时钟分频得到的。
具体过程:2410主频202M,它的APH总线频率是202/4=50M,在经过IIS的PSR(分频比例因子)得到的一个频率用于IIS时钟输出也可以说是同步)。
这个时钟是输出给1380的,对于1380来说它的采样频率即:AD的频率是可以编程控制的。
资料中表明:1可以直接用IIS穿过来的时钟就是上面解释的,1可以用PLL分频后的时钟来确定AD的频率,DA同理就是了。
注意:如果是双声道,上面的就要变化下了,呵呵各位大哥应该都比我明白。
SCLK:在IIS中有2个PSR控制起的,一个用于外部B,另个用于内部A(SCLK)形成时钟用于
PCLK8或者16倍频 (对把这里有点不敢确定不过应该没错就是了)
LR就是左右PHE的切换信号了
SD就是数据输出线
//////////////////////////////
IIC就只有2条线了,论坛里面有人分析过了就不说了
////////////////////////////////
呵呵IISIIC,DMA寄存器的意思当然要明白拉
///////////////////////////////
DMA
其实三星公司已经把很多东西屏蔽了当然是为了我门应用比较简单了呵呵,
从程序上来说只要明白几个函数就可以了:
{
1,s3c2410_request_dma("I2SSDI", s->dma_ch, NULL, audio_dmain_done_callback
2,s3c2410_free_dma(s->dma_ch);
3,s3c2410_dma_queue_buffer(s->dma_ch, (void *) b,/////////////添加DMA BUF
b->dma_addr, b->size, DMA_BUF_WR);
}
这样几个就可以完好DMA了呵呵,
这里有个回掉函数的感念要引起注意啊:
MEANING:驱动提供的一个函数结构地址给DMA的,当然DMA发送完或者接受完触发这个函数的响应
驱动程序的分析
FUNCTION:因为很多东西华恒已经介绍了就不在写了
希望喜欢看驱动的朋友仔细明白audio_buf_t,audio_stream_t并引起重视;;;
1static void audio_clear_buf(audio_stream_t * s)
如果你明白了audio_buf_t,audio_stream_t就很简单了,就是把指针所指的地址的内存释放这里用的是FOR来实现的;;;;
2static int audio_setup_buf这里是用结构提管理的概念实现的内河内存的申请的,
NOTE:用audio_buf_t来管理一段内存,在用audio_stream_t来管理N个audio_buf_t
听说这样的好处是提高了音频给CPU的负担呵呵 鬼知道是不是真的
//////////////////////////
这里有个信号灯的概念要大家注意下:
我们从信号量数据结构开始,它定义在include/asm/semaphore.h中:
struct semaphore {
atomic_t count;
int sleepers;
wait_queue_head_t wait;
}
down()操作可以理解为申请资源,up()操作可以理解为释放资源,因此,信号量实际表示的是资源的数量以及是否有进程正在等待。在 semaphore结构中,count相当于资源计数,为正数或0时表示可用资源数,-1则表示没有空闲资源且有等待进程。而等待进程的数量并不关心。这种设计主要是考虑与信号量的原语相一致,当某个进程执行up()函数释放资源,点亮信号灯时,如果count恢复到0,则表示尚有进程在等待该资源,因此执行唤醒操作。一个典型的down()-up()流程是这样的:
down()-->count做原子减1操作,如果结果不小于0则表示成功申请,从down()中返回;
-->如果结果为负(实际上只可能是-1),则表示需要等待,则调用__down_fail();
__down_fail()调用__down(),__down()用C代码实现,要求已不如down()和__down_fail()严格,在此作实际的等待
//////////////////////////
3 void audio_dmaout_done_callback
这个就是当DMA接收后要唤醒等待的smdk2410_mixer_read
4static void audio_dmain_done_callback
和上面的一样
5int audio_sync
为安全保证,当系统掉点的时候,强烈执行这个函数来保存RAM TO FLASH
6ssize_t smdk2410_audio_write
这里用到阻塞和信号灯的概念,就是把用户空间的内存数据送到DMA传输队列中等待传输去把
7 smdk2410_mixer_read和6一样
8smdk2410_mixer_ioctl
这里主要是利用IIC总线控制,没什么好说的
判断COMMAND,在把ARG传近来和传出去
9iispsr_value(int s_bit_clock, int sample_rate
通过s3c2410_get_bus_clk获得总线时钟,在通过sample_rate来计算比例因子并返回
10audio_set_dsp_speed
通过9返回的值负给已经映射了的寄存器
11smdk2410_audio_ioctl
12init_module
这个华恒书写的很明白了呵呵
看过之后的感受:
1、内存管理重中之重
2、描述对象结构体要仔细的理解各个与的含义
呵呵感觉有点进步了,不过更多的是悲哀
昨天晚上已经实现了MADPLAY的音量控制,不过发现驱动中没有重地音和高音的控制呵呵要自己来写几句程序了
sil80 11month 11.29