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

📄 cc303.c

📁 linux平台上的开放源代码的网络摄像机程序.实现视频捕捉,传输以及云台控制等.非常具有参考价值.
💻 C
📖 第 1 页 / 共 4 页
字号:
// define sequencer fields to be ORed with 10-bit step duration in (pixel) clock periods.//  Actual duration is longer by two 20MHz clock periods. (0->100ns, 1->150ns, etc.)#define	sfld_astop	0x00400	// turn sequencer off#define	sfld_genIn	0x00800	// generate interrupt (at the beginning of this step)#define	sfld_gtNxt	0x01000	// increment address when the duration counter will expire (0 - forever repeat current step)#define	sfld_xen_pend	0x02000	// enable external trigger to branch sequencer to the address 6'h00 AT THE END of the current step. (see NOTE1)#define	sfld_xen_imm	0x04000	// enable external trigger to branch sequencer to the address 6'h00 IMMEDIATELY (see NOTE1)#define	sfld_xt_rst	0x06000	// reset 'was external trigger" flag, enable software modification of the sequencer address.#define	sfld_GATE	0x08000	// turn ON xternal shutter device (i.e. MCP) (see NOTE2)#define	sfld_ARO	0x10000	// send ARO	pulse to zr32112 (see NOTE2)#define	sfld_ARST	0x20000 // send (inverted, active-low) ARO	pulse to zr32112 (see NOTE2)// NOTE1: if both bits sfld_xen_pend and sfld_xen_imm are set - reset 'was external trigger" flag,// enable software modification of the sequencer address.// NOTE2: These bits are combined with other (non-sequencer) bits in DCR before being output#define	MAXEXPOSURE	60000	//60 sec, in 1ms incrementsstatic	volatile int camSeqState;/*#define CAMSEQ_OFF       0 // off#define CAMSEQ_PREERASE  1 // preerasing#define CAMSEQ_WAITTRIG  2 // waiting for trigger#define CAMSEQ_TRIGGERED 3 // triggered#define CAMSEQ_STILLDMA  4 // acquiring still image (DMA running)#define CAMSEQ_STILLGOT  5 // still picture acquired#define CAMSEQ_VIDEOON	 6 // video mode just started, not ready for picture acquisition yet#define CAMSEQ_VIDEORDY	 7 // video mode passed first VACT pulse, ready to acquire a new picture#define CAMSEQ_VIDEOWAIT 8 // video mode - waiting for external trigger (not implemented yet)#define CAMSEQ_VIDEODMA  9 // video mode - acquiring picture#define CAMSEQ_VIDEOGOT 10 // video mode - picture got*/#define PREERASE	5static	volatile int camSeqCount;	// Value= exposure time in msec (left)static	volatile int camSeqPreCount;	// Value= preerase cyclesstatic int getCamSeqState(void) {return	camSeqState;}static int getCamSeqCount(void) {return	camSeqCount;}//static int getCamSeqPreCount(void) {return	camSeqPreCount;}static void setCamSeqState(int v) {camSeqState=v;}static void setCamSeqCount(int v) {camSeqCount=v;}static void setCamSeqPreCount(int v) {camSeqPreCount=v;}static	void initCamIRQs(void){	int	camIRQVectors[8]={0x24,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a};	int i;//	setup cam-sequencer data// seems to be that the best way is to keep reset always on before the exposure - remove sequencing later	port_csp0_addr[CCAM_WA_WWA]=	0x20; // sequencer start(or anything but 0 - reserved for trigger)	port_csp0_addr[CCAM_WA_SEQWRD]=		sfld_xen_imm | sfld_ARST | sfld_gtNxt ;// delay=2 cycles = 100ns	port_csp0_addr[CCAM_WA_SEQWRD]=		sfld_ARST | sfld_xen_imm | sfld_gtNxt | 996 ;	// delay=998 cycles = 49.9 us	for (i=0;i<18;i++) 	port_csp0_addr[CCAM_WA_SEQWRD]=		sfld_ARST | sfld_xen_imm | sfld_gtNxt | 998 ;	// delay=1000 cycles = 50.0 us (x18)	port_csp0_addr[CCAM_WA_SEQWRD]=		sfld_ARST | sfld_xen_imm |sfld_genIn | 998 ; // delay=1000 cycles = 50.0 us		port_csp0_addr[CCAM_WA_WWA]=	0x00; // will get here after trigger	port_csp0_addr[CCAM_WA_SEQWRD]=			sfld_ARST | sfld_gtNxt ;// one more reset pulse for slow phosphors - OK delay=2 cycles = 100ns	if (MCPpresent()) {	  for (i=0;i<18;i++) 	  port_csp0_addr[CCAM_WA_SEQWRD]=		sfld_gtNxt | 998 ;	// delay=1000 cycles = 50.0 us (x18)	  port_csp0_addr[CCAM_WA_SEQWRD]=		sfld_xt_rst | sfld_gtNxt  | 998 ;// reset "was trigger" flag, delay=1000 cycles = 50.0 us	  port_csp0_addr[CCAM_WA_SEQWRD]=		sfld_genIn | sfld_xen_imm | 998 ; // gen interrupt, delay=1000 cycles = 50.0 us	} else {	  for (i=0;i<18;i++) 	  port_csp0_addr[CCAM_WA_SEQWRD]=		sfld_GATE | sfld_gtNxt | 998 ;	// delay=1000 cycles = 50.0 us (x18)	  port_csp0_addr[CCAM_WA_SEQWRD]=		sfld_GATE | sfld_xt_rst | sfld_gtNxt  | 998 ;			// reset "was trigger" flag, delay=1000 cycles = 50.0 us	  port_csp0_addr[CCAM_WA_SEQWRD]=		sfld_GATE | sfld_genIn | sfld_xen_imm | 998 ; // gen interrupt, delay=1000 cycles = 50.0 us	}// enable selected interrupts (for now will use internal vector number) - no INTA generated !!!// set all external interrupt vectors to the same as internally generated - 0x2a - WORKS!	port_csp0_addr[CCAM_WA_WWA]=	0x00;	for (i=0;i<8;i++) port_csp0_addr[CCAM_WA_INTWRWV]=	camIRQVectors[i]; // needed even w/o irqs enabled    DIS_INTERRUPTS;	setCamSeq(0);	//stop, init status//	if(request_irq( 4, camTrig_interrupt, SA_INTERRUPT, "cmoscam XTRN trigger", NULL))	panic("irq4");	if(request_irq(10, camSeq_interrupt, SA_INTERRUPT, "cmoscam sequencer", NULL))	panic("irq10");// Set external vector number generation//	*R_IRQ_MASK0_CLR = 0x10;	//1 << irq_int_vector_nr//	*R_IRQ_MASK0_SET = 0x20;	//1 << irq_ext_vector_nr// No, let's try internal	*R_IRQ_MASK0_SET = 0x10;	//1 << irq_int_vector_nr	printk("CMOS/MCP camera interrupts initialized\n");}static	void setCamSeq(int cmd) {	// 0 - stop (and turn off video mode?), 1 -  run, 2 - set video mode    int expTime=imageParamsR[P_EXPOS];  MD(printk ("# 3 state=%x testDMA=%x, expTime= %x, blFrame= %x, cmd=%x\r\n",getCamSeqState(),testDMA,expTime,blFrame,cmd));  MD(printk ("intm_shadow=%x camSeqPreCount=%x, camSeqCount= %x\r\n",intm_shadow,camSeqPreCount,camSeqCount));//intm_shadow	if (expTime<0) expTime=0; // - minimum - 1 ms	if (expTime>MAXEXPOSURE) expTime=MAXEXPOSURE;	if (cmd==2) { // will switch to CAMSEQ_VIDEOON// just in case - stop previous activity          DIS_INTERRUPTS;	  CCAM_EXP_DIS;	  setCamSeqCount(0);	  setCamSeqPreCount(2);// stop DMA activity (if any)	  FPGA_DMA_STOP;	  RESET_DMA( 5 );	  WAIT_DMA( 5 );          setCamSeqState(CAMSEQ_VIDEOON);          EN_INTERRUPT(nint_vact_end);  MD(printk ("intm_shadow=%x camSeqPreCount=%x, camSeqCount= %x\r\n",intm_shadow,camSeqPreCount,camSeqCount));	  return;	} else if (cmd==1) { // run	  if (imageParamsR[P_VIDEO]) {// video mode should be enabled before - while writing parameters        switch (camSeqState) {		  case  CAMSEQ_VIDEORDY:	//ready to start acquisition		  case  CAMSEQ_VIDEOGOT: {//ready to start acquisition                  setCamSeqState(CAMSEQ_VIDEOWAIT);                  RESET_DMA( 5 );                  WAIT_DMA( 5 );#ifdef	CONFIG_ETRAX_303                 ccam_dma_buf0[0]=0x80000000; //to find out if data sent to memory -- 2 MSBs always 0                 EN_INTERRUPT(nint_vact_end);#else                 EN_INTERRUPT(nint_xferovr);#endif                  *R_DMA_CH5_FIRST = virt_to_phys (&ccam_dma_descr[0]);                  *R_DMA_CH5_CMD   = IO_STATE(R_DMA_CH5_CMD, cmd, start);                  EXT_DMA_0_START ;//  MD(printk ("will set FPGA DMA with %x\r\n",((imageParamsR[P_VIDEO] && imageParamsR[P_TRIG])?RS_EXTERNAL:RS_INTERNAL) |  (RS_MAX_LEN & ((imageParamsR[P_IMAGE_SIZE] >>2) + imageParamsR[P_OVERLAP]))));// for REV0 no difference internal/external - always internal                  if (blFrame) {FPGA_DMA_START_INTERNAL ;}  //should be some "nops" after these writes to FPGA                  else {FPGA_DMA_START ;}		      }		  default: return;	// do nothing		} // switch (camSeqState)                return;	  } else { // still mode	    setCamSeqCount(expTime);	    setCamSeqState(CAMSEQ_PREERASE);	    CCAM_MRST_OFF; // to make sure they are not set	    CCAM_ARST_OFF;	    CCAM_ARO_OFF;	    setCamSeqCount(expTime);	    setCamSeqPreCount(PREERASE);	    setCamSeqState(CAMSEQ_PREERASE);	    port_csp0_addr[CCAM_WA_SEQWRRA]= 0x20; // sequencer start address        EN_INTERRUPT(nint_seq_norm);	    if (blFrame) { CCAM_EXP_DIS;} 	    else {CCAM_EXP_EN;}		    port_csp0_addr[CCAM_WA_SEQSTART]= 0;	  }	} else if (cmd==0) {  //          if (imageParamsR[P_VIDEO] && (getCamSeqState()==CAMSEQ_VIDEOON)) return;	// find better logic?          MD(printk ("disabling interrupts: imageParamsR[P_VIDEO]= %x, getCamSeqState()= %x\r\n",imageParamsR[P_VIDEO],getCamSeqState() ));	  CCAM_EXP_DIS;	  DIS_INTERRUPTS;	  port_csp0_addr[CCAM_WA_SEQSTOP]= 0;	  port_csp0_addr[CCAM_WA_SEQWRRA]= 0x20; // sequencer start address	  setCamSeqCount(0);	  setCamSeqPreCount(0);// stop DMA activity (if any)	  RESET_DMA( 5 );	  WAIT_DMA( 5 );	  FPGA_DMA_STOP;	  if (imageParamsR[P_VIDEO]) {	    if (getCamSeqState()==CAMSEQ_VIDEOGOT) setCamSeqState(CAMSEQ_VIDEORDY); // reset previous image	    if (getCamSeqState()==CAMSEQ_VIDEOON) {              setCamSeqState(CAMSEQ_OFF); // reset completely              imageParamsR[P_VIDEO]=0;//	  disable video mode toggle ARST;	      CCAM_ARST_ON ;	      udelay (1);	      CCAM_ARST_OFF ;            }	  } else {	     setCamSeqState(CAMSEQ_OFF);//	  disable video mode toggle ARST;	     CCAM_ARST_ON ;	     udelay (1);	     CCAM_ARST_OFF ;	  }	}}//writing to CCAM_WA_SEQWRRA should be AFTER EN_INTERRUPT()!! (EN_INTERRUPT after with long MCLK aborts writing CCAM_WA_SEQWRRA)static void camSeq_interrupt(int irq, void *dev_id, struct pt_regs * regs) {// simulate "inta"    DIS_INTERRUPTS;	// disable and clear all interrupts        switch (camSeqState) {         case CAMSEQ_PREERASE:         case CAMSEQ_WAITTRIG: {  //2// check if there was external trigger            EN_INTERRUPT(nint_seq_norm);	// re-enable sequencer interrupt            if (CCAM_SEQ_BEFORE_TRIGER) { // before external trigger              port_csp0_addr[CCAM_WA_SEQWRRA]= 0x20; // just loop sequencer waiting cycle              if ((camSeqPreCount--) <= 0) camSeqState=CAMSEQ_WAITTRIG; //2 - will decrement camSeqPreCount also in state 2 - OK            } else { // after xternal trigger              camSeqState=CAMSEQ_TRIGGERED; //3               port_csp0_addr[CCAM_WA_SEQWRRA]= 0x01; // loop sequencer second (post-trigger) waiting cycle            }	    break;	 }	 case CAMSEQ_TRIGGERED: { //3	    if ((--camSeqCount)<=0) { // exposure over		  port_csp0_addr[CCAM_WA_SEQSTOP]= 0; // stop sequencer		  port_csp0_addr[CCAM_WA_WCTL]= (ccam_cr_shadow |= CCAM_BITS(ARO,1) ); // turn ARO on		  RESET_DMA( 5 );		  WAIT_DMA( 5 );		  *R_DMA_CH5_FIRST = virt_to_phys (&ccam_dma_descr[0]);	 	  *R_DMA_CH5_CMD   = IO_STATE(R_DMA_CH5_CMD, cmd, start);		  EXT_DMA_0_START ;		  FPGA_DMA_START ; // no FPGA access immediately after this write		  camSeqCount=0;		  camSeqState=CAMSEQ_STILLDMA; //4           EN_INTERRUPT(nint_vact_end);	// enable end of frame interrupt	    } else {              EN_INTERRUPT(nint_seq_norm);	// re-enable sequencer interrupt	      port_csp0_addr[CCAM_WA_SEQWRRA]= 0x01; // loop sequencer second (post-trigger) waiting cycle            }	    break;	 }	 case CAMSEQ_STILLDMA: {	// 4 should be end of VACT	    FPGA_DMA_STOP;	    camSeqState=CAMSEQ_STILLGOT;  // all done !	    RESET_DMA( 5 );	    WAIT_DMA( 5 );	    port_csp0_addr[CCAM_WA_WCTL]= (ccam_cr_shadow &= ~CCAM_BITS(ARO,1) ); // turn ARO off	    break;	 }// video modes (for rev 0 will be different - use video wait to delay one more VACT)	 case CAMSEQ_VIDEOON: { //6 Should be caused by VACT. Advance state and start acquisition in video mode            if ((camSeqPreCount--) <= 0) {              camSeqState=CAMSEQ_VIDEORDY;            } else {              EN_INTERRUPT(nint_vact_end);	// re-enable end of frame interrupt            }	    break;	 }	 case CAMSEQ_VIDEOWAIT: { // 8 Should be caused by nint_xferovr. Advance state and finish#ifdef	CONFIG_ETRAX_303          if (ccam_dma_buf0[0] & 0x80000000) {// DMA did not start             EN_INTERRUPT(nint_vact_end); // reanable interrupt, wait for the next VACT end             break;          }#endif	      FPGA_DMA_STOP;	      camSeqState=CAMSEQ_VIDEOGOT;  // all done !	      RESET_DMA( 5 );	      WAIT_DMA( 5 );	    break;	 }	 default: {	// unexpected interrupt - just make sure they are off!        DIS_INTERRUPTS;	// disable and clear all interrupts	 }	}}/* direct port r/w */static int csp0rw_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){   D(printk("csp0rw_ioctl cmd= %x, arg= %x\n\r",cmd,arg));   D(printk("csp0rw_ioctl:  ((int *)file->private_data)[0]= %x\n\r",((int *)file->private_data)[0]));	if(_IOC_TYPE(cmd) != CMOSCAM_IOCTYPE) {		return -EINVAL;	}	if (_IOC_NR(cmd) == IO_CCAM_CR_SHADOW) {//		return (long ) ccam_cr_shadow;// could not make ioctl to return 32 bits - all negative become -1// so I'll throw away bit 30 and use it to return bit 31		return (long ) ((ccam_cr_shadow & 0x3fffffff) | ((ccam_cr_shadow >>1) & 0x40000000));	}	if (( _IOC_NR(cmd) == IO_CCAM_CR_MODIFY ) |//	    ( _IOC_NR(cmd) == IO_CCAM_START_DMA ) |	    ( _IOC_NR(cmd) == IO_CCAM_STOP_DMA )  |	    ( _IOC_NR(cmd) == IO_CCAM_MONITOR_DMA_DESCR )  |	    ( _IOC_NR(cmd) == IO_CCAM_MONITOR_DMA_BUFFER ) |	    ( _IOC_NR(cmd) == IO_CCAM_EXPOSE )  |	    ( _IOC_NR(cmd) == IO_CCAM_EXPOS_END ) |	    ( _IOC_NR(cmd) == IO_CCAM_EXPOS_START ) |	    ( _IOC_NR(cmd) == IO_CCAM_SET_EXT_EXPOSURE ) |	    ( _IOC_NR(cmd) == IO_CCAM_MONITOR_SEQ ) ) {		return ccam_DMA_ioctl (inode,file,cmd,arg);	}	switch (_IOC_CSP0RW_CMD(cmd)) {		case IO_CSP0_R:			return (long ) port_csp0_addr[_IOC_CSP0RW_ADR(cmd)];		case IO_CSP0_W:			if ((_IOC_CSP0RW_ADR(cmd) & 3) == 1)				ccamCRAndOr(0, arg);			else port_csp0_addr[_IOC_CSP0RW_ADR(cmd)]=arg;			break;		default:			return -EINVAL;	}		return 0;}static int ccam_DMA_ioctl(struct inode *inode, struct file *file,unsigned int cmd, unsigned long arg) {//  unsigned char i2cdata[2];  unsigned long flags;	  int i1;//  printk("_IOC_NR(cmd)=%lx", _IOC_NR(cmd));	switch(_IOC_NR(cmd)){	  case IO_CCAM_MONITOR_SEQ : {//    printk("IO_CCAM_MONITOR_SEQ\r\n");		return (arg)? getCamSeqCount(): getCamSeqState();	   }	  case IO_CCAM_SET_EXT_EXPOSURE : {//    printk("IO_CCAM_SET_EXT_EXPOSURE\r\n");	     blFrame=(arg==2)?1:0;	     setCamSeq(arg? 1:0);	// was arg	     return 0;	   }	  case IO_CCAM_CR_MODIFY : {		save_flags(flags);		cli();		i1=((ccam_cr_shadow & (1<<(arg>>2)))!=0);		switch (arg & 3) {		  case 1: {ccam_cr_shadow &= ~(1<<(arg>>2));break;}		  case 2: {ccam_cr_shadow |=  (1<<(arg>>2));break;}		  case 3: {ccam_cr_shadow ^=  (1<<(arg>>2));break;}		}		port_csp0_addr[CCAM_WA_WCTL]= ccam_cr_shadow;		restore_flags(flags);		return i1;	   }	  case IO_CCAM_MONITOR_DMA_DESCR : {//   printk("CCAM_MONITOR_DMA_DESCR [%lx] = %lx\r\n", arg, ( (unsigned long *) &ccam_dma_descr[0])[arg]);	     return (arg < (CCAM_DESCR_SIZE <<2)) ? (( (long *) &ccam_dma_descr[0])[arg] & 0x7fffffff):-EINVAL;//	     return ( (unsigned long *) &ccam_dma_descr[0])[arg];	   }	  case IO_CCAM_MONITOR_DMA_BUFFER :	     return (arg < CCAM_DMA_SIZE )        ? (( (long *) &ccam_dma_buf[0])[arg] & 0x7fffffff):-EINVAL;	  case IO_CCAM_STOP_DMA : {	     FPGA_DMA_STOP ;	     EXT_DMA_0_STOP ;		 RESET_DMA( 5 );		 WAIT_DMA( 5 );	  }	  case IO_CCAM_EXPOS_START :		   CCAM_MRST_OFF ;		   udelay (1);	  	   CCAM_ARO_OFF ;		   CCAM_ARST_ON ;		   udelay (1);		   CCAM_ARST_OFF ;		   i1=arg;//  printk ("i1= %lx\r\n",i1);		   if (i1>100000) i1=100000;	// 1 sec		   for (;i1>0;i1--) udelay (10);		   return 0;

⌨️ 快捷键说明

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