📄 image_sensor.c
字号:
write_cmos_sensor(0x8C, 0x06);
write_cmos_sensor(0x86, 0x35);
write_cmos_sensor(0x50, 0x00);
write_cmos_sensor(0x51, 0xCC);
write_cmos_sensor(0x52, 0x99);
write_cmos_sensor(0x53, 0x00);
write_cmos_sensor(0x54, 0x00);
write_cmos_sensor(0x55, 0x00);
write_cmos_sensor(0x5A, 0xCC);
write_cmos_sensor(0x5B, 0x99);
write_cmos_sensor(0x5C, 0x00);
write_cmos_sensor(0xD3, 0x82);
write_cmos_sensor(0xE5, 0x1F);
write_cmos_sensor(0xE1, 0x67);
write_cmos_sensor(0xE0, 0x00);
write_cmos_sensor(0xDD, 0x7F);
write_cmos_sensor(0x05, 0x00);
//write_cmos_sensor(0x87, 0xD0);
write_cmos_sensor(0xC3, 0x81);
write_cmos_sensor(0xC2, 0x01);
write_cmos_sensor(0x92, 0x01);
write_cmos_sensor(0x93, 0x00);
write_cmos_sensor(0x92, 0x00);
write_cmos_sensor(0x93, 0x00);
#else
// setup sensor output ROI
write_cmos_sensor(0x17, 0x10);
write_cmos_sensor(0x18, 0x43);
write_cmos_sensor(0x32, 0x36);
write_cmos_sensor(0x19, 0x00);
write_cmos_sensor(0x1A, 0x4D);
write_cmos_sensor(0x03, 0x00);
write_cmos_sensor(0x4F, 0xCA); // 50Hz banding AEC 8 LSBs
write_cmos_sensor(0x50, 0xA8); // 60Hz banding AEC 8 LSBs
write_cmos_sensor(0x5A, 0x23); // 50/60Hz banding AEC maximum steps
write_cmos_sensor(0x6D, 0x00); // reserved
write_cmos_sensor(0x3D, 0x38); // PLL/divider setting
write_cmos_sensor(0x39, 0x12); // PWCOM1, reserved
write_cmos_sensor(0x35, 0xDA); // reserved
iTemp = read_cmos_sensor(0x22); // ANCOM3
write_cmos_sensor(0x22, iTemp | 0x10);
write_cmos_sensor(0x37, 0xC3); // reserved
write_cmos_sensor(0x23, 0x00); // reserved
write_cmos_sensor(0x34, 0xC0); // ARCOM2, reserved
write_cmos_sensor(0x36, 0x1A); // reserved
write_cmos_sensor(0x06, 0x88); // reserved
write_cmos_sensor(0x07, 0xC0); // reserved
write_cmos_sensor(0x0D, 0x87); // reserved
write_cmos_sensor(0x0E, 0x41); // reserved
write_cmos_sensor(0x4C, 0x00); // reserved
#endif
gVGAmode = KAL_TRUE;
if (pSensorConfigData->frame_rate == 0x0F) { // MPEG4 Encode Mode
MPEG4_encode_mode = KAL_TRUE;
#ifdef OV2640_MPEG4_QCIF_VIDEO_30FPS
if (pImageWindow->image_target_width == 176 &&
pImageWindow->image_target_height == 144) {
// MT6228 supports QCIF MPEG4 up to 30fps
g_iOV2640_Mode = OV2640_MODE_QCIF_VIDEO;
SET_TG_OUTPUT_CLK_DIVIDER(1); // MCLK = 24MHz
SET_CMOS_RISING_EDGE(0);
SET_CMOS_FALLING_EDGE(1);
SET_TG_PIXEL_CLK_DIVIDER(1); // PCLK = 24MHz
SET_CMOS_DATA_LATCH(1);
//*******************************************
// OV2640 clock calculation:
// Fclk = (64 - 0x3D[5:0]) x MCLK / M, where
// Fclk: PLL output clock
// M = 2 if 0x3D[7:6] = 00
// M = 3 if 0x3D[7:6] = 01
// M = 4 if 0x3D[7:6] = 10
// M = 6 if 0x3D[7:6] = 11
// Fint = Fclk / (2 x (0x11[5:0] + 1)), where
// Fint: internal clock
// PCLK = Fint / 2
//*******************************************
write_cmos_sensor(PAGE_SETTING_REG, 0x01);
write_cmos_sensor(0x3D, 0x38);
write_cmos_sensor(0x11, 0x00);
// iStartX = 4;
// iStartY = 4;
iDummyPixels = OV2640_VIDEO__QCIF_DUMMY_PIXELS;
iDummyLines = 17;
}else {
#endif
// MT6228 supports CIF MPEG4 up to 15fps
g_iOV2640_Mode = OV2640_MODE_CIF_VIDEO;
/* config TG of ISP to match the setting of image sensor*/
SET_TG_OUTPUT_CLK_DIVIDER(1); // MCLK = 24MHz
SET_CMOS_RISING_EDGE(0);
SET_CMOS_FALLING_EDGE(1);
SET_TG_PIXEL_CLK_DIVIDER(3); // PCLK = 12MHz
SET_CMOS_DATA_LATCH(1);
//*******************************************
// OV2640 clock calculation:
// Fclk = (64 - 0x3D[5:0]) x MCLK / M, where
// Fclk: PLL output clock
// M = 2 if 0x3D[7:6] = 00
// M = 3 if 0x3D[7:6] = 01
// M = 4 if 0x3D[7:6] = 10
// M = 6 if 0x3D[7:6] = 11
// Fint = Fclk / (2 x (0x11[5:0] + 1)), where
// Fint: internal clock
// PCLK = Fint / 2
//*******************************************
write_cmos_sensor(PAGE_SETTING_REG, 0x01);
write_cmos_sensor(0x3D, 0x38);
write_cmos_sensor(0x11, 0x01);
// iStartX = 4;
// iStartY = 4;
iDummyPixels = OV2640_VIDEO__CIF_DUMMY_PIXELS;
iDummyLines = 0;
#ifdef OV2640_MPEG4_QCIF_VIDEO_30FPS
}
#endif
}else {
MPEG4_encode_mode = KAL_FALSE;
SET_TG_OUTPUT_CLK_DIVIDER(1); // MCLK = 24MHz
SET_CMOS_RISING_EDGE(0);
SET_CMOS_FALLING_EDGE(1);
SET_TG_PIXEL_CLK_DIVIDER(1); // PCLK = 24MHz
SET_CMOS_DATA_LATCH(1);
//*******************************************
// OV2640 clock calculation:
// Fclk = (64 - 0x3D[5:0]) x MCLK / M, where
// Fclk: PLL output clock
// M = 2 if 0x3D[7:6] = 00
// M = 3 if 0x3D[7:6] = 01
// M = 4 if 0x3D[7:6] = 10
// M = 6 if 0x3D[7:6] = 11
// Fint = Fclk / (2 x (0x11[5:0] + 1)), where
// Fint: internal clock
// PCLK = Fint / 2
//*******************************************
write_cmos_sensor(PAGE_SETTING_REG, 0x01);
write_cmos_sensor(0x3D, 0x38);
write_cmos_sensor(0x11, 0x00);
g_iPV_PCLK_Divider = ((DRV_Reg32(ISP_TG_PHASE_COUNTER_REG) >> 4) & 0x0000000F) + 1;
// iStartX = 4;
// iStartY = 4+2;//remove top dummy line
iDummyPixels = OV2640_PV_DUMMY_PIXELS;
iDummyLines = 0;
g_iOV2640_Mode = OV2640_MODE_PREVIEW;
}
write_cmos_sensor(PAGE_SETTING_REG, 0x01);
iTemp = read_cmos_sensor(0x04) & 0x2F;
switch (pSensorConfigData->image_mirror) {
case IMAGE_NORMAL:
iStartX = 4;
iStartY = 6;
// do nothing
break;
case IMAGE_HV_MIRROR:
iStartX = 4;
#ifdef OV_PROCESSING_RAW
iStartY = 5;
iTemp |= 0xC0;
#else
iStartY = 4;
iTemp |= 0xD0;
#endif
break;
default:
ASSERT(0);
}
write_cmos_sensor(0x04, iTemp);
// compensate OV2640 ABLC for every frame
write_cmos_sensor(PAGE_SETTING_REG, 0x01);
write_cmos_sensor(0x71, 0x94); // reserved register
OV2640_SetDummy(iDummyPixels, iDummyLines);
g_iPreview_Column_Pixel = PV_PERIOD_PIXEL_NUMS + iDummyPixels;
pImageWindow->grab_start_x = iStartX;
pImageWindow->grab_start_y = iStartY;
pImageWindow->exposure_window_width = IMAGE_SENSOR_PV_WIDTH;
pImageWindow->exposure_window_height = IMAGE_SENSOR_PV_HEIGHT;
write_OV2640_shutter(g_iExpLines);
} /* OV2640_Preview */
void OV2640_Capture(image_sensor_exposure_window_struct *pImageWindow, image_sensor_config_struct *pSensorConfigData)
{
kal_uint16 iCapture_Column_Pixel = 0, iShutter = g_iExpLines;
kal_uint16 iDummyPixels = 0, iDummyLines = 0, iStartX, iStartY, iGrabWidth, iGrabHeight;
kal_uint8 iTemp, iCP_PCLK_Div = 1;
const kal_bool bMetaMode = pSensorConfigData->meta_mode != CAPTURE_MODE_NORMAL;
if (pSensorConfigData->enable_shutter_tansfer == KAL_TRUE) {
iShutter = pSensorConfigData->capture_shutter;
}
if ((pImageWindow->image_target_width <= IMAGE_SENSOR_PV_WIDTH) &&
(pImageWindow->image_target_height <= IMAGE_SENSOR_PV_HEIGHT)) {
gVGAmode = KAL_TRUE;
if (pSensorConfigData->frame_rate == 0xF0) { // WEBCAM mode
SET_TG_PIXEL_CLK_DIVIDER(1); // PCLK = 24MHz
SET_CMOS_DATA_LATCH(1);
write_cmos_sensor(PAGE_SETTING_REG, 0x01);
write_cmos_sensor(0x11, 0x00);
iDummyPixels = 600; // to make line period same as preview
iDummyLines = 0;
// iStartX = 4;
// iStartY = 4;
iGrabWidth = IMAGE_SENSOR_PV_WIDTH;
iGrabHeight = IMAGE_SENSOR_PV_HEIGHT - 20;
}else {
if (pImageWindow->digital_zoom_factor >= (ISP_DIGITAL_ZOOM_INTERVAL << 1) || bMetaMode == KAL_TRUE) {
SET_TG_PIXEL_CLK_DIVIDER(7); // PCLK = 6MHz
SET_CMOS_DATA_LATCH(4);
write_cmos_sensor(PAGE_SETTING_REG, 0x01);
write_cmos_sensor(0x11, 0x03);
iDummyPixels = 70;
iDummyLines = 0;
}else { // capture < 2x digital zoom
SET_TG_PIXEL_CLK_DIVIDER(3); // PCLK = 12MHz
SET_CMOS_DATA_LATCH(2);
write_cmos_sensor(PAGE_SETTING_REG, 0x01);
write_cmos_sensor(0x11, 0x01);
iDummyPixels = 0;
iDummyLines = 0;
}
// iStartX = 4;
// iStartY = 4;
iGrabWidth = IMAGE_SENSOR_PV_WIDTH;
iGrabHeight = IMAGE_SENSOR_PV_HEIGHT;
}
switch (pSensorConfigData->image_mirror) {
case IMAGE_NORMAL:
iStartX = 4;
#ifdef OV_PROCESSING_RAW
iStartY = 6;
#else
iStartY = 4;
#endif
break;
case IMAGE_HV_MIRROR:
iStartX = 4;
#ifdef OV_PROCESSING_RAW
iStartY = 5;
#else
iStartY = 4;
#endif
break;
default:
ASSERT(0);
}
iCapture_Column_Pixel = PV_PERIOD_PIXEL_NUMS + iDummyPixels;
iCP_PCLK_Div = ((DRV_Reg32(ISP_TG_PHASE_COUNTER_REG) >> 4) & 0x0000000F) + 1;
iShutter = iShutter * g_iPreview_Column_Pixel / iCapture_Column_Pixel;
iShutter = iShutter * g_iPV_PCLK_Divider / iCP_PCLK_Div;
}else { // 2M UXGA Mode
gVGAmode = KAL_FALSE;
#ifdef OV_PROCESSING_RAW
/*Switch mode to 1610x1210*/
write_cmos_sensor(PAGE_SETTING_REG,0x01);
write_cmos_sensor(0x12, 0x00); // switch to UXGA(1600x1200) mode
// setup sensor output ROI
write_cmos_sensor(0x17, 0x11);
write_cmos_sensor(0x18, 0x76);
write_cmos_sensor(0x32, 0x24);
write_cmos_sensor(0x19, 0x01);
write_cmos_sensor(0x1A, 0x99);
write_cmos_sensor(0x03, 0x0E);
write_cmos_sensor(0x4F, 0xBB); // 50Hz banding AEC 8 LSBs
write_cmos_sensor(0x50, 0x9C); // 60Hz banding AEC 8 LSBs
write_cmos_sensor(0x5A, 0x57); // 50/60Hz banding AEC maximum steps
write_cmos_sensor(0x6D, 0x80); // reserved
// write_cmos_sensor(0x3D, 0x34); // PLL/divider setting
write_cmos_sensor(0x3D, 0x38); // PLL/divider setting
write_cmos_sensor(0x39, 0x02); // PWCOM1, reserved
write_cmos_sensor(0x35, 0x88); // reserved
iTemp = read_cmos_sensor(0x22); // ANCOM3
write_cmos_sensor(0x22, iTemp & 0xEF);
write_cmos_sensor(0x37, 0x40); // reserved
write_cmos_sensor(0x23, 0x00); // reserved
write_cmos_sensor(0x34, 0xA0); // ARCOM2, reserved
write_cmos_sensor(0x36, 0x1A); // reserved
write_cmos_sensor(0x06, 0x02); // reserved
write_cmos_sensor(0x07, 0xC0); // reserved
write_cmos_sensor(0x0D, 0xB7); // reserved
write_cmos_sensor(0x0E, 0x01); // reserved
write_cmos_sensor(0x4C, 0x00); // reserved
write_cmos_sensor(PAGE_SETTING_REG, 0x00);
write_cmos_sensor(0xC0, 0xCA);
write_cmos_sensor(0xC1, 0x98);
write_cmos_sensor(0x8C, 0x02);
write_cmos_sensor(0x86, 0x35);
write_cmos_sensor(0x50, 0x00);
write_cmos_sensor(0x51, 0x94);
write_cmos_sensor(0x52, 0x30);
write_cmos_sensor(0x53, 0x00);
write_cmos_sensor(0x54, 0x00);
write_cmos_sensor(0x55, 0x88);
write_cmos_sensor(0x57, 0x00);
write_cmos_sensor(0x5A, 0x94);
write_cmos_sensor(0x5B, 0x30);
write_cmos_sensor(0x5C, 0x05);
write_cmos_sensor(0xD3, 0x82);
write_cmos_sensor(0xE5, 0x1F);
write_cmos_sensor(0xE1, 0x67);
write_cmos_sensor(0xE0, 0x00);
write_cmos_sensor(0xDD, 0x7F);
write_cmos_sensor(0x05, 0x00);
write_cmos_sensor(0x87, OV_WPC_BPC_CTRL);
write_cmos_sensor(0xC3, 0x01);
write_cmos_sensor(0xC2, 0x81);
write_cmos_sensor(0x92, 0x01);
write_cmos_sensor(0x93, 0x00);
write_cmos_sensor(0x92, 0x00);
write_cmos_sensor(0x93, 0x00);
#else
/*Switch mode to 1610x1210*/
write_cmos_sensor(PAGE_SETTING_REG,0x01);
write_cmos_sensor(0x12, 0x00); // switch to UXGA(1600x1200) mode
// setup sensor output ROI
write_cmos_sensor(0x17, 0x11);
write_cmos_sensor(0x18, 0x75);
write_cmos_sensor(0x32, 0x3A);
write_cmos_sensor(0x19, 0x01);
write_cmos_sensor(0x1A, 0x98);
write_cmos_sensor(0x03, 0x84);
write_cmos_sensor(0x4F, 0xBB); // 50Hz banding AEC 8 LSBs
write_cmos_sensor(0x50, 0x9C); // 60Hz banding AEC 8 LSBs
write_cmos_sensor(0x5A, 0x57); // 50/60Hz banding AEC maximum steps
write_cmos_sensor(0x6D, 0x80); // reserved
// write_cmos_sensor(0x3D, 0x34); // PLL/divider setting
write_cmos_sensor(0x3D, 0x38); // PLL/divider setting
write_cmos_sensor(0x39, 0x02); // PWCOM1, reserved
write_cmos_sensor(0x35, 0x88); // reserved
iTemp = read_cmos_sensor(0x22); // ANCOM3
write_cmos_sensor(0x22, iTemp & 0xEF);
write_cmos_sensor(0x37, 0x40); // reserved
write_cmos_sensor(0x23, 0x00); // reserved
write_cmos_sensor(0x34, 0xA0); // ARCOM2, reserved
write_cmos_sensor(0x36, 0x1A); // reserved
write_cmos_sensor(0x06, 0x02); // reserved
write_cmos_sensor(0x07, 0xC0); // reserved
write_cmos_sensor(0x0D, 0xB7); // reserved
write_cmos_sensor(0x0E, 0x01); // reserved
write_cmos_sensor(0x4C, 0x00); // reserved
#endif
if ((pImageWindow->image_target_width <= IMAGE_SENSOR_FULL_WIDTH) &&
(pImageWindow->image_target_height <= IMAGE_SENSOR_FULL_WIDTH)) {
if (pImageWindow->digital_zoom_factor >= (ISP_DIGITAL_ZOOM_INTERVAL << 1) || bMetaMode == KAL_TRUE) {
// capture >= 2x zoom
if (bMetaMode == KAL_TRUE) {
SET_TG_PIXEL_CLK_DIVIDER(7); // PCLK = 6MHz
SET_CMOS_DATA_LATCH(4);
write_cmos_sensor(PAGE_SETTING_REG, 0x01);
write_cmos_sensor(0x11, 0x03);
iDummyPixels = 400;
iDummyLines = 0;
}else {
SET_TG_PIXEL_CLK_DIVIDER(15); // PCLK = 6MHz
SET_CMOS_DATA_LATCH(8);
write_cmos_sensor(PAGE_SETTING_REG, 0x01);
write_cmos_sensor(0x11, 0x07);
iDummyPixels = 100;
iDummyLines = 0;
}
}else if (pImageWindow->digital_zoom_factor == ISP_DIGITAL_ZOOM_INTERVAL) {
// capture w/o zoom
SET_TG_PIXEL_CLK_DIVIDER(3); // PCLK = 12MHz
SET_CMOS_DATA_LATCH(2);
write_cmos_sensor(PAGE_SETTING_REG, 0x01);
write_cmos_sensor(0x11, 0x01);
iDummyPixels = 115;
iDummyLines = 0;
}else { // 1x < zoom factor < 2x
SET_TG_PIXEL_CLK_DIVIDER(3); // PCLK = 12MHz
SET_CMOS_DATA_LATCH(2);
write_cmos_sensor(PAGE_SETTING_REG, 0x01);
write_cmos_sensor(0x11, 0x01);
iDummyPixels = 1725;
iDummyLines = 0;
}
}else { // 3M capture mode
if (pImageWindow->digital_zoom_factor >= (ISP_DIGITAL_ZOOM_INTERVAL << 1) || bMetaMode == KAL_TRUE) {
SET_TG_PIXEL_CLK_DIVIDER(7); // PCLK = 6MHz
SET_CMOS_DATA_LATCH(4);
write_cmos_sensor(PAGE_SETTING_REG, 0x01);
write_cmos_sensor(0x11, 0x03);
iDummyPixels = 70;
iDummyLines = 0;
}else { // capture < 2x digital zoom
SET_TG_PIXEL_CLK_DIVIDER(3); // PCLK = 12MHz
SET_CMOS_DATA_LATCH(2);
write_cmos_sensor(PAGE_SETTING_REG, 0x01);
write_cmos_sensor(0x11, 0x01);
iDummyPixels = 0;
iDummyLines = 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -