源码地址:https://github.com/yogach/linux-drive/tree/master/cmos_ov7740
硬件原理
自然景观->摄像头模块->硬件接口->S3C2440的摄像头控制器->LCD
ov7740(摄像头模块)
输入信号: 自然景观等的模拟信号
输出信号: RGB、YUV格式的数字信号
1). ov7740参数
输入信号: 自然景观等的模拟信号
输出信号:
可输出格式为:RAW RGB、YUV
可输出分辨率为:VGA(640*480)、QVGA(240*320)、CIF(352*288)、更小的任意大小
有效感光阵列的大小:656*488 = 320128(30W)像素
镜头的大小:1/5寸
像素点颗粒的大小: 4.2um * 4.2um
总结:
以上三个参数,用来描述感光阵列,同为30W像素的摄像头,镜头尺寸越小,那么对应的像素点颗粒就越小,从而感光性就越差,进而拍摄的效果就越差。
输入时钟频率: 6~27MHz 即0V7740摄像头模组的工作频率范围。
扫描模式: 连续扫描
概念介绍:
连续扫描(P):从左到右 一行一行扫描。(720p的p就是代表连续扫描)
隔行扫描(I):每次间隔一行进行扫描
2).ov7740内部数据的处理流程
a.image sensor core 图像传感器核心部分:
翻转、增益大小调整、黑电平校准、饱和度的控制、OTP存储器
b.image sensor processor 图像传感器处理( 由自带DSP处理)部分:
提供测试功能(可默认采集到的图片是一块固定的图片)、镜头补偿功能、自动白平衡、RAW RGB->RGB、RGB->YUV、窗口功能(将采集到原始进行裁剪)、缩小放大功能。
c.image output interface 图像输出接口部分:
输出数据格式RAW RGB/YUV、输出分辨率VGA/QVGA、数据传输方式BT601/BT656。
问:以上这些处理过程,不需要我们人为的做任何设置,它们都能自动完成吗?
答:以上这些处理过程,只有极少部分是自动完成的,而剩余部分是需要我们设置后,才能完成。
问:怎么对它们进行设置呢?
答:是通过IIC总线,操作OV7740的寄存器来进行设置的。
问:RAW RGB与RGB的区别是什么?
答:所谓的RAW RGB就是只有红绿蓝三种颜色的数据。而RGB数据,它不仅只表示红绿蓝三种颜色,而且还能表示由红绿蓝组合成的任何一种颜色。
问:RGB、YUV又分别是什么?
答:RGB、YUV是两种完全不同的颜色空间,它们之间可以相互转换。
3). 原理图(硬件接口)
控制类:
IICSDA -- IIC总线的数据线
IICSCL -- IIC总线的时钟线
数据传输类:
CAMRST -- 复位CMOS摄像头模块
CAMCLK -- 摄像头模块工作的系统时钟(24MHz)
CAM_HREF -- 行同步信号
CAM_VSYNC -- 帧同步信号
CAM_PCLK -- 像素时钟
CAMDATA0~7 -- 数据线
总结:
1.CMOS摄像头模块的接口分为两类:
(1)控制类
-- 初始化:对摄像头模块进行相应的初始化操作,让摄像头模块能够正常的输出摄像头数据
-- 控制: 设置亮度、旋转、缩放等等的操作
(2)数据传输类: 与LCD的接口完全一样。
2.ov7740摄像头模块的控制类是一个IIC设备,需要给它写符合IIC设备那套架构的驱动,从而实现初始化和灵活的控制。
此驱动进行设置之后,摄像头输出的数据格式如下:
分辨率为640*480、30fps、格式YUV、传输方式BT601
4)s3c2440摄像头控制器(CAMIF)
s3c2440摄像头控制器支持BT601、BT656传输方式,支持YUV方式输入编码、支持最高分辨率为4096*4096
问:BT601与BT656的传输方式有什么区别?
答:BT601有独立的行同步信号线、帧同步信号线,而BT656是将这两种信号内嵌到数据中。
支持输入的数据: BT601/656 分辨率4096*4096 8bitYUV
数据处理:可分为预览通道和编码通道。
预览通道:用于预览(画中画)最大支持640*480分辨率,支持缩放、颜色空间转化、旋转,支持RGB16/24格式输出,也支持输出到缓存。
编码通道:用于编码使用,最大支持4096*4096分辨率,支持缩放、编码、旋转,支持YCbCr422/422格式输出,也支持输出到缓存。
中断:中断会在帧同步信号的下降沿时触发,此时可读取帧数据。
二、驱动编写
使用的内核:linux-3.4.2
参考源码:
第32课_新内核下的I2C驱动\i2c\1th_i2c_new_device
第2课第1.1.7节文档和图片(从0写USB摄像头)\myuvc
// camif寄存器设置
// CAMIF
/*
CISRCFMT:
bit[31] -- 选择传输方式为BT601或者BT656(1-BT601)
bit[30] -- 设置偏移值(0 = +0 (正常情况下) - for YCbCr)
bit[29] -- 保留位,必须设置为0
bit[28:16] -- 设置源图片的水平像素值(640)
bit[15:14] -- 设置源图片的颜色顺序(存储格式)(02 = CbYCrY )
bit[12:0] -- 设置源图片的垂直像素值(480)
*/
static unsigned long* CISRCFMT;
/*
CIWDOFST:
bit[31] -- 1 = 使能窗口功能、0 = 不使用窗口功能(此处选1)
bit[30、15:12]-- 清除溢出标志位
bit[26:16] -- 水平方向的裁剪的大小
bit[10:0] -- 垂直方向的裁剪的大小
*/
static unsigned long* CIWDOFST;
/*
CIGCTRL:
bit[31] -- 软件复位CAMIF控制器
bit[30] -- 用于复位外部摄像头模块
bit[29] -- 保留位,必须设置为1
bit[28:27] -- 用于选择信号源(00 = 输入源来自摄像头模块)
bit[26] -- 设置是否翻转像素时钟的极性(猜0)
bit[25] -- 设置是否翻转VSYNC的极性(0)
bit[24] -- 设置是否翻转HREF的极性(0)
*/
static unsigned long* CIGCTRL;
//设置显存物理起始地址 用于DMA
static unsigned long* CIPRCLRSA1;
static unsigned long* CIPRCLRSA2;
static unsigned long* CIPRCLRSA3;
static unsigned long* CIPRCLRSA4;
/*
CIPRTRGFMT:
bit[28:16] -- 表示目标图片的水平像素大小(TargetHsize_Pr)
bit[15:14] -- 是否旋转(00-不旋转)
bit[12:0] -- 表示目标图片的垂直像素大小(TargetVsize_Pr)
*/
static unsigned long* CIPRTRGFMT;
/*
CIPRCTRL:
bit[23:19] -- 主突发长度(Main_burst)
bit[18:14] -- 剩余突发长度(Remained_burst)
bit[2] -- 是否使能LastIRQ功能(不使能)
*/
static unsigned long* CIPRCTRL;
/*
CIPRSCPRERATIO:
bit[31:28]: 预览缩放的变化系数(SHfactor_Pr)
bit[22:16]: 预览缩放的水平比(PreHorRatio_Pr)
bit[6:0]: 预览缩放的垂直比(PreVerRatio_Pr)
CIPRSCPREDST:
bit[27:16]: 预览缩放的目标宽度(PreDstWidth_Pr)
bit[11:0]: 预览缩放的目标高度(PreDstHeight_Pr)
CIPRSCCTRL:
bit[29:28]: 告诉摄像头控制器(图片是缩小、放大)(ScaleUpDown_Pr)
bit[24:16]: 预览主缩放的水平比(MainHorRatio_Pr)
bit[8:0]: 预览主缩放的垂直比(MainVerRatio_Pr)
bit[31]: 必须固定设置为1
bit[30]: 设置图像输出格式是0-RGB16、1-RGB24
bit[15]: 预览缩放开始
*/
static unsigned long* CIPRSCPRERATIO;
static unsigned long* CIPRSCPREDST;
static unsigned long* CIPRSCCTRL;
/*
CIPRTAREA:
表示预览通道的目标区域大小 此区域用于DMA功能 值为目标宽度*目标高度
*/
static unsigned long* CIPRTAREA;
/*
CIIMGCPT:
bit[31]: 用来使能摄像头控制器
bit[30]: 使能编码通道
bit[29]: 使能预览通道
*/
static unsigned long* CIIMGCPT;
如何得到设备地址?
在ov7740手册中写明了设备地址:
写 -- 0x42(01000010)
读 -- 0x43(01000011)
8bit的地址 = 7bit设备地址(高七位) + 1bit的读/写控制位(低一位)
设备地址 = 0100001 = 0x21
问:为什么需要复位摄像头模块?
答:IIC能够正常操作CMOS摄像头模块内部的寄存器的前提是:
-- 提供符合它需求的系统时钟(CAMCLK)
-- 需要给它一个复位信号
问:怎样才能复位摄像头模块?
答:通过操作CAMIF控制器中相应的寄存器,让CAMRST发出复位信号,从而复位摄像头模块,具体操作见驱动源码。
主突发长度
如果我们需要传输48字节数据,但是DMA无法一次性传输48字节,我们就要分批发送
按每次10字节发,此时这个10字节就称为主突发长度 。
48字节 = 10字节 + 10字节 + 10字节 + 10字节 + 8字节
剩余突发长度
继续上述例子,48字节按每10字节发送完毕后,最后一个8字节就是剩余突发长度。
三、驱动测试条件:
1.
要有IIC总线驱动;
要有LCD驱动;
2.
要配置上V4L2相关选项
Device Drivers --->
<*> Multimedia support --->
<*> Video For Linux
[*] Video capture adapters (NEW) --->
[*] V4L USB devices (NEW) --->
[*] V4L platform devices --->