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

📄 hwdrv_apci3120.c

📁 最新版comedi的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
|                    													     |+----------------------------------------------------------------------------+*/int i_APCI3120_CyclicAnalogInput(int mode, comedi_device * dev,comedi_subdevice * s){        	BYTE b_Tmp;	UINT ui_Tmp,ui_DelayTiming=0,ui_TimerValue1=0,dmalen0=0,dmalen1=0,ui_TimerValue2=0,ui_TimerValue0,ui_ConvertTiming;	USHORT us_TmpValue;	//BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver	    //devpriv->b_AiCyclicAcquisition=APCI3120_ENABLE;		//END JK 07.05.04: Comparison between WIN32 and Linux driver		/*******************/	/* Resets the FIFO */	/*******************/    inb(dev->iobase + APCI3120_RESET_FIFO);      	//BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver	//inw(dev->iobase+APCI3120_RD_STATUS);	//END JK 07.05.04: Comparison between WIN32 and Linux driver		/***************************/	/* Acquisition initialized */	/***************************/		//BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver	    devpriv->b_AiCyclicAcquisition = APCI3120_ENABLE;		//END JK 07.05.04: Comparison between WIN32 and Linux driver            // clear software  registers    devpriv->b_TimerSelectMode=0;    devpriv->us_OutputRegister=0;	devpriv->b_ModeSelectRegister=0;	//devpriv->b_DigitalOutputRegister=0;		   	//COMMENT JK 07.05.04: Followings calls are in i_APCI3120_StartAnalogInputAcquisition	   /****************************/   /* Clear Timer Write TC INT */   /****************************/   outl(APCI3120_CLEAR_WRITE_TC_INT,devpriv->i_IobaseAmcc+ APCI3120_AMCC_OP_REG_INTCSR);   /************************************/   /* Clears the timer status register */   /************************************/   //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver   //inw(dev->iobase+APCI3120_TIMER_STATUS_REGISTER);   inb(dev->iobase+APCI3120_TIMER_STATUS_REGISTER);   //END JK 07.05.04: Comparison between WIN32 and Linux driver   /**************************/   /* Disables All Timer     */   /* Sets PR and PA to 0    */   /**************************/	      devpriv->us_OutputRegister = devpriv->us_OutputRegister &                                 APCI3120_DISABLE_TIMER0 &                                 APCI3120_DISABLE_TIMER1 &                                APCI3120_CLEAR_PA_PR;                                   outw(devpriv->us_OutputRegister,dev->iobase + APCI3120_WR_ADDRESS);   /*******************/   /* Resets the FIFO */   /*******************/   //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver   inb (devpriv->iobase + APCI3120_RESET_FIFO);   //END JK 07.05.04: Comparison between WIN32 and Linux driver      devpriv->ui_AiActualScan=0;   devpriv->ui_AiActualScanPosition=0;   s->async->cur_chan=0;   devpriv->ui_AiBufferPtr=0;   devpriv->ui_DmaActualBuffer=0;   // value for timer2  minus -2 has to be done .....dunno y??      ui_TimerValue2 = devpriv->ui_AiNbrofScans-2;    ui_ConvertTiming=devpriv->ui_AiTimer0;  	  if (mode==2) 	     ui_DelayTiming =  devpriv->ui_AiTimer1;    /**********************************/   /* Initializes the sequence array */   /**********************************/	  if (!i_APCI3120_SetupChannelList(dev, s, devpriv->ui_AiNbrofChannels, devpriv->pui_AiChannelList, 0)) 	     return -EINVAL;	 us_TmpValue=(USHORT) inw(dev->iobase+APCI3120_RD_STATUS);  /*** EL241003 : add this section in comment because floats must not be used	 	 if((us_TmpValue & 0x00B0)==0x00B0)	 {                  f_ConvertValue=(((float)ui_ConvertTiming * 0.002) - 2);		ui_TimerValue0=(UINT)f_ConvertValue;		if (mode==2)		{			f_DelayValue     = (((float)ui_DelayTiming * 0.00002) - 2);			ui_TimerValue1  =   (UINT) f_DelayValue;		}	 }   	 else	 {		f_ConvertValue=(((float)ui_ConvertTiming * 0.0012926) - 1);		ui_TimerValue0=(UINT)f_ConvertValue;		if (mode == 2)		{		     f_DelayValue     = (((float)ui_DelayTiming * 0.000012926) - 1);		     ui_TimerValue1  =   (UINT) f_DelayValue;		}	}***********************************************************************************************//*** EL241003 Begin : add this section to replace floats calculation by integer calculations **/	//EL250804: Testing if board APCI3120 have the new Quartz or if it is an APCI3001	if((us_TmpValue & 0x00B0)==0x00B0 || !strcmp(this_board->pc_DriverName,"apci3001") )	   {            ui_TimerValue0 = ui_ConvertTiming * 2 - 2000;	    ui_TimerValue0 = ui_TimerValue0 / 1000;	    	    if (mode==2)	       {	       ui_DelayTiming = ui_DelayTiming / 1000;	       ui_TimerValue1 = ui_DelayTiming * 2 - 200;	       ui_TimerValue1 = ui_TimerValue1 / 100;	       }	    }   	 else	    {	    ui_ConvertTiming = ui_ConvertTiming / 1000;	    ui_TimerValue0 = ui_ConvertTiming * 12926 - 10000;	    ui_TimerValue0 = ui_TimerValue0 / 10000;	    	    if (mode == 2)	       {	       ui_DelayTiming = ui_DelayTiming / 1000;	       ui_TimerValue1 = ui_DelayTiming * 12926 -1;	       ui_TimerValue1 = ui_TimerValue1 / 1000000;	       }	    }/*** EL241003 End ******************************************************************************/              	if(devpriv->b_ExttrigEnable==APCI3120_ENABLE)	{	        i_APCI3120_ExttrigEnable(dev);	// activate EXT trigger	}	switch(mode)	{	  case 1:	    	// init timer0 in mode 2 	    	devpriv->b_TimerSelectMode=(devpriv->b_TimerSelectMode& 0xFC) | APCI3120_TIMER_0_MODE_2;	    	outb(devpriv->b_TimerSelectMode,dev->iobase+APCI3120_TIMER_CRT1);		//Select Timer 0		b_Tmp=((devpriv->b_DigitalOutputRegister) & 0xF0) | APCI3120_SELECT_TIMER_0_WORD;		outb(b_Tmp,dev->iobase+APCI3120_TIMER_CRT0);		//Set the convertion time		outw(((USHORT)ui_TimerValue0),dev->iobase+APCI3120_TIMER_VALUE);		break;	  case 2:	    	// init timer1 in mode 2 	    	devpriv->b_TimerSelectMode=(devpriv->b_TimerSelectMode& 0xF3) | APCI3120_TIMER_1_MODE_2;		outb(devpriv->b_TimerSelectMode,dev->iobase+APCI3120_TIMER_CRT1);		//Select Timer 1		b_Tmp=((devpriv->b_DigitalOutputRegister) & 0xF0) | APCI3120_SELECT_TIMER_1_WORD;		outb(b_Tmp,dev->iobase+APCI3120_TIMER_CRT0);		//Set the convertion time		outw(((USHORT)ui_TimerValue1),dev->iobase+APCI3120_TIMER_VALUE);		// init timer0 in mode 2 		devpriv->b_TimerSelectMode=(devpriv->b_TimerSelectMode& 0xFC) | APCI3120_TIMER_0_MODE_2;		outb(devpriv->b_TimerSelectMode,dev->iobase+APCI3120_TIMER_CRT1);			//Select Timer 0		b_Tmp=((devpriv->b_DigitalOutputRegister) & 0xF0) | APCI3120_SELECT_TIMER_0_WORD;		outb(b_Tmp,dev->iobase+APCI3120_TIMER_CRT0);						//Set the convertion time		outw(((USHORT)ui_TimerValue0),dev->iobase+APCI3120_TIMER_VALUE);		break;    	}	//   ##########common for all modes#################	/***********************/	/* Clears the SCAN bit */	/***********************/    //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver	    //devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister | APCI3120_DISABLE_SCAN;    devpriv->b_ModeSelectRegister = devpriv->b_ModeSelectRegister &                                     APCI3120_DISABLE_SCAN;    //END JK 07.05.04: Comparison between WIN32 and Linux driver                                    	outb(devpriv->b_ModeSelectRegister,dev->iobase+APCI3120_WRITE_MODE_SELECT);	// If DMA is disabled  	if(devpriv->us_UseDma==APCI3120_DISABLE)	 	  { 		// disable EOC and enable EOS                devpriv->b_InterruptMode=APCI3120_EOS_MODE;		devpriv->b_EocEosInterrupt=APCI3120_ENABLE;	        devpriv->b_ModeSelectRegister = (devpriv->b_ModeSelectRegister & APCI3120_DISABLE_EOC_INT) | APCI3120_ENABLE_EOS_INT;			outb(devpriv->b_ModeSelectRegister,dev->iobase+APCI3120_WRITE_MODE_SELECT);                		if (!devpriv->b_AiContinuous) 		  {		       // configure Timer2 For counting  EOS        		       //Reset gate 2 of Timer 2 to disable it (Set Bit D14 to 0)		       devpriv->us_OutputRegister=devpriv->us_OutputRegister & APCI3120_DISABLE_TIMER2 ;		       outw(devpriv->us_OutputRegister,dev->iobase+APCI3120_WR_ADDRESS);	    		       // DISABLE TIMER INTERRUPT 		       devpriv->b_ModeSelectRegister = devpriv->b_ModeSelectRegister & APCI3120_DISABLE_TIMER_INT & 0xEF;		       outb(devpriv->b_ModeSelectRegister,dev->iobase + APCI3120_WRITE_MODE_SELECT);			  		       //(1) Init timer 2 in mode 0 and write timer value		       devpriv->b_TimerSelectMode=(devpriv->b_TimerSelectMode & 0x0F) | APCI3120_TIMER_2_MODE_0;		       outb(devpriv->b_TimerSelectMode,dev->iobase+APCI3120_TIMER_CRT1);         		       //Writing LOW WORD		       b_Tmp=((devpriv->b_DigitalOutputRegister) & 0xF0) | APCI3120_SELECT_TIMER_2_LOW_WORD;		       outb(b_Tmp,dev->iobase+APCI3120_TIMER_CRT0);		       outw(LOWORD(ui_TimerValue2),dev->iobase+APCI3120_TIMER_VALUE);              		       //Writing HIGH WORD		       b_Tmp=((devpriv->b_DigitalOutputRegister) & 0xF0) | APCI3120_SELECT_TIMER_2_HIGH_WORD;		       outb(b_Tmp,dev->iobase+APCI3120_TIMER_CRT0);		       outw(HIWORD(ui_TimerValue2),dev->iobase+APCI3120_TIMER_VALUE);		       //(2) Reset FC_TIMER BIT  Clearing timer status register		       inb(dev->iobase+APCI3120_TIMER_STATUS_REGISTER);		       // enable timer counter and disable watch dog		       devpriv->b_ModeSelectRegister=(devpriv->b_ModeSelectRegister| APCI3120_ENABLE_TIMER_COUNTER) & APCI3120_DISABLE_WATCHDOG;		       // select EOS clock input for timer 2		       devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister| APCI3120_TIMER2_SELECT_EOS;		       // Enable timer2  interrupt		       devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister| APCI3120_ENABLE_TIMER_INT;		       outb(devpriv->b_ModeSelectRegister,dev->iobase+APCI3120_WRITE_MODE_SELECT);		       devpriv->b_Timer2Mode=APCI3120_COUNTER;		       devpriv->b_Timer2Interrupt=APCI3120_ENABLE;		  }	  }	else 	  {        // If DMA Enabled        //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver                //inw(dev->iobase+0);// reset EOC bit           //END JK 07.05.04: Comparison between WIN32 and Linux driver       devpriv->b_InterruptMode=APCI3120_DMA_MODE;      /************************************/	  /* Disables the EOC, EOS interrupt  */	  /************************************/		      devpriv->b_ModeSelectRegister = devpriv->b_ModeSelectRegister &                                       APCI3120_DISABLE_EOC_INT &                                       APCI3120_DISABLE_EOS_INT;               		outb(devpriv->b_ModeSelectRegister,dev->iobase+APCI3120_WRITE_MODE_SELECT);               		dmalen0=devpriv->ui_DmaBufferSize[0];		dmalen1=devpriv->ui_DmaBufferSize[1];				if (!devpriv->b_AiContinuous) 		{			if (dmalen0>(devpriv->ui_AiNbrofScans*devpriv->ui_AiScanLength*2))			{	// must we fill full first buffer?				dmalen0=devpriv->ui_AiNbrofScans*devpriv->ui_AiScanLength*2;			} 			else			if (dmalen1>(devpriv->ui_AiNbrofScans*devpriv->ui_AiScanLength*2-dmalen0)) 	// and must we fill full second buffer when first is once filled?				dmalen1=devpriv->ui_AiNbrofScans*devpriv->ui_AiScanLength*2-dmalen0;		}		if (devpriv->ui_AiFlags & TRIG_WAKE_EOS) 		{			// don't we want wake up every scan?			if (dmalen0>(devpriv->ui_AiScanLength*2)) 			{				dmalen0=devpriv->ui_AiScanLength*2;				if (devpriv->ui_AiScanLength&1) dmalen0+=2;			}			if (dmalen1>(devpriv->ui_AiScanLength*2)) 			{				dmalen1=devpriv->ui_AiScanLength*2;				if (devpriv->ui_AiScanLength&1) dmalen1-=2;				if (dmalen1<4) dmalen1=4;			}		} 		else 		{				// isn't output buff smaller that our DMA buff?			if (dmalen0>(devpriv->ui_AiDataLength)) 			{				dmalen0=devpriv->ui_AiDataLength;			}			if (dmalen1>(devpriv->ui_AiDataLength)) 			{				dmalen1=devpriv->ui_AiDataLength;			}		}		devpriv->ui_DmaBufferUsesize[0]=dmalen0;		devpriv->ui_DmaBufferUsesize[1]=dmalen1;				//Initialize DMA 				// Set Transfer count enable bit and A2P_fifo reset bit in AGCSTS register		//1		ui_Tmp=AGCSTS_TC_ENABLE  | AGCSTS_RESET_A2P_FIFO ;		outl(ui_Tmp,devpriv->i_IobaseAmcc+AMCC_OP_REG_AGCSTS);        		// changed  since 16 bit interface for add on		/*********************/ 		/* ENABLE BUS MASTER */		/*********************/				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); 				// TO VERIFIED		//BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver				outw(0x1000,devpriv->i_IobaseAddon+2); 				//END JK 07.05.04: Comparison between WIN32 and Linux driver			        	        	//2  No change		// A2P FIFO MANAGEMENT	    // A2P fifo reset  & transfer control enable		 /***********************/		 /* A2P FIFO MANAGEMENT */		 /***********************/	    		outl(APCI3120_A2P_FIFO_MANAGEMENT,devpriv->i_IobaseAmcc + 		                                           APCI3120_AMCC_OP_MCSR);		//3		//beginning address of dma buf 		//The 32 bit address of dma buffer is converted into two 16 bit addresses        	// Can done by using _attach and put into into an array		// array used may be for differnet pages 			// DMA Start Adress Low 		outw(APCI3120_ADD_ON_MWAR_LOW,devpriv->i_IobaseAddon+0);		outw((devpriv->ul_DmaBufferHw[0]& 0xFFFF),devpriv->i_IobaseAddon+2);		 /*************************/		 /* DMA Start Adress High */		 /*************************/	

⌨️ 快捷键说明

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