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

📄 chg-pxa_ov_camera.c

📁 ov2640驱动开发
💻 C
📖 第 1 页 / 共 5 页
字号:
        // want a divisor that gives us a clock rate as close to, but not more than the given mclk.        div = (ciclk / (2 * mclk_khz));	div = div - 1;	// write cicr4	value = CICR4;	value &= ~(CI_CICR4_PCLK_EN | CI_CICR4_MCLK_EN | (CI_CICR4_DIV_SMASK<<CI_CICR4_DIV_SHIFT));//clear PCLK_EN,MCLK_EN  AND DIV CICR4[23,19&7:0]	value |= (pclk_enable) ? CI_CICR4_PCLK_EN : 0;	value |= (mclk_enable) ? CI_CICR4_MCLK_EN : 0;	value |= div << CI_CICR4_DIV_SHIFT;	CICR4 = value;   	ovcamprint("CICR4 =%16x\n",value);				ovcamprint("ci_set_clock( - ) \n");			return; }void ci_set_polarity(int pclk_sample_falling, int hsync_active_low, int vsync_active_low){	unsigned int value;		// write cicr4	value = CICR4;	value &= ~(CI_CICR4_PCP | CI_CICR4_HSP | CI_CICR4_VSP);	value |= (pclk_sample_falling)? CI_CICR4_PCP : 0;	value |= (hsync_active_low) ? CI_CICR4_HSP : 0;	value |= (vsync_active_low) ? CI_CICR4_VSP : 0;	CICR4 = value;   		return; }//////////////////////////////////////////////////////////////////////////////////////////FIFO control ////////////////////////////////////////////////////////////////////////////////////////void ci_set_fifo(unsigned int timeout, CI_FIFO_THRESHOLD threshold, int fifo1_enable,               int fifo2_enable){	unsigned int value;	// write citor	CITOR = timeout; 		// write cifr: always enable fifo 0! also reset input fifo 	value = CIFR;	value &= ~(CI_CIFR_FEN0 | CI_CIFR_FEN1 | CI_CIFR_FEN2 | CI_CIFR_RESETF | 	CI_CIFR_THL_0_SMASK<<CI_CIFR_THL_0_SHIFT);	value |= (unsigned int)threshold << CI_CIFR_THL_0_SHIFT;	value |= (fifo1_enable) ? CI_CIFR_FEN1 : 0;	value |= (fifo2_enable) ? CI_CIFR_FEN2 : 0;	value |= CI_CIFR_RESETF | CI_CIFR_FEN0;	CIFR = value;	return; }/////////////////////////////////////////////////////////////////////////////////reset fifo of quick capture interface///////////////////////////////////////////////////////////////////////////////void ci_reset_fifo(void){	unsigned int value;	value = CIFR;	value |= CI_CIFR_RESETF;	CIFR = value;}void ci_set_int_mask(unsigned int mask){	unsigned int value;	// write mask in cicr0  	value = CICR0;	value &= ~CI_CICR0_INTERRUPT_MASK;	value |= (mask & CI_CICR0_INTERRUPT_MASK);	CICR0 = value;   		return; }unsigned int ci_get_int_mask(void){	unsigned int value;	// write mask in cicr0  	value = CICR0;	return (value & CI_CICR0_INTERRUPT_MASK);}////////////////////////////////////////////////////////////Clear all interrupt status//////////////////////////////////////////////////////////void ci_clear_int_status(unsigned int status){	// write 1 to clear	CISR = status;}unsigned int ci_get_int_status(void){	int value;	value = CISR;	return  value;}void ci_set_reg_value(unsigned int reg_offset, unsigned int value){	CI_REG((u32)(ci_regs_base) + reg_offset) = value;}int ci_get_reg_value(unsigned int reg_offset){	int value;	value = CI_REG((u32)(ci_regs_base) + reg_offset);	return value;}void ovcamera_set_int_mask(p_ovcamera_context_t ovcam_ctx, unsigned int mask){	pxa_dma_desc *end_des_virtual;	int dmaend_irq_enable,i;		/* set QCI interrupt mask to enable/disable interrupt */	//ci_set_int_mask( mask & CI_CICR0_INTERRUPT_MASK);		//set dma end interrupt	if ( mask & CAMERA_INTMASK_END_OF_DMA )	{		dmaend_irq_enable = 1;	}	else	{		dmaend_irq_enable = 0;	}	// set fifo0 dma chains' flag	end_des_virtual = (pxa_dma_desc*)ovcam_ctx->fifo0_descriptors_virtual 		+ ovcam_ctx->fifo0_num_descriptors - 1;	for(i=0; i<ovcam_ctx->block_number; i++) 	{		if (dmaend_irq_enable)		{		    end_des_virtual->dcmd |= DCMD_ENDIRQEN;		}		else		{			end_des_virtual->dcmd &= ~DCMD_ENDIRQEN;		}		//end_des_virtual += ovcam_ctx->fifo0_num_descriptors;		end_des_virtual += (ovcam_ctx->fifo0_num_descriptors + ovcam_ctx->fifo1_num_descriptors +ovcam_ctx->fifo2_num_descriptors );	}		return;}void ovcamerachip_gpio_init ( void ){	set_GPIO_mode(  81 | GPIO_ALT_FN_2_IN); /* CIF_DD[0] */	set_GPIO_mode(  55 | GPIO_ALT_FN_1_IN); /* CIF_DD[1] */	set_GPIO_mode(  51 | GPIO_ALT_FN_1_IN); /* CIF_DD[2] */	set_GPIO_mode(  50 | GPIO_ALT_FN_1_IN); /* CIF_DD[3] */	set_GPIO_mode(  52 | GPIO_ALT_FN_1_IN); /* CIF_DD[4] */	set_GPIO_mode(  48 | GPIO_ALT_FN_1_IN); /* CIF_DD[5] */	set_GPIO_mode(  93 | GPIO_ALT_FN_2_IN); /* CIF_DD[6] */	set_GPIO_mode(  108 | GPIO_ALT_FN_1_IN); /* CIF_DD[7] */	set_GPIO_mode(  53 | GPIO_ALT_FN_2_OUT); /* CIF_MCLK */	set_GPIO_mode(  54 | GPIO_ALT_FN_3_IN);  /* CIF_PCLK */	set_GPIO_mode(  85 | GPIO_ALT_FN_3_IN);  /* CIF_LV */	set_GPIO_mode(  84 | GPIO_ALT_FN_3_IN);  /* CIF_FV */	//jhy		GAFR0_U &= ~0x00000003;	GPDR0 |= 0x00010000;	GPSR0 |= 0x00010000;	mdelay(10);	GAFR3_L &= ~0x00000003;	GPDR3 |= 0x00000001;	GPCR3 |= 0x00000001;	mdelay(10);	GPSR3 |= 0x00000001;	mdelay(10);			return;}void ovcamerachip_clock_set ( unsigned int clk_regs_base, int pclk_enable, int mclk_enable, unsigned int mclk_khz){	unsigned int ciclk=0,value,div,cccr_l;		cccr_l = ( CCCR & 0x0000001F ); 		if ( cccr_l < 8 ) 	{		ciclk = ( 13 * cccr_l ) * 100;	}	else if ( cccr_l < 17 ) 	{		ciclk = (( 13 * cccr_l ) * 100 ) >> 1;	}	else if ( cccr_l < 32 )	{		ciclk = (( 13 * cccr_l ) * 100 ) >> 2;	}	ovcamprint("the mclk = %d \n", mclk_khz);		div = ( ciclk + mclk_khz ) / (2 * mclk_khz ) -1; /* zhudavid: ciclk > mclk_khz ?*/		value = CICR4;	value &= ~( CI_CICR4_PCLK_EN | CI_CICR4_MCLK_EN | CI_CICR4_DIV_SMASK << CI_CICR4_DIV_SHIFT);	value |= (mclk_enable) ? CI_CICR4_MCLK_EN : 0;	value |= (pclk_enable) ? CI_CICR4_PCLK_EN : 0;	value |= div << CI_CICR4_DIV_SHIFT;		CICR4 = value;}int ci_init(){	int cken_val;	(unsigned long*)ci_regs_base = (unsigned long*)ioremap(CI_REGS_PHYS, CI_REG_SIZE);	if(!ci_regs_base) 	{		ovcamprint("Remap Quick Capture Interface I/O registers failed \n");		return -1;	}	// clear all CI registers	CICR0 = 0x3FF;   // disable all interrupts	CICR1 = 0;	CICR2 = 0;	CICR3 = 0;	CICR4 = 0;	CISR = ~0;	CIFR = 0;	CITOR = 0;		// enable CI clock	cken_val = CKEN;	cken_val |= CKEN24_CAMERA;	CKEN = cken_val;	return 0;}void ci_deinit(){	CKEN &= ~CKEN24_CAMERA;}void ci_enable ( int dma_en ){	unsigned int value;		value = CICR0;	value |= CI_CICR0_ENB;		if ( dma_en )	{		value |= CI_CICR0_DMA_EN;	}	CICR0 = value;}int ci_disable ( int quick ){	volatile unsigned int value, mask;	int retry;		value = CICR0;	if ( quick )	{		value &= ~CI_CICR0_ENB;		mask = CI_CISR_CQD;	}	else	{		value |= CI_CICR0_DIS;		mask = CI_CISR_CDD;	}	CICR0 = value;		retry = 50;	while ( 0 < retry-- )	{		value = CISR;		if (value & mask) 		{			CISR = mask;			return 0;		}		mdelay(10);	}		return -1;}/*Generate dma descriptorsPre-condition: these variables must be set properly                block_number, fifox_transfer_size                 dma_descriptors_virtual, dma_descriptors_physical, dma_descirptors_sizePost-condition: these variables will be set                fifox_descriptors_virtual, fifox_descriptors_physical                              fifox_num_descriptors */int update_dma_chain( p_ovcamera_context_t p_ovcam_ctx ){	pxa_dma_desc *cur_des_virtual, *cur_des_physical, *last_des_virtual = NULL;	pxa_dma_desc *y_last_virtual = NULL;	pxa_dma_desc *u_last_virtual = NULL;	pxa_dma_desc *v_last_virtual = NULL;	int des_transfer_size, remain_size;	unsigned int i, entry_size, desc_num;	struct dma_buf_struct *buf_entry;	struct list_head *cur_node;	int target_physical = 0;	int target_virtual = 0;	p_ovcamera_context_t camera_context = p_ovcam_ctx;	ovcamprint("update_dma_chain( + ) \n");		 	// clear descriptor pointers	p_ovcam_ctx->fifo0_descriptors_virtual = p_ovcam_ctx->fifo0_descriptors_physical = 0;	p_ovcam_ctx->fifo1_descriptors_virtual = p_ovcam_ctx->fifo1_descriptors_physical = 0;	p_ovcam_ctx->fifo2_descriptors_virtual = p_ovcam_ctx->fifo2_descriptors_physical = 0;	// calculate how many descriptors are needed per frame	p_ovcam_ctx->fifo0_num_descriptors = ( p_ovcam_ctx->fifo0_transfer_size + SINGLE_DESCRIPTORS_TRANSFER_MAX -1 )		 / SINGLE_DESCRIPTORS_TRANSFER_MAX;	p_ovcam_ctx->fifo1_num_descriptors = ( p_ovcam_ctx->fifo1_transfer_size + SINGLE_DESCRIPTORS_TRANSFER_MAX -1 )		 / SINGLE_DESCRIPTORS_TRANSFER_MAX;	p_ovcam_ctx->fifo2_num_descriptors = ( p_ovcam_ctx->fifo2_transfer_size + SINGLE_DESCRIPTORS_TRANSFER_MAX -1 )		 / SINGLE_DESCRIPTORS_TRANSFER_MAX;	ovcamprint("fif0 descriptors = %d\n", p_ovcam_ctx->fifo0_num_descriptors);	ovcamprint("fif1 descriptors = %d\n", p_ovcam_ctx->fifo1_num_descriptors);	ovcamprint("fif2 descriptors = %d\n", p_ovcam_ctx->fifo2_num_descriptors);	ovcamprint("block number = %d\n", p_ovcam_ctx->block_number);	// check if enough memory to generate descriptors	if ( (p_ovcam_ctx->fifo0_num_descriptors + p_ovcam_ctx->fifo1_num_descriptors +  			p_ovcam_ctx->fifo2_num_descriptors) * p_ovcam_ctx->block_number 			> p_ovcam_ctx->ui_dmadest_size)	{		ovcamprint("update_dma_chain( -0 ) \n");				return -1;	}	// generate fifo0 dma chains	p_ovcam_ctx->fifo0_descriptors_virtual = (unsigned)p_ovcam_ctx->p_dmadest_virtual;	p_ovcam_ctx->fifo0_descriptors_physical = (unsigned)p_ovcam_ctx->p_dmadest_physical;	cur_des_virtual = (pxa_dma_desc *)p_ovcam_ctx->fifo0_descriptors_virtual;	cur_des_physical = (pxa_dma_desc *)p_ovcam_ctx->fifo0_descriptors_physical;		cur_node = &camera_context->buf_head;	entry_size = 0;	desc_num = 0;	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->fifo0_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 int)buf_entry->paddr;				target_virtual = (unsigned int)buf_entry->vaddr;				entry_size = buf_entry->size;				cur_node = cur_node->next;			}			if (remain_size > FIFO_0_SINGLE_DESC_TRANS_MAX) 				des_transfer_size = FIFO_0_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 = CIBR0_PHY;       // FIFO0 physical address			cur_des_virtual->dtadr = target_physical;			cur_des_virtual->dcmd = des_transfer_size | DCMD_FLOWSRC | DCMD_INCTRGADDR | DCMD_BURST32;						if (y_last_virtual){				y_last_virtual->ddadr = (unsigned)cur_des_physical;				if (camera_context->capture_mode == CAPTURE_STILL_IMAGE)					y_last_virtual->ddadr |= 0x1;				y_last_virtual->dcmd |= DCMD_ENDIRQEN;				y_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->fifo0_num_descriptors ++;				desc_num ++;				}		last_des_virtual = cur_des_virtual - 1;		y_last_virtual = last_des_virtual;		/* setup U Channel*/			if (!camera_context->fifo1_descriptors_virtual){			camera_context->fifo1_descriptors_virtual = (unsigned)cur_des_virtual;			camera_context->fifo1_descriptors_physical = (unsigned)cur_des_physical;		}		remain_size = camera_context->fifo1_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_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){

⌨️ 快捷键说明

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