📄 image_sensor.c
字号:
{0x3e, 0x30},
{0x81, 0x07},
{0x8F, 0x54},
{0x90, 0x69},
{0x91, 0x0F},
{0x92, 0x99},
{0x93, 0x98},
{0x94, 0x0F},
{0x95, 0x0F},
{0x96, 0xFF},
{0x97, 0x00},
{0x98, 0x10},
{0x99, 0x20},
{0xb7, 0x90},
{0xb8, 0x8d},
{0xb9, 0x03},
{0xba, 0x2b},
{0xbb, 0x74},
{0xbc, 0x9f},
{0xbd, 0x5e},
{0xbe, 0x98},
{0xbf, 0x98},
{0xc0, 0x00},
{0xc1, 0x28},
{0xc2, 0x70},
{0xc3, 0x98},
{0xc4, 0x1a},
{0xaf, 0x29},
{0xa0, 0x00},
{0xa1, 0x0a},
{0xa2, 0x1a},
{0xa3, 0x41},
{0xa4, 0x53},
{0xa5, 0x62},
{0xa6, 0x6e},
{0xa7, 0x7f},
{0xa8, 0x8a},
{0xa9, 0x93},
{0xaa, 0xa5},
{0xab, 0xb3},
{0xac, 0xc7},
{0xad, 0xd7},
{0xae, 0xe1},
{0x31, 0x0f},
{0x38, 0x04},
{0x34, 0x40},
{0x36, 0x40},
{0x37, 0x3b},
{0x89, 0x5c},
{0x8a, 0x11},
{0x8b, 0x12},
{0x8d, 0x50},
{0x96, 0xff},
{0x97, 0x00},
{0xb2, 0x06},
{0xb3, 0x03},
{0xb4, 0x03},
{0xb5, 0x03},
{0xb6, 0x03},
{0xd5, 0x02},
{0xdb, 0x40},
{0xdc, 0x40},
{0x24, 0x68},
{0x25, 0x58},
{0x26, 0x83},
{0x2d, 0xff},
{0x2e, 0x05},
{0x14, 0x92},
{0x11, 0x00},
{0x15, 0x40},
{0x2d, 0x00},
{0x2e, 0x00},
{0x4f, 0x99},
{0x50, 0x7f},
{0x21, 0x23}
};
/*****************************************************************************
* FUNCTION
* init_cmos_sensor
* DESCRIPTION
*
* PARAMETERS
* void
* RETURNS
* void
*****************************************************************************/
void init_cmos_sensor()
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
kal_uint32 i;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
for (i = 0; i < 103; i++)
{
write_cmos_sensor(OV7680_Init_Reg[i].addr, OV7680_Init_Reg[i].value);
}
}
/*****************************************************************************
* FUNCTION
* init_OV7680
* DESCRIPTION
* This function initialize the registers of CMOS sensor and ISP control register.
* PARAMETERS
* void
* RETURNS
* void
*****************************************************************************/
kal_int8 init_OV7680(void)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
cis_module_power_on(KAL_TRUE); /* Power On CIS Power */
kal_sleep_task(2); /* To wait for Stable Power */
RESET_CMOS_SENSOR_MODE2; /* High - reset, Low - normal. */
SET_CMOS_CLOCK_POLARITY_LOW;
SET_VSYNC_POLARITY_LOW;
SET_HSYNC_POLARITY_LOW;
ENABLE_CAMERA_INDATA_FORMAT;
SET_CAMERA_INPUT_TYPE(INPUT_YUV422);
ENABLE_CAMERA_TG_CLK_48M;
UPLL_Enable(UPLL_OWNER_ISP);
set_isp_driving_current(camera_para.SENSOR.reg[CMMCLK_CURRENT_INDEX].para);
/* Reset Sensor */
kal_sleep_task(20);
write_cmos_sensor(0x12, 0x80);
kal_sleep_task(20);
sensor_id = (read_cmos_sensor(0x0A) << 8) | read_cmos_sensor(0x0B);
//kal_prompt_trace(MOD_ENG, "Sensor ID = %x", sensor_id);
if(sensor_id != OV7680_SENSOR_ID)
return -1;
/* Initail Sequence Write In. */
init_cmos_sensor();
return 1;
} /* init_cmos_sensor() */
/*****************************************************************************
* FUNCTION
* power_off_OV7680
* DESCRIPTION
* This function is to turn off sensor module power.
* PARAMETERS
* void
* RETURNS
* void
*****************************************************************************/
void power_off_OV7680(void)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
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 /* HW_SCCB */
} /* power_off_OV7680 */
/*****************************************************************************
* FUNCTION
* get_OV7680_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
* void
*****************************************************************************/
void get_OV7680_id(kal_uint8 *sensor_write_id, kal_uint8 *sensor_read_id)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
*sensor_write_id = 0xc0;
*sensor_read_id = 0xc1;
} /* get_OV7680_id */
/*****************************************************************************
* FUNCTION
* get_OV7680_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
* void
*****************************************************************************/
void get_OV7680_size(kal_uint16 *sensor_width, kal_uint16 *sensor_height)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
*sensor_width = IMAGE_SENSOR_VGA_WIDTH; /* pixel numbers actually used in one frame */
*sensor_height = IMAGE_SENSOR_VGA_HEIGHT; /* line numbers actually used in one frame */
} /* get_OV7680_size */
/*****************************************************************************
* FUNCTION
* get_OV7680_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
* void
*****************************************************************************/
void get_OV7680_period(kal_uint16 *pixel_number, kal_uint16 *line_number)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
*pixel_number = VGA_PERIOD_PIXEL_NUMS; /* pixel numbers in one period of HSYNC */
*line_number = VGA_PERIOD_LINE_NUMS; /* line numbers in one period of VSYNC */
} /* get_OV7680_period */
void write_OV7680_extra_line(kal_uint16 extra_line)
{
write_cmos_sensor(0x2d, extra_line & 0xFF);
write_cmos_sensor(0x2e, (extra_line >> 8) & 0xFF);
}
/*****************************************************************************
* FUNCTION
* OV7680_preview
* DESCRIPTION
*
* PARAMETERS
* image_window [?] [?]
* sensor_config_data [?] [?]
* RETURNS
* void
*****************************************************************************/
void OV7680_preview(image_sensor_exposure_window_struct *image_window, image_sensor_config_struct *sensor_config_data)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
/* volatile kal_uint32 temp_reg2=read_cmos_sensor(0x1E), temp_reg1=(temp_reg2&0x0F); */
kal_uint8 iTemp;
// kal_uint16 current_shutter;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
sensor_cap_state = KAL_FALSE;
g_bMJPEG_mode = KAL_FALSE;
// write_cmos_sensor(0x13, 0xef);
// 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, 0x00);
}
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;
SET_TG_OUTPUT_CLK_DIVIDER(7);
SET_CMOS_RISING_EDGE(0);
SET_CMOS_FALLING_EDGE(4);
ENABLE_CAMERA_PIXEL_CLKIN_ENABLE;
dummy_pixels = 0;
dummy_lines = 20;
}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;
dummy_pixels = 0;
dummy_lines = 20;
}
else
{
MPEG4_encode_mode = KAL_FALSE;
/* config TG of ISP to match the setting of image sensor */
SET_TG_OUTPUT_CLK_DIVIDER(1); /* 30fps */
SET_CMOS_RISING_EDGE(0);
SET_CMOS_FALLING_EDGE(1);
ENABLE_CAMERA_PIXEL_CLKIN_ENABLE;
dummy_pixels = 0;
dummy_lines = 0;
}
preview_pclk_division = ((DRV_Reg32(ISP_TG_PHASE_COUNTER_REG) & 0x0F000000) >> 24) + 1;
SET_CAMERA_INPUT_ORDER(0);
/*
Normal --- reg0x0c=0x16 , reg0x16=0x08, reg0x65=0x8c
H-Mirror --- reg0x0c=0x56 , reg0x16=0x08, reg0x65=0x87
V-Flip---reg0x0c=0x96 , reg0x16=0x28, reg0x65=0x8c
Mirror+Flip ---reg0x0c=0xd6 , reg0x16=0x28, reg0x65=0x87
*/
iTemp = read_cmos_sensor(0x0C) & ~0xC0;
switch (sensor_config_data->image_mirror)
{
case IMAGE_NORMAL:
write_cmos_sensor(0x0C, iTemp);
write_cmos_sensor(0x16, 0x08);
write_cmos_sensor(0x65, 0x8C);
break;
case IMAGE_HV_MIRROR:
write_cmos_sensor(0x0C, iTemp | 0xC0);
write_cmos_sensor(0x16, 0x28);
write_cmos_sensor(0x65, 0x87);
break;
}
image_window->grab_start_x = 1;
image_window->grab_start_y = 2;
image_window->exposure_window_width = IMAGE_SENSOR_VGA_WIDTH - 16;
image_window->exposure_window_height = IMAGE_SENSOR_VGA_HEIGHT - 16;
set_OV7680_dummy(dummy_pixels, dummy_lines);
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, 0xef); // Turn ON AEC/AGC/AWB
}
} /* OV7680_preview */
/*****************************************************************************
* FUNCTION
* OV7680_capture
* DESCRIPTION
*
* PARAMETERS
* image_window [?] [?]
* sensor_config_data [?] [?]
* RETURNS
* void
*****************************************************************************/
void OV7680_capture(image_sensor_exposure_window_struct *image_window, image_sensor_config_struct *sensor_config_data)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
volatile kal_uint32 shutter = exposure_lines;
// kal_uint8 temp_reg;
kal_uint32 extra_line;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
sensor_cap_state = KAL_TRUE;
if (MPEG4_encode_mode)
ASSERT(0);
shutter = read_OV7680_shutter();
extra_line = (read_cmos_sensor(0x2e) << 8) | read_cmos_sensor(0x2d);
if (!(sensor_config_data->frame_rate == 0xF0)) /* If not WEBCAM mode. */
{
write_cmos_sensor(0x13, 0xe8);
if (image_window->image_target_width >= 1280 && image_window->image_target_height >= 960)
{
write_cmos_sensor(0x11, 5);
shutter /= 6;
extra_line /= 6;
dummy_pixels = 0;
dummy_lines = 0;
}
else
{
write_cmos_sensor(0x11, 1);
shutter /= 2;
extra_line /= 2;
dummy_pixels = 0;
dummy_lines = 0;
}
}
else /* Webcam */
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -