基于S5PC100的FIMC控制器解析
作者:邹南,华清远见嵌入式学院讲师。
http://www.cnblogs.com/gooogleman/archive/2012/07/26/2610449.html
CAMERA SENSOR
OV9650/9655是CMOS接口的图像传感器芯片,可以感知外部的视觉信号并将其转换为数字信号并输出。通过下面的框图可以清晰的看到它的工作原理:
我们需要通过XVCLK1给摄像头提供时钟,RESET是复位线,PWDN在摄像头工作时应该始终为低。HREF是行参考信号,PCLK是像素时钟,VSYNC是场同步信号。一旦给摄像头提供了时钟,并且复位摄像头,摄像头就开始工作了,通过HREF,PCLK和VSYNC同步传输数字图像信号。数据是通过D0~D7这八根数据线并行送出的。
OV9650向外传输的图像格式是YUV的格式 ,YUV是一种压缩后的图像数据格式,它里面还包含很多具体的格式类型,我们的摄像头对应的是YCbCr(8 bits, 4:2:2, Interpolated color).一定要搞清楚格式,后面的驱动里面设置的格式一定要和这个格式一致。
OV9650里面有很多寄存器需要配置,配置这些寄存器就需要通过芯片里面的SCCB总线去配置。SCCB其实是一种弱化的I2C总线。我们可以直接把摄像头接在S5PC100的I2C控制器上,利用I2C总线去读写寄存器,当然直接使用GPIO模拟I2C也可以实现读写。
从OV9650采集过来的数据没法直接交给CPU处理。S5PC100芯片里面集成了Camera控制器,叫FIMC(Fully Interactive Mobile Camera)。摄像头需要先把图像数据传给控制器,经过控制器处理(裁剪拉升后直接预览或者编码)之后交给CPU处理。
实际上摄像头工作需要的时钟也是FIMC给它提供的。
Sccb协议简介
SCCB(Serial Camera Control Bus)是和I2C类似的一个协议。 SIO_C和SIO_D分别为SCCB总线的时钟线和数据线。
从设备地址(ID Address,8bit),分为读地址和写地址,高7位用于选中芯片, 第0位是读/写控制位(R/W),决定是对该芯片进行读或写操作;
内部寄存器单元地址(Sub_ Address,8bit),用于决定对内部的哪个寄存器单元进行操作,通常还支持地址单元连续的多字节顺序读写操作。SCCB控制总线功能的实现完全是依靠SIO_C、SIO_D两条总线上电平的状态以及两者之间的相互配合实现的。SCCB总线传输的启动和停止条件如图
过程:采用简单的三相(Phase)写数据的方式,即在写寄存器的过程中先发送OV7650的ID地址(ID Address),然后发送写数据的目地寄存器地址(Sub_address),最后发送要写入的数据(Write Data)。如果给连续的寄存器写数据,写完一个寄存器后,OV7650会自动把寄存器地址加1,程序可继续向下写,而不需要再次输入ID地址,从而三相写数据变为了两相写数据,由于本系统只需对有限个不连续寄存器进行配置,如果采用对全部寄存器都加以配置这一方法的话,会浪费很多时间和资源,所以我们只对需要更改数据的寄存器进行写数据。对于每一个需更改的寄存器,都采用三相写数据的方法。
OV9650是OmniVision公司的COMS摄像头,130万像素,支持SXVGA、VGA、QVGA、CIF等图像输出格式。 最大速率在SXVGA时为15fps,在VGA时为30fps。
OV9650摄像头时序如下图:
在获得摄像头ID号后说明sccb通信方式已经正常运行,就可以对内部的控制寄存器进行配置,主要的内部控制其有:
时钟预分频寄存器:
图像缓冲区格式设置寄存器:
增益控制寄存器:
输出模式设置寄存器
配置完成后,在camera模块数据线上就应该有数据传输出来。然后配置主机中camera控制器进行数据的接收和转换。
CAMIF
该套架构专为摄像头而设计,如下罗列相应的功能以及接口。分析FIMC需要从两方面出发,第一是CAMIF端,第二是传感器端,下面逐一分析。
CAMERA DISCRIBE:
● Camera interface
Mutiple input support
● ITU-R BT 601/656 mode
◆ DMA(axi 64bits interface) mode
◆ MIPI(CSI) mode
Mutiple output support
● DMA(axi 64bits interface)
● Direct FIFIO mode
● Digital Zoom in capability
● 可编程视屏同步信号极性
● 支持最大64M像素输入
● 图像镜像以及旋转支持
● 多样式图像的处理
● 捕捉图像以及通用处理能力
CRAMERA ARCHITECTURAL
1、可同时支持两个摄像头传感器
2、且3路CRAMIF 可同时操作两个摄像头传感器
3、CRAMIFn有自己的本地管道通向FIMD
4、CRAMIFn有私属的AXI总线读写通道
下图给出了各个camif 的属性。
下面来看看如何配置时钟:
图一
图二
图三
简单分析下,FIMC由4路时钟构成,CAM_SCLK如图二所示,xci_pclk由摄像头传感器内部分频后得到,输出返回至CAMIF。
BUS_CLOCK&CORE_CLOCK可选择APLL,MPLL,HPLL,EPLL输入。注意core clock 最大值是133Mhz , CAM_MCLK最大是83Mhz,XciPCLK最大值也是83Mhz 。
在测试中,笔者选择了MPLL这一路,最后经过分频后得到16.7Mhz的BUS/CORE_CLOCK。
知道时钟后,我们可以看看camif的时序部分:
从s5pc100的用户手册中看到这两幅图,清楚的表现了camif timing 。一个垂直同步信号下,会引发一个HREF信号,它是一个水平相关信号,在一个HREF周期中,会发生一次数据传输。这一点基本和lcd的控制器时序是类似的。
program flow
(1,Reg .register)
配置camera source format Reg 需要填写采集的数据图像的大小。这里我们采用的是800x480,其中800是srcHsize ,480是srcVsize。
● 配置 camera window offset Reg 该寄存器主要指定了需要对采集到的源图像的剪裁所需的各个偏移值。
● 配置全局控制寄存器 camera control Reg 该寄存器有很重要的两个bits,一个是控制器的复位,一个是摄像头传感器chip的复位。并且还需要填写扫描方式1,隔行扫描或者逐行扫描。
● 配置Output DMA 的 start address Reg 注意,一共有4个frame,全配上的话会使得图像输刷新更快,图像显示更流畅。
● 配置Target Format Reg , 该寄存器主要是对图像的旋转以及目标尺寸的设置。
● 对Pre-Scaler control Reg 1的配置主要是设置scaler。具体需要看公式:
if(SrcXSize>=64*DstXSize)
error;
else if(SrcXSize>=32*DstXSize) {
X_ratio=32;
X_shift=5;
}
else if(SrcXSize>=16*DstXSize) {
X_ratio=16;
X_shift=4;
}
else if(SrcXSize>=8*DstXSize) {
X_ratio=8;
X_shift=3;
}
else if(SrcXSize>=4*DstXSize) {
X_ratio=4;
X_shift=2;
}
else if(SrcXSize>=2*DstXSize) {
X_ratio=2;
X_shift=1;
}
else {
X_ratio=1;
X_shift=0;
}
PreDstXsize = SRC_Xsize / PreXRatio ;
MainXratio = (SRC_Xsize<<8)/(DST_Xsize<<X_Shift)
SHfactor = 10-(H_Shift + X_Shift);
X={v,h}; v=vertical h=height;
● 对main-scaler control Reg的配置。需要选择LCD的输入路径。并且还有scaler的起始位。
● 配置output DMA offset Reg的设置,它决定了你输出图像的整体偏移量
● 使能 capture enable Reg ,使能捕捉。
按照以上步骤,就可以简单的输出图像了。注意测试的方案为:camif的数据读取地址与lcd的framebuffer一致,这样摄像头采集到的图像可以第一时间被lcd捕获并显示。注意摄像头采集不能通过local fifo给显示设备。
问题与总结:
1、在整个移植过程中会遇到各种各样的未知问题。通过不断地测试与推敲后,最终成功。下面是一些遇到的问题和解决方案:
2、如果无法读取到传感器的product id 以及manufacture id ,则可能是sccb的限时不够或者达不到要求。也有可能是没有进行软复位,这一点要非常注意,在模拟i2c协议时,这一点尤为重要。
3、如果传感器不输出数据,则代表camif的配置还有问题,主要要看时序是否正确,还有是否使能了capture 信号角,main-scaler start bit;
4、如果有数据了,但是显示出来的却不清楚,或者花瓶的话,那恭喜你,你离成功快近了,但是要做好连续奋战几天的准备。因为这个问题就是一个字,实验。最后的问题就是输入的图像像素以及scaler公式配置不正确,导致输出的像素不正确。这样就不会输出正确的图像。
(笔者的实验数据是src/800*480 target/640*320)
内核相关的一些总结
由于在整个移植过程中,我们都参考的是Android 2.6.29内核,现在讲下一些移植的经验。
在linux下,相关的目录
FIMC: ~\drivers\media\video\samsung\fimc
FIMD: ~\drivers\video\samsung
这两个是核心目录,包含了所有FIMC/D体系的代码,只是与内核关联的部分涉及到了I2C子系统,平台设备驱动,以及v4l2视频编程接口,推荐看资料《FS_S5PC100平台上Linux Camera驱动开发详解》。
基于S5PC100的FIMC控制器解析的更多相关文章
- 基于S5PC100裸机程序之SPI(上)
作者:杨老师,华清远见嵌入式学院讲师. SPI作为应用最为广泛的通信总线协议之一,开发人员应当掌握,本章将介绍SPI总线协议的基本理论,以及S5PC100的SPI总线控制器的操作方法. 1. SPI总 ...
- 基于底层的 XML 的解析方式详解
在上一篇博客中,我们介绍了什么是 XML ,http://www.cnblogs.com/ysocean/p/6901008.html,那么这一篇博客我们介绍如何来解析 XML . 部分文档引用:ht ...
- Spring源码学习笔记之基于ClassPathXmlApplicationContext进行bean标签解析
bean 标签在spring的配置文件中, 是非常重要的一个标签, 即便现在boot项目比较流行, 但是还是有必要理解bean标签的解析流程,有助于我们进行 基于注解配置, 也知道各个标签的作用,以及 ...
- canal 基于Mysql数据库增量日志解析
canal 基于Mysql数据库增量日志解析 1.前言 最近太多事情 工作的事情,以及终身大事等等 耽误更新,由于最近做项目需要同步监听 未来电视 mysql的变更了解到公司会用canal做增量监 ...
- 基于Hi3559AV100 RFCN实现细节解析-(2)RFCN数据流分析
下面随笔系列将对Hi3559AV100 RFCN实现细节进行解析,整个过程涉及到VI.VDEC.VPSS.VGS.VO.NNIE,其中涉及的内容,大家可以参考之前我写的博客: Hi3559AV100的 ...
- 基于Hi3559AV100 RFCN实现细节解析-(3)系统输入VI分析一 :
下面随笔系列将对Hi3559AV100 RFCN实现细节进行解析,整个过程涉及到VI.VDEC.VPSS.VGS.VO.NNIE,其中涉及的内容,大家可以参考之前我写的博客: Hi3559AV100的 ...
- 基于Hi3559AV100 RFCN实现细节解析-(3)系统输入VI分析(HiISP)二 :
下面随笔系列将对Hi3559AV100 RFCN实现细节进行解析,整个过程涉及到VI.VDEC.VPSS.VGS.VO.NNIE,其中涉及的内容,大家可以参考之前我写的博客: 基于Hi3559AV10 ...
- 基于Controller接口的控制器及简单应用
DispatcherServlet在Spring当中充当一个前端控制器的角色,它的核心功能是分发请求.请求会被分发给对应处理的Java类,Spring MVC中称为Handle.在Spring 2.5 ...
- 实时音视频互动系列(下):基于 WebRTC 技术的实战解析
在 WebRTC 项目中,又拍云团队做到了覆盖系统全局,保证项目进程流畅.这牵涉到主要三大块技术点: 网络端.服务端的开发和传输算法 WebRTC 协议中牵扯到服务端的应用协议和信令服务 客户端iOS ...
随机推荐
- windows 查看端口号被占用
1.netstat -ano 2.tasklist | findstr xxx 3.进程管理杀掉
- Python之Mail编程
# Mail编程- 管理程序 - Euroda使邮件普及 - Netscape,outlook,forxmail后来居上 - Hotmail使用浏览器发送邮件 ## 邮件工作流程- MUA邮件用户代理 ...
- c#设置button透明
c#设置button透明 1.使用代码进行设置: this.button_welcom_login.FlatStyle = System.Windows.Forms.FlatStyle.Flat; t ...
- jQuery选择器练习中,带空格和不带空格的问题
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- MyBatis中动态SQL元素的使用
掌握MyBatis中动态SQL元素的使用 if choose(when,otherwise) trim where set foreach <SQL>和<include> 在应 ...
- 可序列化serializable的作用是什么
什么情况下需要序列化:a)当你想把的内存中的对象写入到硬盘的时候:b)当你想用套接字在网络上传送对象的时候: 为什么要序列化: 为了将对象可以以流的方式传输到其他位置,就必须要将该对象定义为可序列化的 ...
- nodejs-NPM基本使用
搜索模块 npm search express 更新模块 npm update express 卸载模块 npm uninstall express 安装模块 npm install express ...
- Quartz.Net 使用心得(一)
最近工作内容与定时任务相关,在实际使用Quartz过程中,有两个小问题较为困扰. 一.多个Trigger如何触发一个Job. 比如上下班打卡时推送消息,上班时间为9:30,打卡提醒时间为9:20较好. ...
- 由free命令想到的
root@xdj-Z9PA-D8-Series:~# free -m total used free shared buffers cached Mem: 15977 1683 14293 0 132 ...
- DISCUZ站点DIY后,导致DIY功能失效,无法在前台删除已创建的DIY功能解决的方法
DISCUZ站点DIY后.导致DIY功能失效,无法在前台删除已创建的DIY功能解决的方法.这是一个常常会遇到的问题.在程序调试过程中常常的会遇到这种问题.这里提供一个自己常常使用的解决的方法,供遇到这 ...