📄 image_sensor.c
字号:
*************************************************************************/
void ConfigMinFrameRate(const float fFPS)
{
/****************************************************************
* The unit of exposure time is 8 times of OPCLKˇs period. *
* OPCLK is the internal clock to process one pixel. *
* OPCLK = MCLK * 1/2 * Clock Divider *
* To = 1/OPCLK, period of OPCLK *
* Max Exp time = EXPMAX[23:0] * 8 * To *
****************************************************************/
static const kal_uint32 iOPCLK = MCLK_FOR_MC501CB / CLOCK_DIVIDER_FOR_CAMERA / 2;
const kal_uint32 iMaxExp = (kal_uint32) (iOPCLK / fFPS / 8);
ASSERT(iMaxExp < (1 << 24));
CHANGE_TO_PAGE(3);
write_cmos_sensor(0x38, iMaxExp >> 16);
write_cmos_sensor(0x39, (iMaxExp >> 8) & 0x000000FF);
write_cmos_sensor(0x3A, iMaxExp & 0x000000FF);
} /* ConfigMinFrameRate */
/*************************************************************************
* FUNCTION
* ConfigHBlank
*
* DESCRIPTION
* This function is to set HBlank size.
*
* PARAMETERS
* iBlank: target HBlank size
* iHz: banding frequency
* RETURNS
* None
*
* GLOBALS AFFECTED
*
*************************************************************************/
void ConfigHBlank(const kal_uint16 iBlank)
{
/********************************************************************
* HBLANKH, HBLANKL must be changed together, otherwise no effect *
********************************************************************/
ASSERT(iBlank < 4096);
CHANGE_TO_PAGE(0);
write_cmos_sensor(0x1B, iBlank >> 8);
write_cmos_sensor(0x1C, iBlank & 0x00FF);
} /* ConfigHBlank */
/*************************************************************************
* FUNCTION
* MC501CB_PowerOff
*
* DESCRIPTION
* This function is to turn off sensor module power.
*
* PARAMETERS
* None
*
* RETURNS
* None
*
* GLOBALS AFFECTED
*
*************************************************************************/
void MC501CB_PowerOff(void)
{
#ifndef GEMINI25_DEMO_BB
cis_module_power_on(KAL_FALSE); // power off sensor
SET_SCCB_CLK_LOW;
SET_SCCB_DATA_LOW;
#else
cis_module_power_on(KAL_FALSE); // power off sensor
#endif
} /* MC501CB_PowerOff */
#ifdef GEMINI25_DEMO_BB
void MC501CB_EnterSleep(void)
{
/*Add by Kate*/
CHANGE_TO_PAGE(0);
write_cmos_sensor(0x01, 0x01); // power sleep mode on
// PowerDownCurSensor(DUAL_SENSOR2);
/*Add by Kate*/
} /* MC501CB_PowerOff */
#endif
/*************************************************************************
* FUNCTION
* MC501CB_Get_I2C_ID
*
* DESCRIPTION
* This function return the sensor read/write IDs of I2C I/F.
*
* PARAMETERS
* *pI2C_WriteID : address pointer of sensor's I2C write id
* *pI2C_ReadID : address pointer of sensor's I2C read id
*
* RETURNS
* None
*
* GLOBALS AFFECTED
*
*************************************************************************/
void MC501CB_Get_I2C_ID(kal_uint8 *pI2C_WriteID, kal_uint8 *pI2C_ReadID)
{
*pI2C_WriteID = MC501CB_I2C_WRITE_ID;
*pI2C_ReadID = MC501CB_I2C_READ_ID;
} /* MC501CB_Get_I2C_ID */
/*************************************************************************
* FUNCTION
* MC501CB_GetSize
*
* DESCRIPTION
* This function return the image width and height of image sensor.
*
* PARAMETERS
* *pWidth : address pointer of horizontal effective pixels of image sensor
* *pHeight : address pointer of vertical effective lines of image sensor
*
* RETURNS
* None
*
* GLOBALS AFFECTED
*
*************************************************************************/
void MC501CB_GetSize(kal_uint16 *pWidth, kal_uint16 *pHeight)
{
*pWidth = IMAGE_SENSOR_VGA_WIDTH; // valid pixel # in one frame
*pHeight = IMAGE_SENSOR_VGA_HEIGHT; // valid line # in one frame
} /* MC501CB_GetSize */
/*************************************************************************
* FUNCTION
* MC501CB_GetPeriod
*
* DESCRIPTION
* This function return the image width and height of image sensor.
*
* PARAMETERS
* *pPixelNumber : address pointer of pixel numbers in one period of HSYNC
* *pLineNumber : address pointer of line numbers in one period of VSYNC
*
* RETURNS
* None
*
* GLOBALS AFFECTED
*
*************************************************************************/
void MC501CB_GetPeriod(kal_uint16 *pPixelNumber, kal_uint16 *pLineNumber)
{
/************************************
* No need for YUV sensor driver *
************************************/
// *pPixelNumber = VGA_PERIOD_PIXEL_NUMS; // pixel numbers in one period of HSYNC
// *pLineNumber = VGA_PERIOD_LINE_NUMS; // line numbers in one period of VSYNC
} /* MC501CB_GetPeriod */
/*************************************************************************
* FUNCTION
* MC501CB_Preview
*
* DESCRIPTION
* This function configure the sensor to preview mode.
*
* PARAMETERS
*
* RETURNS
* None
*
* GLOBALS AFFECTED
*
*************************************************************************/
void MC501CB_Preview(image_sensor_exposure_window_struct *pImage_Window, image_sensor_config_struct *pSensor_Config_Data)
{
kal_uint8 iHV_Mirror = 0;
kal_uint8 iStartX = 0, iStartY = 1;
kal_uint8 iTemp = 0;
if (pSensor_Config_Data->frame_rate != 0x0F) {
/************************************************************************************
* Restore original exposure time *
* Preview mode(AE enable) - Capture mode(AE disable) - Preview mode(AE enable) *
* 1.Set manual exposure time (wanted value) after AE off. *
* 2.To come back preview mode, Set initial manual exposure time and toggle *
* (off-on-off) bit[3] of page:3[0x12](Initial AE) in AE off. *
* 3.And AE enable. *
************************************************************************************/
CHANGE_TO_PAGE(3);
write_cmos_sensor(0x33, g_iPreviewExp >> 16);
write_cmos_sensor(0x34, (g_iPreviewExp >> 8) & 0x000000FF);
write_cmos_sensor(0x35, g_iPreviewExp & 0x000000FF);
iTemp = read_cmos_sensor(0x12) & 0xF7;
write_cmos_sensor(0x12, iTemp); // turn off initial AE control
write_cmos_sensor(0x12, iTemp | 0x08); // turn on initial AE control
write_cmos_sensor(0x12, iTemp & 0xF7); // turn off initial AE contrl
}
iTemp = read_cmos_sensor(0x10);
write_cmos_sensor(0x10, iTemp | 0x80); // enable AE
CHANGE_TO_PAGE(4);
iTemp = read_cmos_sensor(0x10);
write_cmos_sensor(0x10, iTemp | 0x80); // enable AWB
if ((pSensor_Config_Data->isp_op_mode == ISP_MJPEG_PREVIEW_MODE) ||
(pSensor_Config_Data->isp_op_mode == ISP_MJPEG_ENCODE_MODE)) { // Motion JPEG mode
g_bVideoMode = KAL_TRUE;
g_bMJPEGMode = KAL_TRUE;
// config TG for video recorder mode
SET_TG_OUTPUT_CLK_DIVIDER(3); // MCLK = 13MHz
SET_CMOS_RISING_EDGE(0);
SET_CMOS_FALLING_EDGE(2);
SET_TG_PIXEL_CLK_DIVIDER(7);
SET_CMOS_DATA_LATCH(4);
// PCLK = [Clock_Divider] * MCLK
CHANGE_TO_PAGE(0);
iTemp = read_cmos_sensor(0x12) & 0xF4;
write_cmos_sensor(0x12, iTemp | 0x01); // set clock divider to 1/2, PCLK = 1/2 MCLK
// disable VBLANK clipping
ConfigVBlank(VBLANK_VIDEO_PREVIEW);
ConfigHBlank(HBLANK_EXTRA_VIDEO_PREVIEW);
/************************************************
* VBLANK clipping must < VBLANK, otherwise *
* there will be no sensor output. *
************************************************/
write_cmos_sensor(0x1F, VBLANK_VIDEO_CLIPPING); // setup VBLANK clipping < VBLANK
iTemp = read_cmos_sensor(0x12) & 0xF7;
write_cmos_sensor(0x12, iTemp | 0x08); // enable VBLANK clipping
}else if (pSensor_Config_Data->frame_rate == 0x0F) { // MPEG4 Encode Mode
g_bVideoMode = KAL_TRUE;
g_bMJPEGMode = KAL_FALSE;
// config TG for video recorder mode
SET_TG_OUTPUT_CLK_DIVIDER(1); // MCLK = 26MHz
SET_CMOS_RISING_EDGE(0);
SET_CMOS_FALLING_EDGE(1);
SET_TG_PIXEL_CLK_DIVIDER(3);
SET_CMOS_DATA_LATCH(2);
// PCLK = [Clock_Divider] * MCLK
CHANGE_TO_PAGE(0);
iTemp = read_cmos_sensor(0x12) & 0xF4;
write_cmos_sensor(0x12, iTemp | 0x01); // set clock divider to 1/2, PCLK = 1/2 MCLK
// disable VBLANK clipping
ConfigVBlank(VBLANK_VIDEO_PREVIEW);
ConfigHBlank(HBLANK_EXTRA_VIDEO_PREVIEW);
/************************************************
* VBLANK clipping must < VBLANK, otherwise *
* there will be no sensor output. *
************************************************/
write_cmos_sensor(0x1F, VBLANK_VIDEO_CLIPPING); // setup VBLANK clipping < VBLANK
iTemp = read_cmos_sensor(0x12) & 0xF7;
write_cmos_sensor(0x12, iTemp | 0x08); // enable VBLANK clipping
}else { // normal camera preview mode
g_bVideoMode = KAL_FALSE;
g_bMJPEGMode = KAL_FALSE;
g_bCaptureMode = KAL_FALSE;
// PCLK = [Clock_Divider] * MCLK
CHANGE_TO_PAGE(0);
iTemp = read_cmos_sensor(0x12) & 0xF4;
write_cmos_sensor(0x12, iTemp | 0x00); // set CLK divider to 1x, PCLK = MCLK
// disable VBLANK clipping
// config TG for camera preview mode
SET_TG_OUTPUT_CLK_DIVIDER(1); // MCLK = 26MHz
SET_CMOS_RISING_EDGE(0);
SET_CMOS_FALLING_EDGE(1);
SET_TG_PIXEL_CLK_DIVIDER(1);
SET_CMOS_DATA_LATCH(1);
ConfigVBlank(VBLANK_CAMERA_PREVIEW);
#ifdef SLOW_DOWN_SENSOR_FOR_240X320_LCD
ConfigHBlank(HBLANK_EXTRA_CAMERA_PREVIEW_WITH_240x320_LCD);
#else
ConfigHBlank(HBLANK_EXTRA_CAMERA_PREVIEW);
#endif
/************************************************
* VBLANK clipping must < VBLANK, otherwise *
* there will be no sensor output. *
************************************************/
write_cmos_sensor(0x1F, VBLANK_CAMERA_CLIPPING); // setup VBLANK clipping < VBLANK
iTemp = read_cmos_sensor(0x12) & 0xF7;
write_cmos_sensor(0x12, iTemp | 0x08); // enable VBLANK clipping
}
CHANGE_TO_PAGE(0);
iHV_Mirror = read_cmos_sensor(0x11) & 0xFC;
switch (pSensor_Config_Data->image_mirror) {
case IMAGE_NORMAL:
iHV_Mirror |= 0x00;
if (g_bVideoMode == KAL_TRUE) {
SET_CAMERA_INPUT_ORDER(INPUT_ORDER_YCbY1Cr);
iStartX = 0;
iStartY = 1;
}else {
SET_CAMERA_INPUT_ORDER(INPUT_ORDER_YCbY1Cr);
iStartX = 0;
iStartY = 1;
}
break;
case IMAGE_HV_MIRROR:
iHV_Mirror |= 0x03;
if (g_bVideoMode == KAL_TRUE) {
SET_CAMERA_INPUT_ORDER(INPUT_ORDER_YCbY1Cr);
iStartX = 0;
iStartY = 1;
}else {
SET_CAMERA_INPUT_ORDER(INPUT_ORDER_YCbY1Cr);
iStartX = 0;
iStartY = 1;
}
break;
default:
ASSERT(0);
}
write_cmos_sensor(0x11, iHV_Mirror);
pImage_Window->grab_start_x = iStartX;
pImage_Window->grab_start_y = iStartY;
pImage_Window->exposure_window_width = IMAGE_SENSOR_VGA_WIDTH - iStartX;
pImage_Window->exposure_window_height = IMAGE_SENSOR_VGA_HEIGHT - iStartY;
} /* MC501CB_Preview */
/*************************************************************************
* FUNCTION
* MC501CB_Capture
*
* DESCRIPTION
* This function configures the sensor to capture mode.
*
* PARAMETERS
*
* RETURNS
* None
*
* GLOBALS AFFECTED
*
*************************************************************************/
void MC501CB_Capture(image_sensor_exposure_window_struct *pImage_Window, image_sensor_config_struct *pSensor_Config_Data)
{
kal_uint8 iStartX = 0, iStartY = 1, iTemp, iMask = 0x00;
kal_uint32 iExp;
g_bCaptureMode = KAL_TRUE;
if (pSensor_Config_Data->frame_rate == 0xF0) {
/************************************
* Webcam mode, AE/AWB still on *
************************************/
// PCLK = [Clock_Divider] * MCLK
CHANGE_TO_PAGE(0);
iTemp = read_cmos_sensor(0x12) & 0xF4;
write_cmos_sensor(0x12, iTemp | 0x00); // set CLK divider to 1x, PCLK = MCLK
// and disable VSYNC clipping
ConfigVBlank(WEBCAM_MODE_VBLANK);
ConfigHBlank(WEBCAM_MODE_HBLANK);
/************************************************
* VBLANK clipping must < VBLANK, otherwise *
* there will be no sensor output. *
************************************************/
write_cmos_sensor(0x1F, WEBCAM_MODE_VBLANK_CLIP); // setup VSYNC clipping size
iTemp = read_cmos_sensor(0x12) & 0xF7;
write_cmos_sensor(0x12, iTemp | 0x08); // enable VSYNC clipping
}else {
/********************************
* Normal camera capture mode *
********************************/
CHANGE_TO_PAGE(3);
iTemp = read_cmos_sensor(0x10) & 0x7F;
write_cmos_sensor(0x10, iTemp); // disable AE
// get the latest exposure in preview mode
iExp = (read_cmos_sensor(0x30) << 16) |
(read_cmos_sensor(0x31) << 8) |
read_cmos_sensor(0x32);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -