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

📄 hwdrv_apci3120.c

📁 最新版comedi的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/**@verbatimCopyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.                 ADDI-DATA GmbH         Dieselstrasse 3         D-77833 Ottersweier         Tel: +19(0)7223/9493-0         Fax: +49(0)7223/9493-92         http://www.addi-data-com         info@addi-data.com This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USAYou shoud also find the complete GPL in the COPYING file accompanying this source code.@endverbatim*//*  +-----------------------------------------------------------------------+  | (C) ADDI-DATA GmbH          Dieselstrasse 3      D-77833 Ottersweier  |  +-----------------------------------------------------------------------+  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |  +-----------------------------------------------------------------------+  | Project     : APCI-3120       | Compiler   : GCC                      |  | Module name : hwdrv_apci3120.c| Version    : 2.96                     |  +-------------------------------+---------------------------------------+  | Project manager: Eric Stolz   | Date       :  02/12/2002              |  +-----------------------------------------------------------------------+  | Description :APCI3120 Module.  Hardware abstraction Layer for APCI3120|  +-----------------------------------------------------------------------+  |                             UPDATE'S                                  |  +-----------------------------------------------------------------------+  |   Date   |   Author  |          Description of updates                |  +----------+-----------+------------------------------------------------+  |          | 		 | 						  |  |          |           |						  |  +----------+-----------+------------------------------------------------+*/#include "hwdrv_apci3120.h"static UINT ui_Temp=0;// FUNCTION DEFINITIONS/*+----------------------------------------------------------------------------+|                           ANALOG INPUT SUBDEVICE   		                 |+----------------------------------------------------------------------------+*//*+----------------------------------------------------------------------------+| Function name     :int i_APCI3120_InsnConfigAnalogInput(comedi_device *dev,||  comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)					 ||                                            						         |+----------------------------------------------------------------------------+| Task              : Calls card specific function  					     ||                     										                 |+----------------------------------------------------------------------------+| Input Parameters  : comedi_device *dev									 ||                     comedi_subdevice *s									 ||                     comedi_insn *insn                                      ||                     lsampl_t *data      					         		 |+----------------------------------------------------------------------------+| Return Value      :              					                         ||                    													     |+----------------------------------------------------------------------------+*/int i_APCI3120_InsnConfigAnalogInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,																			lsampl_t *data){        UINT i;	if((data[0] != APCI3120_EOC_MODE) && (data[0] != APCI3120_EOS_MODE))        return -1 ;                         // Check for Conversion time to be added ??          devpriv->ui_EocEosConversionTime=data[2];                  if(data[0] == APCI3120_EOS_MODE)           {                                 //Test the number of the channel	      for(i=0;i<data[3];i++)		 {			if(CR_CHAN(data[4+i])>=this_board->i_NbrAiChannel)   		       {                          printk("bad channel list\n");                           return -2;		       }		 }                                      devpriv->b_InterruptMode= APCI3120_EOS_MODE;                                   if(data[1])                 {                     devpriv->b_EocEosInterrupt=APCI3120_ENABLE;                     }                  else   devpriv->b_EocEosInterrupt=APCI3120_DISABLE;                                                          // Copy channel list and Range List to devpriv                                      devpriv->ui_AiNbrofChannels= data[3];               for(i=0;i< devpriv->ui_AiNbrofChannels;i++)                  {                       devpriv->ui_AiChannelList[i]=data[4+i];                  }                                                       }         else // EOC           {               devpriv->b_InterruptMode=APCI3120_EOC_MODE;                 if(data[1])                  {                     devpriv->b_EocEosInterrupt=APCI3120_ENABLE;                      }               else                   {                      devpriv->b_EocEosInterrupt=APCI3120_DISABLE;                  }              } 	return insn->n;}/*+----------------------------------------------------------------------------+| Function name     :int i_APCI3120_InsnReadAnalogInput(comedi_device *dev,  ||			comedi_subdevice *s,comedi_insn *insn, lsampl_t *data)	 | |                                            						         |+----------------------------------------------------------------------------+| Task              :  card specific function								 ||				Reads analog input in synchronous mode               ||			  EOC and EOS is selected as per configured              ||                     if no conversion time is set uses default conversion   ||			  time 10 microsec.					      				 ||                     										                 |+----------------------------------------------------------------------------+| Input Parameters  : comedi_device *dev									 ||                     comedi_subdevice *s									 ||                     comedi_insn *insn                                      ||                     lsampl_t *data     									 |+----------------------------------------------------------------------------+| Return Value      :              					                         ||                    													     |+----------------------------------------------------------------------------+*/int i_APCI3120_InsnReadAnalogInput(comedi_device *dev, comedi_subdevice *s, 													comedi_insn *insn, lsampl_t *data){ 	USHORT us_ConvertTiming,us_TmpValue,i;	BYTE b_Tmp;	// fix convertion time to 10 us      	if(!devpriv->ui_EocEosConversionTime)         {          printk("No timer0 Value using 10 us\n");                     us_ConvertTiming=10;        }      	else us_ConvertTiming =(USHORT) (devpriv->ui_EocEosConversionTime/1000);// nano to useconds                       // this_board->i_hwdrv_InsnReadAnalogInput(dev,us_ConvertTiming,insn->n,&insn->chanspec,data,insn->unused[0]);	// Clear software registers        devpriv->b_TimerSelectMode=0;        devpriv->b_ModeSelectRegister=0;        devpriv->us_OutputRegister=0;//        devpriv->b_DigitalOutputRegister=0;        if(insn->unused[0]==222)// second insn read        {                        for(i=0;i< insn->n;i++)            {                data[i]=devpriv->ui_AiReadData[i];            }            	 	}        else        {    	    devpriv->tsk_Current=current; // Save the current process task structure	    //Testing if board have the new Quartz and calculate the time value 	    //to set in the timer	                	    us_TmpValue=(USHORT) inw(devpriv->iobase+APCI3120_RD_STATUS);	    	    //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") )	       {		    us_ConvertTiming=(us_ConvertTiming * 2) -2;		    	       }	    else	       {			us_ConvertTiming=((us_ConvertTiming * 12926)/10000) -1;        		               }     	    us_TmpValue=(USHORT)devpriv->b_InterruptMode; 	                switch(us_TmpValue)               {        	case APCI3120_EOC_MODE:          						// Testing the interrupt flag and set the EOC bit			// Clears the FIFO			inw(devpriv->iobase+APCI3120_RESET_FIFO);						// Initialize the sequence array			//if (!i_APCI3120_SetupChannelList(dev,s,1,chanlist,0))  return -EINVAL;	                                         if (!i_APCI3120_SetupChannelList(dev,s,1,&insn->chanspec,0))  return -EINVAL;	    			//Initialize Timer 0 mode 4	 		devpriv->b_TimerSelectMode=(devpriv->b_TimerSelectMode & 0xFC) |APCI3120_TIMER_0_MODE_4;			outb(devpriv->b_TimerSelectMode,devpriv->iobase+APCI3120_TIMER_CRT1);			// Reset the scan bit and Disables the  EOS, DMA, EOC interrupt        		devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister & APCI3120_DISABLE_SCAN;       			if(devpriv->b_EocEosInterrupt==APCI3120_ENABLE)          		{            			              			//Disables the EOS,DMA and enables the EOC interrupt             			devpriv->b_ModeSelectRegister=(devpriv->b_ModeSelectRegister & APCI3120_DISABLE_EOS_INT) | APCI3120_ENABLE_EOC_INT;             			inw(devpriv->iobase);             			          		}        		else          		{             			devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister & APCI3120_DISABLE_ALL_INTERRUPT_WITHOUT_TIMER;          		}          				outb(devpriv->b_ModeSelectRegister,devpriv->iobase+APCI3120_WRITE_MODE_SELECT);			// Sets gate 0 			devpriv->us_OutputRegister=(devpriv->us_OutputRegister & APCI3120_CLEAR_PA_PR) | APCI3120_ENABLE_TIMER0;			outw(devpriv->us_OutputRegister,devpriv->iobase+APCI3120_WR_ADDRESS);			// Select Timer 0			b_Tmp=((devpriv->b_DigitalOutputRegister) & 0xF0) | APCI3120_SELECT_TIMER_0_WORD;			outb(b_Tmp,devpriv->iobase+APCI3120_TIMER_CRT0);			//Set the convertion time        		outw(us_ConvertTiming,devpriv->iobase+APCI3120_TIMER_VALUE);        		us_TmpValue=(USHORT) inw(dev->iobase+APCI3120_RD_STATUS);       	        		if(devpriv->b_EocEosInterrupt==APCI3120_DISABLE)        		{	  			do	    			{					// Waiting for the end of conversion					us_TmpValue=inw(devpriv->iobase+APCI3120_RD_STATUS);	    			}while((us_TmpValue & APCI3120_EOC)==APCI3120_EOC);			  	 			//Read the result in FIFO  and put it in insn data pointer	 			us_TmpValue=inw(devpriv->iobase+0);	 			*data=us_TmpValue;         	 			inw(devpriv->iobase+APCI3120_RESET_FIFO);        		}                		break;        		case APCI3120_EOS_MODE:                     		inw(devpriv->iobase);          		// Clears the FIFO			inw(devpriv->iobase+APCI3120_RESET_FIFO);                    // clear PA PR  and disable timer 0                    devpriv->us_OutputRegister=(devpriv->us_OutputRegister & APCI3120_CLEAR_PA_PR) | APCI3120_DISABLE_TIMER0;                    						outw(devpriv->us_OutputRegister,devpriv->iobase+APCI3120_WR_ADDRESS);						if (!i_APCI3120_SetupChannelList(dev,s,devpriv->ui_AiNbrofChannels,devpriv->ui_AiChannelList,0))  		return -EINVAL;			//Initialize Timer 0 mode 2			devpriv->b_TimerSelectMode = (devpriv->b_TimerSelectMode & 0xFC) | APCI3120_TIMER_0_MODE_2;			outb(devpriv->b_TimerSelectMode,devpriv->iobase+APCI3120_TIMER_CRT1);						//Select Timer 0			b_Tmp=((devpriv->b_DigitalOutputRegister) & 0xF0) | APCI3120_SELECT_TIMER_0_WORD;        		outb(b_Tmp,devpriv->iobase+APCI3120_TIMER_CRT0);					//Set the convertion time        		outw(us_ConvertTiming,devpriv->iobase+APCI3120_TIMER_VALUE);        			//Set the scan bit			devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister | APCI3120_ENABLE_SCAN;        		outb(devpriv->b_ModeSelectRegister,devpriv->iobase+APCI3120_WRITE_MODE_SELECT);			        		//If Interrupt function is loaded         		if(devpriv->b_EocEosInterrupt==APCI3120_ENABLE)           		{              			//Disables the EOC,DMA and enables the EOS interrupt              			devpriv->b_ModeSelectRegister=(devpriv->b_ModeSelectRegister & APCI3120_DISABLE_EOC_INT) | APCI3120_ENABLE_EOS_INT;              			inw(devpriv->iobase);	                                                                        		}        		else    	      		devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister & APCI3120_DISABLE_ALL_INTERRUPT_WITHOUT_TIMER;                        		outb(devpriv->b_ModeSelectRegister,devpriv->iobase+APCI3120_WRITE_MODE_SELECT);        		inw(devpriv->iobase+APCI3120_RD_STATUS);                        		//Sets gate 0 				                devpriv->us_OutputRegister=devpriv->us_OutputRegister  | APCI3120_ENABLE_TIMER0;			outw(devpriv->us_OutputRegister,devpriv->iobase+APCI3120_WR_ADDRESS);        		//Start conversion        		outw(0,devpriv->iobase+APCI3120_START_CONVERSION);                       		//Waiting of end of convertion if interrupt is not installed        		if(devpriv->b_EocEosInterrupt==APCI3120_DISABLE)           		{              			//Waiting the end of convertion              			do                                  		{                   			us_TmpValue=inw(devpriv->iobase+APCI3120_RD_STATUS);

⌨️ 快捷键说明

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