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

📄 csi2c.c

📁 ov7660摄像头模块的驱动程序源码
💻 C
📖 第 1 页 / 共 2 页
字号:
		return 0;}	void set_ov7660_reg_rgb565(){			int i;		sccb_write(0x12,0x80);  // Reset all registers 	for(i=0;i<2000;i++)		delay10us();			sccb_write_check(0x11 ,0x83);	sccb_write_check(0x92 ,0x00);	sccb_write_check(0x93 ,0x00); 	sccb_write_check(0x9d ,0x31);	sccb_write_check(0x9e ,0x29);	sccb_write_check(0x3b ,0x02);//02 for 60Hz, 0a for 50Hz 	sccb_write_check(0x13 ,0xf2);	sccb_write_check(0x10 ,0x00);	sccb_write_check(0x00 ,0x00);	sccb_write_check(0x01 ,0x80);	sccb_write_check(0x02 ,0x80);	sccb_write_check(0x13 ,0xf7);	 	sccb_write_check(0x12 ,0x14);	sccb_write_check(0x04 ,0x00);	sccb_write_check(0x18 ,0x4b);	sccb_write_check(0x17 ,0x23);	sccb_write_check(0x32 ,0xbf);	sccb_write_check(0x19 ,0x02);	sccb_write_check(0x1a ,0x7a); 	sccb_write_check(0x03 ,0x00);		sccb_write_check(0x0e ,0x84); 	sccb_write_check(0x0f ,0x62); 	sccb_write_check(0x15 ,0x00);	sccb_write_check(0x16 ,0x02);	sccb_write_check(0x1b ,0x01); 	sccb_write_check(0x1e ,0x21); 	sccb_write_check(0x29 ,0x3c);// ;20 for internal regulator	sccb_write_check(0x33 ,0x00); 	sccb_write_check(0x34 ,0x07); 	sccb_write_check(0x35 ,0x84); 	sccb_write_check(0x36 ,0x00); 	sccb_write_check(0x38 ,0x13); 	sccb_write_check(0x39 ,0x43);	sccb_write_check(0x3a ,0x08); 	sccb_write_check(0x3c ,0x6c); 	sccb_write_check(0x3d ,0x90); 	sccb_write_check(0x3f ,0x29); 	sccb_write_check(0x40 ,0xd1); 	sccb_write_check(0x41 ,0x20); 	sccb_write_check(0x6b ,0x0a); 	sccb_write_check(0xa1 ,0xc8); 		sccb_write_check(0x69 ,0x80); 	sccb_write_check(0x43 ,0xf0); 	sccb_write_check(0x44 ,0x10); 	sccb_write_check(0x45 ,0x78); 	sccb_write_check(0x46 ,0xa8); 	sccb_write_check(0x47 ,0x60); 	sccb_write_check(0x48 ,0x80); 	sccb_write_check(0x59 ,0xba); 	sccb_write_check(0x5a ,0x9a); 	sccb_write_check(0x5b ,0x22); 	sccb_write_check(0x5c ,0xb9); 	sccb_write_check(0x5d, 0x9b); 	sccb_write_check(0x5e ,0x10); 	sccb_write_check(0x5f ,0xe0); 	sccb_write_check(0x60 ,0x85);// ;05 for advanced AWB	sccb_write_check(0x61 ,0x60); 	sccb_write_check(0x9f ,0x9d); 	sccb_write_check(0xa0 ,0xa0);		sccb_write_check(0x4f ,0xae);	sccb_write_check(0x50 ,0x26);	sccb_write_check(0x51 ,0x08);	sccb_write_check(0x52 ,0x1a);	sccb_write_check(0x53 ,0xa9);	sccb_write_check(0x54 ,0x0f);	sccb_write_check(0x55 ,0x05);	sccb_write_check(0x56 ,0x46);	sccb_write_check(0x57 ,0xcb);	sccb_write_check(0x58 ,0x77);		sccb_write_check(0x8b ,0xcc); 	sccb_write_check(0x8c ,0xcc);	sccb_write_check(0x8d ,0xcf); 	sccb_write_check(0x6c ,0x40); 	sccb_write_check(0x6d ,0x30); 	sccb_write_check(0x6e ,0x4b); 	sccb_write_check(0x6f ,0x60); 	sccb_write_check(0x70 ,0x70); 	sccb_write_check(0x71 ,0x70); 	sccb_write_check(0x72 ,0x70); 	sccb_write_check(0x73 ,0x70); 	sccb_write_check(0x74 ,0x60); 	sccb_write_check(0x75 ,0x60); 	sccb_write_check(0x76 ,0x50); 	sccb_write_check(0x77 ,0x48);	sccb_write_check(0x78 ,0x3a);	sccb_write_check(0x79 ,0x2e);	sccb_write_check(0x7a ,0x28); 	sccb_write_check(0x7b ,0x22); 	sccb_write_check(0x7c ,0x04); 	sccb_write_check(0x7d ,0x07); 	sccb_write_check(0x7e ,0x10); 	sccb_write_check(0x7f ,0x28); 	sccb_write_check(0x80 ,0x36); 	sccb_write_check(0x81 ,0x44); 	sccb_write_check(0x82 ,0x52); 	sccb_write_check(0x83 ,0x60); 	sccb_write_check(0x84 ,0x6c); 	sccb_write_check(0x85 ,0x78); 	sccb_write_check(0x86 ,0x8c); 	sccb_write_check(0x87 ,0x9e); 	sccb_write_check(0x88 ,0xbb); 	sccb_write_check(0x89 ,0xd2); 	sccb_write_check(0x8a ,0xe6); 		sccb_write_check(0x14 ,0x2e);	sccb_write_check(0x24 ,0x68); 	sccb_write_check(0x25 ,0x58); 		}		SINT32 init_control_signal(void){	/* PWDN: PF21(~CS4), RESET:PF22(~CS5) */	/* Set GPIO functionality */	_reg_GPIO_GIUS(GPIOF) |= 0x00600000;	         		/* Set output configure register */	_reg_GPIO_OCR2(GPIOF) |= 0x00003C00;	         		/* Set direction configure register,output */	_reg_GPIO_DDIR(GPIOF) |= 0x00600000;		return 0;}/* PB13 - avtive hign */SINT32 pwdn_ov7660(SINT8 flag){				if(flag)		_reg_GPIO_DR(GPIOF) |= 0x00200000;	else		_reg_GPIO_DR(GPIOF) &= ~(0x00200000);				return 0;}					/* PB12 - avtive hign */SINT32 reset_ov7660(SINT8 flag){		if(flag)		_reg_GPIO_DR(GPIOF) |= 0x00400000;	else		_reg_GPIO_DR(GPIOF) &= ~(0x00400000);				return 0;}	void enable_sof_interrupt(){	_reg_CSI_CSISR   = 0x10000;	//clear last SOF irq	_reg_CSI_CSICR1  |= 0x10000;			//enable SOF intr}void disable_sof_interrupt(){	_reg_CSI_CSICR1  &= ~0x10000;			//disable SOF intr}static int csi2c_open(struct inode *inode, struct file *filp){	MOD_INC_USE_COUNT;	return 0;}static int dma_init(){		dma_request_t dma;		_reg_DMA_DCR |= 0x01;   //Enable DMA module		if(mx_request_dma(&_gDmaChanel,"CSI"))	{		printk("Request Dma Fail\n");	}else	{		printk("Dma Channel is %d\n",_gDmaChanel);		memset(&dma,0,sizeof(dma_request_t));		dma.sourceType=DMA_TYPE_FIFO;				dma.sourceAddr=(u32 *)0x80000010;		dma.request = DMA_REQ_CSI_RX;		dma.destAddr=(u32 *)dma_buf_phy_addr;			dma.destType=DMA_TYPE_LINEAR;		dma.destPort=DMA_MEM_SIZE_32;		dma.count=QVGA_SIZE;		dma.burstLength=64;		dma.callback=(dma_callback_t)dma_complete_handler;				mx_dma_set_config(_gDmaChanel,&dma);				}		return 0;}static int csi2c_release(struct inode *inode, struct file *filp){	MOD_DEC_USE_COUNT;	if(_gDmaChanel>=0)	{		mx_free_dma(_gDmaChanel);		_gDmaChanel=-1;	}	return 0;}static ssize_t csi2c_read(struct file *filp, char *buf, size_t size, loff_t *l){	g_bad_frame = 0;	//number_sof = 0;		enable_sof_interrupt();			if(!interruptible_sleep_on_timeout(&g_capture_wait,500))	{		printk("\nread time out\n");		return -1;	}	//	if(g_bad_frame)//		return -1;				copy_to_user(buf, csi_data_buf, size);		return size;}static ssize_t csi2c_write(struct file *filp, const char *buf, size_t size, loff_t *l){	return 0;}static int malloc_buffer(){	long i;		if ((csi_data_buf = (UINT32 *)__get_free_pages(GFP_KERNEL, 7)))	// 256 pages = 128x4K = 512K	{		dma_buf_phy_addr = virt_to_phys((void *)csi_data_buf);	}	else	{		printk("*** ERROR: cannot allocate buffer memory for driver ! ***\n");		return -1;	}		for(i=0;i<QVGA_SIZE/4;i++)		csi_data_buf[i] = 0x44332211;			return 0;}static void free_buffer(){	if (csi_data_buf)		__free_pages((void *)csi_data_buf,7);		// 512K}static int csi2c_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){	return 0;}static void dma_complete_handler(){			//printk("dma end!\n");	_reg_DMA_CCR(_gDmaChanel) = 0x800;		// disable DMA channel	_reg_DMA_DISR  = (1 << _gDmaChanel);		// clear DMA channel	number_dma++;	if(_reg_CSI_CSISR)		g_bad_frame = 1;			if(number_dma != number_sof)		g_bad_frame = 1;		//printk("sof=%d,dma=%d\n",number_sof,number_dma);			/*	if(flag)	{		PA_DR |= 0x04;		flag = 0;	}	else	{		PA_DR &= ~0x04;		flag = 1;	}	printk("\n%d,  %d\n",number_sof,number_dma);*/		wake_up_interruptible(&g_capture_wait);	}SINT32 csi_init(){		//disable_sof_interrupt();		_reg_CRM_PCDR1 &= 0xc0ffffff;	_reg_CRM_PCDR1 |= 0x02000000;         //PerClk4 = MPLL/3	_reg_CRM_PCCR0 |= 0x80000000;	_reg_CRM_PCCR0 |= 0x00400000;		_reg_GPIO_GIUS(GPIOB) &= ~0x3FFC00;       //disable GPIO	_reg_GPIO_GPR(GPIOB) &= ~0x3FFC00;		_reg_CSI_CSICR1=0; 			//module reset	_reg_CSI_CSICR1 |= 0x2;	          //latch on rising edge	_reg_CSI_CSICR1 |= 0x10;	//gated clock mode	_reg_CSI_CSICR1 |= 0x800;	//hsync active mode	_reg_CSI_CSICR1 |= 0x100;	//sync FIFO clear	_reg_CSI_CSICR1 |= 0x1200;	//MCLK = PerCLK4/4	_reg_CSI_CSICR1 |= 0x40000000;	//SOF rising edge	_reg_CSI_CSICR1 |= 0x20000;	//SOF rising edge	_reg_CSI_CSICR1 |= 0x10000;	//SOF INT		//_reg_CSI_CSICR1 |= 0x40000;   //RXFF int	_reg_CSI_CSICR1 |= 0x100000;  //RXFF level =16;	//_reg_CSI_CSICR1 |= 0x1000000; //RXFF overflow int		//_reg_CSI_CSICR1 |= 0x80000000;//2 byte of 4 byte swap	//_reg_CSI_CSICR1 |= 0x80;     //big endian		disable_sof_interrupt();				return 0;}	static void csi_intr_handler(){		if(_reg_CSI_CSISR & 0x10000)	              // SOF intr ?	{//		printk("\nSOF interrupt\n");		_reg_CSI_CSISR = 0x10000;					// clear SOF intr	//	CSI_STS_REG |= 0x06;  //Clear rxfifo				//_reg_DMA_CCR(dma_channel) = 0x800;		// disable DMA channel						if(_gDmaChanel>=0)			mx_dma_start(_gDmaChanel);						number_sof++;		//if(number_sof == 1000)		disable_sof_interrupt();			return;	}	printk("*** unknown interrupt ***\n");	return;}static devfs_handle_t devfs_handle;int init_module(){	int result,i;	UINT8 ret;	/* register our character device */ 	result = devfs_register_chrdev(0, "csi2c", &csi2c_fops); 	if ( result < 0 ) 	{		printk("csi2c driver: Unable to register driver\n");		return -ENODEV;	}	devfs_handle = devfs_register(NULL, "csi2c", DEVFS_FL_DEFAULT,				      result, 0,				      S_IFCHR | S_IRUSR | S_IWUSR,				      &csi2c_fops, NULL);      printk("make node for csi2c with 'mknod csi2c c %d 0'\n", result);	gMajor = result;//	iCaptureDone = 1;	if (request_irq(CSI_IRQ, csi_intr_handler, SA_INTERRUPT, "CSI", NULL))		printk("*** Cannot register interrupt handler for CSI ! ***\n");	else		printk("CSI interrupt handler registered\n");	malloc_buffer();	init_control_signal();	sccb_init();	csi_init();	dma_init();		pwdn_ov7660(1);	pwdn_ov7660(0);	reset_ov7660(1);	for(i=0;i<2000;i++);	reset_ov7660(0);	for(i=0;i<2000;i++);		set_ov7660_reg_rgb565();	delay10us();			disable_sof_interrupt();        return 0;}void cleanup_module(){	if (gMajor > 0){		devfs_unregister_chrdev(gMajor, "csi2c");		devfs_unregister(devfs_handle);		}			free_irq(CSI_IRQ, 0);	free_buffer();		printk("Say goodbye to csi2c\n");}

⌨️ 快捷键说明

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