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

📄 image_sensor.c

📁 mtk 6225, ov9660 摄像头驱动源码.可以直接使用
💻 C
📖 第 1 页 / 共 4 页
字号:
  write_cmos_sensor(0x9b, 0x04);
	write_cmos_sensor(0x9c, 0x07);
	write_cmos_sensor(0x9d, 0x10);
	write_cmos_sensor(0x9e, 0x28);
	write_cmos_sensor(0x9f, 0x36);
	write_cmos_sensor(0xa0, 0x44);
	write_cmos_sensor(0xa1, 0x52);
	write_cmos_sensor(0xa2, 0x60);
	write_cmos_sensor(0xa3, 0x6c);
	write_cmos_sensor(0xa4, 0x78);
	write_cmos_sensor(0xa5, 0x8c);
	write_cmos_sensor(0xa6, 0x9e);
	write_cmos_sensor(0xa7, 0xbb);
	write_cmos_sensor(0xa8, 0xd2);
	write_cmos_sensor(0xa9, 0xe5);
	   
#else
	write_cmos_sensor(0xaa, 0x20);
  write_cmos_sensor(0x9b, 0x02);
	write_cmos_sensor(0x9c, 0x07);
	write_cmos_sensor(0x9d, 0x11);
	write_cmos_sensor(0x9e, 0x2e);
	write_cmos_sensor(0x9f, 0x3c);
	write_cmos_sensor(0xa0, 0x4a);
	write_cmos_sensor(0xa1, 0x59);
	write_cmos_sensor(0xa2, 0x66);
	write_cmos_sensor(0xa3, 0x73);
	write_cmos_sensor(0xa4, 0x80);
	write_cmos_sensor(0xa5, 0x96);
	write_cmos_sensor(0xa6, 0xa5);
	write_cmos_sensor(0xa7, 0xc1);
	write_cmos_sensor(0xa8, 0xd4);
	write_cmos_sensor(0xa9, 0xe8);
	
#endif
	write_cmos_sensor(0xAB, 0xe7);
	write_cmos_sensor(0xb0, 0x43);
	write_cmos_sensor(0xac, 0x04);
	write_cmos_sensor(0x84, 0x40);

	write_cmos_sensor(0xad, 0x86);//82
	write_cmos_sensor(0xd9, 0x44);//33
	write_cmos_sensor(0xda, 0x00);
	write_cmos_sensor(0xae, 0x10);

	write_cmos_sensor(0xab, 0xe7);
	write_cmos_sensor(0xb9, 0x50);
	write_cmos_sensor(0xba, 0x3c);
	write_cmos_sensor(0xbb, 0x50);
	write_cmos_sensor(0xbc, 0x3c);

	write_cmos_sensor(0xbd, 0x8);
	write_cmos_sensor(0xbe, 0x19);
	write_cmos_sensor(0xbf, 0x2);
	write_cmos_sensor(0xc0, 0x8);
	write_cmos_sensor(0xc1, 0x2a);
	write_cmos_sensor(0xc2, 0x34);
	write_cmos_sensor(0xc3, 0x2d);
	write_cmos_sensor(0xc4, 0x2d);
	write_cmos_sensor(0xc5, 0x0);
	write_cmos_sensor(0xc6, 0x98);
	write_cmos_sensor(0xc7, 0x18);
	write_cmos_sensor(0x69, 0x48);

	write_cmos_sensor(0x74, 0xc0);

	write_cmos_sensor(0x7c, 0x28);//18
	write_cmos_sensor(0x65, 0x11);
	write_cmos_sensor(0x66, 0x00);
	write_cmos_sensor(0x41, 0xc0);//a0
	write_cmos_sensor(0x5b, 0x24);//28
	write_cmos_sensor(0x60, 0x82);//84
	write_cmos_sensor(0x05, 0x07);
	write_cmos_sensor(0x03, 0x03);
	write_cmos_sensor(0xd2, 0x94);//8c

	write_cmos_sensor(0xc7, 0x90);
	write_cmos_sensor(0xc8, 0x06);
	write_cmos_sensor(0xcb, 0x40);
	write_cmos_sensor(0xcc, 0x40);
	write_cmos_sensor(0xcf, 0x00);
	write_cmos_sensor(0xd0, 0x20);
	write_cmos_sensor(0xd1, 0x00);
	write_cmos_sensor(0xc7, 0x18);

	write_cmos_sensor(0x0d, 0x92);
	write_cmos_sensor(0x0d, 0x90);        

	normal_gain=read_cmos_sensor(0x00);
	sensor_gain_base=read_OV9660_gain();
	
	return 1;
}	/* init_cmos_sensor() */

/*************************************************************************
* FUNCTION
*	power_off_OV9660
*
* DESCRIPTION
*	This function is to turn off sensor module power.
*
* PARAMETERS
*	None
*
* RETURNS
*	None
*
* GLOBALS AFFECTED
*
*************************************************************************/
void power_off_OV9660(void)
{
	cis_module_power_on(KAL_FALSE);      // Power Off CIS Power
	UPLL_Disable(UPLL_OWNER_ISP);
	#ifndef HW_SCCB
	   SET_SCCB_CLK_LOW;
	   SET_SCCB_DATA_LOW;
	#endif
}	/* power_off_OV9660 */

/*************************************************************************
* FUNCTION
*	get_OV9660_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_OV9660_id(kal_uint8 *sensor_write_id, kal_uint8 *sensor_read_id)
{
	*sensor_write_id=OV9660_WRITE_ID;
	*sensor_read_id=OV9660_READ_ID;
}	/* get_OV9660_id */

/*************************************************************************
* FUNCTION
*	get_OV9660_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_OV9660_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;		/* line numbers actually used in one frame */
}	/* get_OV9660_size */

/*************************************************************************
* FUNCTION
*	get_OV9660_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_OV9660_period(kal_uint16 *pixel_number, kal_uint16 *line_number)
{
	*pixel_number=PV_PERIOD_PIXEL_NUMS;			/* pixel numbers in one period of HSYNC */
	*line_number=PV_PERIOD_LINE_NUMS;				/* line numbers in one period of VSYNC */
}	/* get_OV9660_period */

void OV9660_preview(image_sensor_exposure_window_struct *image_window, image_sensor_config_struct *sensor_config_data)
{
    kal_uint8 temp_v_flip_reg2 = read_cmos_sensor(0x04);
    kal_uint8 temp_v_flip_reg1 = (temp_v_flip_reg2 & (~0xC0));
    kal_uint8 temp_h_mirror_reg2 = read_cmos_sensor(0x33);
    kal_uint8 temp_h_mirror_reg1 = (temp_h_mirror_reg2 & (~0x08));

	sensor_cap_state=KAL_FALSE;
	
	#ifdef OUTPUT_DEBUG_INFO
	sprintf(temp_buffer, "Begin of OV9660_preview");
	rmmi_write_to_uart((kal_uint8*) temp_buffer, strlen(temp_buffer), KAL_TRUE);
	sprintf(temp_buffer, "pre_shut:%d", exposure_lines);
	rmmi_write_to_uart((kal_uint8*) temp_buffer, strlen(temp_buffer), KAL_TRUE);
	#endif
	kal_prompt_trace(MOD_ENG,"temp_v_flip_reg2=0x%x, temp_h_mirror_reg2=0x%x",temp_v_flip_reg2,temp_h_mirror_reg2);


	write_cmos_sensor(0x12, 0x40); //vga mode

	write_cmos_sensor(0x63, 0x00); //

	write_cmos_sensor(0x4d, 0x09); //

	write_cmos_sensor(0x17, 0x0d); //0c
	write_cmos_sensor(0x18, 0x5d); //5c
	write_cmos_sensor(0x19, 0x02);
	write_cmos_sensor(0x1a, 0x3f);

	write_cmos_sensor(0x03, 0x03);

	write_cmos_sensor(0x32, 0xad); //0x32
	write_cmos_sensor(0x2b, 0x00);
	write_cmos_sensor(0x64, 0xa4);

	write_cmos_sensor(0xab, 0xe7);

	write_cmos_sensor(0xb9, 0x50);
	write_cmos_sensor(0xba, 0x3c);
	write_cmos_sensor(0xbb, 0x50);
	write_cmos_sensor(0xbc, 0x3c);

	write_cmos_sensor(0x0d, 0x92);
	write_cmos_sensor(0x0d, 0x90);


	
	gPVmode=KAL_TRUE;
	

//    	write_cmos_sensor(0x11,0x80);   //clock PCLK = XCLK / 2   0x80 means double clock
    // 1. Sensor's clock control register setting may cause sensor output some abnormal frame even if
    // it is written with the same value twice
    // 2. MJPEG preview/capture use the same clock divider, no need to update for
    // MJPEG encode mode
    if (sensor_config_data->isp_op_mode != ISP_MJPEG_ENCODE_MODE) {
        write_cmos_sensor(0x11, 0x80);
    }

	if((sensor_config_data->isp_op_mode == ISP_MJPEG_PREVIEW_MODE) ||
		(sensor_config_data->isp_op_mode==ISP_MJPEG_ENCODE_MODE)) {
		MPEG4_encode_mode=KAL_FALSE;

		/* config TG of ISP to match the setting of image sensor*/
	#if 0
		write_cmos_sensor(0x11, 0x01);  //ADD 20080315
		SET_TG_OUTPUT_CLK_DIVIDER(3); //7
		SET_CMOS_RISING_EDGE(0);
		SET_CMOS_FALLING_EDGE(2); // 4
		ENABLE_CAMERA_PIXEL_CLKIN_ENABLE;
		SET_TG_PIXEL_CLK_DIVIDER(3); ///7-->3
		SET_CMOS_DATA_LATCH(3);
	#else
		write_cmos_sensor(0x11, 0x80);  //ADD 20080315
		SET_TG_OUTPUT_CLK_DIVIDER(7); //7
		SET_CMOS_RISING_EDGE(0);
		SET_CMOS_FALLING_EDGE(4); // 4
		ENABLE_CAMERA_PIXEL_CLKIN_ENABLE;
		SET_TG_PIXEL_CLK_DIVIDER(7); ///7-->3
		SET_CMOS_DATA_LATCH(3);
	#endif
	
		//write_cmos_sensor(0x4F, 0x9e);
		//write_cmos_sensor(0x50, 0x84);
		//write_cmos_sensor(0x5A, 0x23);

		//dummy_pixels=0;
		//dummy_lines=(MIN_LINES_PER_FRAME-PV_PERIOD_LINE_NUMS);		
		//dummy_lines&=(~0x1);
		write_cmos_sensor(0x4F, 0x4B);//9e
		write_cmos_sensor(0x50, 0x4B);//84
		write_cmos_sensor(0x5A, 0x67);//23
		
		start_grab_x_offset=0;
		start_grab_y_offset=0;
		
		dummy_pixels=0X4d;
		dummy_lines=0; 

		image_window->grab_start_x=IMAGE_SENSOR_PV_INSERTED_PIXELS+start_grab_x_offset;
		image_window->grab_start_y=IMAGE_SENSOR_PV_INSERTED_LINES+dummy_lines+start_grab_y_offset  ;
		image_window->exposure_window_width=IMAGE_SENSOR_PV_WIDTH-4;
		image_window->exposure_window_height=IMAGE_SENSOR_PV_HEIGHT-50;
    }else if(sensor_config_data->frame_rate==0x0F) {    // MPEG4 Encode Mode
		MPEG4_encode_mode=KAL_TRUE;

		/* config TG of ISP to match the setting of image sensor*/
		SET_TG_OUTPUT_CLK_DIVIDER(3);
		SET_CMOS_RISING_EDGE(0);
		SET_CMOS_FALLING_EDGE(2);
		ENABLE_CAMERA_PIXEL_CLKIN_ENABLE;
		SET_TG_PIXEL_CLK_DIVIDER(3); ///7-->3
		SET_CMOS_DATA_LATCH(3);

		//write_cmos_sensor(0x4F, 0x9e);
		//write_cmos_sensor(0x50, 0x84);
		//write_cmos_sensor(0x5A, 0x23);

		//dummy_pixels=0;
		//dummy_lines=(MIN_LINES_PER_FRAME-PV_PERIOD_LINE_NUMS);
		//dummy_lines&=(~0x1);
		write_cmos_sensor(0x4F, 0x4B);//9e
		write_cmos_sensor(0x50, 0x4B);//84
		write_cmos_sensor(0x5A, 0x67);//23		
		
		dummy_pixels=0X4d;
		dummy_lines=0; 
		
		start_grab_x_offset=0;
		start_grab_y_offset=0;

		image_window->grab_start_x=IMAGE_SENSOR_PV_INSERTED_PIXELS+start_grab_x_offset;
		image_window->grab_start_y=IMAGE_SENSOR_PV_INSERTED_LINES+dummy_lines+start_grab_y_offset  ;
		image_window->exposure_window_width=IMAGE_SENSOR_PV_WIDTH-4;
		image_window->exposure_window_height=IMAGE_SENSOR_PV_HEIGHT-50;
	}else {
		MPEG4_encode_mode=KAL_FALSE;		
		/* config TG of ISP to match the setting of image sensor*/

		write_cmos_sensor(0x11, 0x00);//80
		SET_TG_OUTPUT_CLK_DIVIDER(3);//(1)
		SET_CMOS_RISING_EDGE(0);
		SET_CMOS_FALLING_EDGE(2);//(1)
		ENABLE_CAMERA_PIXEL_CLKIN_ENABLE;
		SET_TG_PIXEL_CLK_DIVIDER(3);// //3-->1//(1)
		SET_CMOS_DATA_LATCH(3);//(1)

		write_cmos_sensor(0x4F, 0x4B);//9e
		write_cmos_sensor(0x50, 0x4B);//84
		write_cmos_sensor(0x5A, 0x67);//23
		
		start_grab_x_offset=0;
		start_grab_y_offset=0;
		
		dummy_pixels=0X4d;
		dummy_lines=0; 


		image_window->grab_start_x=IMAGE_SENSOR_PV_INSERTED_PIXELS+start_grab_x_offset;
		image_window->grab_start_y=IMAGE_SENSOR_PV_INSERTED_LINES+dummy_lines+start_grab_y_offset  ;
		image_window->exposure_window_width=IMAGE_SENSOR_PV_WIDTH-4;
		image_window->exposure_window_height=IMAGE_SENSOR_PV_HEIGHT-4;
	}
	
	preview_pclk_division=((DRV_Reg32(ISP_TG_PHASE_COUNTER_REG)&0xF0)>>4)+1;
	
	//SET_CAMERA_INPUT_ORDER(INPUT_ORDER_YCbY1Cr);

	switch (sensor_config_data->image_mirror)
	{
		case IMAGE_NORMAL:
			SET_FIRST_GRAB_COLOR(BAYER_R);
			SET_CAMERA_INPUT_ORDER(INPUT_ORDER_YCbY1Cr);
		//	while((temp_v_flip_reg2 != (0x00|temp_v_flip_reg1)) ||(temp_h_mirror_reg2!=(0x00|temp_h_mirror_reg1)) )
			{
				write_cmos_sensor(0x33, 0xc0);
	      write_cmos_sensor(0x04, 0x28);
			//	write_cmos_sensor(0x04,(0x00|temp_v_flip_reg1));
				//temp_v_flip_reg2=read_cmos_sensor(0x04);
				
			//	write_cmos_sensor(0x33,(0x00|temp_h_mirror_reg1));
				//temp_h_mirror_reg2=read_cmos_sensor(0x33);
			};
		break;

		case IMAGE_HV_MIRROR:
			SET_FIRST_GRAB_COLOR(BAYER_Gb);
			SET_CAMERA_INPUT_ORDER(INPUT_ORDER_YCbY1Cr);
			//while((temp_v_flip_reg2 != (0xC0|temp_v_flip_reg1)) ||(temp_h_mirror_reg2!=(0x08|temp_h_mirror_reg1)) )
			{
				//write_cmos_sensor(0x04, (0xC0|temp_v_flip_reg1));
				//temp_v_flip_reg2 = read_cmos_sensor(0x04);
				write_cmos_sensor(0x33, 0xc0);
	      write_cmos_sensor(0x04, 0x28);
				//write_cmos_sensor(0x33, (0x08|temp_h_mirror_reg1));
				//temp_h_mirror_reg2 = read_cmos_sensor(0x33);
			};
		break;
	}

	set_OV9660_dummy(dummy_pixels,dummy_lines);
	write_OV9660_shutter(exposure_lines);
	kal_sleep_task(30);
//	write_cmos_sensor(0x13 ,0xE7);  // Turn ON AEC/AGC/AWB
    if (sensor_config_data->isp_op_mode == ISP_MJPEG_ENCODE_MODE) {
		//sensor_config_data->sensor_frame_rate = 10 * (48000000 / preview_pclk_division / 784 / current_shutter / 2); //1fps=10
		sensor_config_data->sensor_frame_rate = 100;    // 10fps
    }else {
	    // ISP_MJPEG_ENCODE_MODE mode does not invok YUV setting API after preview function
	    // If turn on AEC/AGC/AWB in ISP_MJPEG_ENCODE_MODE mode, the AWB setting will be overwriten.
        write_cmos_sensor(0x13, 0xE7);  // Turn ON AEC/AGC/AWB
    }
     temp_v_flip_reg2 = read_cmos_sensor(0x04);
	 temp_h_mirror_reg2 = read_cmos_sensor(0x33);
	kal_prompt_trace(MOD_ENG,"temp_v_flip_reg2=0x%x, temp_h_mirror_reg1=0x%x",temp_v_flip_reg2,temp_h_mirror_reg1);
	#ifdef OUTPUT_DEBUG_INFO
   	sprintf(temp_buffer, "pre_shut:%d, dummy_p=%d, dummy_l=%d", exposure_lines, dummy_pixels, dummy_lines);
	rmmi_write_to_uart((kal_uint8*) temp_buffer, strlen(temp_buffer), KAL_TRUE);
	sprintf(temp_buffer, "End of OV9660_preview");
	rmmi_write_to_uart((kal_uint8*) temp_buffer, strlen(temp_buffer), KAL_TRUE);
	#endif
}	/* OV9660_preview */

void OV9660_capture(image_sensor_exposure_window_struct *image_window, image_sensor_config_struct *sensor_config_data)
{
	volatile kal_uint32 shutter=exposure_lines;
	kal_uint8 temp_reg=0;
	
	kal_uint8 temp_reg_banding=0;

	temp_reg_banding=read_cmos_sensor(0x0c)&0x04;

	sensor_cap_state=KAL_TRUE;
		
	if(MPEG4_encode_mode)
	    ASSERT(0);
	
	resolution_info.width=image_window->image_target_width;
	resolution_info.height=image_window->image_target_height;
	
	if(sensor_config_data->enable_shutter_tansfer==KAL_TRUE)
		shutter=sensor_config_data->capture_shutter;
	
	#ifdef OUTPUT_DEBUG_INFO
	sprintf(temp_buffer, "Begin of OV9660_capture");
	rmmi_write_to_uart((kal_uint8*) temp_buffer, strlen(temp_buffer), KAL_TRUE);
	sprintf(temp_buffer, "cap_shutter:%d, pre_shut:%d", shutter, exposure_lines);
	rmmi_write_to_uart((kal_uint8*) temp_buffer, strlen(temp_buffer), KAL_TRUE);

	
	#endif

	write_cmos_sensor(0x13,0xE0);  //e0 Turn OFF AEC/AGC/AWB

	shutter=read_OV9660_shutter();
	sensor_global_gain=read_OV9660_gain();


	#if 0  //def OUTPUT_DEBUG_INFO
	kal_prompt_trace(MOD_MED,"shutter=%d, sensor_global_gain=%d",shutter,sensor_global_gain);
	#endif

	temp_reg = read_cmos_sensor(0x0f);
	write_cmos_sensor(0x0f, temp_reg & ~0x08);
        //write_cmos_sensor(0x2d, 0x00);  // clear preview dummy lines
	//write_cmos_sensor(0x2e, 0x00);  // clear preview dummy lines
	write_cmos_sensor(0x46, 0x00);  // clear preview dummy lines
	write_cmos_sensor(0x47, 0x00);  // clear preview dummy lines


#if defined(ALWAYS_FULL_RESOLUTION)	
	if ((image_window->image_target_width<=IMAGE_SENSOR_PV_WIDTH)&&
		 (image_window->image_target_height<=IMAGE_SENSOR_PV_HEIGHT)&&
		 (sensor_config_data->meta_mode)||
		 (sensor_config_data->frame_rate==0xF0))
#else
	if ((image_window->image_target_width<=IMAGE_SENSOR_PV_WIDTH)&&
		 (image_window->image_target_height<=IMAGE_SENSOR_PV_HEIGHT)||
		 (sensor_config_data->frame_rate==0xF0))
#endif
	{	/* Less than PV Mode */
	
		gPVmode=KAL_TRUE;
		
		if (image_window->digital_zoom_factor>=(ISP_DIGITAL_ZOOM_INTERVAL<<1))
		{
			write_cmos_sensor(0x11,0x83);

			SET_TG_PIXEL_CLK_DIVIDER(7);
			SET_CMOS_DATA_LATCH(3);

			dummy_pixels=PV_PERIOD_PIXEL_NUMS/4;
			dummy_lines=0;

		
			start_grab_x_offset=0;
			start_grab_y_offset=0;

			
		}
		else
		{
			if(sensor_config_data->frame_rate==0xF0)	// That means WEBCAM mode.
			{

				write_cmos_sensor(0x13,0xE7);  // Turn ON AEC/AGC/AWB
				write_cmos_sensor(0x11,0x81);
                                write_cmos_sensor(0x3d,0x3c);
                                write_cmos_sensor(0x0c,0x3c);
                                write_cmos_sensor(0x4f,0x4B);
                                write_cmos_sensor(0x50,0x4B);
                                write_cmos_sensor(0x5a,0x67);

				SET_TG_PIXEL_CLK_DIVIDER(3);
				SET_CMOS_DATA_LATCH(1);

				dummy_pixels=0X4d;
				dummy_lines=0;

		
				start_grab_x_offset=0;
				start_grab_y_offset=0;

						
			}
			else
			{
				write_cmos_sensor(0x11,0x81);

				SET_TG_PIXEL_CLK_DIVIDER(3);
				SET_CMOS_DATA_LATCH(1);

				dummy_pixels=0X4d;
				dummy_lines=0;

		
				start_grab_x_offset=0;
				start_grab_y_offset=0;

			    
			} 
		}
				
		capture_pclk_division=((DRV_Reg32(ISP_TG_PHASE_COUNTER_REG)&0xF0)>>4)+1;
		
		shutter=(shutter*preview_pclk_division)/capture_pclk_division;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -