📄 cam_module.c
字号:
/* back to preview state */
pap1302_reg_write(pap1302_INTERRUPT_FLAG_ADDR,0); // clear interrupt status //
pap1302_reg_write(0xE2,0x4000);//0xA000
if (digital_zoom_factor!=pap1302_DIGITAL_ZOOM_4X)
{
//pap1302_reg_write(0x98,2);
//mark for OV7660
//pas302_reg_write(0x02,2);
//pas302_reg_write(0x11,1);
//set for OV7660
//pas302_reg_write(0x11, 0x80);//for OV7660 30fps
pap1302_reg_write(0x96, 0x0100);
pap1302_reg_write(0x8c, 0x000e);//R_Sensor_Is_YUV = 1
}
//SW Reset for LCDC & BUF & JPG logic
pap1302_reg_write(0xdf, 0xf0f0);
pap1302_delay(0x40);
pap1302_reg_write(0xdf, 0xffff);
read_data1=pap1302_reg_read(0xE4);//R_GPO
pap1302_reg_write(0xE4,read_data1&0xfb);// GPO_1 =0
pap1302_reg_write(0x40,0x01);
pap1302_reg_write(0x40,0x111);
return(jpeg_file_size);
}
}//burst=false end
}//(read_data &0x1000)
} //if (pap1302_READY) end
else
{
capture_check_count++;
if ((burst_capture_mode==KAL_TRUE)&& (capture_check_count>=30))
{
capture_check_count=0;
if (current_captured_number>=1)
{
pap1302_reg_write(0xE2,0); /* disable all interrupt */
read_data=pap1302_reg_read(0xE5);
pap1302_reg_write(0xE5,(read_data&0xFFFE)); /* disable JPEG codec clock */
read_data=pap1302_reg_read(0x81); /* disable jpeg encode */
pap1302_reg_write(0x81,(read_data&0xFFEF));
pap1302_reg_write(0xC1,0);//N-shot mode disable
jpeg_file_size=pap1302_get_burst_jpeg_file();
if (jpeg_file_size!=0)
return (jpeg_file_size);
}
}
}
return NULL_JPEG_FILE;
} /* check_pap1302_capture_ready() */
//下面子函数主要对LCD显示大小进行设置,对JPEG没任何作用(no use for jpeg encode)
void pap1302_preview_size_setting(kal_uint16 preview_width, kal_uint16 preview_height)
{
kal_uint16 sensor_window_width,sensor_window_height;
kal_uint16 temp_size,display_window_width,display_window_height;
kal_uint8 zoom_factor;
switch (digital_zoom_factor)
{
case pap1302_DIGITAL_ZOOM_NORMAL:
if (preview_height==60)//如果原为为60像素高,而现在要求放大到正常状态,则只能做到240像素高,因为本程序只处理4倍以内的放大与缩小
{//注:60像素高是最小的图片高度QQCIF,本程序只处理60*80,120*160,240*320,480*640四种类型图片
sensor_window_width=320;
sensor_window_height=240;
}
else
{
sensor_window_width=640;
sensor_window_height=480;
}
//add for zoom
//pap1302_reg_write(0x1f, 0x0100);//R_AE_Window_X = 384
// pap1302_reg_write(0x20, 0x0180);//R_AE_Window_Y = 384
break;
case pap1302_DIGITAL_ZOOM_2X://2倍放大
if ((preview_width<=160)&&(preview_height<=120))
{
if (preview_height==60)
{
sensor_window_width=160;
sensor_window_height=120;
}
else
{
sensor_window_width=320;
sensor_window_height=240;
}
//add for zoom
// pap1302_reg_write(0x1f, 128);//R_AE_Window_X
// pap1302_reg_write(0x20, 192);//R_AE_Window_Y
}
else if ((preview_width<=320) && (preview_height<=240))
{
sensor_window_width=preview_width<<1;//*2
sensor_window_height=preview_height<<1;//*2
//add for zoom
// pap1302_reg_write(0x1f, 0x0100);//R_AE_Window_X
// pap1302_reg_write(0x20, 0x0180);//R_AE_Window_Y
}
else
return;
break;
case pap1302_DIGITAL_ZOOM_4X:
if (preview_height==60)
{
sensor_window_width=80;
sensor_window_height=60;
}
else if ((preview_width<=160) && (preview_height<=120))
{
sensor_window_width=160;
sensor_window_height=120;
//add for zoom
// pap1302_reg_write(0x1f, 64);//R_AE_Window_X
// pap1302_reg_write(0x20, 96);//R_AE_Window_Y
}
else
return;
break;
}
/* Set the image window that get from sensor according the ration of preview width and height */
if ((preview_width * sensor_window_height) > (preview_height * sensor_window_width))
{ /* x limit */
temp_size=(preview_height * sensor_window_width)/preview_width;
display_window_width=sensor_window_width;
display_window_height=temp_size;
pap1302_reg_write(0x4B,((640-sensor_window_width)>>1)|0x1000);//bit12=1,是因为SENSOR MASK ENABLE,除以2是因为偏移到MASK的正中间,左右各一半
pap1302_reg_write(0x4C,((480-temp_size)>>1));//除以2是因为偏移到MASK的正中间,上下各一半
}
else
{ /* y limit */
temp_size=(preview_width * sensor_window_height)/preview_height;
display_window_width=temp_size;
display_window_height=sensor_window_height;
pap1302_reg_write(0x4B,(((640-temp_size)>>1)|0x1000));
pap1302_reg_write(0x4C,((480-sensor_window_height)>>1));
}
pap1302_reg_write(0x4D,display_window_width+1);/////add for zoom
pap1302_reg_write(0x4E,display_window_height);
if (digital_zoom_factor==pap1302_DIGITAL_ZOOM_NORMAL)
{
if (preview_width<100)
{
display_window_width>>=2;//回原图片大小值
display_window_height>>=2;//回原图片大小值
pap1302_reg_write(0x44,0x1144);//4倍放大
}
else
{
display_window_width>>=1;//回原图片大小值
display_window_height>>=1;//回原图片大小值
pap1302_reg_write(0x44,0x1122);//2倍放大
}
}
else if (digital_zoom_factor==pap1302_DIGITAL_ZOOM_2X)
{
if (preview_width<100)
{
display_window_width>>=1;//回原图片大小值
display_window_height>>=1;//回原图片大小值
pap1302_reg_write(0x44,0x1122);//2倍放大
}
else
pap1302_reg_write(0x44,0x1100);//0倍放大
}
else
pap1302_reg_write(0x44,0x1100);//0倍放大
/* scalar setting */
if (display_window_width!=preview_width)//这里,我们一般只考虑display_window_width==preview_width的情况就可以了。
{ /* scale down the image that got from sensor */
zoom_factor=((display_window_width<<4)/preview_width);
temp_size=(display_window_width<<4)/zoom_factor;//===> temp_size=[display_window_width/preview_width](取整)
if ((temp_size*zoom_factor)==(display_window_width<<4))
display_window_width=temp_size;
else
display_window_width=temp_size+1;
temp_size=(display_window_height<<4)/zoom_factor;
if ((temp_size*zoom_factor)==(display_window_height<<4))
display_window_height=temp_size;
else
display_window_height=temp_size+1;
pap1302_reg_write(0x45,(0x8080|(zoom_factor<<8)|zoom_factor));
}
else
pap1302_reg_write(0x45,0);//0x45只能对图像进行1/2至1比例调整
/* cut the image width to fit the preview image width */
if (display_window_width!=preview_width)//这里,我们一般只考虑display_window_width==preview_width的情况就可以了。
pap1302_reg_write(0x47,((display_window_width-preview_width)>>1));
else
pap1302_reg_write(0x47,0);
if (display_window_height!=preview_height)//这里,我们一般只考虑display_window_height==preview_height的情况就可以了。
pap1302_reg_write(0x48,((display_window_height-preview_height)>>1));
else
pap1302_reg_write(0x48,0);
pap1302_reg_write(0x49,preview_width);//LCD display final width
pap1302_reg_write(0x4A,preview_height);//LCD display final height
} /* pap1302_preview_size_setting() */
/*************************************************************************
* FUNCTION
* pap1302_preview_frame
*
* DESCRIPTION
* This function ask external camera module to start preview.
*
* PARAMETERS
* *ext_cam_para : the parameters required for preview mode,输入变量.
*
* RETURNS
* None
*
* GLOBALS AFFECTED
*
*************************************************************************/
void pap1302_preview_frame(ext_camera_para_struct *ext_cam_para)
{
kal_uint16 read_data,read_data1,read_data2;
kal_uint16 buffer_offset_x,buffer_offset_y;
read_data1=pap1302_reg_read(0xE4);//R_GPO
pap1302_reg_write(0xE4,read_data1&0xf0);//toggle GPO for oscillloscope GPIO0-3=0,用于示波器观测
video_clip_drop_frame=0;
digital_zoom_flag=0;
if (disable_ae_awb(KAL_TRUE,KAL_TRUE)==KAL_FALSE)
return;
#if (defined(FIREFLY_856_BB)||defined(F_LCM_NEW))
if ((ext_cam_para->preview_width==96)&&(ext_cam_para->preview_height==64))
{
ext_cam_para->preview_width=64;
ext_cam_para->preview_height=96;
}
#endif
//for video recorder
pas302_reg_write(0x92,0x80);//dummy行为128行,0x93=00(初始时时已做)
//pas302_reg_write(0x2b,0x00);
//mark for OV7660(@8D+@CE<=648,@8E+@CF<=488),注:OV7660输出图像原始大小固定为648*488
pap1302_reg_write(0x8E,0x0006);//Y_Offset
pap1302_reg_write(0x8D,0x0008);//X_Offset
pap1302_reg_write(0xCE,640);//默认值
pap1302_reg_write(0xCF,480);//默认值
sensor_flip_status&=0xCF;//bit8-9:表示旋转方向
pap1302_reg_write(0x80,0x2020);//ISP开(enanble)
//mark for OV7660
if (ext_cam_para->preview_rotate==CAMERA_IMAGE_ROTATE_180)
{
sensor_flip_status |= 0x30; // Horizonal and Vertical flip
pap1302_reg_write(0x80,0x2000);//实际中取值0x2020与0x2000没有什么大的区别
}
else if (ext_cam_para->preview_rotate==CAMERA_IMAGE_MIRROR)
{
sensor_flip_status |= 0x20; // Horizonal flip
}
else if (ext_cam_para->preview_rotate==CAMERA_IMAGE_MIRROR_ROTATE_180)
{
sensor_flip_status |= 0x10; // Vertical flip
pap1302_reg_write(0x80,0x2000);
}
pap1302_reg_write(0x40,0x0);
pas302_reg_write(0x1E,sensor_flip_status);//mark for OV7660
//set for OV7660
read_data=pap1302_reg_read(0x96); /* unlock AE state */
read_data &= 0x0200;//sensclk divider=2
if ((read_data==0x0200)&&(digital_zoom_factor!=pap1302_DIGITAL_ZOOM_4X))
{ //如果sensor时钟只有一半,且不是最小的图片输出,则设置爆光线数
read_data2 = OV7660_reg_read(0x04);
//pas302_reg_write(0x11, 0x80);//for OV7660 30fps
pas302_reg_write(0x04,(locked_OV7660_Exposure_Value & 0x0003)|(read_data2&0xfc));//把爆光值的低两位写入0v7660相应寄存器locked_OV7660_Exposure_Value=0x40
pas302_reg_write(0x10,(locked_OV7660_Exposure_Value & 0x03FC)>>2); //把爆光值写入0v7660相应寄存器 ,0x07=0?(爆光值的高6位)
pas302_reg_write(0x2D,locked_OV7660_LSB_dummy);//插入dummy line(v),locked_OV7660_LSB_dummy=0
pas302_reg_write(0x2E,locked_OV7660_MSB_dummy);//插入dummy line(v),locked_OV7660_MSB_dummy=0
}
pap1302_reg_write(0x96, 0x0100);//sensclk divider=1
pap1302_config_data.buffer_width=ext_cam_para->buffer_width;
pap1302_config_data.buffer_height=ext_cam_para->buffer_height;
pap1302_config_data.preview_offset_x = ext_cam_para->preview_offset_x;
pap1302_config_data.preview_offset_y = ext_cam_para->preview_offset_y;
pap1302_config_data.preview_width=ext_cam_para->preview_width;
pap1302_config_data.preview_height=ext_cam_para->preview_height;
pap1302_config_data.snapshot_number = ext_cam_para->snapshot_number;
pap1302_config_data.white_balance_mode1 = ext_cam_para->white_balance_mode1;
pap1302_config_data.ev_value = ext_cam_para->ev_value;
pap1302_config_data.jpeg_compression_ratio = ext_cam_para->jpeg_compression_ratio;
pap1302_config_data.preview_rotate=ext_cam_para->preview_rotate; // temp_solution for demo
pap1302_config_data.banding_freq=ext_cam_para->banding_freq;
pap1302_config_data.image_buffer_ptr=ext_cam_para->image_buffer_ptr;
preview_image_width=ext_cam_para->preview_width;
preview_image_height=ext_cam_para->preview_height;
pap1302_set_para(pap1302_SET_EV_VALUE_CMD,ext_cam_para->ev_value);
pap1302_set_para(pap1302_SET_BAND_MODE_CMD,ext_cam_para->banding_freq);
pap1302_set_para(pap1302_SET_SPECIAL_EFFECT_CMD,ext_cam_para->image_effect1);//Ian
read_data=pap1302_reg_read(0xE3);
pap1302_reg_write(0xE3,(read_data&0xFFFC));
pap1302_reg_write(0xD5,0xF80);//CapRGB用于从LCD显示上抓拍
//pap1302_reg_write(0xC4,0xF80);
//pap1302_reg_write(0xC0,0x10);
pap1302_preview_size_setting(preview_image_width,preview_image_height);
switch (ext_cam_para->white_balance_mode1)//白平衡模式:自动、白天、暗黑、日光灯
{
case pap1302_WB_AUTO:
//pap1302_reg_write(0x8A,0x3000);
pas302_reg_write(0x69,0x50);//B,R
pas302_reg_write(0x01,0x97);//B
pas302_reg_write(0x02,0x2A);//R
//modify by boy on 0720
pap1302_reg_write(0xBC,AWB_R_Gain);////AWB_R_Gain = 0x01D3;
pap1302_reg_write(0xBD,AWB_B_Gain);//AWB_B_Gain = 0x0100;
enable_ae_awb(KAL_FALSE,KAL_TRUE);
wb_selection_auto=KAL_TRUE;
break;
case pap1302_WB_DAYLIGHT:
//pap1302_reg_write(0x8A,0x3000);
//set for OV7660
pas302_reg_write(0x69,0x50);
pas302_reg_write(0x01,0x97);
pas302_reg_write(0x02,0x92);
break;
case pap1302_WB_TUNGSTEN:
//pap1302_reg_write(0x8A,0x3000);
//set for OV7660
pas302_reg_write(0x69,0x80);
pas302_reg_write(0x01,0xa0);
pas302_reg_write(0x02,0x37);
break;
case pap1302_WB_FLUORESCENT://日光灯
//pap1302_reg_write(0x8A,0x3000);
//set for OV7660
pas302_reg_write(0x69,0x50);
pas302_reg_write(0x01,0xCA);
pas302_reg_write(0x02,0x64);
break;
}
if (enable_ae_awb(KAL_TRUE,KAL_FALSE)==KAL_FALSE)
return;
read_data=pap1302_reg_read(0x80);
pap1302_reg_write(0x80,read_data|0x2000); /* enable ISP bit13 */
pap1302_reg_write(0xE2,0x4000);//bit14=1
preview_frame_count=0;
capture_retry_count=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -