美文网首页嵌牛IT观察
调试相机问题总结

调试相机问题总结

作者: oliverabc | 来源:发表于2017-10-23 14:30 被阅读81次

    调试相机问题总结

    姓名:张猛

    引用自:http://blog.csdn.net/tang_jin_chan/article/details/22584387

    【嵌牛导读】:上一周终于解决了hi3518e驱动ov9712并能实时的传输视频,经历了一周多的调试,总结一下这个心酸的过程。主要是参考了网上的一个博客,在这里分享给大家。

    【嵌牛鼻子】:硬件、测试、相机、行同步、场同步

    【嵌牛提问】:拿到一个陌生的相机应该怎么去认识它,并能控制调试控制它。

    【嵌牛正文】:

    1-1.DVP接口:

    官方提供的硬件参考原理图是10根数据线的DVP,而这边的硬件是8根数据线的DVP.并且在官方提供的datasheet并没有找到DVP配置的寄存器.OV好多东西进行了保留,有些寄存器数据手册写着是保留的,但是从其提供过来的sample code却是有所配置的.后来验证了其提供的sample code是支持8bit的DVP;

    1-2.SCCB通讯失败:

    SCCB兼容IIC协议,因此这边直接通过IIC总线操作.之所以出现SCCB通讯失败的原因,我这边主要是因为OV9712的SCCB操作之前需要有MCLK,而MCLK是由CIM(CAMERA控制器)提供.这边的CIM输出的MCLK时钟的使能是受控的,在open的时候使能MCLK输出.通过SCCB操作OV9712之前使能MCLK输出即可.基本上,要进行CMOS操作之前都需要进行MCLK输出,如格科威GC0308;

    1-3.是否正确出图难以判断:

    这边要求的OV9712输出为WXGA(1280x800),而且硬件是新布的,没有镜头调焦距,并且手头只有2.8寸屏(分辨率为320x240),直接铺屏虽然手在CMOS上晃lcd有所反应,但是不能作为正确出图的依据,而且DVP接口屏蔽掉低两位,图像的完整性更无从谈起.后面通过将OV9712出来的Bayer格式通过软件编程分别转换成8位位图、RGB565、RGB888保存图片并通过两次的跳行跳列把Bayer转换为RGB565数据处理显示在320x240LCD上才得以验证图像的完整性.相关代码参考网上,但是都或多或少有问题并存在兼容性可移植性问题,这边已经完善修复,后续提供修正后的相关源代码;

    1-4.HERF模式:

    一般比较复杂的设备都是通过两大部件和主控完成通讯的.一个部件是操作设备内部的功能单元,如配置内部寄存器,这些功能单元都是通过一定的协议完成的.如OV9712通过SCCB配置其图像效果,声卡UDA1341通过L3协议调节音量;另一部件则是有效数据的交互,如CMOS通过VSYNC、HSYNC、PCLK、DATA PORT来配合完成图像数据,声卡UDA1341则通过IIS总线完成音频数据的传输.OV9712默认就是采用HERF模式(见datasheet),在一帧图像传输过程中HERF脚为低,而不像HSYNC(行同步信号)在一帧图像传输过程中有电平变化(这当然了,一帧图像是有多个行数据组成的).在HERF模式下,主控端需要配置HSYNC脚为下降沿有效;

    1-5.别扭的datasheet:

    格科威的datasheet比较简单明了,比如要配置图像的宽度高度DVP位数都有明确的寄存器.而OV9712,是直接"位"操作.比如配置WXGA(1280x800)的寄存器,根据datasheet说明如下:0x58是Vertical Size MSBs的高8位,这里写0xc8,还有低两位在0x57寄存bit[1:0](值为0),一共10位,拼成10bit就是1100100000b,转换成10进制就是800;0x59Output Horizontal Size MSBs,这里写0xA0,还有低三位在0x57寄存器bit[4:2](值为0),拼成11位就是10100000000b,转换成10进制就是1280.提外话,更为复杂的是美光的MI367,提供了两种地址访问.

    2-1.图像输出格式:

    CMOS都有图像输出格式的,如BAYER(BGGR),YUV422(平铺)等.这将可能涉及到主控平台CIM端的接收数据的顺序还有上层针对CMOS图像格式处理的编程.如某CMOS输出的图像格式是YUV422打包格式,我们可以通过设置CIM端FIFO的对数据的接收顺序控制,使得FIFO端的YUV422打包格式到了DMA层变成了YUV422平铺格式,这一步是硬件完成的,这时候再到达用户空间的图像数据必然是YUV422平铺格式了.针对此图像格式需要通过编程实现转换成RGB565或RGB888.因此,用户空间程序处理明确你要处理的图像数据是什么格式,否则就是乱七八糟的图像显示(这一点可以自行补充一下图像相关的知识);

    2-2.极性匹配:

    CMOS和主控端的VSYNC、HSYNC和PCLK的极性要一致,比如VSYNC是上升沿有效还是下降沿有效.参考主控平台和CMOS的数据手册可以实现配置两者极性一致.否则有可能出现图像丢数据或色素偏差甚至获取不了图像(DMA计数达不到预期数量);

    2-3.图像数据接收顺序:

    一般而言,如果CPU有支持数据打包方式,即把sensor端接收过来的4个8字节拼成32位的一个字的排序,需要选择或者尝试多种拼接方式.

    新拿到的硬件,是好是坏,或者有没有一些大意或细节的错误,当然需要驱动程序并结合一些电气工具如(示波器)去检测.

    1.SCCB:

    当然这是最首检测也是必须检测的.这里我是用iic-tools工具(LINUX平台支持用户空间驱动的项目,需要内核编译相关的支持).源码可以网上搜索移植.后续会提供我这边提供整理简化的IIC-TOOLS源码.iic-tools是LINUX平台调试IIC设备的利器.一共有i2cdetect,i2cset,i2cget,i2cdump四个工具,可以遍历iic总线上的设备.其具体用法可网上搜索.OV9712标识了其SCCB设备地址为0x60,如果i2cdetect出来的结果和其设备地址有出入,就需要检查一下硬件了.当然,前期是可以用iic-tools工具大体检测,如果是有特殊接口API要求,则就需要具体的API编程.例如下面是我获取OV9712的PID的函数:

    unsigned short ov9712GetId(int iic_fd)

    {unsigned short pid = 0;

    unsigned char tmp = 0;

    iic_set_addr(iic_fd,OV9712ADDR);

    tmp =iic_read(iic_fd,PIDHADDR);

    pid =tmp;

    pid = pid<< 8;

    tmp =iic_read(iic_fd,PIDLADDR);

    pid = pid |tmp;

    if(0x9711== pid)

    printf("Found Sensor OV9712.So Lucky!\n");

    else

    printf("Oops:Miss OV9712.\n");

    returnpid;

    }

    0x9711是OV9712的产品ID,可以查看其数据手册.

    这里曾遇到个问题,就是SCCB通讯失败,原因是OV9712必须有MCLK才可以SCCB通讯的.

    2.初始化OV9712:

    确认SCCB通讯是没问题的,就直接往OV9712堆sample code吧.把原厂提供的初始化代码通过SCCB协议,往里面塞.塞完寄存器后大体量一下MCLK、VSYNC、HSYNC、PCLK及DATA引脚,都有信号输出并且是正常的.截取了一部分原始数据铺在320x240的屏上显示只有一些彩条乱七八糟的.出现这种情况当时就往两个方向想了:一个是极性问题;第二个对出来的图像数据直接铺屏(RGB565)的问题.

    2-1.极性匹配:

    厂家提供的代码里面间没有对VSYNC、HSYNC和PCLK的极性进行重新配置,就是采用默认的.于是查找OV9712数据手册找到VSYNC、HSYNC、PCLK的极性控制寄存器.如下:

    可见,OV9712的VSYNC、HSYNC默认的极性是Positive,即上升沿有效.

    注意,这里不要这里的寄存器坑了,HSYNC默认确实是positive,但是前提是你选定的是HSYNC模式.OV9712支持三种模式:HREF、HSYNC、CCIR565.默认的就是HERF模式而不是HSYNC模式.HERF和HSYNC是同一个pin脚,不同的是,HERF模式下,HERF引脚为低的时候VSYNC引脚输出才有效.见OV9712的数据手册的时序图,如下:

    因此,在HREF模式下,是下降沿有效的.在这种模式下主控端需要配置HSYNC引脚为下降沿有效.我把JZ4776主控端配置成上升沿有效的时候,是获取不了图片的.既然废弃了HSYNC行同步,那么会不会出现行同步不一致而导致主控拒绝接收数据呢?个人认为,有VSYNC足够了,它引发了中断,就意味着一帧图像传输完毕,主控端就可以去处理数据了,HSYNC是可以被忽略的.如果遇到一些平台比较严格的话,还需要处理HSYNC同步的话,就具体处理了.

    PCLK的极性如下:

    因此,我们可以确定HREF模式下PIN脚VSYNC、HREF(HSYNC)、PCLK的极性分别为:

    VSYNC:上升沿;

    HERF(HSYNC):下降沿;

    PCLK:上升沿.

    因此,再根据设备去配置主控端的相应极性:

    默认的VSYN和PCLK极性是一致的,主要是把HSP配置为1(即下降沿有效).

    2-2.接收图像的顺序:

    一般CPU的CIM控制器都有从SENSOR端过来的接收到的数据进行重组排序处理的.一般而言,SENSOR端输出的是YUV或RAWRGB,一般而言,数据手册都可以找到明确其明确格式,比如OV9712的图像输出格式就是BAYER(RAW DATA)中的一种.从其数据手册可以看到如下字样:

    The color filters are arranged in a Bayer pattern. Theprimary color BG/GR array is arranged in line-alternating fashion.

    「小技巧:」无论是YUV还是RAW DATA,如果是接收顺序反了的话,一般都有轮廓.可以适当尝试一下别的字节重组顺序.JZ4775对从SENSOR接收过来的4个字节拼成32位的字,有下面8种方式:

    这里选择第五种方式,即3'b100.高低位调转的方式.核对了上述两点之外,出来的图像依然看不出图像的完整性.配置依然可能存在问题,镜头也没调焦距,上层转换函数也有可能存在问题.这三个方面的因素都有可能导致同样的现象.于是想了下有没有更好更直接的快捷方式.通过查阅OV9712的数据手册,发现其提供了个test pattern模式.进入这种模式下,显示8段彩条.如下:

    当然,还要设置寄存器0xca进入TestPattern模式.代码如下:

    void ov9712TestPattern(int iic_fd)

    {

    iic_write(iic_fd,0xca,0x24);

    iic_write(iic_fd,0x12,0x02);

    iic_write(iic_fd,0x97,0x88);

    }

    然后把SENSOR端过来的数据转RGB565保存起来,发现图片有断层情况.后来检查发现是转换函数的bmp头构造得有问题.修复后效果和test pattern一致.为了调试方便,决定把转换出来的RGB565(1280 X 800)显示在2.8寸屏(320 x 240)上.通过跳行跳列实现.代码如下:

    Function:

    Skip OneRow And One Column.

    Date:

    2014-3-29

    Author:

    SE7EN

    void skipPiexl1(const u16 *inBuf,u16 *outBuf,const u32width,const u32 height,u32 div)

    {

    assert((inBuf && outBuf && (0 == (width % 4) &&(0 == (height % 4)) && (0 == (div % 4)))));

    const u16*pInW = inBuf;

    u16 *pOut =outBuf;

    u32 i = 0,j= 0,k = 0,sum = 0,aver = 0;

    for(i = 0;i < height; i+=2)

    {

    for(j = 0; j < width; j+=2)

    {

    *pOut = *pInW;

    pOut++;

    pInW +=2;

    }

    pInW = pInW + width;

    }

    }

    因为我的是竖屏,因此还需要把两次缩放的像素buf旋转90度,代码如下:

    Function:

    OperationFor RGB.

    Date:

    2014-3-29

    Author:

    SE7EN

    */

    #include "skippiexl.h"

    void rgb565_rotate90(const u16 *input, u16 *output,u32width_in,u32 height_in)

    {const u16*pIn=input;

    u16*pOut=output;

    inti,j;

    for(i=0;i

    {

    for(j=0; j

    {*pOut = *pIn++;

    pOut = output+height_in*j + i;

    }

    }

    }

    3.小结:

    SENSOR其实是挺复杂的一个东西,很多过中涉及的概念都只是有个笼统的概念.在此作录备忘,后续还需要调试图像质量,这个只能靠技术支持了.

    相关文章

      网友评论

        本文标题:调试相机问题总结

        本文链接:https://www.haomeiwen.com/subject/fyzouxtx.html