亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? csi2c.c

?? 飛思卡爾的imx1的csi的驅動參考
?? C
?? 第 1 頁 / 共 2 頁
字號:
/*Special notes for CMOS sensor data capture.There are two capture modes: continuous mode (also called rolling-shutter) andsingle frame mode.The single frame mode is to be used only when there is flash.So we pick the continuous mode. And under such mode there are two different streaming modes: continuous streaming and single-frame streaming. While single-frame streaming mode functions more-or-less the same way as the singel-framecapture mode (which is not suitable for us), we have to choose the continuousstreaming mode.When continuous capture mode + continuous streaming mode is used, the CMOS sensor keeps dumping out data through the CSI interface. Every frame of datais marked by a Start Of Frame (hereafter called "SOF") signal. The simple way is to use the SOF interrupt to setup the DMA transfer for a particularframe and keep on for the following frames.However, the first bit of image data will be sent out from the CMOS sensor 32CMOS sensor clocks (which may be several times slower than MX1's systemclock) after the rising edge of the SOF signal. So for a non-realtime OS suchas Linux, it is possible that the setup of the DMA channel will be later thanthe first bit of image data (which keep on rolling out). In such case, dataloss will occur, which will result in lost-sync of image data (shifting of image data on the display).To solve this problem, we have chosen the following scheme:- use SOF interrupt to setup the DMA channel for the first time- number every SOF interrupt and DMA complete interrupt with consecutive number- in every SOF interrupt, check whether there is missing DMA complete interrupt  by comparing the SOF sequence number with the DMA complete sequence number.  - if there is missing DMA complete interrupt, stop the current DMA transfer    and start a new one- in every DMA complete interrupt, check whether there is still data in the   CSI receive FIFO (this is to ensure that the DMA complete interrupt is not  a "shifted one"*)  - if the receive FIFO is not empty, discard the interrupt and treat it as lost  - if there is no data in the receive FIFO, it is counted as a normal DMA    complete interrupt. It will then setup the next DMA transfer  *REMARK:When a SOF interrupt find a lost DMA complete interrupt, it will stop the currenttransfer. However, it is possible that the DMA transfer is completed just before it is terminated in the SOF interrupt. So there will be a DMA complete interruptjust right after completion of the SOF interrupt. We have to identify such "shifted" DMA interrupt, instead of treating it as a normal DMA complete interrupt.  Figure 1: two kinds of normal DMA complete interrupt  SOF                                            SOF       <---------- image data ---------->       ^-- DMA transfer started here                                         ^-- DMA transfer ended here   ^-- DMA channel setup here  SOF                                            SOF       <---------- image data ---------->               <---------- image data ---------->              DMA transfer ended here --^              and setup next DMA transfer                                                        ^-- DMA channel setup here                                                               DMA transfer ended here --^Figure 2: a shifted DMA complete interrupt  SOF                                            SOF       <---------- image data ---------->              <---------- image data ---------->         ^-- DMA transfer started here                                                          ^-- DMA transfer ended here   ^-- DMA channel setup here                                (not terminated by the SOF interrupt)                                                 */#include <linux/kernel.h>#include <linux/module.h>#include <linux/compatmac.h>#include <linux/hdreg.h>#include <linux/vmalloc.h>#include <linux/fs.h>#include <linux/module.h>#include <linux/blkpg.h>//#include <asm/arch/hardware.h>#include <linux/i2c.h>#include <linux/i2c-algo-bit.h>#include <linux/i2c-id.h>#include <linux/slab.h>#include <asm/io.h>//#include <asm/proc-armv/cache.h>#include <linux/mm.h>#include <linux/wrapper.h>#include <asm/dma.h>#include <linux/miscdevice.h>#include "type.h"#include "mx1hw.h"//#define DEBUG_CSI2C#ifdef DEBUG_CSI2C#define dprintcsi2c(str...) printk("<"__FUNCTION__"> "str)#else#define dprintcsi2c(str...)	// nothing#endif#define IOCTL_CSI_INIT			1#define IOCTL_I2C_WRITE			2#define IOCTL_I2C_READ			3#define IOCTL_SUBSAMPLE			4#define IOCTL_SET_GAIN			5#define IOCTL_SET_VF_WIDTH		6#define IOCTL_SET_INT_TIME		7#define IOCTL_DMA_CAPTURE		8//#define IOCTL_RESET_ASSERT		11//#define IOCTL_RESET_RELEASE	12#define IOCTL_STOP_CAPTURE		13#define IOCTL_INC_FRM			20		// increment frame rate meter#define CSI_IRQ					6#define I2C_DRIVERID_I2CCSI	0x1001/* Define of Massage Flag */#define EMBEDDED_REGISTER		0x01#define I2C_M_READ				0x02#define I2C_M_WRITE					0x04//	I2C clock divider//#define I2C_CLKDIV		0x17		// 0x17 => /960 => 100k I2C clock for 96 MHz system clock#define I2C_CLKDIV		0x13		// 0x13 => /480 => 100k I2C clock for 48 MHz system clock////	SENSOR read/write command//#define SCM20014_ADDR_W (U32) 0x66	//01100110b, last bit 0 => WRITE#define SCM20014_ADDR_R (U32) 0x67	//01100111b, last bit 1 => READ// 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);static void I2C_init(void);static U32 CSI_init(U32 systemClock, U32 sensorClock);static void I2C_read(U32 reg, U32 * _data);static void I2C_write(U32 reg, U32 data);static void port_init_SENSOR(void);static U32 SFCM_capture_DMA(U32 nPixel);static int i2c_csi_attach_adapter (struct i2c_adapter * adap);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 U8 badFrame;static U32 dma_buf_phy_addr;static U32 dma_data_size;static U8 dmaStopped;static U8 SOFintrStopped;static DECLARE_WAIT_QUEUE_HEAD(dma_wait);static DECLARE_WAIT_QUEUE_HEAD(stop_capture_wait);static struct i2c_driver i2c_csi_driver = {	name:					"i2c-csi client driver",	id:					I2C_DRIVERID_I2CCSI,	flags:				I2C_DF_DUMMY | I2C_DF_NOTIFY,	attach_adapter:	i2c_csi_attach_adapter,	detach_client:		NULL,	/*i2c_csi_detach_client,*/	command:				NULL};static struct i2c_client i2c_csi_client = {	name:		"i2c-csi client",	id:		1,	flags:	0,	addr:		-1,	adapter:	NULL,	driver:	&i2c_csi_driver,	data:		NULL};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 = 0; dma_channel < 11; dma_channel++)	{		if ( (request_dma(dma_channel, "CMOS Sensor")) == 0)		{			printk("dma channel %d granted\n", dma_channel);			*((U32 *)(DMA_SAR0+dma_channel*0x40)) = 0x00224010;	// CSI RxFIFO register			*((U32 *)(DMA_RSSR0+dma_channel*0x40)) = 7;					// CSI data			*((U32 *)(DMA_BLR0+dma_channel*0x40)) = 64;					// burst length : 16 words = 64 bytes			*((U32 *)(DMA_RTOR0+dma_channel*0x40)) = 0;					// burst timeout, not used			*((U32 *)(DMA_BUCR0+dma_channel*0x40)) = 0;					// bus utilization, not used			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_t csi2c_read(struct file *filp, char *buf, size_t size, loff_t *l){	U32 flags;	U32 captureDone;		dprintcsi2c("*** read ***\n");	do	{		captureDone = 0;		save_flags(flags);		cli();		if (capSeqNum > readSeqNum)			captureDone = 1;		restore_flags(flags);		if (!captureDone)			interruptible_sleep_on(&dma_wait);		if (badFrame)			captureDone = 1;				} while (!captureDone);			if (badFrame)	{//		printk("--- bad frame ---\n");		return 0;	// a zero size frame implies bad frame	}	else	{		readSeqNum++;		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){	dprintcsi2c("*** write ***\n");	return 0;}static int malloc_buffer() {	if ((csi_data_buf = (U32 *)__get_free_pages(GFP_KERNEL, 7)))	// 128 pages = 128x4K = 512K	{		dma_buf_phy_addr = virt_to_phys((void *)csi_data_buf);		dprintcsi2c("Buffer start: 0x%08x, DMA addr: 0x%08x\n", (int)csi_data_buf, (int)dma_buf_phy_addr);	}	else	{		printk("*** ERROR: cannot allocate buffer memory for driver ! ***\n");		return -1;	}	return 0;}static void free_buffer(){	dprintcsi2c("free buffer\n");	if (csi_data_buf)		__free_pages((void *)csi_data_buf,7);		// 512K}static void	setSubsample(int subsample){	U32 value;		switch (subsample)	{		case 2:		// divide by 2			value = 0x25;			break;		case 4:		// divide by 4			value = 0x2A;			break;		case 8:		// divide by 8			value = 0x2F;			break;		default:		// i.e. full subsampling			value = 0;		// REMARK: "cm" bit must be cleared for full-sampling	}	I2C_write(0x41, value);}			static void setGlobalGain(int gain){	I2C_write(0x10, gain);}static void setVFwidth(int width){	I2C_write(0x52, width >> 8);	I2C_write(0x53, width & 0xFF);}			static void	setIntegrationTime(int value){	I2C_write(0x4E, value >> 8);	I2C_write(0x4F, value & 0xFF);}static void stopCMOScapture(){	U32 flags;	U8 allStopped;		save_flags(flags);	cli();	stopCapture = 1;	dmaStopped = 0;	SOFintrStopped = 0;	allStopped = 0;	restore_flags(flags);		do	{		save_flags(flags);		cli();		if ((dmaStopped) && (SOFintrStopped))		{			allStopped = 1;			restore_flags(flags);		}		else		{			interruptible_sleep_on(&stop_capture_wait);					restore_flags(flags);		}	} while (!allStopped);}static int csi2c_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){	dprintcsi2c("cmd: 0x%08x, arg: 0x%08x\n", cmd, (int)arg);	switch(cmd)	{		case IOCTL_CSI_INIT:			dprintcsi2c("Init CSI, bus clock: %d MHz, sensor clock: %d MHz\n", (int)(arg >> 8), (int)(arg & 0xFF));			{				return (CSI_init(arg >> 8, arg & 0xFF));			}			break;		case IOCTL_I2C_WRITE:			dprintcsi2c("I2C write - reg: 0x%02x, data: 0x%02x\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:			dprintcsi2c("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:			stopCMOScapture();			break;		case IOCTL_INC_FRM:			{				U32 flags = 0;				save_flags(flags);				cli();				sensorFrameCount++;				restore_flags(flags);			}			break;	}	return 0;}static int i2c_csi_attach_adapter (struct i2c_adapter * adap){	/* find out the adapter for the I2C module in the DBMX1*/	if (memcmp(adap->name, "DBMX I2C Adapter", 16) != 0 )		return -ENODEV;	/* store the adapter to the client driver */	i2c_csi_client.adapter = adap;	return 0;}static void I2C_init(void){	// init port	//	PA15 : I2C_DATA	//	PA16 : I2C_CLK	* (U32 *)PTA_DDIR |=  0x00018000;	* (U32 *)PTA_GIUS &= ~0x00018000;		/* 	 * set the address of the CMOS sensor to the client	 */	i2c_csi_client.addr = SCM20014_ADDR_W;	/* 	 * call the i2c_add_driver() to register the driver 

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
亚洲精品国产一区二区精华液| www.欧美.com| 三级欧美韩日大片在线看| 亚洲狠狠爱一区二区三区| 日日摸夜夜添夜夜添精品视频 | 精品日韩在线观看| 亚洲欧美日韩国产综合在线| 蜜桃久久av一区| 91官网在线免费观看| 精品久久久久久久久久久院品网| 国产欧美日韩另类视频免费观看| 国产精品国产三级国产三级人妇| 欧美成人性福生活免费看| 欧美国产1区2区| 毛片一区二区三区| 欧美日韩一区成人| 亚洲欧美成aⅴ人在线观看| 久久99精品久久只有精品| 欧美在线观看一区| 樱花草国产18久久久久| 国产成人精品综合在线观看| 7777精品伊人久久久大香线蕉完整版| 欧美国产禁国产网站cc| 国产在线播放一区二区三区| 精品美女在线观看| 国产自产2019最新不卡| 欧美精品一区二区三区久久久| 天堂影院一区二区| 欧美巨大另类极品videosbest| 亚洲一区二区三区四区不卡| 色综合久久中文字幕综合网| 亚洲黄色在线视频| 欧美三级韩国三级日本一级| 亚洲国产综合视频在线观看| 7777精品伊人久久久大香线蕉 | 26uuu久久天堂性欧美| 国产伦精品一区二区三区免费| 久久综合色8888| 色偷偷久久人人79超碰人人澡| 一区二区国产视频| 欧美精品一卡两卡| 国产69精品久久777的优势| 亚洲国产经典视频| 欧美视频中文字幕| 国产剧情一区二区| 亚洲色图欧美激情| 久久夜色精品一区| 欧美日韩亚洲综合在线| 国产成人av资源| 日韩和欧美一区二区三区| 国产欧美综合色| 51精品国自产在线| av爱爱亚洲一区| 国产大陆a不卡| 午夜日韩在线观看| 亚洲资源中文字幕| 亚洲日穴在线视频| 国产精品美女久久久久aⅴ国产馆| 欧洲人成人精品| 日本韩国欧美一区二区三区| av日韩在线网站| 91啪亚洲精品| 日本韩国视频一区二区| 欧美中文字幕一区二区三区 | 亚洲va韩国va欧美va精品| 欧美一级xxx| 日韩一区国产二区欧美三区| 欧美日韩三级一区二区| 9191久久久久久久久久久| 欧美肥大bbwbbw高潮| 欧美日韩日日摸| 色婷婷激情一区二区三区| 色综合久久综合| 欧美三级午夜理伦三级中视频| 99这里都是精品| 欧美亚洲愉拍一区二区| 欧美一级欧美三级| 久久久久久夜精品精品免费| 精品国产乱子伦一区| 中文字幕欧美一| 天天操天天色综合| 国产精品99久久久久久久vr| 成人国产精品免费观看| 日本精品视频一区二区| 久久婷婷色综合| 亚洲国产精品久久久男人的天堂| 亚洲一级二级在线| 国产一级精品在线| 91精品国产手机| 亚洲欧美另类图片小说| 国产综合色视频| 日韩亚洲欧美高清| 亚洲福利视频三区| av在线不卡电影| 国产欧美日韩综合精品一区二区 | 久久国产精品一区二区| 欧美日韩另类一区| 亚洲欧美日韩国产手机在线| 国产精品996| 国产片一区二区| 国产91精品入口| 欧美激情一区二区三区不卡| 国产原创一区二区三区| 久久看人人爽人人| 成人性视频免费网站| 国产三级精品三级| 成人午夜激情视频| 亚洲人成电影网站色mp4| 精品视频一区三区九区| 青青草97国产精品免费观看| 日韩视频免费观看高清完整版在线观看 | 国产成人亚洲综合a∨婷婷 | 成人国产精品免费观看动漫| 国产欧美日韩久久| 色哟哟欧美精品| 三级久久三级久久久| 国产日韩欧美亚洲| 91麻豆国产在线观看| 视频一区国产视频| 日本一区二区高清| 欧美三级蜜桃2在线观看| 久久电影网电视剧免费观看| 国产精品午夜电影| 欧美午夜精品一区二区蜜桃| 六月丁香婷婷色狠狠久久| 久久精品人人做人人爽人人| 欧美专区在线观看一区| 国产一区999| 久久精品国产在热久久| 亚洲成人一二三| 欧美成人猛片aaaaaaa| 在线亚洲精品福利网址导航| 国产电影一区在线| 国产福利91精品| 久久99国产精品成人| 午夜国产精品一区| 亚洲国产欧美另类丝袜| 亚洲日本在线天堂| 亚洲视频综合在线| 亚洲蜜臀av乱码久久精品蜜桃| 26uuu国产一区二区三区| 精品第一国产综合精品aⅴ| 欧美一区二区三区啪啪| 欧美精品777| 久久综合狠狠综合久久综合88| 欧美丰满高潮xxxx喷水动漫| 日韩免费看的电影| 欧美xxxxxxxxx| 欧美精品一区二区久久婷婷| 久久久一区二区三区捆绑**| 中文字幕一区二区三区av| 亚洲特黄一级片| 亚洲一级二级三级在线免费观看| 日韩综合小视频| 国产a精品视频| 欧美视频一区在线| 精品久久久网站| 亚洲美女免费在线| 久久99热国产| 成人一区二区三区在线观看| 在线观看免费一区| 国产亚洲成aⅴ人片在线观看| 亚洲精品国产无天堂网2021 | 欧美精品第1页| 欧美国产丝袜视频| 性久久久久久久久| 成人动漫视频在线| 日韩免费一区二区三区在线播放| 亚洲丝袜另类动漫二区| 日韩成人av影视| 在线亚洲一区观看| 国产精品国产三级国产三级人妇 | 中文字幕一区在线| 国内一区二区在线| 欧美哺乳videos| 日韩高清在线电影| 欧美日韩精品一区二区天天拍小说 | 精品国产乱码久久久久久图片| 亚洲一区二区三区四区在线免费观看 | 国产一区二区不卡在线| 久久免费视频色| 国产成人av电影免费在线观看| 欧美一区二区三区在线看| 天堂资源在线中文精品| 在线成人av影院| 国产精品996| 亚洲免费资源在线播放| 色视频成人在线观看免| 亚洲综合成人在线| 日韩欧美黄色影院| 成人黄色片在线观看| 亚洲毛片av在线| 欧美狂野另类xxxxoooo| 狠狠色丁香久久婷婷综| 日韩一区欧美小说| 一本大道综合伊人精品热热| 亚洲国产婷婷综合在线精品| 精品少妇一区二区三区日产乱码| 成人免费高清在线观看| 婷婷一区二区三区|