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

📄 chg-pxa_ov_camera.c

📁 ov2640驱动开发
💻 C
📖 第 1 页 / 共 5 页
字号:
				des_transfer_size = entry_size;			}			cur_des_virtual->ddadr = (unsigned)cur_des_physical + sizeof(pxa_dma_desc);			cur_des_virtual->dsadr = CIBR1_PHY;       // FIFO1 physical address			cur_des_virtual->dtadr = target_physical;			cur_des_virtual->dcmd = des_transfer_size | DCMD_FLOWSRC | DCMD_INCTRGADDR | DCMD_BURST32;						if (u_last_virtual){				u_last_virtual->ddadr = (unsigned )cur_des_physical;				if (camera_context->capture_mode == CAPTURE_STILL_IMAGE)					u_last_virtual->ddadr |= 0x1;				u_last_virtual->dcmd |= DCMD_ENDIRQEN;				u_last_virtual = NULL;			}			// advance pointers			remain_size -= des_transfer_size;			entry_size -= des_transfer_size;			cur_des_virtual++;			cur_des_physical++;			target_physical += des_transfer_size;			camera_context->fifo1_num_descriptors ++;				desc_num ++;		}		last_des_virtual = cur_des_virtual - 1;		u_last_virtual = last_des_virtual;		}		//printk("%s: %d block %d u channel, desc_num=%d\n", __FUNCTION__, __LINE__, i, desc_num);		/* setup V Channel */		if (!camera_context->fifo2_descriptors_virtual){			camera_context->fifo2_descriptors_virtual = (unsigned)cur_des_virtual;			camera_context->fifo2_descriptors_physical = (unsigned)cur_des_physical;		}		remain_size = camera_context->fifo2_transfer_size;		if(remain_size){		while(remain_size){			if (desc_num >= camera_context->dma_descriptors_size){				printk("%s: %d, BUG.\n", __FUNCTION__, __LINE__);				return -ENOMEM;			}			if (entry_size == 0){				buf_entry = get_list_entry(cur_node);				if (!buf_entry){					printk("%s: %d, BUG.\n", __FUNCTION__, __LINE__);					return -ENOMEM;				}				target_physical = (unsigned)buf_entry->paddr;				target_virtual = (unsigned)buf_entry->vaddr;				entry_size = buf_entry->size;				cur_node = cur_node->next;			}			if (remain_size > FIFO_2_SINGLE_DESC_TRANS_MAX) 				des_transfer_size = FIFO_2_SINGLE_DESC_TRANS_MAX;			else		       		des_transfer_size = remain_size;			if (entry_size < des_transfer_size){				des_transfer_size = entry_size;			}			cur_des_virtual->ddadr = (unsigned)cur_des_physical + sizeof(pxa_dma_desc);			cur_des_virtual->dsadr = CIBR2_PHY;       // FIFO1 physical address			cur_des_virtual->dtadr = target_physical;			cur_des_virtual->dcmd = des_transfer_size | DCMD_FLOWSRC | DCMD_INCTRGADDR | DCMD_BURST32;						if (v_last_virtual){				v_last_virtual->ddadr = (unsigned)cur_des_physical;				if (camera_context->capture_mode == CAPTURE_STILL_IMAGE)					v_last_virtual->ddadr |= 0x1;				v_last_virtual->dcmd |= DCMD_ENDIRQEN;				v_last_virtual = NULL;			}			// advance pointers			remain_size -= des_transfer_size;			entry_size -= des_transfer_size;			cur_des_virtual++;			cur_des_physical++;			target_physical += des_transfer_size;			camera_context->fifo2_num_descriptors ++;				desc_num ++;		}		last_des_virtual = cur_des_virtual - 1;		v_last_virtual = last_des_virtual;		//printk("%s: %d block %d v channel, desc_num=%d\n", __FUNCTION__, __LINE__, i, desc_num);		}	}		if(camera_context->fifo0_transfer_size)		y_last_virtual->ddadr = ((unsigned)camera_context->fifo0_descriptors_physical);	if(camera_context->fifo1_transfer_size)		u_last_virtual->ddadr = ((unsigned)camera_context->fifo1_descriptors_physical);	if(camera_context->fifo2_transfer_size)		v_last_virtual->ddadr = ((unsigned)camera_context->fifo2_descriptors_physical);	y_last_virtual->dcmd |= DCMD_ENDIRQEN;	if (camera_context->capture_mode == CAPTURE_STILL_IMAGE){		if(camera_context->fifo0_transfer_size)			y_last_virtual->ddadr |= 0x1;		if(camera_context->fifo1_transfer_size)			u_last_virtual->ddadr |= 0x1;		if(camera_context->fifo2_transfer_size)			v_last_virtual->ddadr |= 0x1;	}	camera_context->fifo0_num_descriptors /= camera_context->block_number;	camera_context->fifo1_num_descriptors /= camera_context->block_number;	camera_context->fifo2_num_descriptors /= camera_context->block_number;	printk( "%s:%d Ysize=%d,Usize=%d,Vsize=%d,block_number=%d\n", \			__FUNCTION__, __LINE__,\			camera_context->fifo0_transfer_size,\			camera_context->fifo1_transfer_size, \			camera_context->fifo2_transfer_size,\			camera_context->block_number);#if 0		// assume the blocks are stored consecutively		target_physical = (unsigned)p_ovcam_ctx->p_buffer_physical + p_ovcam_ctx->block_size * i;		target_virtual = (unsigned)p_ovcam_ctx->p_buffer_virtual + p_ovcam_ctx->block_size * i;				for(j=0; j<p_ovcam_ctx->fifo0_num_descriptors; j++) 		{			 // set descriptor		        if (remain_size > SINGLE_DESCRIPTORS_TRANSFER_MAX)         			des_transfer_size = SINGLE_DESCRIPTORS_TRANSFER_MAX;        		else		       		des_transfer_size = remain_size;		        cur_des_virtual->ddadr = (unsigned)cur_des_physical + sizeof(pxa_dma_desc);        		cur_des_virtual->dsadr = CIBR0_PHY;       // FIFO0 physical address        		cur_des_virtual->dtadr = target_physical;        		cur_des_virtual->dcmd = des_transfer_size | DCMD_FLOWSRC | DCMD_INCTRGADDR | DCMD_BURST32;		        // advance pointers        		remain_size -= des_transfer_size;        		cur_des_virtual++;		        cur_des_physical++;        		target_physical += des_transfer_size;		        target_virtual += des_transfer_size;		}        		// stop the dma transfer on one frame captured		last_des_virtual = cur_des_virtual - 1;		//last_des_virtual->ddadr |= 0x1;	}	last_des_virtual->ddadr = ((unsigned)p_ovcam_ctx->fifo0_descriptors_physical);//LOOP    	// generate fifo1 dma chains	if (p_ovcam_ctx->fifo1_transfer_size) 	{		// record fifo1 descriptors' start address		p_ovcam_ctx->fifo1_descriptors_virtual = (unsigned)cur_des_virtual;		p_ovcam_ctx->fifo1_descriptors_physical = (unsigned)cur_des_physical;		for(i=0; i<p_ovcam_ctx->block_number; i++) 		{			// in each iteration, generate one dma chain for one frame			remain_size = p_ovcam_ctx->fifo1_transfer_size;    		// assume the blocks are stored consecutively    		target_physical = (unsigned)p_ovcam_ctx->p_buffer_physical + p_ovcam_ctx->block_size * i     	                    + p_ovcam_ctx->fifo0_transfer_size;    		target_virtual = (unsigned)p_ovcam_ctx->p_buffer_virtual + p_ovcam_ctx->block_size * i     	                    + p_ovcam_ctx->fifo0_transfer_size;        		for(j=0; j<p_ovcam_ctx->fifo1_num_descriptors; j++)     		{    		        // set descriptor				if (remain_size > SINGLE_DESCRIPTORS_TRANSFER_MAX)				{ 					des_transfer_size = SINGLE_DESCRIPTORS_TRANSFER_MAX;				}    		    else    		    {		            des_transfer_size = remain_size;    		    }		        cur_des_virtual->ddadr = (unsigned)cur_des_physical + sizeof(pxa_dma_desc);		        cur_des_virtual->dsadr = CIBR1_PHY;      // FIFO1 physical address		        cur_des_virtual->dtadr = target_physical;		        cur_des_virtual->dcmd = des_transfer_size | DCMD_FLOWSRC | DCMD_INCTRGADDR | DCMD_BURST32;		        // advance pointers		        remain_size -= des_transfer_size;		        cur_des_virtual++;		        cur_des_physical++;		        target_physical += des_transfer_size;		        target_virtual += des_transfer_size;    		}        	// stop the dma transfer on one frame captured        	last_des_virtual = cur_des_virtual - 1;			//last_des_virtual->ddadr |= 0x1;        }		last_des_virtual->ddadr = ((unsigned)p_ovcam_ctx->fifo1_descriptors_physical);	}    	// generate fifo2 dma chains	if (p_ovcam_ctx->fifo2_transfer_size) 	{		// record fifo1 descriptors' start address		p_ovcam_ctx->fifo2_descriptors_virtual = (unsigned)cur_des_virtual;		p_ovcam_ctx->fifo2_descriptors_physical = (unsigned)cur_des_physical;		for(i=0; i<p_ovcam_ctx->block_number; i++) 		{			// in each iteration, generate one dma chain for one frame			remain_size = p_ovcam_ctx->fifo2_transfer_size;			// assume the blocks are stored consecutively			target_physical = (unsigned)p_ovcam_ctx->p_buffer_physical + p_ovcam_ctx->block_size * i                             + p_ovcam_ctx->fifo0_transfer_size + p_ovcam_ctx->fifo1_transfer_size;    	        for(j=0; j<p_ovcam_ctx->fifo2_num_descriptors; j++) 	        {            		// set descriptor            		if (remain_size > SINGLE_DESCRIPTORS_TRANSFER_MAX)            		{             			des_transfer_size = SINGLE_DESCRIPTORS_TRANSFER_MAX;            		}            		else            		{            			des_transfer_size = remain_size;            		}            		cur_des_virtual->ddadr = (unsigned)cur_des_physical + sizeof(pxa_dma_desc);            		cur_des_virtual->dsadr = CIBR2_PHY;      // FIFO2 physical address            		cur_des_virtual->dtadr = target_physical;            		cur_des_virtual->dcmd = des_transfer_size | DCMD_FLOWSRC | DCMD_INCTRGADDR | DCMD_BURST32;            		// advance pointers            		remain_size -= des_transfer_size;            		cur_des_virtual++;            		cur_des_physical++;            		target_physical += des_transfer_size;	        }	        // stop the dma transfer on one frame captured    		last_des_virtual = cur_des_virtual - 1;		//last_des_virtual->ddadr |= 0x1;    	}		last_des_virtual->ddadr = ((unsigned)p_ovcam_ctx->fifo2_descriptors_physical);	}#endif	ovcamprint("update_dma_chain( - ) \n");			return 0;   }//////////////////////////////////////////////////////////////////////////////////////Manual Set the DDADR and Start DMA transfer////////////////////////////////////////////////////////////////////////////////////void dma_transfer_start ( p_ovcamera_context_t p_ovcam_ctx, unsigned int block_id ){	pxa_dma_desc *des_virtual, *des_physical;	int 	block_desc;    	 	ovcamprint("dma_transfer_start( + ) \n");		   	if ( block_id >= p_ovcam_ctx->block_number)	{   		return;    	}        	block_desc = p_ovcam_ctx->fifo0_num_descriptors + p_ovcam_ctx->fifo1_num_descriptors +\		     p_ovcam_ctx->fifo2_num_descriptors;	// start channel 0#if 0	des_virtual = (pxa_dma_desc *)p_ovcam_ctx->fifo0_descriptors_virtual		+ block_id * p_ovcam_ctx->fifo0_num_descriptors;	des_physical = (pxa_dma_desc *)p_ovcam_ctx->fifo0_descriptors_physical 		+ block_id * p_ovcam_ctx->fifo0_num_descriptors;#endif	des_virtual = (pxa_dma_desc *)p_ovcam_ctx->fifo0_descriptors_virtual 		+ block_id * block_desc;	des_physical = (pxa_dma_desc *)p_ovcam_ctx->fifo0_descriptors_physical 		+ block_id * block_desc;	DDADR(p_ovcam_ctx->dma_channels[0]) = des_physical;	DCSR(p_ovcam_ctx->dma_channels[0]) |= DCSR_RUN;	// start channel 1	if ( p_ovcam_ctx->fifo1_descriptors_virtual ) 	{#if 0		des_virtual = (pxa_dma_desc *)p_ovcam_ctx->fifo1_descriptors_virtual + 			block_id * p_ovcam_ctx->fifo1_num_descriptors;		des_physical = (pxa_dma_desc *)p_ovcam_ctx->fifo1_descriptors_physical + 			block_id * p_ovcam_ctx->fifo1_num_descriptors;#endif		des_virtual = (pxa_dma_desc *)p_ovcam_ctx->fifo1_descriptors_virtual + 			block_id * block_desc;		des_physical = (pxa_dma_desc *)p_ovcam_ctx->fifo1_descriptors_physical + 			block_id * block_desc;        	DDADR(p_ovcam_ctx->dma_channels[1]) = des_physical;        	DCSR(p_ovcam_ctx->dma_channels[1]) |= DCSR_RUN;	}	// start channel 2	if ( p_ovcam_ctx->fifo2_descriptors_virtual ) 	{#if 0		des_virtual = (pxa_dma_desc *)p_ovcam_ctx->fifo2_descriptors_virtual + 			block_id * p_ovcam_ctx->fifo2_num_descriptors;		des_physical = (pxa_dma_desc *)p_ovcam_ctx->fifo2_descriptors_physical + 			block_id * p_ovcam_ctx->fifo2_num_descriptors;#endif		des_virtual = (pxa_dma_desc *)p_ovcam_ctx->fifo2_descriptors_virtual + 			block_id * block_desc;		des_physical = (pxa_dma_desc *)p_ovcam_ctx->fifo2_descriptors_physical + 			block_id * block_desc;        	DDADR(p_ovcam_ctx->dma_channels[2]) = des_physical;        	DCSR(p_ovcam_ctx->dma_channels[2]) |= DCSR_RUN;	}	 	ovcamprint("dma_transfer_start( - ) \n");		}void dma_transfer_stop ( p_ovcamera_context_t p_ovcam_ctx ){	        int ch0, ch1, ch2;	ovcamprint("dma_transfer_stop( + ) \n");		        ch0 = p_ovcam_ctx->dma_channels[0];        ch1 = p_ovcam_ctx->dma_channels[1];        ch2 = p_ovcam_ctx->dma_channels[2];        DCSR(ch0) &= ~DCSR_RUN;        DCSR(ch1) &= ~DCSR_RUN;        DCSR(ch2) &= ~DCSR_RUN;        	ovcamprint("dma_transfer_stop( - ) \n");			return;}static int capture_start ( p_ovcamera_context_t p_ovcam_ctx, unsigned int block_id, unsigned int frames ){	int ret;		ovcamprint("capture_start( + ) \n");				ci_reset_fifo ();		ci_clear_int_status ( 0xFFFFFFFF );		g_camera_control.frames_captured = 0;	dma_transfer_start ( p_ovcam_ctx, block_id );				ret = p_ovcam_ctx->camera_functions->capture_start ( p_ovcam_ctx, frames );		ovcamprint("capture_start( - ) \n");			return ret;}static int ovcamera_init ( p_ovcamera_context_t p_ovcam_ctx ){	int ret = 0;	int i;	ovcamprint("ovcamera_init ( + ) \n");			// parameter check	if (p_ovcam_ctx->p_buffer_virtual == NULL || p_ovcam_ctx->p_buffer_physical == NULL || p_ovcam_ctx->ui_buffer_size == 0)	{		ovcamprint("ovcamera_init ( -1 ) \n");				return STATUS_WRONG_PARAMETER; 	}		if (p_ovcam_ctx->p_dmadest_virtual == NULL || p_ovcam_ctx->p_dmadest_physical == NULL || 		p_ovcam_ctx->ui_dmadest_size == 0)	{		ovcamprint("ovcamera_init ( -2 ) \n");				return STATUS_WRONG_PARAMETER; 	}			if (p_ovcam_ctx->cf.in > CAMERA_IMAGE_FORMAT_MAX ||		p_ovcam_ctx->cf.out > CAMERA_IMAGE_FORMAT_MAX)	{		ovcamprint("ovcamera_init ( -4 ) \n");				return STATUS_WRONG_PARAMETER; 	}		// check the function dispatch table according to the sensor type	if ( !p_ovcam_ctx->camera_functions )	{		ovcamprint("ovcamera_init ( -5 ) \n");				return STATUS_WRONG_PARAMETER;	}		if ( !p_ovcam_ctx->camera_functions->init || 			 !p_ovcam_ctx->camera_functions->deinit ||		 !p_ovcam_ctx->camera_functions->capture_set_format ||		 !p_ovcam_ctx->camera_functions->capture_start ||		 !p_ovcam_ctx->camera_functions->capture_stop )	{     			ovcamprint("ovcamera_init ( -6 ) \n");				return STATUS_WRONG_PARAMETER;	}	// init context status	for(i=0; i<3; i++)	{		p_ovcam_ctx->dma_channels[i] = 0xFF;	}		(int)p_ovcam_ctx->fifo0_descriptors_virtual = NULL;	(int)p_ovcam_ctx->fifo1_descriptors_virtual = NULL;	(int)p_ovcam_ctx->fifo2_descriptors_virtual = NULL;	(int)p_ovcam_ctx->fifo0_descriptors_physical = NULL;	(int)p_ovcam_ctx->fifo1_descriptors_physical = NULL;	(int)p_ovcam_ctx->fifo2_descriptors_physical = NULL;		p_ovcam_ctx->fifo0_num_descriptors = 0;	p_ovcam_ctx->fifo1_num_descriptors = 0;	p_ovcam_ctx->fifo2_num_descriptors = 0;	p_ovcam_ctx->fifo0_transfer_size = 0;	p_ovcam_ctx->fifo1_transfer_size = 0;	p_ovcam_ctx->fifo2_transfer_size = 0;		p_ovcam_ctx->block_number = 0;	p_ovcam_ctx->block_size = 0;	p_ovcam_ctx->block_header = 0;	p_ovcam_ctx->block_tail = 0;	p_ovcam_ctx->block_header_t = 0;	p_ovcam_ctx->block_tail_t = 0;	// Enable hardware	ovcamerachip_gpio_init();	    	// capture interface init	ci_init();	// sensor init	ret = p_ovcam_ctx->camera_functions->init(p_ovcam_ctx);    	if (ret)	{		ovcamprint("ovcamera_init ( -7 ) \n");				goto camera_init_err;	}	//dma channels	p_ovcam_ctx->dma_channels[0] = ci_dma_y;	p_ovcam_ctx->dma_channels[1] = ci_dma_u;	p_ovcam_ctx->dma_channels[2] = ci_dma_v;		// set capture format	ret = ovcamera_set_capture_format(p_ovcam_ctx);	if (ret)	{		ovcamprint("ovcamera_init ( -8 ) \n");		

⌨️ 快捷键说明

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