📄 cam_module.c
字号:
burst_capture_mode=KAL_FALSE;;
pap1302_reg_write(0x40,0x01);//set LCD operation mode:preview
pap1302_reg_write(0x40,0x111);//set LCD display start and display data captured into jpeg buffer(64KB)
//计算图片主机存放处:
if (preview_image_width!=64)
{
buffer_offset_x=(ext_cam_para->buffer_width-ext_cam_para->preview_width)>>1;//把图片放于正中,计算起始点时要除以2
buffer_offset_y=(ext_cam_para->buffer_height-ext_cam_para->preview_height)>>1;//把图片放于正中,计算起始点时要除以2
}
else
{ /* special case for 64x96 */
buffer_offset_x=0;
buffer_offset_y=0;
}
//计算开始存放点(左上角处)
image_shadow_ptr=(kal_uint16 *) (ext_cam_para->image_buffer_ptr + buffer_offset_y *
ext_camera_config_data.buffer_width + buffer_offset_x);
do
{
if (pap1302_READY)
{
read_data=pap1302_reg_read(pap1302_INTERRUPT_FLAG_ADDR);
if (read_data & 0x4000)//0x2000
{
pap1302_reg_write(pap1302_INTERRUPT_FLAG_ADDR,0); /* clear interrupt status */
preview_frame_count++;
}
}
} while (preview_frame_count<3);
pap1302_get_image();//读取预演图片入主mcu,图片大小为preview_image_width*preview_image_height
} /* pap1302_preview_frame() */
void pap1302_stop_preview(void)
{
digital_zoom_factor=pap1302_DIGITAL_ZOOM_NORMAL;
} /* pap1302_stop_preview() */
/*************************************************************************
* FUNCTION
* pap1302_capture_frame
*
* DESCRIPTION
* This function ask external camera module to start capture a frame and
* encode it as jpeg file.
*
* PARAMETERS
* *ext_cam_para : the parameters required for capture mode.
*
* RETURNS
* None
*
* GLOBALS AFFECTED
*
*************************************************************************/
void pap1302_capture_frame(ext_camera_para_struct *ext_cam_para)
{
kal_uint16 read_data,read_data1,read_data2;
kal_uint8 i;
kal_uint16 lpf,exposure_line_offset,exposure_line;
kal_uint16 OV7660_exposure_line;
pap1302_reg_write(0xE2,0x4000); /* wait Vsync rising--- bit14此中断一来,表示一帧图片刚过,另外bit3也表同样的意思,中是、bit14表示上升沿,bit3表示下降沿*/
//从ov7660时序图来看,Vsync上升沿表示一帧信号结束, Vsync下降沿表示一帧信号开始,
//modify by boy on 0720
AWB_R_Gain = pap1302_reg_read(0xBC);
AWB_B_Gain = pap1302_reg_read(0xBD);
//SW Reset for LCDC & BUF & JPG logic
// pap1302_reg_write(0xdf, 0xf0f0);
//pap1302_delay(0x40);
//pap1302_reg_write(0xdf, 0xffff);
//LED flash timing setting => Set GPO3 to LED flash timing
//read_data1=pap1302_reg_read(0xE4);
//pap1302_reg_write(0xE4,(read_data1|0x0010));//turn on
//Ptr_JpgFile Setting 对于QCIF及QQCIF图片统一存在一个固定地方
if(((preview_image_width==64) && (preview_image_height==96))||((preview_image_width==80) && (preview_image_height==60)) || ((preview_image_width==128) && (preview_image_height==160)))
pap1302_reg_write(0xd2, 0x5fff);//用16KB来存,注:内存范围是0-0x7fff(32K Words),
else
pap1302_reg_write(0xd2, 0x1478);//55KB来存。上电默认值是0x1478(注意是word地址,而非byte地址)
if (burst_capture_mode==KAL_TRUE)//如果是连拍
{
pap1302_reg_write(0xd2, 0x1478); //所有连拍图片从0x1478开始存
while (!pap1302_READY) {};
pap1302_reg_write(pap1302_INTERRUPT_FLAG_ADDR,0);
pap1302_config_data.burst_capture_ptr=ext_cam_para->burst_capture_ptr;
jpeg_file_shadow_ptr=ext_cam_para->jpeg_buffer_ptr;
pap1302_reg_write(0xC1,ext_cam_para->snapshot_number-1);//设置连拍张数
current_captured_number=0;
read_data=pap1302_reg_read(0xE5);
pap1302_reg_write(0xE5,(read_data|0x0001)); /* enable JPEG codec clock */
//---------------------------此段可以不要------------------------------------
pap1302_reg_write(0xE1,0x8002);//hsync fall interrupt enable
for (i=0;i<8;i++)
{ /* pap1302 limit, wait some H sync signal to make sure the data can be captured */
while (!pap1302_READY) {};
pap1302_reg_write(pap1302_INTERRUPT_FLAG_ADDR,0);
}
//---------------------------此段结束------------------------------------
pap1302_reg_write(0xE1,0x8000);
//jpeg enc mode,注:在preview mode下,寄予存器0x40的bit8位同样可以实现jpeg enc功能,但是对LCD显示图片而言
//两种jpeg方式图片存放buffer位置也有差别
read_data=pap1302_reg_read(0x40);
pap1302_reg_write(0x40,(read_data|0x02));
pap1302_reg_write(0xE2,0x1000); /* enable JPEG encode OK interrupt */
pap1302_reg_write(pap1302_INTERRUPT_FLAG_ADDR,0);
read_data=pap1302_reg_read(0x81); /* activate snap */
pap1302_reg_write(0x81,(read_data|0x10));
return;
}
else if (ext_cam_para->snapshot_number>1)//如果不是连拍,而是只是多张拍(不连续)
{
pap1302_reg_write(0xd2, 0x1478); //for 64x96/160x120 burst capture 12 image
pap1302_capture_ptr=ext_cam_para;
burst_capture_mode=KAL_TRUE;
if ((ext_cam_para->image_width!=160) || (ext_cam_para->image_height!=120))//说明多拍只对160*120而言
{
ASSERT(0);// 无效退出
}
}
current_captured_number=0;
read_data2=pap1302_reg_read(0xE3);
read_data2 &= 0xEFFC;//bit12=0:QQVGA不存于0xF80开始处
if (((ext_cam_para->image_width)*(ext_cam_para->image_height)<45000) &&
((ext_cam_para->image_width!=160) && (ext_cam_para->image_height!=120)))
{
while (!pap1302_READY) {};
//add to solve burstshot ==> snap 120*160 picture fail
pap1302_reg_write(0xc1,0);
read_data=pap1302_reg_read(pap1302_INTERRUPT_FLAG_ADDR);
if (read_data & 0x4000)//0x2000
pap1302_reg_write(pap1302_INTERRUPT_FLAG_ADDR,0); /* clear interrupt status */
if ((preview_image_width!=ext_cam_para->image_width)||
(preview_image_height!=ext_cam_para->image_height))
{
pap1302_preview_size_setting(ext_cam_para->image_width,ext_cam_para->image_height); //change CapRGB_Size
}
while (!pap1302_READY) {};//This file is fail. Because of CapRGB_Size(LCD_HSize & LCD_VSize) is change from 64*96 to 80*60
pap1302_reg_write(pap1302_INTERRUPT_FLAG_ADDR,0);
while (!pap1302_READY) {};//This file is ok. Because of CapRGB_Size is 80*60
pap1302_reg_write(pap1302_INTERRUPT_FLAG_ADDR,0);
//read_data2 = 0x1000;
// if (disable_ae_awb(KAL_TRUE,KAL_TRUE)==KAL_FALSE)
// return;
read_data=pap1302_reg_read(0x8D);
read_data1=pap1302_reg_read(0x8E);
if (digital_zoom_factor==pap1302_DIGITAL_ZOOM_NORMAL)
{
if (ext_cam_para->image_height==160)//160*240?
{//公式:@8D*2+@CE=640;@8E*2+@CF=480
pap1302_reg_write(0x8D,read_data+128);
pap1302_reg_write(0x8E,read_data1);
pap1302_reg_write(0xCE,384);//(640-128*2)
pap1302_reg_write(0xCF,480);//(480-0*2)
pap1302_reg_write(0xE3,0x0000);
pap1302_reg_write(0x44,0x3322);//jpeg按128*160
}
if (ext_cam_para->image_height==60)//80*60
{
pap1302_reg_write(0x8D,read_data+160);
pap1302_reg_write(0x8E,read_data1+120);
pap1302_reg_write(0xCE,320);
pap1302_reg_write(0xCF,240);
pap1302_reg_write(0xE3,0x0003);
pap1302_reg_write(0x44,0x2244);//jpeg按160*120,
}
}
else if (digital_zoom_factor==pap1302_DIGITAL_ZOOM_2X)
{
if (ext_cam_para->image_height==160)
{
pap1302_reg_write(0x8D,read_data+192);
pap1302_reg_write(0x8E,read_data1+80);
pap1302_reg_write(0xCE,256);
pap1302_reg_write(0xCF,320);
pap1302_reg_write(0xE3,0x0003);
}
if (ext_cam_para->image_height==60)
{
pap1302_reg_write(0x8D,read_data+240);
pap1302_reg_write(0x8E,read_data1+180);
pap1302_reg_write(0xCE,160);
pap1302_reg_write(0xCF,120);
pap1302_reg_write(0xE3,0x0000);
pap1302_reg_write(0x44,0x2222);//jpeg按80*60
}
}
else //digital_zoom_factor==pap1302_DIGITAL_ZOOM_4X
{
if (ext_cam_para->image_height==60)
{
pap1302_reg_write(0x8D,read_data+280);
pap1302_reg_write(0x8E,read_data1+210);
pap1302_reg_write(0xCE,80);
pap1302_reg_write(0xCF,60);
pap1302_reg_write(0xE3,0x0000);
pap1302_reg_write(0x44,0x1100);
}
}
}
else
{
while (!pap1302_READY) {};
pap1302_reg_write(pap1302_INTERRUPT_FLAG_ADDR,0); /* clear interrupt status */
//while (!pap1302_READY) {};
//pap1302_reg_write(pap1302_INTERRUPT_FLAG_ADDR,0); /* clear interrupt status */
//if (disable_ae_awb(KAL_TRUE,KAL_TRUE)==KAL_FALSE)
// return;
read_data=pap1302_reg_read(0x8D);
read_data1=pap1302_reg_read(0x8E);
if (digital_zoom_factor==pap1302_DIGITAL_ZOOM_2X)
{
if ((ext_cam_para->image_width>320)||(ext_cam_para->image_height)>240)
{
ext_cam_para->image_width>>=1;
ext_cam_para->image_height>>=1;
}
pap1302_reg_write(0x8D,read_data+160);
pap1302_reg_write(0x8E,read_data1+120);
pap1302_reg_write(0xCE,320);
pap1302_reg_write(0xCF,240);
if ((ext_cam_para->image_width==160) && (ext_cam_para->image_height==120))
read_data2 |=0x3;//read_data2是前面读的0xE3的值
}
else if (digital_zoom_factor==pap1302_DIGITAL_ZOOM_4X)
{
if ((ext_cam_para->image_width>320)||(ext_cam_para->image_height)>240)
{
ext_cam_para->image_width>>=2;
ext_cam_para->image_height>>=2;
}
else if ((ext_cam_para->image_width>160)||(ext_cam_para->image_height)>120)
{
ext_cam_para->image_width>>=1;
ext_cam_para->image_height>>=1;
}
pap1302_reg_write(0x8D,read_data+240);
pap1302_reg_write(0x8E,read_data1+180);
pap1302_reg_write(0xCE,160);
pap1302_reg_write(0xCF,120);
}
else
{
pap1302_reg_write(0xCE,640);//ISP_HSize
pap1302_reg_write(0xCF,480);//ISP_VSize
pap1302_reg_write(0x8D,read_data);
pap1302_reg_write(0x8E,read_data1);
//
if ((ext_cam_para->image_width==320) && (ext_cam_para->image_height==240))
read_data2 |=0x3;
else if ((ext_cam_para->image_width==160) && (ext_cam_para->image_height==120))
read_data2 |=0x2;
else if ((ext_cam_para->image_width<160) && (ext_cam_para->image_height<120))
read_data2 = 0x1000;//设置QQVGA图片存于0xF80开始处。
else if ((ext_cam_para->image_width!=640)||(ext_cam_para->image_height!=480))
ASSERT(0);
}
pap1302_reg_write(0xE3,read_data2);
}
//pap1302_reg_write(0xE3,read_data2);
read_data=pap1302_reg_read(0x40);
if (read_data==0x111)
{
//pap1302_reg_write(0xE2,0x4000); // wait Vsync rising// <== OPEN Vsync Rsing Interrupt
//pap1302_reg_write(0xE2,0x0004);//0x8004 // wait for LCD display_end interrupt //
pap1302_reg_write(0x40,2);
while (!pap1302_READY) {};
pap1302_reg_write(pap1302_INTERRUPT_FLAG_ADDR,0);
}
if (disable_ae_awb(KAL_TRUE,KAL_TRUE)==KAL_FALSE)
return;
//mark for OV7660
read_data = OV7660_reg_read(0x04);
read_data1 = OV7660_reg_read(0x10);
OV7660_Exposure_Value = ((read_data&0x03) | ((read_data1&0xff)<<2));
locked_OV7660_Exposure_Value = OV7660_Exposure_Value;
locked_OV7660_LSB_dummy = OV7660_reg_read(0x2D);
locked_OV7660_MSB_dummy = OV7660_reg_read(0x2E);
OV7660_exposure_line = locked_OV7660_Exposure_Value + locked_OV7660_LSB_dummy + (locked_OV7660_MSB_dummy*256);
if ((digital_zoom_factor!=pap1302_DIGITAL_ZOOM_4X)&&(capture_retry_count==0))
{
OV7660_exposure_line = OV7660_exposure_line>>1;
if (OV7660_exposure_line<505)
{
pas302_reg_write(0x04,((read_data&0xfc)|(OV7660_exposure_line&0x03)));
pas302_reg_write(0x10,((OV7660_exposure_line & 0x03fc)>>2));
pas302_reg_write(0x2D, 0x00);
pas302_reg_write(0x2E, 0x00);
}
else
{
OV7660_exposure_line = OV7660_exposure_line - 504;
pas302_reg_write(0x04,(read_data&0xfc));
pas302_reg_write(0x10,0x7e);//126*4 = 504
pas302_reg_write(0x2D, (OV7660_exposure_line&0x00ff));
pas302_reg_write(0x2E, (OV7660_exposure_line&0xff00)>>8);
}
//pas302_reg_write(0x11, 0x81);//for OV7660 15fps
pap1302_reg_write(0x96, 0x0200);
}
read_data=pap1302_reg_read(0xE5);
pap1302_reg_write(0xE5,(read_data|0x0001)); /* enable JPEG codec clock */
pap1302_reg_write(0xC0,0x0);
//add for solve 128*160 & 80*60 image qulity
if(((preview_image_width==64) && (preview_image_height==96))||((preview_image_width==80) && (preview_image_height==60)) || ((preview_image_width==128) && (preview_image_height==160)))
{
read_data1=0;
switch (ext_cam_para->jpeg_compression_ratio)
{
case pap1302_JPEG_QUALITY_LOW://慢调
read_data1 |= 40;
break;
case pap1302_JPEG_QUALITY_NORMAL://正常调
read_data1 |= 35;
break;
case pap1302_JPEG_QUALITY_HIGH://快调
read_data1 |= 30;
break;
case pap1302_JPEG_QUALITY_FINE://精调
read_data1 |= 25;
break;
}
read_data1+=(10*capture_retry_count);
pap1302_reg_write(0xC9,read_data1);
}
else//VGA & QVGA & QQVGA image size quality setting ==> no change
{
read_data1=0;
switch (ext_cam_para->jpeg_compression_ratio)
{
case pap1302_JPEG_QUALITY_LOW:
read_data1 |= 80;
break;
case pap1302_JPEG_QUALITY_NORMAL:
read_data1 |= 60;
break;
case pap1302_JPEG_QUALITY_HIGH:
read_data1 |= 40;
break;
case pap1302_JPEG_QUALITY_FINE:
read_data1 |= 25;
break;
}
read_data1+=(20*capture_retry_count);
pap1302_reg_write(0xC9,read_data1);
}
pap1302_config_data.jpeg_compression_ratio=ext_cam_para->jpeg_compression_ratio;
pap1302_config_data.image_width=ext_cam_para->image_width;
pap1302_config_data.image_height=ext_cam_para->image_height;
pap1302_config_data.jpeg_buffer_ptr=ext_cam_para->jpeg
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -