在 OK210 下添加摄像头(自制的 SDIO 摄像头)驱动,请参照如下流程:
1. 修改 X :\WINCE600\PLATFORM\SMDKV210\SRC\DRIVERS\CAMERAIF\HAL\INC camera_typedef.h 文件。
在上述文件中找到 MODULE_SENSOR 结构体,在 UNKNOWN_MODULE 和 MODULE_ID_MAX 之间添加一条记录,用于确定你所添加的摄像头的唯一 ID 标识。记住该标识,该标识对以后的操作非常重要。比如你添加了摄像头 OV9650 的驱动,在标识处你可以添加了标识 OV_9650 (名称自定)。
在结构定义后加入 const char *SENSORNAMES[] = {"SYSLSI_S5K3BA", "SYSLSI_S5K4EAGX", "SYSLSI_S5K6AAFX", "TI_TVP5150", "OV_3640", "OV_9650"}; 字符串定义。
2. 在 VS2005 中的 OK210 的工程文件中 X :\WINCE600\PLATFORM\SMDKV210\SRC\DRIVERS\CAMERAIF\ HAL\MODULES上点击右键,选择 add->new sources subproject
选择 ,在 subproject name 下输入 OV9650_MODULE (名称自定)点击完成。
3. 打开工程自动生成的文件夹,用文本编辑器打开 sources 文件,加入如下代码:
INCLUDES= \
$(INCLUDES); \
$(_TARGETPLATROOT)\src\drivers\CAMERAIF\INC; \
$(_TARGETPLATROOT)\src\drivers\CAMERAIF\HAL\INC; \
$(_TARGETPLATROOT)\src\drivers\C MM; \
4. 打开上述工程,其中 Readme 文件可以删除。在工程中添加两个文件, ov9650_module_regs.h 和 ov9650_module.cpp 。
5. ov9650_module_regs.h中记录了需要写入摄像头 I2C 中的设置值。这些值决定了摄像头的输出数据的基本信息,包括采集信息的数据类型,视频宽度高度等。一般由摄像头供应商提供。
6. ov9650_module.cpp文件主要是提供了 OV9650 的操作类的具体实现。具体代码请参考开发包中的相关文件。
7. 到 X :\WINCE600\PLATFORM\SMDKV210\SRC\DRIVERS\CAMERAIF\HAL\HAL_MAIN 文件夹,用文本编辑工具打开 sources 文件,在 SOURCELIBS 下加入 $(_TARGETPLATROOT)\lib\$(_CPUINDPATH)\ OV9650 _MODULE.lib 一行。
8. 在 X :\WINCE600\PLATFORM\SMDKV210\SRC\DRIVERS\CAMERAIF\HAL\INC 下添加新文件 ov 9650 _module.h (名称自定)
该文件中将设定摄像头的基本定义和 ov9650_module.cpp 文件中的操作类的定义。这里是 OV9650 的该文件代码:
#ifndef __OV9650_MODULE_H__
#define __OV9650_MODULE_H__
//注意这里包含的头文件
#include <bsp.h>
#include "module.h"
#include "camera_typedef.h"
//注意这里的 CAM_OV9650_DEVICE_ID 是硬件摄像头的 I2C 写地址
#define CAM_OV9650_DEVICE_ID 0x60
//这里为 I2C 的系统时钟,最大值不能超过 400 ,推荐 100
#define CAM_OV9650_I2C_CLOCK 100
//========================================================
// OV9650 default mode
//摄像头采集端的模式,一般设置为 ITU601 或者 ITU656 。
//对应 210 寄存器为 CISRCFMT [ n ]> ITU601_656n (第 31 位)
// 1 = ITU-R BT.601 YCbCr 8-bit mode enable
// 0 = ITU-R BT.656 YCbCr 8-bit mode enable
//具体摄像头使用那种采集模式请参阅摄像头数据手册
#define OV9650_MODULE_ITUXXX CAM_ITU601
//指定外部摄像头扫描方法。
//对应 210 寄存器为 CIGCTRL [ n ]> Cam _ Interlace(第 0 位)
//1 =隔行扫描 0= 逐行
//具体摄像头采用扫描方法请参阅摄像头数据手册
//比如 TVP5150 采取的就是逐行扫描方式
#define OV9650_MODULE_INTERLACE 0
//指定外部摄像头的输入模式。
//对应 210 寄存器为 CIGCTRL [ n ]> SelCam_CAMIF (第 3 位)
//1=MIPI模式 0 =ITU 模式
//具体摄像头采用输入模式请参阅摄像头数据手册
#define OV9650_MODULE_MIPI (FALSE)
//指定摄像头在 8 位模式下输入的 YCbCr 顺序
//对应 210 寄存器为 CISRCFMT [ n ]> Order422_CAM[ 第 1 4- 1 5位 ]
// 00 = Y0Cb0Y1Cr0…
// 01 = Y0Cr0Y1Cb0…
// 10 = Cb0Y0Cr0Y1…
// 11 = Cr0Y0Cb0Y1…
//具体摄像头输出数据 YCbCr 顺序请参阅摄像头数据手册并参考摄像头设置字符串。
#define OV9650_MODULE_YUVORDER CAM_ORDER_YCBYCR
//指定源水平像素数(相机或 FIFO 输入)。
//欲了解更多信息,请参阅聚会扩展寄存器( SrcHsize_CAM_ext )。
//该值应该为 16 的倍数。如果 PreHorRatioWinOfsEn 设定为 0 ,则必须为 4 的倍数。
//对应 210 寄存器为 CISRCFMT [ n ]> SrcHsize_CAM[ 第 1 6-28位 ]
//具体摄像头输出数据水平像素数请参阅摄像头数据手册并参考摄像头设置字符串。
#define OV9650_MODULE_HSIZE 640
//指定源垂直像素数(相机或 FIFO 输入)。
//欲了解更多信息,请参阅聚会扩展寄存器( SrcHsize_CAM_ext )。
//该值应该为 PreVerRatio 的倍数。
//如果 V scale down 或者 WinOfsEn 为 0 ,则必须为 2 的倍数。
//对应 210 寄存器为 CISRCFMT [ n ]> SrcVsize _CAM[ 第 0- 1 3位 ]
//具体摄像头输出数据垂直像素数请参阅摄像头数据手册并参考摄像头设置字符串。
#define OV9650_MODULE_VSIZE 480
//指定窗口水平偏移像素单元。
//它应该是 2 的倍数。通道 0 和通道 2 :该值为 16 的倍数。
//对应 210 寄存器为 CIWDOFST [ n ]> WinHorOfst [ 第 16-26 位 ]
//具体摄像头输出数据请参阅摄像头数据手册并参考摄像头设置字符串。
#define OV9650_MODULE_HOFFSET 0
//指定窗口垂直偏移像素单元。隔行输入的情况下,这个值应该是 2 的倍数。
//对应 210 寄存器为 CIWDOFST [ n ]> WinVerOfst [ 第 0-11 位 ]
//具体摄像头输出数据请参阅摄像头数据手册并参考摄像头设置字符串。
#define OV9650_MODULE_VOFFSET 0
//控制 CB , CR 值的偏移量
//对应 210 寄存器为 CISRCFMT [ n ]> UVOffset [ 第 30 位 ]
//具体摄像头输出数据请参阅摄像头数据手册并参考摄像头设置字符串。
#define OV9650_MODULE_UVOFFSET CAM_UVOFFSET_0
//控制摄像头模块的外部输入时钟
//具体摄像头需要使用的外部时钟频率请参阅摄像头数据手册
#define OV9650_MODULE_CLOCK 24000000
//控制 210 输出到显示的输出模式
//对应 210 寄存器为 CISRCFMT [ n ]> OutFormat [ 第 29-30 位 ]
//详细设置请参考 210 芯片数据手册
#define OV9650_MODULE_CODEC CAM_FORMAT_YCBYCR422_1PLANE
#define OV9650_MODULE_HIGHRST 1
#define OV9650_MODULE_INVPCLK 1
#define OV9650_MODULE_INVVSYNC 0
#define OV9650_MODULE_INVHREF 0
#define OV 9650_MODULE_ OUTFLIP 1
//下面是 OV9650 摄像头操作类的设置,请参考该类的设置书写自己的摄像头操作类。
//========================================================
// OV9650 infomation
class OV9650 : public CamModule
{
public:
OV9650();
OV9650(ICamComm *CommIF);
~OV9650();
MODULE_STATUS Init();
MODULE_STATUS Deinit();
MODULE_STATUS InitSensor();
MODULE_STATUS Power(BOOL bOnOff);
MODULE_STATUS Standby(BOOL bActive);
MODULE_STATUS Reset(BOOL bActive);
MODULE_STATUS GetSupportFormat(MODULE_DESCRIPTOR *outModuleDesc);
MODULE_STATUS SetFormatSize(CAMIF_IMG_SIZE Size);
MODULE_STATUS SensorPrepare();
MODULE_STATUS SensorStart();
};
#endif //__OV9650_MODULE_H__
9. 修改 X :\WINCE600\PLATFORM\SMDKV210\SRC\DRIVERS\CAMERAIF\HAL\MODULES\COMMON \ module_interface.cpp 文件。
在文件中找到 ModuleInit 函数,在 switch 中加入 case OV_9650: g_pCamModule = new OV9650(); break;其中 OV_9650 为摄像头的唯一 ID 标识, OV9650 是操作类的名称。
10. 修改文件 X :\WINCE600\PLATFORM\SMDKV210\SRC\DRIVERS\CAMERAFILTER\CAMERA_PDD \ camera_pdd.cpp
在文件中找到 GetVideoFormatList 函数,在 switch 循环中加入 OV9650 的选项。
其中参数 DCAM_StreamMode_REG565_640X480_30 可以在 sensorformats.h 文件中修改。
关于默认摄像头的选择。
(1)更新11月补丁后,需要更改WINCE600\PLATFORM\SMDKV210\SRC\BOOTLOADER\EBOOT下的menu.c文件。在menu.c文件中找到m_menuCameraType函数,在摄像头选择项中增加一条。在SetCameraType函数中,修改dwCameraType>6为新的数值。
(2)未更新11月补丁前,在CAMERAFILTER\CAMERA_PDD文件夹下找到source文件,用文本编辑器打开。找到下面这段代码:
!if 1
CDEFINES=$(CDEFINES) -DCAMERA_PORT=CAM_A_PORT
CDEFINES=$(CDEFINES) -DCAMERA_MODULE_NAME=OV_3640
!endif
将其中的OV_3640改为OV_9650(唯一标识)。