基于S5PC100的FIMC控制器解析

摘要:
SCCB实际上是一个弱化的I2C总线。我们可以将相机直接连接到S5PC100的I2C控制器,并使用I2C总线读取和写入寄存器。当然,直接使用GPIO模拟I2C也可以实现读写。S5PC100芯片与称为FIMC的相机控制器集成。事实上,摄像机操作所需的时钟也由FIMC提供。SCCB控制总线功能的实现完全取决于SIO_ C、SIO_ D。实现了两条总线上的电平状态以及它们之间的相互协作。分析FIMC需要从两个方面入手,第一个是CAMIF,第二个是传感器。让我们逐一分析它们。这基本上类似于LCD控制器的定时。

作者:邹南,华清远见嵌入式学院讲师。

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这八根数据线并行送出的。

基于S5PC100的FIMC控制器解析第1张

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总线传输的启动和停止条件如图

基于S5PC100的FIMC控制器解析第2张

过程:采用简单的三相(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摄像头时序如下图:

基于S5PC100的FIMC控制器解析第3张

在获得摄像头ID号后说明sccb通信方式已经正常运行,就可以对内部的控制寄存器进行配置,主要的内部控制其有:

时钟预分频寄存器:

基于S5PC100的FIMC控制器解析第4张

基于S5PC100的FIMC控制器解析第5张

图像缓冲区格式设置寄存器:

基于S5PC100的FIMC控制器解析第6张

增益控制寄存器:

基于S5PC100的FIMC控制器解析第7张

输出模式设置寄存器

基于S5PC100的FIMC控制器解析第8张

配置完成后,在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

基于S5PC100的FIMC控制器解析第9张

1、可同时支持两个摄像头传感器
        2、且3路CRAMIF 可同时操作两个摄像头传感器
        3、CRAMIFn有自己的本地管道通向FIMD
        4、CRAMIFn有私属的AXI总线读写通道

下图给出了各个camif 的属性。

基于S5PC100的FIMC控制器解析第10张

下面来看看如何配置时钟:

基于S5PC100的FIMC控制器解析第11张
图一

基于S5PC100的FIMC控制器解析第12张
图二

基于S5PC100的FIMC控制器解析第13张
图三

简单分析下,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的FIMC控制器解析第14张

基于S5PC100的FIMC控制器解析第15张

从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: ~driversmediavideosamsungfimc
        FIMD: ~driversvideosamsung

这两个是核心目录,包含了所有FIMC/D体系的代码,只是与内核关联的部分涉及到了I2C子系统,平台设备驱动,以及v4l2视频编程接口,推荐看资料《FS_S5PC100平台上Linux Camera驱动开发详解》。

免责声明:文章转载自《基于S5PC100的FIMC控制器解析》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Java如何正确的将数值转化为ArrayList?AutoCAD 自动管理字体插件[使用ObjectARX C++]下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

FPGA基础知识关键点摘要

FPGA基础知识关键点摘要 一.组合逻辑和时序逻辑的区别:组合逻辑与输入直接实时相关,时序逻辑还必须在时钟上升沿出发后输出新值,有没有时钟输入是他们最大的区别!组合时序容易出现竞争冒险现象出现亚稳态,时序逻辑不会出现,且更容易达到时序收敛所以必须很好的掌握时序逻辑 设置不使用的 IO 为 为 in-tri 状态 RTL,Register Transfer...

STM32---喜提点灯

一:编译第一个程序 intmain()  //主函数 { } voidSystemInit()  //在执行主函数前,会被调用。不进行实现。在启动文件中被调用 { } ; Reset handler Reset_Handler PROC EXPORT Reset_Handler...

STM32F030, 使用嘀嗒定时器Systick实现LED闪烁

本文主要解决两个问题 1 STM32的IO口要反转,怎么实现? 2 嘀嗒定时器systick的配置 解答1: 单片机的口,反转非常easy。sbit led = P1 ^6;led = ~led;而STM32的口要让它反转。如何实现呢? 非常easy,对想要反转的IO口取异或: GPIOx->ODR ^= GPIO_Pin; 解答2: SysTi...

32位x86处理器编程架构

1. IA-32架构的基本执行环境 1.1 寄存器的扩展   为了在汇编语言程序中使用经过扩展(Extend) 的寄存器:  在32位模式下,为了生成32位物理地址,处理器需要使用32位的指令指针寄存器。标志寄存器也扩展到32位,第16位和原先保持一致。  32位处理器依然需要以段位单位访问内存,即,只分一个段,段地基地址是0x00000000,段地长度(...

Java内存模型(JMM)总结

Java内存模型(JMM) 我们常说的JVM内存模型指的是JVM的内存分区;而Java内存模型是一种虚拟机规范。 Java虚拟机规范中定义了Java内存模型(Java Memory Model,JMM),用于屏蔽掉各种硬件和操作系统的内存访问差异,实现让Java程序在各种平台下都能达到一致的并发效果,JMM规范了Java虚拟机与计算机内存是如何协同工作的:...

STM32 USART整理说明(转)

  该接口通过3个引脚连接到另外的外部设备上。    任何USART双向通信都至少需要两个引脚:接收数据输入RX和发送数据输出TX。    当发送器禁能时输出引脚恢复到I/O端口配置。当发送器使能时且无数据发送,TX引脚为高电平。     字长可以通过设置USART_CR1寄存器中的M位来选择是8位还是9位。    TX引脚在起始位期间为低,停止位期间为高...