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

📄 cc303.c

📁 linux平台上的开放源代码的网络摄像机程序.实现视频捕捉,传输以及云台控制等.非常具有参考价值.
💻 C
📖 第 1 页 / 共 4 页
字号:
  return count;}static ssize_t cmoscam_raw_read4(struct file * file, char * buf, size_t count, loff_t *off) {  unsigned long p,bp,dp,fs,x,l,n,bw;  char * bccam_dma_buf= (char *) ccam_dma_buf;//imageParamsR[P_LPR]// printk("cmoscam_raw_read: buf address=%x count=%x\r\n",(long) buf, (long) count);  bw=imageParamsR[P_ACTUAL_WIDTH];  if (bw & 1) bw++;		// byte align  bw=bw>>1;	// in bytes  fs=(bw*imageParamsR[P_ACTUAL_HEIGHT]);  p = file->f_pos;// printk ("p= %x imageParamsR[P_IMAGE_SIZE]=%x file size=%x\r\n",p,imageParamsR[P_IMAGE_SIZE],fs);  if(p >= fs) return -EFAULT;  if( (p + count) > fs) { /* truncate count */    count = fs - p;  }// line length may be not aligned to 32-bit words  l=imageParamsR[P_LPR]<<2;  n=p/bw;  x=p-n*bw;  dp=n*l+x;  //copy first line  n=bw-x;  if (n>count) n=count;  bp=0;  while (bp<count)  {    for (;dp<n;bp++) buf[bp]=bccam_dma_buf[dp++];	dp+=(l-bw);	n=bw;	if (n>(count-bp)) n=count-bp;  }  file->f_pos += count;// printk("cmoscam_raw_read returned %x\r\n", count);  return count;}static loff_t cmoscam_raw_lseek(struct file * file, loff_t offset, int orig){/* *  orig 0: position from begning of eeprom *  orig 1: relative from current position *  orig 2: position from last eeprom address */  unsigned long fs;//printk("cmoscam_raw_lseek: orig= %x\r\n",orig);  fs=((imageParamsR[P_ACTUAL_WIDTH]*imageParamsR[P_ACTUAL_HEIGHT]) << 1);    switch (orig)  {   case 0:     file->f_pos = offset;     break;   case 1:     file->f_pos += offset;     break;   case 2:     file->f_pos = fs - offset;     break;   default:     return -EINVAL;  }  /* truncate position */  if (file->f_pos < 0) {    file->f_pos = 0;        return(-EOVERFLOW);  }    if (file->f_pos >= fs) {    file->f_pos = fs - 1;    return(-EOVERFLOW);  }  return ( file->f_pos );}// **************************************************************static int __init cmoscam_init(void){  extern void init_ioremap(void);	int i,res;//	unsigned long dmaArrIndex;//	unsigned long dai;//        unsigned char data[2];	ccam_cr_shadow=0;	res = register_chrdev(CMOSCAM_MAJOR, cmoscam_name, &cmoscam_fops);	if(res < 0) {		printk(KERN_ERR "ccam: couldn't get a major number.\n");		return res;	}	printk(CMOSCAM_DRIVER_NAME);	ccam_dma_buf=ccam_dma_buf0;	if (((unsigned long)(&ccam_dma_buf[0])) & (PAGE_SIZE-1)) {          ccam_dma_buf=(unsigned long *) (((unsigned long)(&ccam_dma_buf[0]) & ~(PAGE_SIZE-1)) + PAGE_SIZE);	      printk("+++++++++++ should not get here - why??? \n");    	}// else printk("++++++++++ remove this alingment alltogether - not needed anymore!!!\n");	for (i=0;i<=CCAM_MAXMINOR;i++) minors[i]=0;    init_ioremap();// Initialize genconfig and it's shadow - needed only once	printk("Initializing genconfig/DMA registers\n");	genconfig_shadow = ( (genconfig_shadow & ~IO_MASK(R_GEN_CONFIG, dma5) ) |                          ( IO_STATE( R_GEN_CONFIG, dma5, extdma0 ) ) );    	*R_GEN_CONFIG = genconfig_shadow;// additional configuration for external dma 0	*R_EXT_DMA_0_ADDR = 0x90000000;	// csp0, uncashed	extdma0_cmd_shadow = \	  IO_STATE( R_EXT_DMA_0_CMD, cnt, disable )	 | // disable transfer counter	  IO_STATE( R_EXT_DMA_0_CMD, rqpol, ahigh )	 | // DREQ active high	  IO_STATE( R_EXT_DMA_0_CMD, apol, ahigh )	 | // DACK active high	  IO_STATE( R_EXT_DMA_0_CMD, rq_ack, burst ) | // burst mode	  IO_STATE( R_EXT_DMA_0_CMD, wid, dword )	 | // 32-bit mode	  IO_STATE( R_EXT_DMA_0_CMD, dir, input )	 | // input mode	  IO_STATE( R_EXT_DMA_0_CMD, run, stop );	*R_EXT_DMA_0_CMD = extdma0_cmd_shadow;	// initialize static DMA descriptor list	DMABufferLength=0;//    setDMABuffer(CCAM_DMA_SIZE);	// just init to the longest size - will be called from programSensor from init_sensor	init_sensor();	programEncoder();// Init MCP here#ifdef CONFIG_ETRAX_CMOSCAM_MCP	if (MCP_initmodule()== 0) printk ("MCP module initialized\r\n");	else			  printk ("no MCP module detected\r\n");#endif  printk("after MCP_initmodule ccam_cr_shadow=%lx, MCPpresent()=%x\n\r",ccam_cr_shadow,MCPpresent());	initCamIRQs();  printk("after initCamIRQs ccam_cr_shadow=%lx\n\r",ccam_cr_shadow);	return 0;}int setDMABuffer(unsigned long length) {	unsigned long dai;	int i=0;	if (length>CCAM_DMA_SIZE) return -1;	if (length == DMABufferLength) return 0;// Stop DMA (just in case)	EXT_DMA_0_STOP;	for (dai=0; dai < length; dai+=0x4000) {/*  printk("dai=%x &ccam_dma_buf[dai]=%x (unsigned long) virt_to_phys (&ccam_dma_buf[dai])=%x\r\n",dai,\		(unsigned long) &ccam_dma_buf[dai], (unsigned long) virt_to_phys (&ccam_dma_buf[dai])); */	  ccam_dma_descr[i].buf=		((unsigned long) virt_to_phys (&ccam_dma_buf[dai]))   | 0x80000000;	  ccam_dma_descr[i].hw_len=	0;	  ccam_dma_descr[i].status=	0;	  if (dai + 0x4000 >= length) { //last descriptor	    ccam_dma_descr[i].sw_len=	((dai + 0x4000 - length) & 0x3fff) << 2;	    ccam_dma_descr[i].ctrl=	1;	// last in list	    ccam_dma_descr[i].next=		// let's loop it (just in case)		((unsigned long) virt_to_phys (&ccam_dma_descr[0])) | 0x80000000;	  }	else { // not the last one	    ccam_dma_descr[i].sw_len=	0;	    ccam_dma_descr[i].ctrl=	0;	    ccam_dma_descr[i].next= ((unsigned long) virt_to_phys (&ccam_dma_descr[i+1])) | 0x80000000;	  }	  i++;	}	DMABufferLength=length;	return 0;}int init_sensor(void) { int i; printk("removing MRST from the sensor, setting DMA burst size, setting MCLK to 20MHz\n");        ccamCRAndOr(0,0);	// just clear control register		CCAM_MRST_OFF;		PROGRAM_CLK_DIV(2) ;		PROGRAM_CLK_EN(1);		PROGRAM_BLKSZ(0x10); writeSensorDefaults(&default_common[0],sizeof(default_common)/sizeof(default_common[0])/2); // set common defaults for (i=0;i<256;i++) sensor_i2c_regs[i]=0; // shadow registers#ifdef CONFIG_ETRAX_CMOSCAM_ZR32112 if (imageParamsR[P_SENSOR]==0) init_ZR32112();	// try ZR32112#endif#ifdef CONFIG_ETRAX_CMOSCAM_ZR32212 if (imageParamsR[P_SENSOR]==0) init_ZR32212();	// try ZR32212#endif#ifdef CONFIG_ETRAX_CMOSCAM_KAC1310 if (imageParamsR[P_SENSOR]==0) init_KAC1310();  // try KAC-1310#endif if (imageParamsR[P_SENSOR]==0) {   printk("No image sensor found\n");   return -1; } else return programSensor();}int programSensor(void){   // program appropriate sensor	int i=-1;	unsigned long flags;// remove disabling irqs if desired	save_flags(flags);	cli();	if (imageParamsR[P_PARS_CHANGED]) {// TODO: stop sensor if running before writing parameters ???		imageParamsR[P_DMA_VALID]=0;// process common parameters (not sensor specific)//P_BAYER		imageParamsR[P_BAYER]=imageParamsW[P_BAYER]; // TODO: remove		imageParamsR[P_DMA_SZ]=(imageParamsW[P_DMA_SZ] < 0x3f)? imageParamsW[P_DMA_SZ]:0x3f;		imageParamsR[P_EXPOS]= (imageParamsW[P_EXPOS]>0)?imageParamsW[P_EXPOS]:1;		imageParamsR[P_OVERLAP]=imageParamsW[P_OVERLAP];// reset videomode if it was on and now off		if (imageParamsR[P_VIDEO] && !imageParamsW[P_VIDEO]) {		  imageParamsR[P_VIDEO]=0;		  setCamSeq(0);	// reset sequencer state, toggle ARST        }		imageParamsR[P_VIDEO]=  imageParamsW[P_VIDEO];#ifdef	CONFIG_ETRAX_303		imageParamsR[P_TRIG]=  (imageParamsW[P_TRIG] && (imageParamsW[P_VIDEO]==0))?1:0;  // no xtern trigger in video mode for Rev "0"		imageParamsR[P_BITS]=  10;		imageParamsR[P_SHIFTL]=0;		imageParamsR[P_AUXCM]=0;		imageParamsR[P_MCLK]= 4;		imageParamsR[P_MCLK_DIS]=  0;#else		imageParamsR[P_TRIG]=  imageParamsW[P_TRIG];		imageParamsR[P_BITS]=  (imageParamsW[P_BITS] < 5)? 4 : (imageParamsW[P_BITS] < 9)? 8: 10; // TODO: add DMA size support 		imageParamsR[P_SHIFTL]=(imageParamsW[P_SHIFTL] < 3)? imageParamsW[P_SHIFTL] : 3;		imageParamsR[P_AUXCM]=(imageParamsW[P_AUXCM] < 2)? imageParamsW[P_AUXCM] : 2;		imageParamsR[P_MCLK]=  (imageParamsW[P_MCLK]<129)?((imageParamsW[P_MCLK]>1)?imageParamsW[P_MCLK]:2):129;		imageParamsR[P_MCLK_DIS]=  imageParamsW[P_MCLK_DIS];#endif//  MD(printk ("imageParamsR[P_VIDEO]= %x, imageParamsW[P_VIDEO]= %x\r\n",imageParamsR[P_VIDEO],imageParamsW[P_VIDEO]));// set MCLK to 20MHz (for I2C, etc)// program FPGA  mclk		PROGRAM_CLK_DIV(2);		PROGRAM_CLK_EN(1);// process  sensor specific parameters		switch (imageParamsR[P_SENSOR] & SENSOR_MASK) {#ifdef CONFIG_ETRAX_CMOSCAM_ZR32112		 case SENSOR_ZR32112: {i=program_ZR32112();break;}#endif#ifdef CONFIG_ETRAX_CMOSCAM_ZR32212		 case SENSOR_ZR32212: {i=program_ZR32212();break;}#endif#ifdef CONFIG_ETRAX_CMOSCAM_KAC1310		 case SENSOR_KAC1310: {i=program_KAC1310();break;}#endif		}// adjust exposure to variable MCLK 		if (imageParamsR[P_MCLK]!=4) imageParamsR[P_EXPOS]= (imageParamsR[P_EXPOS]<<2)/imageParamsR[P_MCLK];		if (imageParamsR[P_EXPOS]<1) imageParamsR[P_EXPOS]=1;// program FPGA  mclk		PROGRAM_CLK_DIV( imageParamsR[P_MCLK]-2 );		PROGRAM_CLK_EN( 1-imageParamsR[P_MCLK_DIS] );		ccamInitWndSize();// program DMA block size		PROGRAM_BLKSZ(imageParamsR[P_DMA_SZ]);// program depth		PROGRAM_DEPTH(imageParamsR[P_BITS]);// program shift		PROGRAM_SHIFT( (imageParamsR[P_BITS]==10) ? 2 : imageParamsR[P_SHIFTL] );// program color	    PROGRAM_COLOR(imageParamsR[P_COLOR]);	// set in program_XXX// program auxclk	    PROGRAM_AUXCM(imageParamsR[P_AUXCM]);// program DMA buffer length 1 - 1 frame, 2 - 2 frames..15 - 15 frames, else - as specified.// imageParamsR[P_IMAGE_SIZE] calculated in	ccamInitWndSize()		imageParamsR[P_DMA_LOOP]=(imageParamsW[P_DMA_LOOP] > 15) ?\			 imageParamsW[P_DMA_LOOP]: (imageParamsW[P_DMA_LOOP] * imageParamsR[P_IMAGE_SIZE]);		setDMABuffer(imageParamsR[P_DMA_LOOP]);		imageParamsR[P_PARS_CHANGED]=0;	}	imageParamsR[P_UPDATE]=1;  // in sync	imageParamsW[P_UPDATE]=0;  // not needed	restore_flags(flags);// restart video mode (skip frame) if parameters were actually changed in sensor's registers        if ((i>0) && imageParamsR[P_VIDEO] ) setCamSeq(2); // start waiting for frame to skip	return i;}// **************************************************************static void ccamInitWndSize (void) {   int i,ppl;   switch (imageParamsR[P_SENSOR] & SENSOR_MASK) {#ifdef CONFIG_ETRAX_CMOSCAM_ZR32112	 case SENSOR_ZR32112: {ccamInitWndSizeZR32112();break;}#endif#ifdef CONFIG_ETRAX_CMOSCAM_ZR32212	 case SENSOR_ZR32212: {ccamInitWndSizeZR32212();break;}#endif#ifdef CONFIG_ETRAX_CMOSCAM_KAC1310	 case SENSOR_KAC1310: {ccamInitWndSizeKAC1310();break;}#endif   }   switch (imageParamsR[P_BITS]) {      case 10: {ppl=3;break;}      case  8: {ppl=4;break;}      case  4: {ppl=8;break;}	  default: {ppl=3;break;}   }   i=imageParamsR[P_ACTUAL_WIDTH]/ppl;   imageParamsR[P_LPR] = (ppl*i == imageParamsR[P_ACTUAL_WIDTH])? i: i+1;	    imageParamsR[P_IMAGE_SIZE] = (imageParamsR[P_LPR] * imageParamsR[P_ACTUAL_HEIGHT]) << 2;  D2(printk("imageParamsR[P_ACTUAL_WIDTH]= %d\r\n",imageParamsR[P_ACTUAL_WIDTH]));  D2(printk("imageParamsR[P_ACTUAL_HEIGHT]=%d\r\n",imageParamsR[P_ACTUAL_HEIGHT]));  D2(printk("imageParamsR[P_LPR]=   %d\r\n",imageParamsR[P_LPR]));  D2(printk("imageParamsR[P_IMAGE_SIZE]=       %d\r\n",imageParamsR[P_IMAGE_SIZE]));   imageParamsR[P_DMA_VALID]=1;	// updated;}//*******************************************************************#ifndef	CONFIG_ETRAX_303void programEncoder (void) {  int a=0;  int d=0;  int i,c, adiff2code;  int codetab[]=   {128,1,3,7,15,31,63,95};  int threshtab[]= {1,2,5,11,23,47,79,111};  port_csp0_addr[CCAM_WA_WWA]= 0; // reset address counter  for (a=0;a<128;a++) {     adiff2code=0;	 for (i=0;i<8;i++) if (a<threshtab[i]) {adiff2code=i;break;}     d=	 (adiff2code << 22) | (((codetab[adiff2code]-a) & 0x3f) << 16);	 if ((a & 0x18) != 0x08) {	    c=((a & 0x10)?((a & 0x08)?(a-1):(a+1)):a) & 7;         d|= (( (c == 0)? 8:((a & 0x20) ? (-c):c)) & 0x0f) << 8;		d|= ( (a & 0x20) ? (-codetab[c]): codetab[c]) & 0xff;	 }     port_csp0_addr[CCAM_WA_ENCOD]= d; // write data, inc address  if ((a & 0x7) == 0) printk ("\r\n%2x:",a);//  printk(" %x:%x:%07x",adiff2code,c,d);     printk(" %07x",d);     }  printk("\r\n");}#endif/* this makes sure that cmoscam_init is called during boot */module_init(cmoscam_init);MODULE_LICENSE("GPL");MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>.");MODULE_DESCRIPTION(MY_MODULE_DESCRIPTION);MODULE_DESCRIPTION("Elphel model 303 rev A camera driver");/****************** END OF FILE cmoscam.c ********************************/

⌨️ 快捷键说明

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