📄 image_sensor.c
字号:
write_cmos_sensor(0x9b, 0x04);
write_cmos_sensor(0x9c, 0x07);
write_cmos_sensor(0x9d, 0x10);
write_cmos_sensor(0x9e, 0x28);
write_cmos_sensor(0x9f, 0x36);
write_cmos_sensor(0xa0, 0x44);
write_cmos_sensor(0xa1, 0x52);
write_cmos_sensor(0xa2, 0x60);
write_cmos_sensor(0xa3, 0x6c);
write_cmos_sensor(0xa4, 0x78);
write_cmos_sensor(0xa5, 0x8c);
write_cmos_sensor(0xa6, 0x9e);
write_cmos_sensor(0xa7, 0xbb);
write_cmos_sensor(0xa8, 0xd2);
write_cmos_sensor(0xa9, 0xe5);
#else
write_cmos_sensor(0xaa, 0x20);
write_cmos_sensor(0x9b, 0x02);
write_cmos_sensor(0x9c, 0x07);
write_cmos_sensor(0x9d, 0x11);
write_cmos_sensor(0x9e, 0x2e);
write_cmos_sensor(0x9f, 0x3c);
write_cmos_sensor(0xa0, 0x4a);
write_cmos_sensor(0xa1, 0x59);
write_cmos_sensor(0xa2, 0x66);
write_cmos_sensor(0xa3, 0x73);
write_cmos_sensor(0xa4, 0x80);
write_cmos_sensor(0xa5, 0x96);
write_cmos_sensor(0xa6, 0xa5);
write_cmos_sensor(0xa7, 0xc1);
write_cmos_sensor(0xa8, 0xd4);
write_cmos_sensor(0xa9, 0xe8);
#endif
write_cmos_sensor(0xAB, 0xe7);
write_cmos_sensor(0xb0, 0x43);
write_cmos_sensor(0xac, 0x04);
write_cmos_sensor(0x84, 0x40);
write_cmos_sensor(0xad, 0x86);//82
write_cmos_sensor(0xd9, 0x44);//33
write_cmos_sensor(0xda, 0x00);
write_cmos_sensor(0xae, 0x10);
write_cmos_sensor(0xab, 0xe7);
write_cmos_sensor(0xb9, 0x50);
write_cmos_sensor(0xba, 0x3c);
write_cmos_sensor(0xbb, 0x50);
write_cmos_sensor(0xbc, 0x3c);
write_cmos_sensor(0xbd, 0x8);
write_cmos_sensor(0xbe, 0x19);
write_cmos_sensor(0xbf, 0x2);
write_cmos_sensor(0xc0, 0x8);
write_cmos_sensor(0xc1, 0x2a);
write_cmos_sensor(0xc2, 0x34);
write_cmos_sensor(0xc3, 0x2d);
write_cmos_sensor(0xc4, 0x2d);
write_cmos_sensor(0xc5, 0x0);
write_cmos_sensor(0xc6, 0x98);
write_cmos_sensor(0xc7, 0x18);
write_cmos_sensor(0x69, 0x48);
write_cmos_sensor(0x74, 0xc0);
write_cmos_sensor(0x7c, 0x28);//18
write_cmos_sensor(0x65, 0x11);
write_cmos_sensor(0x66, 0x00);
write_cmos_sensor(0x41, 0xc0);//a0
write_cmos_sensor(0x5b, 0x24);//28
write_cmos_sensor(0x60, 0x82);//84
write_cmos_sensor(0x05, 0x07);
write_cmos_sensor(0x03, 0x03);
write_cmos_sensor(0xd2, 0x94);//8c
write_cmos_sensor(0xc7, 0x90);
write_cmos_sensor(0xc8, 0x06);
write_cmos_sensor(0xcb, 0x40);
write_cmos_sensor(0xcc, 0x40);
write_cmos_sensor(0xcf, 0x00);
write_cmos_sensor(0xd0, 0x20);
write_cmos_sensor(0xd1, 0x00);
write_cmos_sensor(0xc7, 0x18);
write_cmos_sensor(0x0d, 0x92);
write_cmos_sensor(0x0d, 0x90);
normal_gain=read_cmos_sensor(0x00);
sensor_gain_base=read_OV9660_gain();
return 1;
} /* init_cmos_sensor() */
/*************************************************************************
* FUNCTION
* power_off_OV9660
*
* DESCRIPTION
* This function is to turn off sensor module power.
*
* PARAMETERS
* None
*
* RETURNS
* None
*
* GLOBALS AFFECTED
*
*************************************************************************/
void power_off_OV9660(void)
{
cis_module_power_on(KAL_FALSE); // Power Off CIS Power
UPLL_Disable(UPLL_OWNER_ISP);
#ifndef HW_SCCB
SET_SCCB_CLK_LOW;
SET_SCCB_DATA_LOW;
#endif
} /* power_off_OV9660 */
/*************************************************************************
* FUNCTION
* get_OV9660_id
*
* DESCRIPTION
* This function return the sensor read/write id of SCCB interface.
*
* PARAMETERS
* *sensor_write_id : address pointer of sensor write id
* *sensor_read_id : address pointer of sensor read id
*
* RETURNS
* None
*
* GLOBALS AFFECTED
*
*************************************************************************/
void get_OV9660_id(kal_uint8 *sensor_write_id, kal_uint8 *sensor_read_id)
{
*sensor_write_id=OV9660_WRITE_ID;
*sensor_read_id=OV9660_READ_ID;
} /* get_OV9660_id */
/*************************************************************************
* FUNCTION
* get_OV9660_size
*
* DESCRIPTION
* This function return the image width and height of image sensor.
*
* PARAMETERS
* *sensor_width : address pointer of horizontal effect pixels of image sensor
* *sensor_height : address pointer of vertical effect pixels of image sensor
*
* RETURNS
* None
*
* GLOBALS AFFECTED
*
*************************************************************************/
void get_OV9660_size(kal_uint16 *sensor_width, kal_uint16 *sensor_height)
{
*sensor_width=IMAGE_SENSOR_FULL_WIDTH; /* pixel numbers actually used in one frame */
*sensor_height=IMAGE_SENSOR_FULL_HEIGHT; /* line numbers actually used in one frame */
} /* get_OV9660_size */
/*************************************************************************
* FUNCTION
* get_OV9660_period
*
* DESCRIPTION
* This function return the image width and height of image sensor.
*
* PARAMETERS
* *pixel_number : address pointer of pixel numbers in one period of HSYNC
* *line_number : address pointer of line numbers in one period of VSYNC
*
* RETURNS
* None
*
* GLOBALS AFFECTED
*
*************************************************************************/
void get_OV9660_period(kal_uint16 *pixel_number, kal_uint16 *line_number)
{
*pixel_number=PV_PERIOD_PIXEL_NUMS; /* pixel numbers in one period of HSYNC */
*line_number=PV_PERIOD_LINE_NUMS; /* line numbers in one period of VSYNC */
} /* get_OV9660_period */
void OV9660_preview(image_sensor_exposure_window_struct *image_window, image_sensor_config_struct *sensor_config_data)
{
kal_uint8 temp_v_flip_reg2 = read_cmos_sensor(0x04);
kal_uint8 temp_v_flip_reg1 = (temp_v_flip_reg2 & (~0xC0));
kal_uint8 temp_h_mirror_reg2 = read_cmos_sensor(0x33);
kal_uint8 temp_h_mirror_reg1 = (temp_h_mirror_reg2 & (~0x08));
sensor_cap_state=KAL_FALSE;
#ifdef OUTPUT_DEBUG_INFO
sprintf(temp_buffer, "Begin of OV9660_preview");
rmmi_write_to_uart((kal_uint8*) temp_buffer, strlen(temp_buffer), KAL_TRUE);
sprintf(temp_buffer, "pre_shut:%d", exposure_lines);
rmmi_write_to_uart((kal_uint8*) temp_buffer, strlen(temp_buffer), KAL_TRUE);
#endif
kal_prompt_trace(MOD_ENG,"temp_v_flip_reg2=0x%x, temp_h_mirror_reg2=0x%x",temp_v_flip_reg2,temp_h_mirror_reg2);
write_cmos_sensor(0x12, 0x40); //vga mode
write_cmos_sensor(0x63, 0x00); //
write_cmos_sensor(0x4d, 0x09); //
write_cmos_sensor(0x17, 0x0d); //0c
write_cmos_sensor(0x18, 0x5d); //5c
write_cmos_sensor(0x19, 0x02);
write_cmos_sensor(0x1a, 0x3f);
write_cmos_sensor(0x03, 0x03);
write_cmos_sensor(0x32, 0xad); //0x32
write_cmos_sensor(0x2b, 0x00);
write_cmos_sensor(0x64, 0xa4);
write_cmos_sensor(0xab, 0xe7);
write_cmos_sensor(0xb9, 0x50);
write_cmos_sensor(0xba, 0x3c);
write_cmos_sensor(0xbb, 0x50);
write_cmos_sensor(0xbc, 0x3c);
write_cmos_sensor(0x0d, 0x92);
write_cmos_sensor(0x0d, 0x90);
gPVmode=KAL_TRUE;
// write_cmos_sensor(0x11,0x80); //clock PCLK = XCLK / 2 0x80 means double clock
// 1. Sensor's clock control register setting may cause sensor output some abnormal frame even if
// it is written with the same value twice
// 2. MJPEG preview/capture use the same clock divider, no need to update for
// MJPEG encode mode
if (sensor_config_data->isp_op_mode != ISP_MJPEG_ENCODE_MODE) {
write_cmos_sensor(0x11, 0x80);
}
if((sensor_config_data->isp_op_mode == ISP_MJPEG_PREVIEW_MODE) ||
(sensor_config_data->isp_op_mode==ISP_MJPEG_ENCODE_MODE)) {
MPEG4_encode_mode=KAL_FALSE;
/* config TG of ISP to match the setting of image sensor*/
#if 0
write_cmos_sensor(0x11, 0x01); //ADD 20080315
SET_TG_OUTPUT_CLK_DIVIDER(3); //7
SET_CMOS_RISING_EDGE(0);
SET_CMOS_FALLING_EDGE(2); // 4
ENABLE_CAMERA_PIXEL_CLKIN_ENABLE;
SET_TG_PIXEL_CLK_DIVIDER(3); ///7-->3
SET_CMOS_DATA_LATCH(3);
#else
write_cmos_sensor(0x11, 0x80); //ADD 20080315
SET_TG_OUTPUT_CLK_DIVIDER(7); //7
SET_CMOS_RISING_EDGE(0);
SET_CMOS_FALLING_EDGE(4); // 4
ENABLE_CAMERA_PIXEL_CLKIN_ENABLE;
SET_TG_PIXEL_CLK_DIVIDER(7); ///7-->3
SET_CMOS_DATA_LATCH(3);
#endif
//write_cmos_sensor(0x4F, 0x9e);
//write_cmos_sensor(0x50, 0x84);
//write_cmos_sensor(0x5A, 0x23);
//dummy_pixels=0;
//dummy_lines=(MIN_LINES_PER_FRAME-PV_PERIOD_LINE_NUMS);
//dummy_lines&=(~0x1);
write_cmos_sensor(0x4F, 0x4B);//9e
write_cmos_sensor(0x50, 0x4B);//84
write_cmos_sensor(0x5A, 0x67);//23
start_grab_x_offset=0;
start_grab_y_offset=0;
dummy_pixels=0X4d;
dummy_lines=0;
image_window->grab_start_x=IMAGE_SENSOR_PV_INSERTED_PIXELS+start_grab_x_offset;
image_window->grab_start_y=IMAGE_SENSOR_PV_INSERTED_LINES+dummy_lines+start_grab_y_offset ;
image_window->exposure_window_width=IMAGE_SENSOR_PV_WIDTH-4;
image_window->exposure_window_height=IMAGE_SENSOR_PV_HEIGHT-50;
}else if(sensor_config_data->frame_rate==0x0F) { // MPEG4 Encode Mode
MPEG4_encode_mode=KAL_TRUE;
/* config TG of ISP to match the setting of image sensor*/
SET_TG_OUTPUT_CLK_DIVIDER(3);
SET_CMOS_RISING_EDGE(0);
SET_CMOS_FALLING_EDGE(2);
ENABLE_CAMERA_PIXEL_CLKIN_ENABLE;
SET_TG_PIXEL_CLK_DIVIDER(3); ///7-->3
SET_CMOS_DATA_LATCH(3);
//write_cmos_sensor(0x4F, 0x9e);
//write_cmos_sensor(0x50, 0x84);
//write_cmos_sensor(0x5A, 0x23);
//dummy_pixels=0;
//dummy_lines=(MIN_LINES_PER_FRAME-PV_PERIOD_LINE_NUMS);
//dummy_lines&=(~0x1);
write_cmos_sensor(0x4F, 0x4B);//9e
write_cmos_sensor(0x50, 0x4B);//84
write_cmos_sensor(0x5A, 0x67);//23
dummy_pixels=0X4d;
dummy_lines=0;
start_grab_x_offset=0;
start_grab_y_offset=0;
image_window->grab_start_x=IMAGE_SENSOR_PV_INSERTED_PIXELS+start_grab_x_offset;
image_window->grab_start_y=IMAGE_SENSOR_PV_INSERTED_LINES+dummy_lines+start_grab_y_offset ;
image_window->exposure_window_width=IMAGE_SENSOR_PV_WIDTH-4;
image_window->exposure_window_height=IMAGE_SENSOR_PV_HEIGHT-50;
}else {
MPEG4_encode_mode=KAL_FALSE;
/* config TG of ISP to match the setting of image sensor*/
write_cmos_sensor(0x11, 0x00);//80
SET_TG_OUTPUT_CLK_DIVIDER(3);//(1)
SET_CMOS_RISING_EDGE(0);
SET_CMOS_FALLING_EDGE(2);//(1)
ENABLE_CAMERA_PIXEL_CLKIN_ENABLE;
SET_TG_PIXEL_CLK_DIVIDER(3);// //3-->1//(1)
SET_CMOS_DATA_LATCH(3);//(1)
write_cmos_sensor(0x4F, 0x4B);//9e
write_cmos_sensor(0x50, 0x4B);//84
write_cmos_sensor(0x5A, 0x67);//23
start_grab_x_offset=0;
start_grab_y_offset=0;
dummy_pixels=0X4d;
dummy_lines=0;
image_window->grab_start_x=IMAGE_SENSOR_PV_INSERTED_PIXELS+start_grab_x_offset;
image_window->grab_start_y=IMAGE_SENSOR_PV_INSERTED_LINES+dummy_lines+start_grab_y_offset ;
image_window->exposure_window_width=IMAGE_SENSOR_PV_WIDTH-4;
image_window->exposure_window_height=IMAGE_SENSOR_PV_HEIGHT-4;
}
preview_pclk_division=((DRV_Reg32(ISP_TG_PHASE_COUNTER_REG)&0xF0)>>4)+1;
//SET_CAMERA_INPUT_ORDER(INPUT_ORDER_YCbY1Cr);
switch (sensor_config_data->image_mirror)
{
case IMAGE_NORMAL:
SET_FIRST_GRAB_COLOR(BAYER_R);
SET_CAMERA_INPUT_ORDER(INPUT_ORDER_YCbY1Cr);
// while((temp_v_flip_reg2 != (0x00|temp_v_flip_reg1)) ||(temp_h_mirror_reg2!=(0x00|temp_h_mirror_reg1)) )
{
write_cmos_sensor(0x33, 0xc0);
write_cmos_sensor(0x04, 0x28);
// write_cmos_sensor(0x04,(0x00|temp_v_flip_reg1));
//temp_v_flip_reg2=read_cmos_sensor(0x04);
// write_cmos_sensor(0x33,(0x00|temp_h_mirror_reg1));
//temp_h_mirror_reg2=read_cmos_sensor(0x33);
};
break;
case IMAGE_HV_MIRROR:
SET_FIRST_GRAB_COLOR(BAYER_Gb);
SET_CAMERA_INPUT_ORDER(INPUT_ORDER_YCbY1Cr);
//while((temp_v_flip_reg2 != (0xC0|temp_v_flip_reg1)) ||(temp_h_mirror_reg2!=(0x08|temp_h_mirror_reg1)) )
{
//write_cmos_sensor(0x04, (0xC0|temp_v_flip_reg1));
//temp_v_flip_reg2 = read_cmos_sensor(0x04);
write_cmos_sensor(0x33, 0xc0);
write_cmos_sensor(0x04, 0x28);
//write_cmos_sensor(0x33, (0x08|temp_h_mirror_reg1));
//temp_h_mirror_reg2 = read_cmos_sensor(0x33);
};
break;
}
set_OV9660_dummy(dummy_pixels,dummy_lines);
write_OV9660_shutter(exposure_lines);
kal_sleep_task(30);
// write_cmos_sensor(0x13 ,0xE7); // Turn ON AEC/AGC/AWB
if (sensor_config_data->isp_op_mode == ISP_MJPEG_ENCODE_MODE) {
//sensor_config_data->sensor_frame_rate = 10 * (48000000 / preview_pclk_division / 784 / current_shutter / 2); //1fps=10
sensor_config_data->sensor_frame_rate = 100; // 10fps
}else {
// ISP_MJPEG_ENCODE_MODE mode does not invok YUV setting API after preview function
// If turn on AEC/AGC/AWB in ISP_MJPEG_ENCODE_MODE mode, the AWB setting will be overwriten.
write_cmos_sensor(0x13, 0xE7); // Turn ON AEC/AGC/AWB
}
temp_v_flip_reg2 = read_cmos_sensor(0x04);
temp_h_mirror_reg2 = read_cmos_sensor(0x33);
kal_prompt_trace(MOD_ENG,"temp_v_flip_reg2=0x%x, temp_h_mirror_reg1=0x%x",temp_v_flip_reg2,temp_h_mirror_reg1);
#ifdef OUTPUT_DEBUG_INFO
sprintf(temp_buffer, "pre_shut:%d, dummy_p=%d, dummy_l=%d", exposure_lines, dummy_pixels, dummy_lines);
rmmi_write_to_uart((kal_uint8*) temp_buffer, strlen(temp_buffer), KAL_TRUE);
sprintf(temp_buffer, "End of OV9660_preview");
rmmi_write_to_uart((kal_uint8*) temp_buffer, strlen(temp_buffer), KAL_TRUE);
#endif
} /* OV9660_preview */
void OV9660_capture(image_sensor_exposure_window_struct *image_window, image_sensor_config_struct *sensor_config_data)
{
volatile kal_uint32 shutter=exposure_lines;
kal_uint8 temp_reg=0;
kal_uint8 temp_reg_banding=0;
temp_reg_banding=read_cmos_sensor(0x0c)&0x04;
sensor_cap_state=KAL_TRUE;
if(MPEG4_encode_mode)
ASSERT(0);
resolution_info.width=image_window->image_target_width;
resolution_info.height=image_window->image_target_height;
if(sensor_config_data->enable_shutter_tansfer==KAL_TRUE)
shutter=sensor_config_data->capture_shutter;
#ifdef OUTPUT_DEBUG_INFO
sprintf(temp_buffer, "Begin of OV9660_capture");
rmmi_write_to_uart((kal_uint8*) temp_buffer, strlen(temp_buffer), KAL_TRUE);
sprintf(temp_buffer, "cap_shutter:%d, pre_shut:%d", shutter, exposure_lines);
rmmi_write_to_uart((kal_uint8*) temp_buffer, strlen(temp_buffer), KAL_TRUE);
#endif
write_cmos_sensor(0x13,0xE0); //e0 Turn OFF AEC/AGC/AWB
shutter=read_OV9660_shutter();
sensor_global_gain=read_OV9660_gain();
#if 0 //def OUTPUT_DEBUG_INFO
kal_prompt_trace(MOD_MED,"shutter=%d, sensor_global_gain=%d",shutter,sensor_global_gain);
#endif
temp_reg = read_cmos_sensor(0x0f);
write_cmos_sensor(0x0f, temp_reg & ~0x08);
//write_cmos_sensor(0x2d, 0x00); // clear preview dummy lines
//write_cmos_sensor(0x2e, 0x00); // clear preview dummy lines
write_cmos_sensor(0x46, 0x00); // clear preview dummy lines
write_cmos_sensor(0x47, 0x00); // clear preview dummy lines
#if defined(ALWAYS_FULL_RESOLUTION)
if ((image_window->image_target_width<=IMAGE_SENSOR_PV_WIDTH)&&
(image_window->image_target_height<=IMAGE_SENSOR_PV_HEIGHT)&&
(sensor_config_data->meta_mode)||
(sensor_config_data->frame_rate==0xF0))
#else
if ((image_window->image_target_width<=IMAGE_SENSOR_PV_WIDTH)&&
(image_window->image_target_height<=IMAGE_SENSOR_PV_HEIGHT)||
(sensor_config_data->frame_rate==0xF0))
#endif
{ /* Less than PV Mode */
gPVmode=KAL_TRUE;
if (image_window->digital_zoom_factor>=(ISP_DIGITAL_ZOOM_INTERVAL<<1))
{
write_cmos_sensor(0x11,0x83);
SET_TG_PIXEL_CLK_DIVIDER(7);
SET_CMOS_DATA_LATCH(3);
dummy_pixels=PV_PERIOD_PIXEL_NUMS/4;
dummy_lines=0;
start_grab_x_offset=0;
start_grab_y_offset=0;
}
else
{
if(sensor_config_data->frame_rate==0xF0) // That means WEBCAM mode.
{
write_cmos_sensor(0x13,0xE7); // Turn ON AEC/AGC/AWB
write_cmos_sensor(0x11,0x81);
write_cmos_sensor(0x3d,0x3c);
write_cmos_sensor(0x0c,0x3c);
write_cmos_sensor(0x4f,0x4B);
write_cmos_sensor(0x50,0x4B);
write_cmos_sensor(0x5a,0x67);
SET_TG_PIXEL_CLK_DIVIDER(3);
SET_CMOS_DATA_LATCH(1);
dummy_pixels=0X4d;
dummy_lines=0;
start_grab_x_offset=0;
start_grab_y_offset=0;
}
else
{
write_cmos_sensor(0x11,0x81);
SET_TG_PIXEL_CLK_DIVIDER(3);
SET_CMOS_DATA_LATCH(1);
dummy_pixels=0X4d;
dummy_lines=0;
start_grab_x_offset=0;
start_grab_y_offset=0;
}
}
capture_pclk_division=((DRV_Reg32(ISP_TG_PHASE_COUNTER_REG)&0xF0)>>4)+1;
shutter=(shutter*preview_pclk_division)/capture_pclk_division;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -