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

📄 hwdrv_apci3120.c

📁 最新版comedi的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
                 		if ((!int_daq)&&(!(int_amcc&ANY_S593X_INT))) 	{    		comedi_error(dev,"IRQ from unknow source");		return;	}		outl(int_amcc|0x00ff0000, devpriv->i_IobaseAmcc+AMCC_OP_REG_INTCSR);// shutdown IRQ reasons in AMCC                int_daq = (int_daq >> 12) & 0xF;        	 	   	if(devpriv->b_ExttrigEnable == APCI3120_ENABLE)	{		//Disable ext trigger		i_APCI3120_ExttrigDisable(dev);		devpriv->b_ExttrigEnable = APCI3120_DISABLE;	}		//clear the timer 2 interrupt	inb(devpriv->i_IobaseAmcc+ APCI3120_TIMER_STATUS_REGISTER);	if (int_amcc&MASTER_ABORT_INT)    		comedi_error(dev,"AMCC IRQ - MASTER DMA ABORT!");	if (int_amcc&TARGET_ABORT_INT)    		comedi_error(dev,"AMCC IRQ - TARGET DMA ABORT!");	          // Ckeck if EOC interrupt	if(((int_daq & 0x8) == 0) && (devpriv->b_InterruptMode==APCI3120_EOC_MODE))	   {               if(devpriv->b_EocEosInterrupt==APCI3120_ENABLE)                 {                                          	// Read the AI Value             	               		            devpriv->ui_AiReadData[0]=(UINT)inw(devpriv->iobase+0);       			devpriv->b_EocEosInterrupt = APCI3120_DISABLE;                 	send_sig(SIGIO,devpriv->tsk_Current,0); // send signal to the sample                 }                 else                 {                  	//Disable EOC Interrupt                 	devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister & APCI3120_DISABLE_EOC_INT;                 	outb(devpriv->b_ModeSelectRegister,devpriv->iobase+APCI3120_WRITE_MODE_SELECT);                                    }           }	  	// Check If EOS interrupt 	  	 if( (int_daq & 0x2) && (devpriv->b_InterruptMode==APCI3120_EOS_MODE) )   	   {               		                if(devpriv->b_EocEosInterrupt==APCI3120_ENABLE)// enable this in without DMA ???                 {                                        if(devpriv->b_AiCyclicAcquisition==APCI3120_ENABLE)                      {	                 	ui_Check=0;  		 			i_APCI3120_InterruptHandleEos(dev);		 	 		devpriv->ui_AiActualScan++;	 	 			devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister | APCI3120_ENABLE_EOS_INT;      		        	outb(devpriv->b_ModeSelectRegister,dev->iobase+APCI3120_WRITE_MODE_SELECT);                        }                       else                       { 					ui_Check=0;                       		for(i=0;i< devpriv->ui_AiNbrofChannels;i++)                          	{                                     us_TmpValue=inw(devpriv->iobase+0);                          	 	devpriv->ui_AiReadData[i]=(UINT) us_TmpValue;                         					}                        		devpriv->b_EocEosInterrupt = APCI3120_DISABLE;                       		devpriv->b_InterruptMode=APCI3120_EOC_MODE;                       		                       		send_sig(SIGIO,devpriv->tsk_Current,0); // send signal to the sample                                          }                  }                else                  {                  		devpriv->b_ModeSelectRegister= devpriv->b_ModeSelectRegister & APCI3120_DISABLE_EOS_INT;                 		outb(devpriv->b_ModeSelectRegister,dev->iobase+APCI3120_WRITE_MODE_SELECT);                   		devpriv->b_EocEosInterrupt = APCI3120_DISABLE; //Default settings                  		devpriv->b_InterruptMode=APCI3120_EOC_MODE;                  }	       }    		//Timer2 interrupt		if(int_daq & 0x1)	  	{	      			   	       		switch(devpriv->b_Timer2Mode)		 	{  		     case APCI3120_COUNTER:                                                devpriv->b_AiCyclicAcquisition=APCI3120_DISABLE;                       	devpriv->b_ModeSelectRegister= devpriv->b_ModeSelectRegister & APCI3120_DISABLE_EOS_INT;                        outb(devpriv->b_ModeSelectRegister,dev->iobase+APCI3120_WRITE_MODE_SELECT);		                           // stop timer 2                             devpriv->us_OutputRegister=devpriv->us_OutputRegister & APCI3120_DISABLE_ALL_TIMER;	                outw(devpriv->us_OutputRegister,dev->iobase+APCI3120_WR_ADDRESS);                        //stop timer 0 and timer 1		        i_APCI3120_StopCyclicAcquisition(dev,s);                        devpriv->b_AiCyclicAcquisition=APCI3120_DISABLE;                        			//UPDATE-0.7.57->0.7.68comedi_done(dev,s); 			s->async->events |= COMEDI_CB_EOA;			comedi_event(dev,s,s->async->events);								        break;					                         		     case APCI3120_TIMER:			  	//Send a signal to from kernel to user space			   	send_sig(SIGIO,devpriv->tsk_Current,0);                         break;                       		     case APCI3120_WATCHDOG:                        //Send a signal to from kernel to user space			    send_sig(SIGIO,devpriv->tsk_Current,0);                         break;                       		     default :		      	                          // disable Timer Interrupt                         				devpriv->b_ModeSelectRegister = devpriv-> b_ModeSelectRegister & APCI3120_DISABLE_TIMER_INT; 				 				outb(devpriv->b_ModeSelectRegister,	dev->iobase+ APCI3120_WRITE_MODE_SELECT);		   		                   		                                                                 }	       	       b_DummyRead= inb(dev->iobase+APCI3120_TIMER_STATUS_REGISTER);	       	  }  		if ((int_daq & 0x4) &&(devpriv->b_InterruptMode == APCI3120_DMA_MODE))	  {                if(devpriv->b_AiCyclicAcquisition==APCI3120_ENABLE) 	      	{		    			/****************************/	   		/* Clear Timer Write TC INT */	   		/****************************/        		outl(APCI3120_CLEAR_WRITE_TC_INT,devpriv->i_IobaseAmcc+ APCI3120_AMCC_OP_REG_INTCSR);            		/************************************/	   		/* Clears the timer status register */	   		/************************************/	   		inw(dev->iobase+APCI3120_TIMER_STATUS_REGISTER);             			v_APCI3120_InterruptDma(irq,d,regs); // do some data transfer		}                else                {		/* Stops the Timer */		outw(devpriv->us_OutputRegister & APCI3120_DISABLE_TIMER0 & APCI3120_DISABLE_TIMER1,dev->iobase+APCI3120_WR_ADDRESS);                }          }           	   return;}/*+----------------------------------------------------------------------------+| Function name     :int i_APCI3120_InterruptHandleEos(comedi_device *dev)   ||                                        									 ||                                            						         |+----------------------------------------------------------------------------+| Task              : This function handles EOS interrupt.                   ||                     This function copies the acquired data(from FIFO)      ||				to Comedi buffer.		 							 ||                     										                 |+----------------------------------------------------------------------------+| Input Parameters  : comedi_device *dev									 ||                     														 ||                                                 					         |+----------------------------------------------------------------------------+| Return Value      : 0            					                         ||                    													     |+----------------------------------------------------------------------------+*//*int i_APCI3120_InterruptHandleEos(comedi_device *dev){         int n_chan,i;       sampl_t *data;       comedi_subdevice *s=dev->subdevices+0;       comedi_async *async = s->async;       data=async->data+async->buf_int_ptr;//new samples added from here onwards       n_chan=devpriv->ui_AiNbrofChannels;              for(i=0;i<n_chan;i++)         {            data[i]=inw(dev->iobase+0);         }       async->buf_int_count+=n_chan*sizeof(sampl_t);       async->buf_int_ptr+=n_chan*sizeof(sampl_t);       comedi_eos(dev,s);       if (s->async->buf_int_ptr>=s->async->data_len) //  for buffer rool over           { */	        /* buffer rollover *//*	        s->async->buf_int_ptr=0;		comedi_eobuf(dev,s);         } 	return 0;}*/  int i_APCI3120_InterruptHandleEos(comedi_device *dev){         int n_chan,i;       comedi_subdevice *s=dev->subdevices+0;       int err=1;              n_chan=devpriv->ui_AiNbrofChannels;              s->async->events = 0;              for(i=0;i<n_chan;i++)                  err &= comedi_buf_put(s->async, inw(dev->iobase+0));                s->async->events |= COMEDI_CB_EOS;               		if (err==0)	   s->async->events |= COMEDI_CB_OVERFLOW;	        comedi_event(dev,s,s->async->events);	          	return 0;}/*+----------------------------------------------------------------------------+| Function name     : void v_APCI3120_InterruptDma(int irq, void *d,         ||			 struct pt_regs *regs) 									 ||                                        									 |+----------------------------------------------------------------------------+| Task              : This is a handler for the DMA interrupt                ||			  This function copies the data to Comedi Buffer.        ||			  For continuous DMA it reinitializes the DMA operation. ||			  For single mode DMA it stop the acquisition.           ||													     			 |+----------------------------------------------------------------------------+| Input Parameters  : int irq, void *d, struct pt_regs *regs				 ||                     														 |+----------------------------------------------------------------------------+| Return Value      :  void        					                         ||                    													     |+----------------------------------------------------------------------------+*/ void v_APCI3120_InterruptDma(int irq, void *d, struct pt_regs *regs) {    	comedi_device *dev = d;	comedi_subdevice *s = dev->subdevices + 0;		unsigned int next_dma_buf, samplesinbuf;	unsigned long low_word,high_word,var;		UINT ui_Tmp;              	samplesinbuf=devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer]-inl(devpriv->i_IobaseAmcc+AMCC_OP_REG_MWTC);		if (samplesinbuf<devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer]) 	{	    comedi_error(dev,"Interrupted DMA transfer!");	}	if (samplesinbuf & 1) 	{	        comedi_error(dev,"Odd count of bytes in DMA ring!");		i_APCI3120_StopCyclicAcquisition(dev,s);                devpriv->b_AiCyclicAcquisition=APCI3120_DISABLE;		return;	}	samplesinbuf=samplesinbuf>>1;	// number of received samples	if (devpriv->b_DmaDoubleBuffer) 	{		// switch DMA buffers if is used double buffering		next_dma_buf=1-devpriv->ui_DmaActualBuffer;				ui_Tmp=AGCSTS_TC_ENABLE  | AGCSTS_RESET_A2P_FIFO ;		outl(ui_Tmp,devpriv->i_IobaseAddon+AMCC_OP_REG_AGCSTS);						// changed  since 16 bit interface for add on		outw(APCI3120_ADD_ON_AGCSTS_LOW,devpriv->i_IobaseAddon+0);		outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW,devpriv->i_IobaseAddon+2);		outw(APCI3120_ADD_ON_AGCSTS_HIGH,devpriv->i_IobaseAddon+0);		outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH ,devpriv->i_IobaseAddon+2); // 0x1000 is out putted in windows driver 				var=devpriv->ul_DmaBufferHw[next_dma_buf];        	low_word=var & 0xffff;		var=devpriv->ul_DmaBufferHw[next_dma_buf];		high_word=var /65536;				/* DMA Start Adress Low */		outw(APCI3120_ADD_ON_MWAR_LOW,devpriv->i_IobaseAddon+0);		outw(low_word,devpriv->i_IobaseAddon+2);				/* DMA Start Adress High */		outw(APCI3120_ADD_ON_MWAR_HIGH,devpriv->i_IobaseAddon+0);		outw(high_word,devpriv->i_IobaseAddon+2);				var=devpriv->ui_DmaBufferUsesize[next_dma_buf];				low_word=var & 0xffff;		var=devpriv->ui_DmaBufferUsesize[next_dma_buf];		high_word=var /65536;				/* Nbr of acquisition LOW */		outw(APCI3120_ADD_ON_MWTC_LOW,devpriv->i_IobaseAddon+0);		outw(low_word,devpriv->i_IobaseAddon+2);				/* Nbr of acquisition HIGH */		outw(APCI3120_ADD_ON_MWTC_HIGH,devpriv->i_IobaseAddon+0);		outw(high_word,devpriv->i_IobaseAddon+2);				// To configure A2P FIFO 		// ENABLE A2P FIFO WRITE AND ENABLE AMWEN 		// AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03		outw(3,devpriv->i_IobaseAddon + 4);		//initialise end of dma interrupt  AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI)    		outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2| APCI3120_ENABLE_WRITE_TC_INT), devpriv->i_IobaseAmcc+AMCC_OP_REG_INTCSR);	                   	}/*UPDATE-0.7.57->0.7.68		ptr=(sampl_t *)devpriv->ul_DmaBufferVirtual[devpriv->ui_DmaActualBuffer];		// if there is not enough space left in the buffer to copy all data contained in the DMABufferVirtual	if(s->async->buf_int_ptr+samplesinbuf*sizeof(sampl_t)>=devpriv->ui_AiDataLength)	{		m=(devpriv->ui_AiDataLength-s->async->buf_int_ptr)/sizeof(sampl_t);		v_APCI3120_InterruptDmaMoveBlock16bit(dev,s,(void *)ptr,((void *)(devpriv->AiData))+s->async->buf_int_ptr,m); 		s->async->buf_int_count+=m*sizeof(sampl_t);		ptr+=m*sizeof(sampl_t);                samplesinbuf-=m;		s->async->buf_int

⌨️ 快捷键说明

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