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

📄 csi2c.c

📁 ARM9的摄像头驱动程序
💻 C
字号:
#include "mx1hw.h"#include "khead.h"#include "csi2c.h"#include "i2c.h"#include "im8803.h"#include "csi.h"//static void port_init_SENSOR(void);static U32 SFCM_capture_DMA(U32 nPixel);static void dma_complete_handler(void);static void dma_error_handler(int error_type);static int gMajor = 0;static U32 *csi_data_buf = 0;//static U32 gSensorClock;int sensorFrameCount = 0;static dmach_t dma_channel;static U32 readSeqNum;static U32 capSeqNum;static U32 SOFseqNum;static U8 stopCapture;static U32 dma_buf_phy_addr;static U32 dma_data_size;static DECLARE_WAIT_QUEUE_HEAD(dma_wait);#include "dma_fun.c"#include "dma.c"// functions and interfacestatic int csi2c_open(struct inode *inode, struct file *filp);static int csi2c_release(struct inode *inode, struct file *filp);static ssize_t csi2c_read(struct file *filp, char *buf, size_t size,			  loff_t * l);static ssize_t csi2c_write(struct file *filp, const char *buf, size_t size,			   loff_t * l);static int csi2c_ioctl(struct inode *inode, struct file *file,		       unsigned int cmd, unsigned long arg);struct file_operations csi2c_fops = {      open:csi2c_open,      release:csi2c_release,      read:csi2c_read,      write:csi2c_write,      ioctl:csi2c_ioctl,};static int csi2c_open(struct inode *inode, struct file *filp){	dprintcsi2c("*** open ***\n");	MOD_INC_USE_COUNT;	/* request DMA channel for RxFIFO data */	for (dma_channel = 3; dma_channel < 11; dma_channel++) {		if ((request_dma(dma_channel, "CMOS Sensor")) == 0) {			printk("dma channel %d granted\n", dma_channel);			//Burst length: 32			//Src:                  0x00224010(CSI RxFifo)			//ByteCount:    153600(240x320x2)			//Dest:                 dma_buf_phy_addr			//ReqSrc:               7(CSI)			//Rpt:          1			DMA_init(dma_channel, 32, 0x00224010, 153600,				 dma_buf_phy_addr, 7, 1);			request_dma_intr(dma_channel,					 (callback_t) dma_complete_handler,					 (err_callback_t)					 dma_error_handler);			break;		}	}	if (dma_channel > 11)		printk("*** ERROR: no dma channel is available ! ***\n");	return 0;}static int csi2c_release(struct inode *inode, struct file *filp){	dprintcsi2c("*** close ***\n");	MOD_DEC_USE_COUNT;	free_dma_intr(dma_channel);	free_dma(dma_channel);	return 0;}static ssize_tcsi2c_read(struct file *filp, char *buf, size_t size, loff_t * l){	dprintcsi2c("*** read ***\n");	interruptible_sleep_on(&dma_wait);	copy_to_user(buf, csi_data_buf, size);	return size;}static ssize_tcsi2c_write(struct file *filp, const char *buf, size_t size, loff_t * l){	dprintcsi2c("*** write ***\n");	return 0;}static intcsi2c_ioctl(struct inode *inode, struct file *file,	    unsigned int cmd, unsigned long arg){	unsigned long tmp;	tmp = arg;	dprintcsi2c("cmd: 0x%08x, arg: 0x%08x\n", cmd, (int) arg);	switch (cmd) {	case IOCTL_CSI_INIT:		break;	case IOCTL_I2C_WRITE:		dprintcsi2c("I2C write - reg: 0x%02lx, data: 0x%02lx\n",			    arg >> 8, arg & 0xFF);		I2C_write(arg >> 8, arg & 0xFF);		break;	case IOCTL_I2C_READ:		{			int rv;			dprintcsi2c("I2C read\n");			I2C_read(arg, &rv);			return (rv);		}		break;	case IOCTL_SUBSAMPLE:		dprintcsi2c("Set subsample: %d\n", (int) arg);		//setSubsample(arg);		break;	case IOCTL_SET_GAIN:		dprintcsi2c("Set global gain to %d\n", (int) arg);		//setGlobalGain(arg);		break;	case IOCTL_SET_VF_WIDTH:		dprintcsi2c("Set virtual frame width to 0x%04x\n",			    (int) arg);		//setVFwidth(arg);		break;	case IOCTL_SET_INT_TIME:		dprintcsi2c("Set integration time to 0x%04x\n", (int) arg);		//setIntegrationTime(arg);		break;	case IOCTL_DMA_CAPTURE:		printk("DMA capture for %d bytes\n", (int) arg);		return SFCM_capture_DMA((U32) arg);		break;		/*		   case IOCTL_RESET_ASSERT:		   * (U32 *)PTB_DR   |= (0x1 << 18);    // RESET asserted		   break;		   case IOCTL_RESET_RELEASE:		   * (U32 *)PTB_DR   &= ~(0x1 << 18);   // RESET released		   break;		 */	case IOCTL_STOP_CAPTURE:		*(U32 *) CSI_CTRL_REG1 &= ~0x10000;		*(U32 *) (DMA_CCR0 + dma_channel * 0x40) = 0x800;		stopCMOScapture();		break;	case IOCTL_INC_FRM:		{			U32 flags = 0;			save_flags(flags);			cli();			sensorFrameCount++;			restore_flags(flags);		}		break;	case IOCTL_MOD_SATURATION:		PDEBUG("Set saturation to %d\n", (int) tmp);		//set_saturation(tmp);		break;	}	return 0;}////      Test on I2C channel////      Read / write one of the register//      compare and verify if the data is correct//U32 I2C_test(void){	U32 rdata;	U32 wdata;	//generat MCLK to sensor	CSI_init();	//init sensor port#ifdef MP3DSC	standby_disable();	sensor_reset();#endif#ifdef ADS	ADS_standby_disable();	ADS_sensor_reset();#endif	//This part test on reading default value read 	//should read 0x4	I2C_read(0x01, &rdata);	PDEBUG("should be 0x01: %08x\n", rdata);	/*      	   while(1)	   {	   I2C_read(0x09, &rdata);	   PDEBUG("should be 0x4: %08x\n", rdata);	   my_delay();	   }	 */	//This part test on the access to Image Core	I2C_write(0x01, 0x04);	//select Image Core channel	wdata = 0x03FF;		//least 10 bits can be R/W	I2C_write(0x02, wdata);	PDEBUG("wdata: %08x\n", wdata);	I2C_read(0x02, &rdata);	PDEBUG("rdata: %08x\n", rdata);	//soft reset	I2C_write(0x0D, 0x01);	I2C_write(0x0D, 0x00);	if (rdata == wdata) {		printk("I2C test OK\n");		return 0;	//OK	} else {		printk("I2C test FAIL\n");		return 1;	//fail	}}static devfs_handle_t devfs_handle;int init_module(){	int result;	printk("CSI driver " __DATE__ " / " __TIME__ "\n");	/* 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;	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();	//I2C_init();	I2C_test();	//TestFrameSize();	CSI_init();	IM8803_QVGA_init4();   //240x320 WOI	//IM8803_QVGA_init();		//320x240 Decimation	return 0;}void cleanup_module(){	if (gMajor > 0) {		devfs_unregister_chrdev(gMajor, "csi2c");		devfs_unregister(devfs_handle);	}	free_irq(CSI_IRQ, 0);	//I2C_cleanup();	free_buffer();	printk("Say goodbye to csi2c\n");}

⌨️ 快捷键说明

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