⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cam_module.c

📁 手机摄像头带jpeg压缩芯片PAP1302有关C语言代码,含ISP
💻 C
📖 第 1 页 / 共 5 页
字号:
	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 + -