zoukankan      html  css  js  c++  java
  • android camera(四):camera 驱动 GT2005

    摄像头主要参数:

    1、MCLK  24MHz;

    2、PCLK  48~52MHz~;

    3、电压 1.8V(1.5V)、2.8V;

    4、scl(IIC时钟)100KHz或者400KHz。

    下载:常用摄像头规格书(个别有android驱动程序)  :bf3703 30W、gc0308 30W、ov7670、gt2005 200W、gt2015 200W、NT99250 200W、s5k5ba 200W、s5k4ba

    一、摄像头驱动

    我们以GT2005为例,来讲述一个摄像头驱动的调试过程:

    摄像头和主控的关系图,如下:

    摄像头驱动比较简单,完成一面三大步就可以:

    摄像头的上电、时钟这些基本条件;

    IIC保证摄像头的初始化;

    摄像头工作后传回数据到主控。

    完成这三个步骤就完成了摄像头基本工作的调试。

    1、 摄像头的上电、时钟这些基本条件的实现

    电源部分,上电时对应规格书,确认上电时序;MCLK摄像头的主时钟是否提供,看下面是和电和规格书中的

    (1)、主意摄像头工作要两组电压:1.8V(1.5V)、2.8V还有MCLK

    程序中对电源控制:我们在archarmmach-smdkv310.c中,完成上面两个步骤的代码,(这一点不同平台也许有所不同,这里这是一个实例,这部分代码只是针对三星平台的)

    [cpp] view plaincopy
     
    1. #ifdef CONFIG_VIDEO_GT2005  
    2. static void set_cam2005_main_power(int onoff)  
    3.   
    4. {  
    5.   
    6.     unsigned int gpio;  
    7.     int err;  
    8.       
    9.     if(onoff)  
    10.     {  
    11.         err = gpio_request(S5PV210_GPB(2), "GPB");  
    12.         if (err)  
    13.             printk(KERN_ERR "#### failed to request GPB2 for CAM ");  
    14.             s3c_gpio_cfgpin(S5PV210_GPB(2),S3C_GPIO_OUTPUT);  
    15.             s3c_gpio_setpull(S5PV210_GPB(2), S3C_GPIO_PULL_UP);  
    16.             gpio_direction_output(S5PV210_GPB(2), 1);  
    17.             gpio_free(S5PV210_GPB(2));  
    18.   
    19.         //RESET  
    20.             err = gpio_request(S5PV210_GPE1(4), "GPE1");  
    21.             if (err)  
    22.                 printk(KERN_ERR "#### failed to request GPE1_4 for CAM ");  
    23.                 s3c_gpio_setpull(S5PV210_GPE1(4), S3C_GPIO_PULL_NONE);  
    24.                 gpio_direction_output(S5PV210_GPE1(4),0);  
    25.                 mdelay(100);  
    26.                 gpio_direction_output(S5PV210_GPE1(4), 1);  
    27.                 gpio_free(S5PV210_GPE1(4));  
    28.   
    29.   
    30.         //PWDN CAM_back  
    31.             err = gpio_request(S5PV210_GPB(4), "GPB");  
    32.             if (err)  
    33.                 printk(KERN_ERR "#### failed to request GPB4 for CAM ");  
    34.                 s3c_gpio_cfgpin(S5PV210_GPB(4),S3C_GPIO_OUTPUT);  
    35.                 s3c_gpio_setpull(S5PV210_GPB(4), S3C_GPIO_PULL_UP);  
    36.                 gpio_direction_output(S5PV210_GPB(4), 0);  
    37.                 mdelay(100);  
    38.                 gpio_direction_output(S5PV210_GPB(4), 1);  
    39.                 gpio_free(S5PV210_GPB(4));  
    40.   
    41.     }  
    42.     else      
    43.     {     
    44.         ………………  
    45.     }  
    46.     return;  
    47. }  
    48. #endif  

    提供MCLK代码如下:

    [cpp] view plaincopy
     
    1. static int smdkv210_cam_clk_init(void)  
    2. {  
    3.     unsigned int tempvalue=0;  
    4.         tempvalue = readl(S5P_CLK_DIV1);      
    5.     tempvalue = (tempvalue &0xffff0fff);      
    6.     writel(tempvalue,S5P_CLK_DIV1);   
    7.     tempvalue = readl(S5P_CLK_SRC1);      
    8.     tempvalue = (tempvalue &0xffff0fff)|0x00001000;   
    9.     writel(tempvalue,S5P_CLK_SRC1);   
    10.   
    11.     return 0;  
    12. }  

    这时拿示波器抓到上电时的波形和MCLK24MHZ的时钟,信号就说明我们完成了这一步,其实在实际工作中,我们一般出问题的时候才会测这些数据,确认问题点。

    上电时序:

    (1)、上电时序;

    (2)、MCLK如下所示。

    2、 IIC和一些参数的配置

    [cpp] view plaincopy
     
    1. #ifdef CONFIG_VIDEO_GT2005  
    2. static struct GT2005_platform_data GT2005_plat = {  
    3.     .default_width = 640,  
    4.     .default_height = 480,  
    5.     .pixelformat = V4L2_PIX_FMT_UYVY,   //  .freq = 24000000,  
    6.     .is_mipi = 0,  
    7. };  
    8.   
    9. static struct i2c_board_info GT2005_i2c_info = {  
    10.     I2C_BOARD_INFO("GT2005", 0x78 >> 1), //1、IIC地址  
    11.     .platform_data = >2005_plat,  
    12. };  
    13.   
    14. static struct s3c_platform_camera GT2005 = {  
    15. #ifdef CAM_ITU_CH_A  
    16.     .id     = CAMERA_PAR_A,     
    17. #else  
    18.     .id     = CAMERA_PAR_B,  
    19. #endif  
    20.     .type       = CAM_TYPE_ITU,   //2、数据接口选择(ITUMIPI等)  
    21.     .fmt        = ITU_601_YCBCR422_8BIT,  
    22.     .order422   = CAM_ORDER422_8BIT_CBYCRY, //3、图像数据格式   
    23.   
    24.     .i2c_busnum = 1,  
    25.     .info       = >2005_i2c_info,  
    26.     .pixelformat    = V4L2_PIX_FMT_UYVY,      
    27.     .srclk_name = "mout_mpll",              //4、这部分关系到时钟  
    28.     .clk_name   = "sclk_cam1",  
    29.     .clk_rate   = 24000000,             /* 24MHz */   
    30.     .line_length    = 640,              /* 640*480 */  
    31.     /* default resol for preview kind of thing */  
    32.     .width      = 640,  
    33.     .height     = 480,  
    34.     .window     = {  
    35.         .left   = 16,  
    36.         .top    = 0,  
    37.         .width  = (640 - 16),  
    38.         .height = 480,  
    39.     },  
    40.   
    41.     /* Polarity */                            //5、信号的极性,    .inv_pclk   = 0,  
    42.     .inv_vsync  = 1,  
    43.     .inv_href   = 0,  
    44.     .inv_hsync  = 1,  
    45.   
    46.     .initialized    = 0,  
    47.     .cam_power=set_cam2005_main_power  
    48. };  
    49. #endif  

    注意下面几个参数:

    (1)、IIC地址

    (2)、数据接口选择(ITUMIPI等),这几个数据接口我们在前面提到过;

    (3)、图像数据格式 ,这就是我们前面提到的YVUUVY之类不同的数据顺序;

    (4)、这部分关系到时钟;

    (5)、输出信号的极性,就是我们PCLK、VSYNC、HSVNC这些信号的极性,不正确时会没有图像之类现象,这个也要注意了。

    完成这一步确认IIC通信是否正常,如下图所抓到波形:

    3、 完成上面两步,摄像头基本配置完成,我们确认下输出端PCLK、VHSN、SVSN、D1-D7



    二、摄像头调试过程中常遇到的问题

    1、录相在预览时正常,播放录像时花屏(程序解释为三星s5pv210/s5pv310是的,其它的可以参考,找相应代码)

    原因分析:
    (1)录相用fimc2,

    在android/device/samsung/proprietary/libcamera/SecCamera.cpp中
    int SecCamera::startRecord(void)

    [cpp] view plaincopy
     
    1. m_cam_fd_rec = open(CAMERA_DEV_NAME2, O_RDWR);  
    2.   
    3. vendorsecsec_proprietarysmdkc110libcameraSecCamera.h  
    4. #define CAMERA_DEV_NAME2      "/dev/video2"  

    (2)所用的视频格式,在

    android/device/samsung/proprietary/libcamera/SecCameraHWInterface.cpp中

    void CameraHardwareSec::m_initDefaultParameters(int camera_id)

    [cpp] view plaincopy
     
    1.  int default_preview_pixel_format = mSecCamera->getPreviewDefaultPixelFormat();  
    2.     switch (default_preview_pixel_format) {  
    3.     default:  
    4.     case V4L2_PIX_FMT_NV21:  
    5.         p.setPreviewFormat(CameraParameters::PIXEL_FORMAT_YUV420SP);  
    6.         break;  
    7.     case V4L2_PIX_FMT_NV12T:  
    8.         p.setPreviewFormat("yuv420sp_tiled");  
    9.         break;  
    10.     }  
    11.   
    12. 其中mSecCamera->getPreviewDefaultPixelFormat()在  
    13. vendorsecsec_proprietarysmdkc110libcameraSecCamera.cpp中实现,  
    14. int SecCamera::getPreviewDefaultPixelFormat(void)  
    15. {  
    16.     return DEFAULT_PREVIEW_PIXEL_FORMAT;  
    17. }  
    18. 在android/device/samsung/proprietary/libcamera/SecCamera.h中设定初始值。我们这里设的是  
    19. #ifdef DUAL_PORT_RECORDING  
    20.     #define DEFAULT_PREVIEW_PIXEL_FORMAT  (V4L2_PIX_FMT_NV21)  
    21. #else  
    22.     #define DEFAULT_PREVIEW_PIXEL_FORMAT  (V4L2_PIX_FMT_NV12T)  
    23. #endif  

    以上得出视频格式为V4L2_PIX_FMT_NV21。

    2、图像干扰问题,如下图所示

    原因可能是:

    (1)、摄像头模组有问题,换一个摄像头试一下;

    (2)、数据线驱动能力不足,这个可以在摄像头寄存器里面改,问下摄像头模组FAE,看改那些地方;

    (3)、两个摄像头共用数据线时,不工作的摄像头会把工作的数据信号减弱;

    (4)、PCB 走线太长,也会有干扰,不过我觉得这个可能性小,调试好就一款这样的的,模组厂FAE说的,不过他们模组本身也有问题,两方面因素都有吧:PCB(线过长)、模组打样也有问题。

    3、YUV顺序不对:

    yuv顺序不对时,出现如下现象。

    看下摄像头规格书,把相应寄存器的值改一下就可以了。如下以红框里是不同yuv顺序,找到改为相应的。

    4、 预览方向不对(摄像头寄存器只能改以 180度为基数的,90度的就要在FIMC中改)

    想知道和比较明确说明翻转角度,最常用的就是写一个“F”,然后看预览里的是怎么转的。

    上面有90度的翻转,因为这是FIMC中的寄存器,一般不会改这一部分的值。要不就在模组寄存器中改,要不就在上层。上面只是说明如何去确认图像翻转。

    看下GT2005关于翻转的寄存器吧:

    5、 杂光,鬼影:

    其行业的专业术语统称为Flare,是指在拍摄光源或者强光物体时,边缘出现光影或出现一个完整物体的影子,而且这种现象只能减轻不能完全消失,原因是由于镜片的材质导致光线不但存在折射还存在反射,整机由于镜头面到保护镜片距离很大会更明显!

    6、 常见问题相关

    摄像头效果评测都有哪些?

    以上以gt2005为例,说了一下摄像头驱动,和驱动中常见到的问题,如果上面的问题解决,摄像头点亮,说明在平台是运行是没问题的,小的问题和细节,要找模组厂的FAE过来协助解决,不过你想多研究一下的话,也可以,如果项目允许,就多看看,做到调试一个驱动,所有问题都了解,这样对工作经验、积累很重要的,希望对大家有用。

  • 相关阅读:
    深入理解递归函数的调用过程
    关于字符串和字符数组的再讨论
    返回字符串的长度
    再写静态变量的有效范围
    一道关于返回指针和返回数组名的面试题
    关于TCP/IP的三次握手和四次挥手解释
    C++面向对象的编程(二)
    关于面试宝典中的检测并修改不适合的继承
    argc和argv
    基于C的文件操作(转)
  • 原文地址:https://www.cnblogs.com/biglucky/p/4414503.html
Copyright © 2011-2022 走看看