📄 image_sensor.c
字号:
}
#endif
/*************************************************************************
* FUNCTION
* init_cmos_sensor
*
* DESCRIPTION
* This function initialize the registers of CMOS sensor
*
* PARAMETERS
* None
*
* RETURNS
* None
*
* GLOBALS AFFECTED
*
*************************************************************************/
kal_int8 init_MT9D011(void)
{
volatile signed char i;
kal_uint16 sensor_id=0;
cis_module_power_on(KAL_TRUE); // Power On CIS Power
kal_sleep_task(2); // To wait for Stable Power
RESET_CMOS_SENSOR_MODE2; // Low Active
SET_CMOS_CLOCK_POLARITY_LOW;
SET_VSYNC_POLARITY_HIGH;
SET_HSYNC_POLARITY_LOW;
SET_FIRST_GRAB_COLOR(FIRST_GRAB_COLOR);
set_isp_driving_current((kal_uint8)camera_para.SENSOR.reg[CMMCLK_CURRENT_INDEX].para);
#ifdef USE_48MHZ
SET_TG_OUTPUT_CLK_DIVIDER(3);
SET_CMOS_RISING_EDGE(0);
SET_CMOS_FALLING_EDGE(2);
//ENABLE_CAMERA_PIXEL_CLKIN_ENABLE;
DISABLE_CAMERA_TG_CLK_48M;
#endif
// Reset
write_cmos_sensor(0x0D, 0x01);
kal_sleep_task(40);
write_cmos_sensor(0x0D, 0x00);
kal_sleep_task(40);
for(i=0;i<3;i++)
{
sensor_id=read_cmos_sensor(0x00);
if(sensor_id == MT9D011_SENSOR_ID)
break;
}
if(sensor_id != MT9D011_SENSOR_ID)
{
kal_prompt_trace(MOD_MED, "[#ID] FAIL=%d\n",sensor_id);
return -1;
}
// Initail Sequence Write In.
camera_para_to_sensor();
#if (defined(MT6228)||defined(MT6229)||defined(MT6230))
// Initial Shutter Priority Table */
init_shutter_pri_table();
// Initial Shutter Priority Table */
init_aperture_pri_table();
// Initial Shutter Priority Table */
init_iso_pri_table();
#endif
normal_gain=read_cmos_sensor(0x2F);
sensor_gain_base=read_MT9D011_gain();
return 1;
} /* init_cmos_sensor() */
/*************************************************************************
* FUNCTION
* power_off_MT9D011
*
* DESCRIPTION
* This function is to turn off sensor module power.
*
* PARAMETERS
* None
*
* RETURNS
* None
*
* GLOBALS AFFECTED
*
*************************************************************************/
void power_off_MT9D011(void)
{
cis_module_power_on(KAL_FALSE); // Power Off CIS Power
#ifdef USE_48MHZ
UPLL_Disable(UPLL_OWNER_ISP);
#endif
SET_SCCB_CLK_LOW;
SET_SCCB_DATA_LOW;
} /* power_off_MT9D011 */
/*************************************************************************
* FUNCTION
* get_MT9D011_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_MT9D011_id(kal_uint8 *sensor_write_id, kal_uint8 *sensor_read_id)
{
*sensor_write_id=MT9D011_WRITE_ID;
*sensor_read_id=MT9D011_READ_ID;
} /* get_MT9D011_id */
/*************************************************************************
* FUNCTION
* get_MT9D011_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_MT9D011_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-window_high_offset; /* line numbers actually used in one frame */
} /* get_MT9D011_size */
/*************************************************************************
* FUNCTION
* get_MT9D011_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_MT9D011_period(kal_uint16 *pixel_number, kal_uint16 *line_number)
{
*pixel_number=PV_PERIOD_PIXEL_NUMS+PV_dummy_pixels; /* pixel numbers in one period of HSYNC */
*line_number=PV_PERIOD_LINE_NUMS+PV_dummy_lines; /* line numbers in one period of VSYNC */
} /* get_MT9D011_period */
void MT9D011_preview(image_sensor_exposure_window_struct *image_window, image_sensor_config_struct *sensor_config_data)
{
start_grab_x_offset=0;
start_grab_y_offset=0;
window_high_offset=0;
current_sensor_expo_width=sensor_expo_width;
/* config TG of ISP to match the setting of image sensor*/
/* Target Size > 176X220 LCD;(QVGA LCD)*/
if(((image_window->image_target_width>176)&&(image_window->image_target_height>220))||
((image_window->image_target_width>220)&&(image_window->image_target_height>176)) )
{
if(sensor_config_data->frame_rate==0x0F) // MPEG4 Encode Mode
{
MPEG4_30fps_mode = KAL_FALSE;
MPEG4_encode_mode = KAL_TRUE;
//For CIF 15fps test
SET_TG_OUTPUT_CLK_DIVIDER(3); // 12Mhz/12MHz, Sync
SET_CMOS_RISING_EDGE(0);
SET_CMOS_FALLING_EDGE(2);
ENABLE_CAMERA_PIXEL_CLKIN_ENABLE;
SET_TG_PIXEL_CLK_DIVIDER(3);
SET_CMOS_DATA_LATCH(2);
PV_dummy_pixels = 0;
PV_dummy_lines = 33; // 15 fps
#if ((defined(MT6228)||defined(MT6229)||defined(MT6230))&&((!defined(__MAUI_BASIC__))&& (!defined(__L1_STANDALONE__))))
if (tv_operation_state!=TV_IDLE_STATE)
{
#if (defined(MT6228))
PV_dummy_pixels = 0;
PV_dummy_lines = 33; // 15 fps
#else // MT6229
PV_dummy_pixels = 64;
PV_dummy_lines = 150; // 12 fps
#endif
}
#endif
}
else // Preview Mode
{
SET_TG_OUTPUT_CLK_DIVIDER(1); // 24Mhz/24MHz, Sync
SET_CMOS_RISING_EDGE(0);
SET_CMOS_FALLING_EDGE(1);
ENABLE_CAMERA_PIXEL_CLKIN_ENABLE;
SET_TG_PIXEL_CLK_DIVIDER(1);
SET_CMOS_DATA_LATCH(1);
#if (defined(MT6227)||defined(MT6229)||defined(MT6230))
PV_dummy_pixels = 1156+200; // 24000000/12/(816+1156) = 871
#else
PV_dummy_pixels = 376; // 24000000/12/(816+700) = 1319
#endif
PV_dummy_lines = 0; // 1253/(621+48) = 23.66 fps
sensor_expo_width=PV_PERIOD_PIXEL_NUMS+PV_dummy_pixels;
current_sensor_expo_width=sensor_expo_width;
#if ((defined(MT6228)||defined(MT6229)||defined(MT6230))&&((!defined(__MAUI_BASIC__))&& (!defined(__L1_STANDALONE__))))
if (tv_operation_state!=TV_IDLE_STATE)
{
#if (defined(MT6228))
PV_dummy_pixels = 676; // 24000000/12/(816+1000) = 1101
PV_dummy_lines = 0; // 1253/(621+48) = 19.7 fps
#else // MT6229
PV_dummy_pixels = 700;
PV_dummy_lines = 200;
#endif
}
current_sensor_expo_width=PV_PERIOD_PIXEL_NUMS+PV_dummy_pixels;
#endif
}
}
/* Target Size < 176X220 LCD */
else
{
if(sensor_config_data->frame_rate==0x0F) // MPEG4 Encode Mode
{
MPEG4_encode_mode = KAL_TRUE;
#if (defined(MT6228))
MPEG4_30fps_mode = KAL_TRUE;
//For QVGA 30fps test
SET_TG_OUTPUT_CLK_DIVIDER(1); // 24Mhz/24MHz, Sync
SET_CMOS_RISING_EDGE(0);
SET_CMOS_FALLING_EDGE(1);
ENABLE_CAMERA_PIXEL_CLKIN_ENABLE;
SET_TG_PIXEL_CLK_DIVIDER(1);
SET_CMOS_DATA_LATCH(1);
PV_dummy_pixels = 0;
PV_dummy_lines = 33;
#else
MPEG4_30fps_mode = KAL_FALSE;
SET_TG_OUTPUT_CLK_DIVIDER(3); // 12Mhz/12MHz, Sync, ~16FPS
SET_CMOS_RISING_EDGE(0);
SET_CMOS_FALLING_EDGE(2);
ENABLE_CAMERA_PIXEL_CLKIN_ENABLE;
SET_TG_PIXEL_CLK_DIVIDER(3);
SET_CMOS_DATA_LATCH(2);
if(((LCD_WIDTH>176)&&(LCD_HEIGHT>220)) ||((LCD_WIDTH>220)&&(LCD_HEIGHT>176)) )
{
PV_dummy_pixels = 0;
PV_dummy_lines = 140;
}
else
{
PV_dummy_pixels = 0;
PV_dummy_lines = 33;
}
#endif
#if ((defined(MT6229)||defined(MT6230))&&((!defined(__MAUI_BASIC__))&& (!defined(__L1_STANDALONE__))))
if (tv_operation_state!=TV_IDLE_STATE)
{
PV_dummy_pixels = 64;
PV_dummy_lines = 150; // 12 fps
}
#endif
}
else // Preview Mode
{
SET_TG_OUTPUT_CLK_DIVIDER(1); // 24Mhz/24MHz, Sync
SET_CMOS_RISING_EDGE(0);
SET_CMOS_FALLING_EDGE(1);
ENABLE_CAMERA_PIXEL_CLKIN_ENABLE;
SET_TG_PIXEL_CLK_DIVIDER(1);
SET_CMOS_DATA_LATCH(1);
PV_dummy_pixels = 156; // 24000000/12/(816+480) = 1543
PV_dummy_lines=0; // 1543/(621+48) = 27.68 fps
#if ((defined(MT6229)||defined(MT6230))&&((!defined(__MAUI_BASIC__))&& (!defined(__L1_STANDALONE__))))
if (tv_operation_state!=TV_IDLE_STATE)
{
PV_dummy_pixels = 500;
PV_dummy_lines = 200;
}
#endif
}
}
/* cal MAX Exposure line for limit min frame rate */
#ifdef USE_48MHZ
ENABLE_CAMERA_TG_CLK_48M;
UPLL_Enable(UPLL_OWNER_ISP);
sensor_pclk = 48000000 / (((DRV_Reg32(ISP_TG_PHASE_COUNTER_REG)&0xF0)>>4)+1);
#else
sensor_pclk = 52000000 / (((DRV_Reg32(ISP_TG_PHASE_COUNTER_REG)&0xF0)>>4)+1);
#endif
MAX_EXPOSURE_LINES = (kal_uint16)((sensor_pclk/MIN_FRAME_RATE)/(PV_PERIOD_PIXEL_NUMS+PV_dummy_pixels));
write_cmos_sensor(0x00F2, 0x000B);
write_cmos_sensor(0x0003, 0x04DA);
write_cmos_sensor(0x0004, 0x0660);
switch (sensor_config_data->image_mirror)
{
case IMAGE_NORMAL:
write_cmos_sensor(0x20,0x90);
sensor_flip_value=0;
break;
case IMAGE_H_MIRROR:
write_cmos_sensor(0x20,0x92);
sensor_flip_value=2;
break;
case IMAGE_V_MIRROR:
write_cmos_sensor(0x20,0x91);
sensor_flip_value=1;
break;
case IMAGE_HV_MIRROR:
write_cmos_sensor(0x20,0x93);
sensor_flip_value=3;
break;
}
if(sensor_flip_value == 3)
{
start_grab_y_offset = 18;
window_high_offset = 8;
/* Config Image Window */
image_window->grab_start_x=IMAGE_SENSOR_PV_INSERTED_PIXELS+start_grab_x_offset;
image_window->grab_start_y=IMAGE_SENSOR_PV_INSERTED_LINES+start_grab_y_offset;
image_window->exposure_window_width=IMAGE_SENSOR_PV_WIDTH;
image_window->exposure_window_height=IMAGE_SENSOR_PV_HEIGHT-window_high_offset;
}
else
{
start_grab_y_offset=0;
/* Config Image Window */
image_window->grab_start_x=IMAGE_SENSOR_PV_INSERTED_PIXELS+start_grab_x_offset;
image_window->grab_start_y=IMAGE_SENSOR_PV_INSERTED_LINES+start_grab_y_offset;
image_window->exposure_window_width=IMAGE_SENSOR_PV_WIDTH;
image_window->exposure_window_height=IMAGE_SENSOR_PV_HEIGHT;
}
image_window->current_exposure_pixel=current_sensor_expo_width;
image_window->exposure_pixel=sensor_expo_width;
write_cmos_sensor(0x05, IMAGE_SENSOR_PV_HBLANKING+PV_dummy_pixels);
write_cmos_sensor(0x06, IMAGE_SENSOR_PV_VBLANKING+PV_dummy_lines);
write_cmos_sensor(0x09, exposure_lines);
} /* MT9D011_preview */
void MT9D011_capture(image_sensor_exposure_window_struct *image_window, image_sensor_config_struct *sensor_config_data)
{
volatile kal_uint16 shutter=exposure_lines;
kal_uint16 sensor_flip;
kal_uint16 sensor_output_width;
kal_uint16 resize_factor = ISP_DIGITAL_ZOOM_INTERVAL;
kal_bool full_cap = 0;
// Check Meta Mode (ALWAYS FULL MODE or not)
if( sensor_config_data->meta_mode == CAPTURE_MODE_NORMAL )
full_cap = KAL_TRUE;
else
full_cap = KAL_FALSE;
sensor_flip=sensor_flip_value&0x03;
if(sensor_config_data->enable_shutter_tansfer==KAL_TRUE)
shutter=sensor_config_data->capture_shutter;
if(sensor_flip == 3)
{
if(sensor_config_data->frame_rate==0xF0)
{
start_grab_x_offset = 0;
start_grab_y_offset = 12;
window_high_offset = 8;
}
else if(full_cap==KAL_FALSE)
{
start_grab_x_offset = 6;
start_grab_y_offset = 18;
window_high_offset = 8;
}
else
{
start_grab_x_offset = 8;
start_grab_y_offset = 34;
window_high_offset = 16;
}
}
else
{
start_grab_x_offset = 0;
start_grab_y_offset = 0;
window_high_offset = 0;
}
// Check Webcam Mode
if(sensor_config_data->frame_rate==0xF0)
{
gPVmode=1;
write_cmos_sensor(0xF2, 0x000B); //Set to Context B
write_cmos_sensor(0x20, 0x090|sensor_flip); // Set readout mode, 2ADC, column and row skip mode
SET_TG_OUTPUT_CLK_DIVIDER(1); // 24Mhz/24MHz, Sync
SET_CMOS_RISING_EDGE(0);
SET_CMOS_FALLING_EDGE(1);
ENABLE_CAMERA_PIXEL_CLKIN_ENABLE;
SET_TG_PIXEL_CLK_DIVIDER(1);
SET_CMOS_DATA_LATCH(1);
FULL_dummy_pixels = 556; // 24000000/12/(816+880) = 24000000/12/1696=1179
FULL_dummy_lines = 0; // 1179/(621+48) = 21.14 fps
MAX_EXPOSURE_LINES = (kal_uint16)((sensor_pclk/MIN_FRAME_RATE)/(PV_PERIOD_PIXEL_NUMS+PV_dummy_pixels));
write_cmos_sensor(0x05, IMAGE_SENSOR_PV_HBLANKING+PV_dummy_pixels);
write_cmos_sensor(0x06, IMAGE_SENSOR_PV_VBLANKING+PV_dummy_lines);
image_window->grab_start_x=IMAGE_SENSOR_PV_INSERTED_PIXELS+start_grab_x_offset;
image_window->grab_start_y=IMAGE_SENSOR_PV_INSERTED_LINES+start_grab_y_offset;
image_window->exposure_window_width=IMAGE_SENSOR_PV_WIDTH-12;
image_window->exposure_window_height=IMAGE_SENSOR_PV_HEIGHT-16;
}
else if ((image_window->image_target_width<=IMAGE_SENSOR_PV_WIDTH)&&
(image_window->image_target_height<=IMAGE_SENSOR_PV_HEIGHT) &&
(full_cap==KAL_FALSE) )
{ /* Less than PV Mode */
gPVmode=1;
/* Check Zoom Factor */
sensor_output_width = (IMAGE_SENSOR_PV_WIDTH*ISP_DIGITAL_ZOOM_INTERVAL)/(image_window->digital_zoom_factor);
resize_factor = ((image_window->image_target_width)*ISP_DIGITAL_ZOOM_INTERVAL)/sensor_output_width;
write_cmos_sensor(0xF2, 0x000B); //Set to Context B
if ((resize_factor>=(ISP_DIGITAL_ZOOM_INTERVAL<<1))||
(sensor_config_data->meta_mode==CAPTURE_MODE_META_EXT) )
{
write_cmos_sensor(0x20, 0x090|sensor_flip); // Set readout mode, 2ADC, column and row skip mode
SET_TG_OUTPUT_CLK_DIVIDER(7); // 6/6MHz, Sync
SET_CMOS_RISING_EDGE(0);
SET_CMOS_FALLING_EDGE(3);
ENABLE_CAMERA_PIXEL_CLKIN_ENABLE;
SET_TG_PIXEL_CLK_DIVIDER(7);
SET_CMOS_DATA_LATCH(3);
shutter >>= 2;
}
else
{
write_cmos_sensor(0x20, 0x090|sensor_flip); // Set readout mode, 2ADC, column and row skip mode
SET_TG_OUTPUT_CLK_DIVIDER(3); // 12Mhz/12MHz, Sync
SET_CMOS_RISING_EDGE(0);
SET_CMOS_FALLING_EDGE(2);
ENABLE_CAMERA_PIXEL_CLKIN_ENABLE;
SET_TG_PIXEL_CLK_DIVIDER(3);
SET_CMOS_DATA_LATCH(2);
shutter>>=1;
}
image_window->grab_start_x=IMAGE_SENSOR_PV_INSERTED_PIXELS+start_grab_x_offset;
image_window->grab_start_y=IMAGE_SENSOR_PV_INSERTED_LINES+start_grab_y_offset;
image_window->exposure_window_width=IMAGE_SENSOR_PV_WIDTH;
image_window->exposure_window_height=IMAGE_SENSOR_PV_HEIGHT-window_high_offset;
}
else
{ /* 1.3M SXGA / 2M Mode */
gPVmode=0;
/* Check Zoom Factor */
sensor_output_width = (IMAGE_SENSOR_FULL_WIDTH*ISP_DIGITAL_ZOOM_INTERVAL)/(image_window->digital_zoom_factor);
resize_factor = ((image_window->image_target_width)*ISP_DIGITAL_ZOOM_INTERVAL)/sensor_output_width;
if ((resize_factor>=(ISP_DIGITAL_ZOOM_INTERVAL<<1))||
#if ((defined(MT6228)||defined(MT6229)||defined(MT6230))&&((!defined(__MAUI_BASIC__))&& (!defined(__L1_STANDALONE__))))
(tv_operation_state!=TV_IDLE_STATE) ||
#endif
(sensor_config_data->meta_mode==CAPTURE_MODE_META_EXT))
{ /* digital zoom factor >=2 */
write_cmos_sensor(0x20, 0x00|sensor_flip); // Set readout mode, 2ADC, no column or row skip
SET_TG_OUTPUT_CLK_DIVIDER(7);
SET_CMOS_RISING_EDGE(0);
SET_CMOS_FALLING_EDGE(3);
ENABLE_CAMERA_PIXEL_CLKIN_ENABLE;
SET_TG_PIXEL_CLK_DIVIDER(7);
SET_CMOS_DATA_LATCH(3);
FULL_dummy_pixels = 156;
FULL_dummy_lines = 0;
shutter=(shutter*(PV_PERIOD_PIXEL_NUMS+PV_dummy_pixels))/((FULL_PERIOD_PIXEL_NUMS+FULL_dummy_pixels)*4);
}
else
{
write_cmos_sensor(0x20, 0x00|sensor_flip); // Set readout mode, 2ADC, no column or row skip
SET_TG_OUTPUT_CLK_DIVIDER(3); // 12Mhz/12MHz, Sync
SET_CMOS_RISING_EDGE(0);
SET_CMOS_FALLING_EDGE(2);
ENABLE_CAMERA_PIXEL_CLKIN_ENABLE;
SET_TG_PIXEL_CLK_DIVIDER(3);
SET_CMOS_DATA_LATCH(2);
FULL_dummy_pixels = 156;
FULL_dummy_lines = 0;
shutter=(shutter*(PV_PERIOD_PIXEL_NUMS+PV_dummy_pixels))/((FULL_PERIOD_PIXEL_NUMS+FULL_dummy_pixels)*2);
}
write_cmos_sensor(0x05, IMAGE_SENSOR_FULL_HBLANKING+FULL_dummy_pixels);
write_cmos_sensor(0x06, IMAGE_SENSOR_FULL_VBLANKING+FULL_dummy_lines);
image_window->grab_start_x=IMAGE_SENSOR_FULL_INSERTED_PIXELS+start_grab_x_offset;
image_window->grab_start_y=IMAGE_SENSOR_FULL_INSERTED_LINES+start_grab_y_offset;
image_window->exposure_window_width=IMAGE_SENSOR_FULL_WIDTH;
image_window->exposure_window_height=IMAGE_SENSOR_FULL_HEIGHT-window_high_offset;
}
#if (!defined(MT6219))
/*Flash Light Shutter/Duty */
if(sensor_config_data->enable_flashlight_tansfer==KAL_TRUE)
{
kal_uint32 ori_shutter = shutter;
/* cal offset: valid line after VD falling edge */
if(gPVmode==1)
sensor_config_data->flashlight_offset = IMAGE_SENSOR_PV_HEIGHT;
else
sensor_config_data->flashlight_offset = IMAGE_SENSOR_FULL_HEIGHT;
/* cal shutter and factor, must > flashlight_offset */
sensor_config_data->flashlight_shut_factor = BASEGAIN; /* /1 */
if((shutter<<1)>(sensor_config_data->flashlight_offset))
sensor_config_data->flashlight_shut_factor = BASEGAIN*2; /* /2 */
else if((shutter*3)>(sensor_config_data->flashlight_offset))
sensor_config_data->flashlight_shut_factor = BASEGAIN*3; /* /3 */
else if((shutter<<2)>(sensor_config_data->flashlight_offset))
sensor_config_data->flashlight_shut_factor = BASEGAIN*4; /* /4, if shutter*4 still < flashlight offset, disable */
shutter = shutter*(sensor_config_data->flashlight_shut_factor)/BASEGAIN;
/* cal duty , can't > device_support_info.autoflash.duty */
if(shutter>sensor_config_data->flashlight_offset)
{
kal_uint32 pixelclk, duty;
if((REG_ISP_TG_PHASE_COUNTER & REG_TGPC_PIXEL_CLK_SELECT_BIT)!= 0)
pixelclk=((kal_uint32)(48000000/(((DRV_Reg32(ISP_TG_PHASE_COUNTER_REG)&0xF0)>>4)+1)));
else
pixelclk=((kal_uint32)(52000000/(((DRV_Reg32(ISP_TG_PHASE_COUNTER_REG)&0xF0)>>4)+1)));
sensor_config_data->flashlight_duty = shutter - (sensor_config_data->flashlight_offset);
duty = device_support_info.autoflash.duty*(pixelclk/12000000);
if(sensor_config_data->flashlight_duty > duty )
sensor_config_data->flashlight_duty = duty;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -