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

📄 chg-pxa_ov_camera.c_bak

📁 ov2640驱动开发
💻 C_BAK
📖 第 1 页 / 共 5 页
字号:
				}
				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_1_SINGLE_DESC_TRANS_MAX) 
				des_transfer_size = FIFO_1_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 = 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;
		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);

	}
	y_last_virtual->ddadr = ((unsigned)camera_context->fifo0_descriptors_physical);
	u_last_virtual->ddadr = ((unsigned)camera_context->fifo1_descriptors_physical);
	v_last_virtual->ddadr = ((unsigned)camera_context->fifo2_descriptors_physical);
	y_last_virtual->dcmd |= DCMD_ENDIRQEN;
	if (camera_context->capture_mode == CAPTURE_STILL_IMAGE){
		y_last_virtual->ddadr |= 0x1;
		u_last_virtual->ddadr |= 0x1;
		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)

⌨️ 快捷键说明

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