📄 ov2630.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
//
// (C) Copyright 2006 Marvell International Ltd.
// All Rights Reserved
//
#include <windows.h>
#include <ceddk.h>
#include "Cs.h"
#include "Csmedia.h"
#include "CameraPDDProps.h"
#include "dstruct.h"
#include "dbgsettings.h"
#include <Camera.h>
#include "CameraDriver.h"
#include "PinDriver.h"
#include "SensorFormats.h"
#include "monahans.h"
#include "Ov2630.h"
#include "Ov2630_hw.h"
#include "Camera_SOC.h"
#include "GPIO_platform.h"
#include "GPIO_SOC.h"
#include "GPX_API.h"
PHYSICAL_ADDRESS PA;
MAKE_STREAM_MODE_YV12(DCAM_StreamMode_QCIF_YV12_Convert, 176, -144, 12, 15);
MAKE_STREAM_MODE_YV12(DCAM_StreamMode_CIF_YV12, 352, -288, 12, 15);
MAKE_STREAM_MODE_YV12(DCAM_StreamMode_SVGA_YV12, 800, -600, 12, 30);
MAKE_STREAM_MODE_YV12(DCAM_StreamMode_UXGA_YV12, 1600, -1200, 12, 15);
MAKE_STREAM_MODE_IJPG(DCAM_StreamMode_UXGA_IJPG, 1600, 1200, 16, 15);
MAKE_STREAM_MODE_IJPG(DCAM_StreamMode_CIF_IJPG, 352, 288, 16, 15);
MAKE_STREAM_MODE_IJPG(DCAM_StreamMode_SVGA_IJPG, 800, 600, 16, 15);
UCHAR get_analog_gain(UINT16 gain);
void get_digi_gain(UINT16 gain, UCHAR* digi_gain1, UCHAR* digi_gain2);
static color_cfg_t color_cfg =
{
0,
(UCHAR*)NULL,
{
(float)1.036, (float)0.097, (float)-0.133,
(float)-0.006, (float)1.217, (float)-0.211,
(float)0.012, (float)-0.386, (float)1.374
}
};
//Convert from RAW10 to YV16 by QCI HW, Convert from CIF to QCIF and YV16 to YV12 by SW
static camera_cfg_t strQCIFYV12 =
{
&DCAM_StreamMode_QCIF_YV12_Convert,
PXA_CAMERA_IMAGE_FORMAT_RAW10, /* sensor format *///input format to QCI
CIF,
/* qci_format_t */
{
PXA_CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR,//output format from QCI
352, 288
},
&color_cfg
};
static camera_cfg_t strCIFYV12 =
{
&DCAM_StreamMode_CIF_YV12,
PXA_CAMERA_IMAGE_FORMAT_RAW10, /* sensor format */
CIF,
/* qci_format_t */
{
PXA_CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR,
352, 288
},
&color_cfg
};
static camera_cfg_t strCIFIJPG =
{
&DCAM_StreamMode_CIF_IJPG,
PXA_CAMERA_IMAGE_FORMAT_RAW10, /* sensor format */
CIF,
/* qci_format_t */
{
PXA_CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR,
352, 288
},
&color_cfg
};
static camera_cfg_t strSVGAYV12 =
{
&DCAM_StreamMode_SVGA_YV12,
PXA_CAMERA_IMAGE_FORMAT_RAW10, /* sensor format */
SVGA,
/* qci_format_t */
{
PXA_CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR,
800, 600
},
&color_cfg
};
static camera_cfg_t strSVGAIJPG =
{
&DCAM_StreamMode_SVGA_IJPG,
PXA_CAMERA_IMAGE_FORMAT_RAW10, /* sensor format */
SVGA,
/* qci_format_t */
{
PXA_CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR,
800, 600
},
&color_cfg
};
static camera_cfg_t strUXGAIJPG =
{
&DCAM_StreamMode_UXGA_IJPG,
PXA_CAMERA_IMAGE_FORMAT_RAW10, /* sensor format */
UXGA,
/* qci_format_t */
{
PXA_CAMERA_IMAGE_FORMAT_RAW10,
//PXA_CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR,
1600, 1200
},
&color_cfg
};
static camera_cfg_t strUXGAYV12 =
{
&DCAM_StreamMode_UXGA_YV12,
PXA_CAMERA_IMAGE_FORMAT_RAW10, /* sensor format */
UXGA,
/* qci_format_t */
{
//PXA_CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR,
PXA_CAMERA_IMAGE_FORMAT_RAW10,
1600, 1200
},
&color_cfg
};
static qci_interface_t ov2630_interface =
{
PXA_CI_MODE_MP,
PXA_CI_DATA_WIDTH10,
2600,
FALSE,
FALSE,
FALSE
};
static UCHAR lut[] = {
// RED Look up table
0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, 0x18, 0x1c,
0x20, 0x24, 0x28, 0x2c, 0x30, 0x34, 0x38, 0x3c,
0x40, 0x44, 0x48, 0x4c, 0x50, 0x54, 0x58, 0x5c,
0x60, 0x64, 0x68, 0x6c, 0x70, 0x74, 0x78, 0x7c,
0x80, 0x84, 0x88, 0x8c, 0x90, 0x94, 0x98, 0x9c,
0xa0, 0xa4, 0xa8, 0xac, 0xb0, 0xb4, 0xb8, 0xbc,
0xc0, 0xc4, 0xc8, 0xcc, 0xd0, 0xd4, 0xd8, 0xdc,
0xe0, 0xe4, 0xe8, 0xec, 0xf0, 0xf4, 0xf8, 0xfc,
// BLUE Look up table
0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, 0x18, 0x1c,
0x20, 0x24, 0x28, 0x2c, 0x30, 0x34, 0x38, 0x3c,
0x40, 0x44, 0x48, 0x4c, 0x50, 0x54, 0x58, 0x5c,
0x60, 0x64, 0x68, 0x6c, 0x70, 0x74, 0x78, 0x7c,
0x80, 0x84, 0x88, 0x8c, 0x90, 0x94, 0x98, 0x9c,
0xa0, 0xa4, 0xa8, 0xac, 0xb0, 0xb4, 0xb8, 0xbc,
0xc0, 0xc4, 0xc8, 0xcc, 0xd0, 0xd4, 0xd8, 0xdc,
0xe0, 0xe4, 0xe8, 0xec, 0xf0, 0xf4, 0xf8, 0xfc,
// GREEN Look up table
0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, 0x18, 0x1c,
0x20, 0x24, 0x28, 0x2c, 0x30, 0x34, 0x38, 0x3c,
0x40, 0x44, 0x48, 0x4c, 0x50, 0x54, 0x58, 0x5c,
0x60, 0x64, 0x68, 0x6c, 0x70, 0x74, 0x78, 0x7c,
0x80, 0x84, 0x88, 0x8c, 0x90, 0x94, 0x98, 0x9c,
0xa0, 0xa4, 0xa8, 0xac, 0xb0, 0xb4, 0xb8, 0xbc,
0xc0, 0xc4, 0xc8, 0xcc, 0xd0, 0xd4, 0xd8, 0xdc,
0xe0, 0xe4, 0xe8, 0xec, 0xf0, 0xf4, 0xf8, 0xfc,
};
#define SENSOR_INIT_WAIT 150
#ifdef DEBUG
static void dump_Ov2630();
#endif
static IppiRawPixProcSpec_P3R* rggb2yuv_init(UINT32 width,
UINT32 height,
float* coe);
static void rggb2yuv_deinit(IppiRawPixProcSpec_P3R *ippiRPPSpec);
extern void fill_buffer_yv12(PUCHAR* dest_plane, frame_t* frame);
static void yv16_to_yv12_convert_rotate_shrink(PUCHAR* dest_plane, frame_t* frame);
bool Ov2630::Initialize()
{
m_pRGB2YUVBuf = (PUCHAR)malloc(1600*1200*3/2);//malloc buffer for IPP using to change from RAW RGB to YUV411
if (NULL == m_pRGB2YUVBuf)
{
ERRORMSG(1,(L"[Camera]: RGB2YUV malloc Failed!!!"));
return FALSE;
}
qci_interface = &ov2630_interface;
timing.BFW = 0x01;
timing.BLW = 0x01; /*GRBG to RGGB*/
m_SkipFrames = 3;
#if 0
rpp_mcu = rggb2yuv_init(1600, 1200, color_cfg.color_correct_coe);
if (NULL == rpp_mcu)
{
ERRORMSG(1,(L"[Camera]: IPP Initializing Failed!!!"));
return FALSE;
}
#endif
return TRUE;
}
void Ov2630::DeInitialize()
{
if (m_pRGB2YUVBuf)
{
free(m_pRGB2YUVBuf);
m_pRGB2YUVBuf = NULL;
}
#if 0
if (rpp_mcu)
{
rggb2yuv_deinit(rpp_mcu);
rpp_mcu = NULL;
}
#endif
}
bool Ov2630::detect()
{
UINT8 pid = 0, rev = 0;
OV2630VersionRevision(&pid, &rev);
RETAILMSG(1, (TEXT("CAM: Detect OV2630 sensor PID 0x%x, REV 0x%x!\r\n"),pid, rev));
return pid == PIDH_OV2630 && rev == PIDL_OV2630;
}
UINT32 Ov2630::get_formats(ULONG type, PCS_DATARANGE_VIDEO** formats)
{
// Video Format initialization
UINT32 nformats = 1;
*formats = new PCS_DATARANGE_VIDEO[nformats];
if( NULL == *formats )
{
return 0;
}
switch (type)
{
case CAPTURE:
case PREVIEW:
(*formats)[0] = &DCAM_StreamMode_QCIF_YV12_Convert;
break;
case STILL:
//(*formats)[0] = &DCAM_StreamMode_UXGA_YV12;
(*formats)[0] = &DCAM_StreamMode_UXGA_IJPG;
//(*formats)[0] = &DCAM_StreamMode_CIF_YV12;
//(*formats)[0] = &DCAM_StreamMode_CIF_IJPG;
//(*formats)[0] = &DCAM_StreamMode_SVGA_IJPG;
break;
default:
break;
}
return nformats;
}
void Ov2630::start_capture()
{
UINT16 exposure = 250;
UINT16 gain = 4;
if (frame_size == UXGA)
{
exposure *= 2;
}
OV2630AutoFunctionOff();
OV2630ViewfinderOn();
set_exposure_gain(exposure, gain);
// dump_Ov2630();
//For CETK "Video capture filter and camera driver component test" 1104 sub-case "PinFlowingTests".
//OV2630 sends out the first frame too slow, it takes about 150ms to send out after starting OV2630.
//So, a trick is to delay some time here, to shorten the interval between the next "RUN" command and receiving the first frame.
//Sleep(100);
}
void Ov2630::stop_capture()
{
OV2630ViewfinderOff();
}
//extern void set_voltage(UCHAR camera_ana, UCHAR camera_io, UCHAR camera_core, BOOL is_on);
enum SensorPowerPins
{
DOVDD = 0x13,// sensor pin name, PMIC LDO Regs
AVDD = 0x14,
DVDD = 0x92
};
#define PMIC_REG_CTRL 0x17
void Ov2630::set_voltage(UCHAR camera_ana, UCHAR camera_io, UCHAR camera_core, BOOL is_on)
{
UCHAR reg;
pic_read_reg(AVDD, ®);
if ((reg & 0xf) != camera_ana)
pic_write_reg(AVDD, (reg & 0xf0) | camera_ana);
#ifdef SETUP_IO_CORE_VOLTAGE
pic_read_reg(DOVDD, ®);
pic_write_reg(DOVDD, (reg & 0xf0) | camera_io);
pic_read_reg(DVDD, ®);
if ((reg & 0xf) != camera_core)
pic_write_reg(DVDD, (reg & 0xf0) | camera_core);
#endif
const UCHAR ldo_en = 0x80;
UCHAR set_value = is_on? ldo_en : 0;
pic_read_reg(PMIC_REG_CTRL, ®);
if ((reg & ldo_en) != set_value)
{
reg &= ~ldo_en;
pic_write_reg(PMIC_REG_CTRL, reg | set_value);
}
}
void Ov2630::set_power_mode(bool is_on)
{
set_voltage(0xa, 0xa, 0x0, is_on);
/* Call_GPX */
GPX_SetDirection(GPX_GPIO_CAMERA_HI_PWDN, PXA_GPIO_DIRECTION_OUT);
OV2630PowerDown(is_on? PXA_CAMERA_POWER_FULL : PXA_CAMERA_POWER_OFF);
if (is_on)
Sleep(200);
}
camera_cfg_t* Ov2630::get_camera_cfg(PCS_VIDEOINFOHEADER pCsVideoInfoHdr, ULONG mode)
{
UINT32 width = abs(pCsVideoInfoHdr->bmiHeader.biWidth);
UINT32 height = abs(pCsVideoInfoHdr->bmiHeader.biHeight);
switch (pCsVideoInfoHdr->bmiHeader.biCompression & ~BI_SRCPREROTATE)
{
case FOURCC_IJPG:
{
if (width == 352 && height == 288)
return &strCIFIJPG;
else if (width == 1600 && height == 1200)
return &strUXGAIJPG;
else if (width == 800 && height == 600)
return &strSVGAIJPG;
else
ERRORMSG(1,(L"[Camera]: FOURCC_IJPG Unrecognized resolution!"));
break;
}
case FOURCC_YV12:
{
if (width == 176 && height == 144)
return &strQCIFYV12;
else if (width == 352 && height == 288)
return &strCIFYV12;
else if (width == 1600 && height == 1200)
return &strUXGAYV12;
else if (width == 800 && height == 600)
return &strSVGAYV12;
else
ERRORMSG(1,(L"[Camera]: FOURCC_YV12 Unrecognized resolution!"));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -