Linux_S3C2440_CAMIF接口驱动程序(一)驱动和系统相关的学习

来源:互联网 发布:手机淘宝怎么退货退款 编辑:程序博客网 时间:2024/05/22 12:33

实例为OV9650

驱动在内核源码中的路径:/drivers/media/video/ov9650.c或者\linux-2.6.30.4\drivers\media\video\tq2440\ov9650.c

【对Linux时钟的了解】可以参考http://blog.csdn.net/bingqingsuimeng/article/category/1228965

【对CAMIF接口的了解】参考上篇文章
【工作大概】

当启动视频系统工作后,CMOS摄像头采集到的图像数据经过Camera接口的2个DMA通道,以不同的编码格式缓存在各自的ping2pong存储器中,需要保存的图像被编码后保存到Flash中,用于显示的图像数据由LCD控制器通过专用的DMA通道将图像数据从ping2pong存储器输出到LCD驱动器,这一过程是自动完成的,不需要CPU的参与,然后LCD驱动器根据特定的时序将图像完整地显示在液晶屏上。在实际的操作中可以通过I2C总线接口对CMOS摄像头的工作参数进行设置。

【硬件接口简单分析】

图2为COM59650摄像头与$3C2440硬件接n设计框图,其中对OV9650的特殊寄存器进行设置或者读取操作使用IIC总线,即使用SDA和SCL信号线。CAMCLKOUT信号足控制
器提供给COMS9650的时钟采样频率。视频像数码流的传输主要使用CAMPCLK、CAMVSYNC、CAMHREF和CAMDATA[7:0]信号。CAPCLK为像数同步信号,CAMVSYNC为帧同步信号,CAMHREF为行同步信号,CAMDATA[7:0]是8位的数据传输并行总线。
当视频采样开始以后,每传输完一帧图像数据则会产生一个CAMVSYNC脉冲,这个脉冲信号一般用来产生视频采样中断和用来场消隐。每扫描完一行信号,则产生一个CAM·HREF行同步信号,在行扫描的过程中,在CAMDATAz总线上,每传输一个8位的Y或者cb、cr图像数据,则产生一个CAMPCLK信号。若采用YCbCr4:2:2数据格式,每4个像素点需要4个Y信号、2个cb信号和2个cr信号。


【摄像头的工作方式了解】

转http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=3634173

首先要明确一下摄像头工作方式:
一、摄像头是怎么把数据传送给mini2440的呢?
这个摄像头有10个数据口,mini2440通过这些数据口采集摄像头的数据。
二、硬件以什么样的方式交换采集数据呢?
摄像头将采集到的图像数据以一些标准的格式通过数据口输出。有两种输出方式,一种是一次输出10个bits.另一种是每次输出8bits.我们的mini2440采集的是第二种接法。
三、camera interface怎么把数据传给我们的程序呢?
我们在程序中设定一大块内存区如:frame_bufffer[][],这样的数组,并把这个数组的地址传给 camera interface的相应寄存器。这样camera interface会自动把摄像头传给它的数据经过自己的处理后存入那个内存区。至于camera interface做何种处理是我们可以通过寄
存器设定的。
四、ov9650以什么格式输出呢,参见(二)红色字体
ov9650支持很多种格式,比如说我们常用的YCbCr4:2:2格式,这种格式我们的camera interface也支持。只到我们把两方都设成这种格式,camera interface就能正确处理数据。
五、camera interface以什么格式存入我们给的内存区中呢?
这个也是可以通过设定寄存器设置的。
比如说我们设成RGB565格式,camera interface就会把从ov9650拿到的YCbCr像素用硬件广商设定的程序转换成RGB565的格式,并存内我们的数组里,我们按照这个格式从数 组里取数据就可以,也可以直接把这个地址给LCD的寄存器,LCD就可以直接显示了。
六、mini2440怎么设置ov9650中的寄存器呢?
ov9650有SCCB总线,我们可以用mini2440的IO口模拟一个SCCB总线传送方式。其实SCCB总线是弱化的IIC总线,我们也可以用IIC总线传送命令。

(一种3线串行总线,由SCCB_E,SIO_C,SIO_D组成,通过它用户可以很方便地对芯片进行编程操作以实现对摄像头输出图像的处理。在简化芯片引脚,SCCB可以再2线串行模式下,芯片封装缩减为2根线,SIO_C和SIO_D,相当于简化的IIC协议)
七、ov9650中有很多寄存有设置啊?
是啊,真多,不过广商提供一些标准的设置方法,我们只要写成数据,并循环写入就可以了。


【CAMIF接口初始化】

CMAIF模块初始化即对S3C2440的摄像头控制单元进行视频采集的配置,在这个配置过程决定了视频采集的操作和视频输出的方式以及定义目标窗口大小和比例分割尺度
等"J。输出方式主要有两种,一种直接用来视频预览,采用RGB格式,另一种用来视频压缩编码,采用YCbCr格式。这些数据经过处理,直接进入帧缓冲区,帧缓冲区由4个Pin妒ong存贮器组成,因此图像帧的读写操作町以同时进行。当一帧图像数据采集完成以后,可以通过两种DMA通道进行传输,P线路的DMA通道可以直接输出到视频显存,对采集的图像进行比例缩放显示。初始化流程一般为:1.设置视频码流的输入格式;2设置原窗口尺寸大小和目标窗口尺寸大小以及缩放比
例;3设置采样频率;4指定RGB帧和YCbCr帧的起始地址。4计算DMA传输的突发参数;5计算视频预览分割比例。在CAMIF中主要有以下寄存器:GLOBALCONTROLREGISTER全局控制寄存器,CICOTRGFMT码流格式寄存器,PRE-SCAL-ERCONTROL REGISTER尺度预缩放寄存器,CODEMAIN-SCALERCONTROL
REGISTER尺度—琶缩放寄存器,STARTAD—DRESSREGISTER帧起始地址寄存器,ST删SREGISTER状态寄存器等,这些寄存器控制着视频码流的格式、视频预览的
参数以及CAMIF工作状态。

驱动程序有两种加载方式,一种是直接编译进LINUX内核,直接调用即可。另一种是模块加载方式。CMOS摄像头驱动以 MODULES 的形式编写,MODULES形式的驱动可动态加载到Linux 内核,节省了系统开销。程序的设计围绕下面的 file_operations数据结构体展开,主要编码工作就是具体实现结构体中相应的各个函数的功能。通过这些系统调用,应用程序就可实现对 CMOS摄像头的打开、关闭、视频数据的读取、内部寄存器的设置等操作。 
static struct file_operations cam_fops ={ 
     owner:THIS_MODULE, 
     llseek:no_llseek , 
     open :cam_open , 
     read :cam_read , 
     write:cam_write , 
     ioctl:cam_ioctl , 
     release:cam_release , 
}; 另外有两个重要的宏为: 
(1) module_init(init_s3c2440_ov9650) 
它是驱动程序的入口点,相当于应用程序的 main 函数,用户进程加载该驱动程序时就会自动调用init_s3c2440_ov9650 函数,实现: 
①产生下降沿脉冲,使 OV9650 复位; 
②初始化 S3C2440A 的摄像头接口,主要是配置相关的寄存器,包括配置端口J的引脚功能,作为摄像头的控制和数据线;将端口J 的数据寄存器清零; 
③配置UPLL时钟频率及摄像头的输入时钟频率等; 
④配置端口E的控制寄存器,设置IIC总线的控制功能,主要是设置IIC总线的数据位、停止位、摄像头从地址、时钟频率等; 
⑤通过 request_irq  系统调用向Linux  系统申请注册中断,以便随时响应用户对摄像头设备文件的调用。 
(2) module_exit(exit_s3c2440_ov9650 )进程卸载该驱动程序,自动调用 exit_s3c2440_ov9650  函数,完成进程地址空间、存储缓冲区的释放,关闭中断请求工作。

【硬件和软件示意图】






【参考阅读:一个裸机使用摄像头的测试程序】

http://blog.csdn.net/yaozhenguo2006/article/details/7179361

摘要:

主要涉及到配置两个寄存器,OV9650的寄存器和CAMIF接口寄存器

OV9650寄存器在模块内部,S3C2440是以sccb总线和ov9650通信,可以通过gpio口来模拟sccb总线,一般sccb和iic总线式接在一块的。当然必须可以直接用iic。必须要关心的是厂商ID寄存器(确保设备读取安装正确);

CAMIF接口配置较为麻烦,大致有3类:

1.摄像头接口输入视频格式寄存
器CISRCFMT,功能是设置摄像头接口的输入数据的格式与长宽。s3c2440的摄像头接口提供了两个DMA通道,一个预览输出DMA,有四块DMA缓冲区,这个通道用于将采集到的视频图像直接显示到Lcd上。

2.编码
输出DMA,也有四块DMA缓冲区,用于后期处理视频。所以第二类是预览输出视频格式寄存器。(Ppath)

3.编码输出视频格式寄存器。(Cpath)

所以操作摄像头的步骤基本为:

(1) 读取厂商ID,来判定摄像头是否安装正确,这首先需要正确操作sccb总线,这一步也可以用来判定sccb总线时序是否正确。   

(2) 配置摄像头,事先将寄存器的地址以及对应的值写入数组,直接通过循环完成配置,配置完成之后就不需要操作sccb总线了,也就是不需要管ov9650这端了。以下的操作设置摄像头接口这端的寄存器就可以了。

(3) 设置摄像头所需的时钟,设置控制寄存器,复位摄像头。

(4) 根据lcd的类型以及需要显示视频的大小,设置源图像寄存器,预览输出寄存器等


【思路较清晰的一个实现流程】

参见http://home.eeworld.com.cn/my/space-uid-67366-blogid-70422.html

【驱动代码的个人分析见(二)】

0 0
原创粉丝点击