📄 camsensor_ov9650.c
字号:
#define RETURN_ON_FALSE(rc) if ((rc)==FALSE) return FALSE
/* From the logic analyzer measurements */
#define OV9650_FULL_SIZE_WIDTH 1280
#define OV9650_FULL_SIZE_HEIGHT 1024
/*
* Maximum number of trials before aborting a register write operation
*
*/
#define MAX_REGISTER_WRITE_TRIALS 3
#define MAX_REGISTER_READ_TRIALS 3
/*
* Time in milisecs for waiting for the sensor to go
* into standby state.
*/
#define SENSOR_STANDBY_DELAY_MSECS 50
/*
* Time in milisecs for waiting for the sensor to reset.
*/
#define SENSOR_RESET_DELAY_MSECS 50
/*
* Sensor rowtime in SXGA mode.
* (In pixel clock units, including row blanking)
*
*/
#define SENSOR_SXGA_ROW_TIME 1520
#define MIN_PIXEL_CLOCK 10000000
#define DEFAULT_PIXEL_CLOCK 24000000
#define MAX_PIXEL_CLOCK 48000000
#define DEFAULT_PREVIEW_FRAME_RATE 15
#define MAX_LINE_STEP 15
/*============================================================================
DATA DECLARATIONS
============================================================================*/
LOCAL const char camsensor_ov9650_sensor_name[] = "Omnivision OV9650 1.3 MP";
LOCAL uint32 previous_line;
/*****************************************************************************
* RUN TIME VARIABLES
****************************************************************************/
/*lint -save -e785*/
LOCAL camsensor_chromatix_output_type camsensor_chromatix_ov9650_struct =
{
#include "chromatix_ov9650.h"
};
/*lint -restore*/
/*============================================================================
MACRO DEFINITIONS
============================================================================*/
/*============================================================================
FORWARD DECLARATIONS
============================================================================*/
LOCAL void camsensor_ov9650_register(camsensor_function_table_type *camsensor_function_table_ptr);
LOCAL void camsensor_ov9650_setup_camctrl_tbl(camctrl_tbl_type *camctrl_tbl_ptr);
LOCAL boolean ov9650_write_register(uint8 reg, uint8 data);
LOCAL boolean ov9650_read_register(uint8 reg, uint8 *data);
LOCAL boolean ov9650_write_register_bit_section(uint8 reg,
uint32 data,
uint8 source_start_bit,
uint8 dest_start_bit,
uint8 bit_section_length);
LOCAL boolean ov9650_initialize_registers(void);
LOCAL float camsensor_ov9650_register_to_real_gain(uint16 reg_gain);
LOCAL uint16 camsensor_ov9650_real_to_register_gain(float gain);
LOCAL camera_ret_code_type camsensor_ov9650_set_frame_rate(uint16 fps);
/*============================================================================
EXPORTED FUNCTIONS
============================================================================*/
/*===========================================================================
FUNCTION CAMSENSOR_OV9650_INIT
DESCRIPTION
Initialize the camera sensor during power up;
DEPENDENCIES
None
RETURN VALUE
if successful
TRUE
else
FALSE
SIDE EFFECTS
None
===========================================================================*/
boolean camsensor_ov9650_init(camsensor_function_table_type *camsensor_function_table_ptr,
camctrl_tbl_type *camctrl_tbl_ptr)
{
uint8 manufacturer_id_msb;
uint8 manufacturer_id_lsb;
uint8 product_id_msb;
uint8 product_id_lsb;
/*
* Check if this is the right sensor:
*/
/* 1. Initiate I2C: */
camsensor_i2c_command.bus_id = I2C_BUS_HW_CTRL;
camsensor_i2c_command.slave_addr = OV9650_I2C_ID;
camsensor_i2c_command.options = I2C_REG_DEV | I2C_STOP_START_BEFORE_READ; /*lint !e655 assignment intentional */
/* 2. Reset sensor: */
if (ov9650_write_register(COM7_REG_ADDRESS,
COM7_REG_SENSOR_RESET_VALUE) == FALSE)
{
return FALSE;
}
/* Wait for the reset operation to complete. */
camera_timed_wait(SENSOR_RESET_DELAY_MSECS);
/* 3. Read sensor manufacturer ID MSB: */
if (ov9650_read_register(MIDH_REG_ADDRESS, &manufacturer_id_msb) == FALSE)
{
return FALSE;
}
/* 4. Read sensor manufacturer ID LSB: */
if (ov9650_read_register(MIDL_REG_ADDRESS, &manufacturer_id_lsb) == FALSE)
{
return FALSE;
}
/* 5. Read sensor product ID MSB: */
if (ov9650_read_register(PID_REG_ADDRESS, &product_id_msb) == FALSE)
{
return FALSE;
}
/* 6. Read sensor product ID LSB: */
if (ov9650_read_register(VER_REG_ADDRESS, &product_id_lsb) == FALSE)
{
return FALSE;
}
/* 7. Compare sensor manufactorer ID to Omnivision manufacturer ID: */
if ( (manufacturer_id_msb != MIDH_REG_DEFAULT_VALUE) ||
(manufacturer_id_lsb != MIDL_REG_DEFAULT_VALUE) )
{
return FALSE;
}
/* 8. Compare sensor product ID to OV9650 product ID: */
if ( (product_id_msb != PID_REG_DEFAULT_VALUE) ||
(product_id_lsb != VER_REG_DEFAULT_VALUE) )
{
return FALSE;
}
/* If we got to this point, the sensor is Omnivision 9650. */
/*
* Initialize sensor's registers.
*/
/* 3. Write default values to HW. */
if (ov9650_initialize_registers() == FALSE)
{
return FALSE;
}
previous_line = 0xFFFF - (MAX_LINE_STEP+1);
/* Register function table: */
camsensor_ov9650_register(camsensor_function_table_ptr);
/* Setup camctrl_tbl */
camsensor_ov9650_setup_camctrl_tbl(camctrl_tbl_ptr);
return TRUE;
} /* camsensor_ov9650_init */
/*===========================================================================
FUNCTION CAMSENSOR_OV9650_START
DESCRIPTION
Initialize the camsensor parameters.
DEPENDENCIES
None
RETURN VALUE
if successful
TRUE
else
FALSE
SIDE EFFECTS
None
===========================================================================*/
boolean camsensor_ov9650_start(camsensor_static_params_type *camsensor_params)
{
/* Check the Chromatix version */
if (camsensor_chromatix_ov9650_struct.chromatix_version != CHROMATIX_DMSS6550_VERSION)
{
return(FALSE);
}
/* Initialize CAMIF operation mode */
camsensor_params->camif_config.SyncMode = CAMIF_APS;
camsensor_params->camif_config.HSyncEdge = CAMIF_High;
camsensor_params->camif_config.VSyncEdge = CAMIF_High;
camsensor_params->camif_efs_config.EFS_EOL = 0x0000;
camsensor_params->camif_efs_config.EFS_SOL = 0x0000;
camsensor_params->camif_efs_config.EFS_EOF = 0x0000;
camsensor_params->camif_efs_config.EFS_SOF = 0x0000;
/* Bayer sensor must enable gamma correction. */
camsensor_params->gammaCorrection = TRUE;
/* Defect pixel correction */
camsensor_params->defectPixelCorrection.enable = TRUE;
camsensor_params->defectPixelCorrection.minThreshold = (uint16)(0.25 * Q6);
camsensor_params->defectPixelCorrection.maxThreshold = (uint16)(1.75 * Q6);
/* Bayer sensor must enable color conversion */
camsensor_params->colorConversion.enable = TRUE;
camsensor_params->colorConversion.Ch0_max = 255;
camsensor_params->colorConversion.Ch1_max = 255;
camsensor_params->colorConversion.Ch2_max = 255;
camsensor_params->colorConversion.Ch0_min = 0;
camsensor_params->colorConversion.Ch1_min = 0;
camsensor_params->colorConversion.Ch2_min = 0;
/* Bayer sensor must enable color correction */
camsensor_params->colorCorrection.enable = TRUE;
camsensor_params->colorCorrection.Ch0_max = 1023; /* G or Y */
camsensor_params->colorCorrection.Ch1_max = 1023; /* B or Cb */
camsensor_params->colorCorrection.Ch2_max = 1023; /* R or Cr */
camsensor_params->colorCorrection.Ch0_min = 0;
camsensor_params->colorCorrection.Ch1_min = 0;
camsensor_params->colorCorrection.Ch2_min = 0;
/* 3x3 luma filter parameters */
camsensor_params->f3x3LumaFilter.A11 = 0;
camsensor_params->f3x3LumaFilter.A12 = 0;
camsensor_params->f3x3LumaFilter.A13 = 0;
camsensor_params->f3x3LumaFilter.A21 = 0;
camsensor_params->f3x3LumaFilter.A22 = 16;
camsensor_params->f3x3LumaFilter.A23 = 0;
camsensor_params->f3x3LumaFilter.A31 = 0;
camsensor_params->f3x3LumaFilter.A32 = 0;
camsensor_params->f3x3LumaFilter.A33 = 0;
/* Black level configuration */
/* 2 black lines of 1024 pixels each = 2048 pixels = 2^11 */
camsensor_params->blackCorrection.enable = FALSE;
camsensor_params->blackCorrection.lastPixel = 1023;
camsensor_params->blackCorrection.firstPixel = 0;
camsensor_params->blackCorrection.lastLine = 1;
camsensor_params->blackCorrection.firstLine = 0;
camsensor_params->blackCorrection.shift = 11;
/* ------------------------------------------- */
/* Configure the extra Camera Layer Parameters */
/* Point to output of Chromatix - for sensor specific params */
camsensor_params->chromatix_parms = &camsensor_chromatix_ov9650_struct;
/* ------------------ Sensor-specific Config -------------- */
/* Make/model of sensor */
camsensor_params->sensor_model = CAMSENSOR_OMNI_VISION_9650;
/* CCD or CMOS */
camsensor_params->sensor_type = CAMSENSOR_CMOS;
/* BAYER or YCbCr */
camsensor_params->output_format = CAMSENSOR_BAYER;
/* What is the maximum FPS that can be supported by this sensor in video mode? */
camsensor_params->max_video_fps = 15 * Q8;
/* Application assigned FPS in video mode */
camsensor_params->video_fps = 15 * Q8;
/* Snapshot mode operation */
camsensor_params->max_preview_fps = 15 * Q8;
camsensor_params->nightshot_fps = 15 * Q8 /2;
/* May be assigned with max_preview_fps or nightshot_fps. */
camsensor_params->preview_fps = 15 * Q8;
/* The following one variables are only used for bayer sensor
* The camif_gain_factor is the ratio between preview and snapshot exposure
* time. A general equation is:
* camif_gain_factor
* = Q8 * (sFPS * pExpLC * sLPF) / (pFPS * sExpLC * pLPF)
* = Q8 sFPS/pFPS * pExpLc/sExpLc * sLPF/pLPF
* p = preview
* s = snapshot
* FPS = frames per second.
* ExpLC = exposure line count.
* LPF = lines per frame (including vertical blanking)
* The camera service will multiply the preview gain with this gain factor
* when encoding the picture.
* camif_gain_factor is in Q8 format. The lower 8 bits are fractional. */
/* Sensor output capability */
/* setup for 1280x1024 */
camsensor_params->full_size_width = OV9650_FULL_SIZE_WIDTH;
camsensor_params->full_size_height = OV9650_FULL_SIZE_HEIGHT;
camsensor_params->qtr_size_width = OV9650_FULL_SIZE_WIDTH;
camsensor_params->qtr_size_height = OV9650_FULL_SIZE_HEIGHT;
camsensor_params->preview_dx_decimation = Q12;
camsensor_params->preview_dy_decimation = Q12;
camsensor_params->camsensor_width = camsensor_params->full_size_width;
camsensor_params->camsensor_height = camsensor_params->full_size_height;
/* A pointer to the sensor name for EXIF tags */
camsensor_params->sensor_name = camsensor_ov9650_sensor_name;
/* Sensor's black level offset in 10 bit domain, used when offset
exists and black rows are not output for VFE to use Black Level
module */
camsensor_params->black_level = 12;
/* ------------ Auto Exposure Control Config -------------- */
camsensor_params->aec_enable = TRUE;
/* Index into the exposure table that is considered the cut
off point for dim indoor lighting conditions */
/* Measured by MVD/achiu on 2/18/05 in lightbox as follows:
*250 LUX target
*Cool white using GretagMacbeth
*pointing sensor toward the back wall of the unit
*value = 255
*/
camsensor_params->indoor_index = 180;
/* Index into the exposure table that is considered the cut
off point for outside lighting conditions ( greater than 2000 LUX) */
/* Measured by MVD/achiu on 2/18/05 in lightbox as follows:
*2000 LUX target
*TL84 using GretagMacbeth
*pointing sensor dirctly up toward the light source and about 1 foot
from the light source to achieve 2000 LUX
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -