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

📄 pxa_camera-hzh.c

📁 基于intel xscale下的linux系统camera驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
// parameter check	if (camera_context->buffer_virtual == NULL || camera_context->buffer_physical == NULL || camera_context->buf_size == 0)		return STATUS_WRONG_PARAMETER; 	if (camera_context->dma_descriptors_virtual == NULL || camera_context->dma_descriptors_physical == NULL || 		camera_context->dma_descriptors_size == 0)		return STATUS_WRONG_PARAMETER; 	if (camera_context->sensor_type > CAMERA_TYPE_MAX)		return STATUS_WRONG_PARAMETER; 	if (camera_context->capture_input_format > CAMERA_IMAGE_FORMAT_MAX ||		camera_context->capture_output_format > CAMERA_IMAGE_FORMAT_MAX)		return STATUS_WRONG_PARAMETER; 	// check the function dispatch table according to the sensor type	if ( !camera_context->camera_functions )		return STATUS_WRONG_PARAMETER;	if ( !camera_context->camera_functions->init || 			 !camera_context->camera_functions->deinit ||		 !camera_context->camera_functions->set_capture_format ||		 !camera_context->camera_functions->start_capture ||		 !camera_context->camera_functions->stop_capture )     			return STATUS_WRONG_PARAMETER;	// init context status	for(i=0; i<3; i++)	camera_context->dma_channels[i] = 0xFF;	(int)camera_context->fifo0_descriptors_virtual = NULL;	(int)camera_context->fifo1_descriptors_virtual = NULL;	(int)camera_context->fifo2_descriptors_virtual = NULL;	(int)camera_context->fifo0_descriptors_physical = NULL;	(int)camera_context->fifo1_descriptors_physical = NULL;	(int)camera_context->fifo2_descriptors_physical = NULL;		camera_context->fifo0_num_descriptors = 0;	camera_context->fifo1_num_descriptors = 0;	camera_context->fifo2_num_descriptors = 0;	camera_context->fifo0_transfer_size = 0;	camera_context->fifo1_transfer_size = 0;	camera_context->fifo2_transfer_size = 0;		camera_context->block_number = 0;	camera_context->block_size = 0;	camera_context->block_header = 0;	camera_context->block_tail = 0;	// Enable hardware	camera_gpio_init();	    	// capture interface init	ci_init();	// sensor init	ret = camera_context->camera_functions->init(camera_context);    	if (ret)	goto camera_init_err;	camera_context->dma_channels[0] = ci_dma_y;	camera_context->dma_channels[1] = ci_dma_cb;	camera_context->dma_channels[2] = ci_dma_cr;	// set capture format	ret = camera_set_capture_format(camera_context);	if (ret)		goto camera_init_err;		// set frame rate	camera_set_capture_frame_rate(camera_context);		return 0;camera_init_err:	camera_deinit(camera_context);	return -1; }void camera_gpio_init(){	pxa_gpio_mode(  27 | GPIO_ALT_FN_3_IN); /* CIF_DD[0] */	pxa_gpio_mode( 114 | GPIO_ALT_FN_1_IN); /* CIF_DD[1] */	pxa_gpio_mode( 116 | GPIO_ALT_FN_1_IN); /* CIF_DD[2] */	pxa_gpio_mode( 115 | GPIO_ALT_FN_2_IN); /* CIF_DD[3] */	pxa_gpio_mode(  90 | GPIO_ALT_FN_3_IN); /* CIF_DD[4] */	pxa_gpio_mode(  91 | GPIO_ALT_FN_3_IN); /* CIF_DD[5] */	pxa_gpio_mode(  17 | GPIO_ALT_FN_2_IN); /* CIF_DD[6] */	pxa_gpio_mode(  12 | GPIO_ALT_FN_2_IN); /* CIF_DD[7] */	pxa_gpio_mode(  23 | GPIO_ALT_FN_1_OUT); /* CIF_MCLK */	pxa_gpio_mode(  26 | GPIO_ALT_FN_2_IN);  /* CIF_PCLK */	pxa_gpio_mode(  25 | GPIO_ALT_FN_1_IN);  /* CIF_LV */	pxa_gpio_mode(  24 | GPIO_ALT_FN_1_IN);  /* CIF_FV */#ifdef OV9640	pxa_gpio_mode( 120 | GPIO_OUT);		 /* CAMERA_PWR */#endif	return;}int camera_deinit( p_camera_context_t camera_context ){	int ret;	// deinit sensor	ret = camera_context->camera_functions->deinit(camera_context);  		// capture interface deinit	ci_deinit();		return ret;}/*********************************************************************** * * Capture APIs * ***********************************************************************/// Set the image formatint camera_set_capture_format( p_camera_context_t camera_context ){	int ret;	unsigned int frame_size;	unsigned int block_number = 0;	CI_IMAGE_FORMAT ci_input_format, ci_output_format;	CI_MP_TIMING timing;	// set capture interface	if (camera_context->capture_input_format >  CAMERA_IMAGE_FORMAT_MAX ||		camera_context->capture_output_format > CAMERA_IMAGE_FORMAT_MAX )		return STATUS_WRONG_PARAMETER;	ci_input_format = FORMAT_MAPPINGS[camera_context->capture_input_format];	ci_output_format = FORMAT_MAPPINGS[camera_context->capture_output_format];	if (ci_input_format == CI_INVALID_FORMAT || ci_output_format == CI_INVALID_FORMAT)		return STATUS_WRONG_PARAMETER;	ci_set_image_format(ci_input_format, ci_output_format);	timing.BFW = timing.BLW = 0;        	ci_configure_mp(camera_context->capture_width-1, camera_context->capture_height-1, &timing);	// set sensor setting	ret = camera_context->camera_functions->set_capture_format(camera_context);	if (ret)  		return ret;	// ring buffer init	switch(camera_context->capture_output_format) {	case CAMERA_IMAGE_FORMAT_RGB565:		frame_size = camera_context->capture_width * camera_context->capture_height * 2;		camera_context->fifo0_transfer_size = frame_size;		camera_context->fifo1_transfer_size = 0;		camera_context->fifo2_transfer_size = 0;		break;        case CAMERA_IMAGE_FORMAT_YCBCR422_PACKED:                frame_size = camera_context->capture_width * camera_context->capture_height * 2;	        camera_context->fifo0_transfer_size = frame_size;        	camera_context->fifo1_transfer_size = 0;        	camera_context->fifo2_transfer_size = 0;        	break;        case CAMERA_IMAGE_FORMAT_YCBCR422_PLANAR:        	frame_size = camera_context->capture_width * camera_context->capture_height * 2;        	camera_context->fifo0_transfer_size = frame_size / 2;	//FIFO0(Y通道)DMA传送字节数        	camera_context->fifo1_transfer_size = frame_size / 4;	//FIFO0(Cb通道)DMA传送字节数        	camera_context->fifo2_transfer_size = frame_size / 4;	//FIFO0(Cr通道)DMA传送字节数        	break;        case CAMERA_IMAGE_FORMAT_RGB666_PLANAR:        	frame_size = camera_context->capture_width * camera_context->capture_height * 4;        	camera_context->fifo0_transfer_size = frame_size;        	camera_context->fifo1_transfer_size = 0;        	camera_context->fifo2_transfer_size = 0;        	break;        case CAMERA_IMAGE_FORMAT_RGB666_PACKED:        	frame_size = camera_context->capture_width * camera_context->capture_height * 3;        	camera_context->fifo0_transfer_size = frame_size;        	camera_context->fifo1_transfer_size = 0;        	camera_context->fifo2_transfer_size = 0;        	break;        case CAMERA_IMAGE_FORMAT_RGB888_PLANAR:        	frame_size = camera_context->capture_width * camera_context->capture_height * 4;        	camera_context->fifo0_transfer_size = frame_size;        	camera_context->fifo1_transfer_size = 0;        	camera_context->fifo2_transfer_size = 0;        	break;        default:        	return STATUS_WRONG_PARAMETER;        	break;    	}	camera_context->block_size = frame_size;	block_number = camera_context->buf_size / frame_size;	camera_context->block_number = block_number > MAX_BLOCK_NUM ? MAX_BLOCK_NUM : block_number;	camera_context->block_header = camera_context->block_tail = 0;	// generate dma descriptor chain	ret = update_dma_chain(camera_context);	if (ret)        	return -1;	return 0;}// take a picture and copy it into the ring bufferint camera_capture_still_image( p_camera_context_t camera_context, unsigned int block_id ){	int status;	// init buffer status & capture	camera_context->block_header = camera_context->block_tail = block_id;  	camera_context->capture_status = 0;	status = start_capture( camera_context, block_id, 1 );	return status;}// capture motion video and copy it to the ring bufferint camera_start_video_capture( p_camera_context_t camera_context, unsigned int block_id ){	int status;	// init buffer status & capture	camera_context->block_header = camera_context->block_tail = block_id; 	camera_context->capture_status = CAMERA_STATUS_VIDEO_CAPTURE_IN_PROCESS;	status = start_capture( camera_context, block_id, 0 );	return status;}// disable motion video image capturevoid camera_stop_video_capture( p_camera_context_t camera_context ){	int status;	// stop capture	status = camera_context->camera_functions->stop_capture(camera_context);	// stop dma	stop_dma_transfer(camera_context);	// update the flag	if ( !(camera_context->capture_status & CAMERA_STATUS_RING_BUFFER_FULL) )		camera_context->capture_status &= ~CAMERA_STATUS_VIDEO_CAPTURE_IN_PROCESS;	return;}/*********************************************************************** * * Flow Control APIs * ***********************************************************************/// continue capture image to next available buffervoid camera_continue_transfer( p_camera_context_t camera_context ){	// don't think we need this either.  JR	// continue transfer on next block	start_dma_transfer( camera_context, camera_context->block_tail );}// Return 1: there is available buffer, 0: buffer is fullint camera_next_buffer_available( p_camera_context_t camera_context ){	camera_context->block_header = (camera_context->block_header + 1) % camera_context->block_number;	if (((camera_context->block_header + 1) % camera_context->block_number) != camera_context->block_tail)	{		return 1;	}	camera_context->capture_status |= CAMERA_STATUS_RING_BUFFER_FULL;	return 0;}// Application supplies the FrameBufferID to the driver to tell it that the application has completed processing of // the given frame buffer, and that buffer is now available for re-use.void camera_release_frame_buffer( p_camera_context_t camera_context, unsigned int frame_buffer_id ){	camera_context->block_tail = (camera_context->block_tail + 1) % camera_context->block_number;	// restart video capture only if video capture is in progress and space is available for image capture	if( (camera_context->capture_status & CAMERA_STATUS_RING_BUFFER_FULL ) && 		(camera_context->capture_status & CAMERA_STATUS_VIDEO_CAPTURE_IN_PROCESS))	{		if (((camera_context->block_header + 2) % camera_context->block_number) != camera_context->block_tail)		{			camera_context->capture_status &= ~CAMERA_STATUS_RING_BUFFER_FULL;			start_capture( camera_context, camera_context->block_tail, 0 );		}	}}// Returns the FrameBufferID for the first filled frame// Note: -1 represents buffer emptyint camera_get_first_frame_buffer_id( p_camera_context_t camera_context ){	// check whether buffer is empty	if ( (camera_context->block_header == camera_context->block_tail) && 		 !(camera_context->capture_status & CAMERA_STATUS_RING_BUFFER_FULL) )	return -1;	// return the block header	return camera_context->block_header;}// Returns the FrameBufferID for the last filled frame, this would be used if we were polling for image completion data, // or we wanted to make sure there were no frames waiting for us to process.// Note: -1 represents buffer emptyint camera_get_last_frame_buffer_id( p_camera_context_t camera_context ){	int ret;	// check whether buffer is empty	if ( (camera_context->block_header == camera_context->block_tail) && 		 !(camera_context->capture_status & CAMERA_STATUS_RING_BUFFER_FULL) )		return -1;	// return the block before the block_tail	ret = ( camera_context->block_tail + camera_context->block_number -1 ) % camera_context->block_number;	return ret;}/*********************************************************************** * * Buffer Info APIs * ***********************************************************************/// Return: the number of frame buffers allocated for use.unsigned int camera_get_num_frame_buffers( p_camera_context_t camera_context ){	return camera_context->block_number;}// FrameBufferID is a number between 0 and N-1, where N is the total number of frame buffers in use.  Returns the address of// the given frame buffer.  The application will call this once for each frame buffer at application initialization only.void* camera_get_frame_buffer_addr( p_camera_context_t camera_context, unsigned int frame_buffer_id ){	return (void*)((unsigned)camera_context->buffer_virtual + camera_context->block_size * frame_buffer_id);}// Return the block idint camera_get_frame_buffer_id( p_camera_context_t camera_context, void* address ){	if ( ((unsigned)address >= (unsigned)camera_context->buffer_virtual) && 		 ((unsigned)address <= (unsigned)camera_context->buffer_virtual + camera_context->buf_size ))		return ((unsigned)address - (unsigned)camera_context->buffer_virtual) / camera_context->block_size;	return -1;}/*********************************************************************** * * Frame rate APIs * ***********************************************************************/// Set desired frame ratevoid camera_set_capture_frame_rate( p_camera_context_t camera_context ){	ci_set_frame_rate(camera_context->frame_rate);	return;} // return current settingvoid camera_get_capture_frame_rate( p_camera_context_t camera_context ){	camera_context->frame_rate = ci_get_frame_rate();	return;} /*********************************************************************** * * Interrupt APIs * ***********************************************************************/// set interrupt mask void camera_set_int_mask( p_camera_context_t camera_context, unsigned int mask ){	pxa_dma_desc *end_des_virtual;	int dma_interrupt_on;	unsigned int i;	// set CI interrupt	ci_set_int_mask( mask & CI_CICR0_INTERRUPT_MASK );	// set dma end interrupt	if ( mask & CAMERA_INTMASK_END_OF_DMA )		dma_interrupt_on = 1;	else		dma_interrupt_on = 0;	// set fifo0 dma chains' flag	end_des_virtual = (pxa_dma_desc*)camera_context->fifo0_descriptors_virtual 		+ camera_context->fifo0_num_descriptors - 1;	for(i=0; i<camera_context->block_number; i++) {		if (dma_interrupt_on)//如果使能DMA,在每块的最后一个传输描述符里使能结束中断		        end_des_virtual->dcmd |= DCMD_ENDIRQEN;		else			end_des_virtual->dcmd &= ~DCMD_ENDIRQEN;		end_des_virtual += camera_context->fifo0_num_descriptors;	}} // get interrupt mask unsigned int camera_get_int_mask( p_camera_context_t camera_context ){	pxa_dma_desc *end_des_virtual;	unsigned int ret;	// get CI mask	ret = ci_get_int_mask();		// get dma end mask	end_des_virtual = (pxa_dma_desc *)camera_context->fifo0_descriptors_virtual + camera_context->fifo0_num_descriptors - 1;	if (end_des_virtual->dcmd & DCMD_ENDIRQEN)		ret |= CAMERA_INTMASK_END_OF_DMA;	return ret;   } // clear interrupt statusvoid camera_clear_int_status( p_camera_context_t camera_context, unsigned int status )

⌨️ 快捷键说明

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