📄 hwdrv_apci1500.c
字号:
/**@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 Dieselstraße 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-1500 | Compiler : GCC | | Module name : hwdrv_apci1500.c| Version : 2.96 | +-------------------------------+---------------------------------------+ | Project manager: Eric Stolz | Date : 02/12/2002 | +-------------------------------+---------------------------------------+ | Description : Hardware Layer Acces For APCI-1500 | +-----------------------------------------------------------------------+ | UPDATES | +----------+-----------+------------------------------------------------+ | Date | Author | Description of updates | +----------+-----------+------------------------------------------------+ | | | | | | | | | | | | +----------+-----------+------------------------------------------------+*/#include "hwdrv_apci1500.h"int i_TimerCounter1Init=0;int i_TimerCounter2Init=0;int i_WatchdogCounter3Init=0;int i_Event1Status=0,i_Event2Status=0;int i_TimerCounterWatchdogInterrupt=0;int i_Logic=0,i_CounterLogic=0;int i_InterruptMask=0;int i_InputChannel=0; int i_TimerCounter1Enabled=0, i_TimerCounter2Enabled=0,i_WatchdogCounter3Enabled=0;/* +----------------------------------------------------------------------------+| Function Name : int i_APCI1500_ConfigDigitalInputEvent || (comedi_device *dev,comedi_subdevice *s, | | comedi_insn *insn,lsampl_t *data) |+----------------------------------------------------------------------------+| Task : An event can be generated for each port. || The first event is related to the first 8 channels || (port 1) and the second to the following 6 channels || (port 2). An interrupt is generated when one or both || events have occurred |+----------------------------------------------------------------------------+| Input Parameters : comedi_device *dev : Driver handle || lsampl_t *data : Data Pointer contains || configuration parameters as below || | | data[0] :Number of the input port on || which the event will take place || (1 or 2) data[1] : The event logic for port 1 has || three possibilities || :0 APCI1500_AND :This logic || links || the inputs || with an AND || logic. || 1 APCI1500_OR :This logic || links || the inputs || with a || OR logic. || 2 APCI1500_OR_PRIORITY || :This logic || links || the inputs || with a || priority || OR logic. || Input 1 || has the || highest || priority || level and || input 8 || the smallest|| For the second port the user has|| 1 possibility: || APCI1500_OR :This logic || links || the inputs || with a || polarity || OR logic || data[2] : These 8-character word for port1|| and 6-character word for port 2 || give the mask of the event. || Each place gives the state || of the input channels and can || have one of these six characters|| || 0 : This input must be on 0 || 1 : This input must be on 1 || 2 : This input reacts to || a falling edge || 3 : This input reacts to a || rising edge || 4 : This input reacts to both edges || | 5 : This input is not || used for event |+----------------------------------------------------------------------------+| Output Parameters : -- |+----------------------------------------------------------------------------+| Return Value : TRUE : No error occur || : FALSE : Error occur. Return the error || |+----------------------------------------------------------------------------+*/INT i_APCI1500_ConfigDigitalInputEvent(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data){int i_PatternPolarity=0,i_PatternTransition=0,i_PatternMask=0;int i_MaxChannel=0,i_Count=0,i_EventMask=0;int i_PatternTransitionCount=0,i_RegValue;int i; /*************************************************/ /* Selects the master interrupt control register */ /*************************************************/ outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER); /**********************************************/ /* Disables the main interrupt on the board */ /**********************************************/ outb(0x00,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER); if (data[0] == 1) { i_MaxChannel = 8; }// if (data[0] == 1) else { if(data[0]==2) { i_MaxChannel = 6; }// if(data[0]==2) else { printk("\nThe specified port event does not exist\n"); return -EINVAL; }//else if(data[0]==2) }//else if (data[0] == 1)switch(data[1]) { case 0: data[1]= APCI1500_AND; break; case 1: data[1]= APCI1500_OR; break; case 2: data[1]= APCI1500_OR_PRIORITY; break; default:printk("\nThe specified interrupt logic does not exist\n"); return -EINVAL; }//switch(data[1]); i_Logic=data[1]; for (i_Count = i_MaxChannel,i=0; i_Count >0;i_Count --,i++) { i_EventMask=data[2+i]; switch(i_EventMask) { case 0 : i_PatternMask = i_PatternMask | (1 << (i_MaxChannel-i_Count)); break; case 1 : i_PatternMask = i_PatternMask | (1 << (i_MaxChannel-i_Count)); i_PatternPolarity = i_PatternPolarity |(1 << (i_MaxChannel-i_Count)); break; case 2 : i_PatternMask = i_PatternMask |(1 << (i_MaxChannel-i_Count)); i_PatternTransition = i_PatternTransition |(1 << (i_MaxChannel-i_Count)); break; case 3 : i_PatternMask = i_PatternMask | (1 << (i_MaxChannel-i_Count)); i_PatternPolarity = i_PatternPolarity |(1 << (i_MaxChannel-i_Count)); i_PatternTransition = i_PatternTransition |(1 << (i_MaxChannel-i_Count)); break; case 4 : i_PatternTransition = i_PatternTransition |(1 << (i_MaxChannel-i_Count)); break; case 5 : break; default : printk("\nThe option indicated in the event mask does not exist\n"); return -EINVAL; }// switch(i_EventMask) }//for (i_Count = i_MaxChannel; i_Count >0;i_Count --) if (data[0]== 1) { /****************************/ /* Test the interrupt logic */ /****************************/ if (data[1] == APCI1500_AND || data[1] == APCI1500_OR || data[1] == APCI1500_OR_PRIORITY) { /**************************************/ /* Tests if a transition was declared */ /* for a OR PRIORITY logic */ /**************************************/ if (data[1]== APCI1500_OR_PRIORITY && i_PatternTransition != 0) { /********************************************/ /* Transition error on an OR PRIORITY logic */ /********************************************/ printk("\nTransition error on an OR PRIORITY logic\n"); return -EINVAL; }// if (data[1]== APCI1500_OR_PRIORITY && i_PatternTransition != 0) /*************************************/ /* Tests if more than one transition */ /* was declared for an AND logic */ /*************************************/ if (data[1]== APCI1500_AND) { for (i_Count = 0; i_Count < 8; i_Count++) { i_PatternTransitionCount=i_PatternTransitionCount+((i_PatternTransition>>i_Count)&0x1); } //for (i_Count = 0; i_Count < 8; i_Count++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -