📄 image_sensor_ov7660.c
字号:
ENABLE_SCCB;
REG_SCCB_DATA = OV76X0_READ_ID | SCCB_DATA_REG_ID_ADDRESS;
REG_SCCB_DATA=0;
while (SCCB_IS_READING) {};
get_byte = REG_SCCB_READ_DATA & 0xFF;
#else
I2C_START_TRANSMISSION;
for(j=0;j<OV7660_SENSOR_I2C_DELAY;j++);
OV7660_SCCB_send_byte(OV7660_WRITE_ID);
for(j=0;j<OV7660_SENSOR_I2C_DELAY;j++);
OV7660_SCCB_send_byte(addr);
for(j=0;j<OV7660_SENSOR_I2C_DELAY;j++);
I2C_STOP_TRANSMISSION;
for(j=0;j<OV7660_SENSOR_I2C_DELAY;j++);
I2C_START_TRANSMISSION;
for(j=0;j<OV7660_SENSOR_I2C_DELAY;j++);
OV7660_SCCB_send_byte(OV7660_READ_ID);
for(j=0;j<OV7660_SENSOR_I2C_DELAY;j++);
get_byte=OV7660_SCCB_get_byte();
for(j=0;j<OV7660_SENSOR_I2C_DELAY;j++);
I2C_STOP_TRANSMISSION;
#endif
return get_byte;
} /* ov7660_read_cmos_sensor() */
void write_OV76X0_shutter(kal_uint16 shutter)
{
kal_uint8 temp_reg;
if(shutter<=OV7660_VGA_EXPOSURE_LIMITATION)
{
OV7660_sensor_frame_rate=(10*OV7660_PIXEL_CLK/OV7660_VGA_PERIOD_PIXEL_NUMS)/(OV7660_VGA_PERIOD_LINE_NUMS+OV7660_dummy_lines);
OV7660_extra_exposure_lines=0;
}
else
{
OV7660_sensor_frame_rate=(10*OV7660_PIXEL_CLK/OV7660_VGA_PERIOD_PIXEL_NUMS)/(shutter+OV7660_dummy_lines);
OV7660_extra_exposure_lines=shutter-OV7660_VGA_EXPOSURE_LIMITATION;
}
if(shutter>OV7660_VGA_EXPOSURE_LIMITATION)
shutter=OV7660_VGA_EXPOSURE_LIMITATION;
ov7660_write_cmos_sensor(0x2D,OV7660_extra_exposure_lines&0xFF); // ADVFL(LSB of extra exposure lines)
ov7660_write_cmos_sensor(0x2E,(OV7660_extra_exposure_lines&0xFF00)>>8); // ADVFH(MSB of extra exposure lines)
temp_reg=ov7660_read_cmos_sensor(0x04);
ov7660_write_cmos_sensor(0x04,( (temp_reg&0xFC) | (shutter&0x3) )); // AEC[b1~b0]
ov7660_write_cmos_sensor(0x10,((shutter&0x3FC)>>2)); // AEC[b9~b2]
ov7660_write_cmos_sensor(0x07,((shutter&0x400)>>10)); // AEC[b10]/AEC[b15~b10]
} /* write_OV76X0_shutter */
kal_uint16 read_OV76X0_shutter(void)
{
kal_uint8 temp_reg1, temp_reg2, temp_reg3;
kal_uint16 temp_reg;
temp_reg1=ov7660_read_cmos_sensor(0x04); // AEC[b1~b0]
temp_reg2=ov7660_read_cmos_sensor(0x10); // AEC[b9~b2]
temp_reg3=ov7660_read_cmos_sensor(0x07); // AEC[b15~b10]
temp_reg=((temp_reg3&0x1)<<10)|(temp_reg2<<2)|(temp_reg1&0x3); // AEC[b10]/AEC[b15~b10]
return temp_reg;
} /* read_OV76X0_shutter */
void write_OV76X0_gain(kal_uint16 gain)
{
kal_uint16 temp_reg = 0;
if(gain>=1*BASEGAIN && gain<2*BASEGAIN)
{
ov7660_sensor_global_gain=gain&(~0x3);
temp_reg=(ov7660_sensor_global_gain-1*BASEGAIN)/4;
}
else if(gain>=2*BASEGAIN && gain<4*BASEGAIN)
{
ov7660_sensor_global_gain=gain&(~0x7);
temp_reg=0x10;
temp_reg|=(ov7660_sensor_global_gain-2*BASEGAIN)/8;
}
else if(gain>=4*BASEGAIN && gain<8*BASEGAIN)
{
ov7660_sensor_global_gain=gain&(~0xF);
temp_reg=0x30;
temp_reg|=(ov7660_sensor_global_gain-4*BASEGAIN)/16;
}
else if(gain>=8*BASEGAIN && gain<16*BASEGAIN)
{
ov7660_sensor_global_gain=gain&(~0x1F);
temp_reg=0x70;
temp_reg|=(ov7660_sensor_global_gain-8*BASEGAIN)/32;
}
else if(gain>=16*BASEGAIN)
{
ov7660_sensor_global_gain=gain&(~0x3F);
temp_reg=0xF0;
temp_reg|=(ov7660_sensor_global_gain-16*BASEGAIN)/64;
}
else
ASSERT(0);
ov7660_write_cmos_sensor(0x00,temp_reg);
} /* write_OV76X0_gain */
kal_uint16 ov7660_read_gain(void)
{
kal_uint8 sensor_gain;
kal_uint16 temp_reg;
temp_reg=camera_para.SENSOR.cct[OV7660_GLOBAL_GAIN_INDEX].para;
sensor_gain=(BASEGAIN+((temp_reg&0x1F)*BASEGAIN)/16);
if(temp_reg&0x20)
sensor_gain<<=1;
if(temp_reg&0x40)
sensor_gain<<=1;
if(temp_reg&0x80)
sensor_gain<<=1;
return sensor_gain;
} /* ov7660_read_gain */
void set_OV76X0_dummy(kal_uint16 pixels, kal_uint16 lines)
{
ov7660_write_cmos_sensor(0x2A,((pixels&0x700)>>4));
ov7660_write_cmos_sensor(0x2B,(pixels&0xFF));
ov7660_write_cmos_sensor(0x92,(lines&0xFF));
ov7660_write_cmos_sensor(0x93,((lines&0xFF00)>>8));
} /* set_OV76X0_dummy */
/*************************************************************************
* FUNCTION
* config_OV76X0_window
*
* DESCRIPTION
* This function config the hardware window of OV76X0 for getting specified
* data of that window.
*
* PARAMETERS
* start_x : start column of the interested window
* start_y : start row of the interested window
* width : column widht of the itnerested window
* height : row depth of the itnerested window
*
* RETURNS
* the data that read from OV76X0
*
* GLOBALS AFFECTED
*
*************************************************************************/
void config_OV76X0_window(kal_uint16 startx,kal_uint16 starty,kal_uint16 width, kal_uint16 height)
{
kal_uint16 endx=(startx+width-1);
kal_uint16 endy=(starty+height-1);
kal_uint8 temp_reg1, temp_reg2;
temp_reg1=(ov7660_read_cmos_sensor(0x03)&0xF0);
temp_reg2=(ov7660_read_cmos_sensor(0x32)&0xC0);
// Horizontal
ov7660_write_cmos_sensor(0x32,0x80|((endx&0x7)<<3)|(startx&0x7)); // b[5:3]:HREF end low 3bits. b[2:0]:HREF start low 3bits.
ov7660_write_cmos_sensor(0x17,(startx&0x7F8)>>3); // HREF start high 8bits
ov7660_write_cmos_sensor(0x18,(endx&0x7F8)>>3); // HREF end high 8bits
// Vertical
ov7660_write_cmos_sensor(0x03,temp_reg1|((endy&0x3)<<2)|(starty&0x3)); // b[3:2]:VREF end low 2bits. b[1:0]:VREF start low 2bits.
ov7660_write_cmos_sensor(0x19,(starty&0x3FC)>>2); // VREF start high 8bits
ov7660_write_cmos_sensor(0x1A,(endy&0x3FC)>>2); // VREF end high 8bits
} /* config_OV76X0_window */
/*************************************************************************
* FUNCTION
* OV7660_init
*
* DESCRIPTION
* This function initialize the registers of CMOS sensor and ISP control register.
*
* PARAMETERS
* None
*
* RETURNS
* None
*
* GLOBALS AFFECTED
*
*************************************************************************/
kal_int8 OV7660_init(void)
{
cis_module_power_on(KAL_TRUE); // Power On CIS Power
kal_sleep_task(2); // To wait for Stable Power
#if (defined DRV_ISP_6238_SERIES)
REG_ISP_CMOS_SENSOR_MODE_CONFIG |= REG_CMOS_SENSOR_RESET_BIT;
REG_ISP_CMOS_SENSOR_MODE_CONFIG &= ~REG_CMOS_SENSOR_RESET_BIT;
#else
RESET_CMOS_SENSOR_MODE1; // High - reset, Low - normal.
#endif
SET_CMOS_CLOCK_POLARITY_LOW;
SET_VSYNC_POLARITY_LOW;
SET_HSYNC_POLARITY_LOW;
#if defined(SENSOR_ROTATE_0)
SET_FIRST_GRAB_COLOR(BAYER_R);;
#else
SET_FIRST_GRAB_COLOR(BAYER_Gb);;
#endif
set_isp_driving_current(camera_para.SENSOR.reg[OV7660_CMMCLK_CURRENT_INDEX].para);
set_isp_interrupt_trigger_delay_lines(1);
// Reset Sensor
ov7660_write_cmos_sensor(0x12,0x80);
kal_sleep_task(2);
OV7660_sensor_id=(ov7660_read_cmos_sensor(0x0A)<<8)|ov7660_read_cmos_sensor(0x0B);
if((OV7660_sensor_id != OV7660_SENSOR_ID) && (OV7660_sensor_id != OV7670_SENSOR_ID))
return -1;
// Initail Sequence Write In.
OV7660_camera_para_to_sensor();
ov7660_normal_gain=ov7660_read_cmos_sensor(0x00);
OV7660_sensor_gain_base=ov7660_read_gain();
return 1;
} /* init_cmos_sensor() */
/*************************************************************************
* FUNCTION
* OV7660_init
*
* DESCRIPTION
* This function initialize the registers of CMOS sensor and ISP control register.
*
* PARAMETERS
* None
*
* RETURNS
* None
*
* GLOBALS AFFECTED
*
*************************************************************************/
kal_uint32 OV7660_detect_sensor_id(void)
{
kal_uint16 iSensor_ID;
cis_module_power_on(KAL_TRUE); // Power On CIS Power
kal_sleep_task(2); // To wait for Stable Power
#if defined(OV7660_RAW)
#if (defined DRV_ISP_6238_SERIES)
REG_ISP_CMOS_SENSOR_MODE_CONFIG |= REG_CMOS_SENSOR_RESET_BIT;
REG_ISP_CMOS_SENSOR_MODE_CONFIG &= ~REG_CMOS_SENSOR_RESET_BIT;
#else
RESET_CMOS_SENSOR_MODE1; // High - reset, Low - normal.
#endif
#else
RESET_CMOS_SENSOR_MODE1; // High - reset, Low - normal.
#endif
SET_CMOS_CLOCK_POLARITY_LOW;
SET_VSYNC_POLARITY_LOW;
SET_HSYNC_POLARITY_LOW;
// Reset Sensor
ov7660_write_cmos_sensor(0x12,0x80);
kal_sleep_task(2);
iSensor_ID = (ov7660_read_cmos_sensor(0x0A)<<8)|ov7660_read_cmos_sensor(0x0B);
if((iSensor_ID != OV7660_SENSOR_ID) && (iSensor_ID != OV7670_SENSOR_ID))
{
cis_module_power_on(KAL_FALSE); // Power Off CIS Power
return -1;
}
return iSensor_ID;
} /* init_cmos_sensor() */
/*************************************************************************
* FUNCTION
* OV7660_power_off
*
* DESCRIPTION
* This function is to turn off sensor module power.
*
* PARAMETERS
* None
*
* RETURNS
* None
*
* GLOBALS AFFECTED
*
*************************************************************************/
void OV7660_power_off(void)
{
cis_module_power_on(KAL_FALSE); // Power Off CIS Power
#ifndef HW_SCCB
SET_SCCB_CLK_LOW;
SET_SCCB_DATA_LOW;
#endif
} /* OV7660_power_off */
/*************************************************************************
* FUNCTION
* OV7660_get_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 OV7660_get_id(kal_uint8 *sensor_write_id, kal_uint8 *sensor_read_id)
{
*sensor_write_id=OV7660_WRITE_ID;
*sensor_read_id=OV7660_READ_ID;
} /* OV7660_get_id */
/*************************************************************************
* FUNCTION
* OV7660_get_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 OV7660_get_size(kal_uint16 *sensor_width, kal_uint16 *sensor_height)
{
*sensor_width=IMAGE_SENSOR_VGA_WIDTH-6; /* pixel numbers actually used in one frame */
*sensor_height=IMAGE_SENSOR_VGA_HEIGHT-8; /* line numbers actually used in one frame */
} /* OV7660_get_size */
/*************************************************************************
* FUNCTION
* OV7660_get_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 OV7660_get_period(kal_uint16 *pixel_number, kal_uint16 *line_number)
{
*pixel_number=OV7660_VGA_PERIOD_PIXEL_NUMS; /* pixel numbers in one period of HSYNC */
*line_number=OV7660_VGA_PERIOD_LINE_NUMS; /* line numbers in one period of VSYNC */
} /* OV7660_get_period */
void OV7660_preview(image_sensor_exposure_window_struct *image_window, image_sensor_config_struct *sensor_config_data)
{
volatile kal_uint32 temp_reg2=ov7660_read_cmos_sensor(0x1E), temp_reg1=(temp_reg2&0x0F);
#ifdef OUTPUT_DEBUG_INFO
sprintf(temp_buffer, "Begin of OV7660_preview");
rmmi_write_to_uart((kal_uint8*) temp_buffer, strlen(temp_buffer), KAL_TRUE);
sprintf(temp_buffer, "pre_shut:%d", OV7660_exposure_lines);
rmmi_write_to_uart((kal_uint8*) temp_buffer, strlen(temp_buffer), KAL_TRUE);
#endif
ov7660_write_cmos_sensor(0x12,0x05);
#if defined(OV7660_RAW)
config_OV76X0_window(137,8,(IMAGE_SENSOR_VGA_WIDTH+4),(IMAGE_SENSOR_VGA_HEIGHT+2));
#elif defined(OV7670_RAW)
config_OV76X0_window(158,10,(IMAGE_SENSOR_VGA_WIDTH+4),(IMAGE_SENSOR_VGA_HEIGHT+2));
#else
config_OV76X0_window(137,8,(IMAGE_SENSOR_VGA_WIDTH+4),(IMAGE_SENSOR_VGA_HEIGHT+2));
#endif
ov7660_write_cmos_sensor(0x11,0x80);
if(sensor_config_data->frame_rate==0x0F) // MPEG4 Encode Mode
{
OV7660_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(7);
SET_CMOS_DATA_LATCH(3);
#if 0
#if defined(OV7670_RAW)
/* under construction !*/
/* under construction !*/
#else
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif
#else
OV7660_dummy_pixels=250; // Video period is (OV7660_VGA_PERIOD_PIXEL_NUMS + OV7660_dummy_pixels)
OV7660_dummy_lines= 125; //0; // add dummy lines to avoid Java mode screen split
#endif
OV7660_start_grab_x_offset=1;
OV7660_start_grab_y_offset=0;
}
else
{
OV7660_MPEG4_encode_mode=KAL_FALSE;
/* config TG of ISP to match the setting of image sensor*/
#if defined(CAM_PREVIEW_15FPS)
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(7);
SET_CMOS_DATA_LATCH(3);
OV7660_start_grab_x_offset=1;
OV7660_start_grab_y_offset=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -