| /** |
| @verbatim |
| |
| Copyright (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 USA |
| |
| You should 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 : API APCI1710 | Compiler : gcc | |
| | Module name : DIG_IO.C | Version : 2.96 | |
| +-------------------------------+---------------------------------------+ |
| | Project manager: Eric Stolz | Date : 02/12/2002 | |
| +-----------------------------------------------------------------------+ |
| | Description : APCI-1710 digital I/O module | |
| | | |
| | | |
| +-----------------------------------------------------------------------+ |
| | UPDATES | |
| +-----------------------------------------------------------------------+ |
| | Date | Author | Description of updates | |
| +----------+-----------+------------------------------------------------+ |
| | 16/06/98 | S. Weber | Digital input / output implementation | |
| |----------|-----------|------------------------------------------------| |
| | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 | |
| | | | available | |
| +-----------------------------------------------------------------------+ |
| | | | | |
| | | | | |
| +-----------------------------------------------------------------------+ |
| */ |
| |
| /* Digital Output ON or OFF */ |
| #define APCI1710_ON 1 |
| #define APCI1710_OFF 0 |
| |
| /* Digital I/O */ |
| #define APCI1710_INPUT 0 |
| #define APCI1710_OUTPUT 1 |
| |
| #define APCI1710_DIGIO_MEMORYONOFF 0x10 |
| #define APCI1710_DIGIO_INIT 0x11 |
| |
| /* |
| +----------------------------------------------------------------------------+ |
| | Function Name : int i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev, | |
| | struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)| |
| +----------------------------------------------------------------------------+ |
| | Task : Configure the digital I/O operating mode from selected | |
| | module (b_ModulNbr). You must calling this function be| |
| | for you call any other function witch access of digital| |
| | I/O. | |
| +----------------------------------------------------------------------------+ |
| | Input Parameters : | |
| | unsigned char_ b_ModulNbr data[0]: Module number to | |
| | configure (0 to 3) | |
| | unsigned char_ b_ChannelAMode data[1] : Channel A mode selection | |
| | 0 : Channel used for digital | |
| | input | |
| | 1 : Channel used for digital | |
| | output | |
| | unsigned char_ b_ChannelBMode data[2] : Channel B mode selection | |
| | 0 : Channel used for digital | |
| | input | |
| | 1 : Channel used for digital | |
| | output | |
| data[0] memory on/off |
| Activates and deactivates the digital output memory. |
| After having | |
| | called up this function with memory on,the output you have previously| |
| | activated with the function are not reset |
| +----------------------------------------------------------------------------+ |
| | Output Parameters : - | |
| +----------------------------------------------------------------------------+ |
| | Return Value : 0: No error | |
| | -1: The handle parameter of the board is wrong | |
| | -2: The module parameter is wrong | |
| | -3: The module is not a digital I/O module | |
| | -4: Bi-directional channel A configuration error | |
| | -5: Bi-directional channel B configuration error | |
| +----------------------------------------------------------------------------+ |
| */ |
| |
| static int i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev, |
| struct comedi_subdevice *s, |
| struct comedi_insn *insn, |
| unsigned int *data) |
| { |
| struct addi_private *devpriv = dev->private; |
| unsigned char b_ModulNbr, b_ChannelAMode, b_ChannelBMode; |
| unsigned char b_MemoryOnOff, b_ConfigType; |
| int i_ReturnValue = 0; |
| unsigned int dw_WriteConfig = 0; |
| |
| b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec); |
| b_ConfigType = (unsigned char) data[0]; /* Memory or Init */ |
| b_ChannelAMode = (unsigned char) data[1]; |
| b_ChannelBMode = (unsigned char) data[2]; |
| b_MemoryOnOff = (unsigned char) data[1]; /* if memory operation */ |
| i_ReturnValue = insn->n; |
| |
| /**************************/ |
| /* Test the module number */ |
| /**************************/ |
| |
| if (b_ModulNbr >= 4) { |
| DPRINTK("Module Number invalid\n"); |
| i_ReturnValue = -2; |
| return i_ReturnValue; |
| } |
| switch (b_ConfigType) { |
| case APCI1710_DIGIO_MEMORYONOFF: |
| |
| if (b_MemoryOnOff) /* If Memory ON */ |
| { |
| /****************************/ |
| /* Set the output memory on */ |
| /****************************/ |
| |
| devpriv->s_ModuleInfo[b_ModulNbr]. |
| s_DigitalIOInfo.b_OutputMemoryEnabled = 1; |
| |
| /***************************/ |
| /* Clear the output memory */ |
| /***************************/ |
| devpriv->s_ModuleInfo[b_ModulNbr]. |
| s_DigitalIOInfo.dw_OutputMemory = 0; |
| } else /* If memory off */ |
| { |
| /*****************************/ |
| /* Set the output memory off */ |
| /*****************************/ |
| |
| devpriv->s_ModuleInfo[b_ModulNbr]. |
| s_DigitalIOInfo.b_OutputMemoryEnabled = 0; |
| } |
| break; |
| |
| case APCI1710_DIGIO_INIT: |
| |
| /*******************************/ |
| /* Test if digital I/O counter */ |
| /*******************************/ |
| |
| if ((devpriv->s_BoardInfos. |
| dw_MolduleConfiguration[b_ModulNbr] & |
| 0xFFFF0000UL) == APCI1710_DIGITAL_IO) { |
| |
| /***************************************************/ |
| /* Test the bi-directional channel A configuration */ |
| /***************************************************/ |
| |
| if ((b_ChannelAMode == 0) || (b_ChannelAMode == 1)) { |
| /***************************************************/ |
| /* Test the bi-directional channel B configuration */ |
| /***************************************************/ |
| |
| if ((b_ChannelBMode == 0) |
| || (b_ChannelBMode == 1)) { |
| devpriv->s_ModuleInfo[b_ModulNbr]. |
| s_DigitalIOInfo.b_DigitalInit = |
| 1; |
| |
| /********************************/ |
| /* Save channel A configuration */ |
| /********************************/ |
| |
| devpriv->s_ModuleInfo[b_ModulNbr]. |
| s_DigitalIOInfo. |
| b_ChannelAMode = b_ChannelAMode; |
| |
| /********************************/ |
| /* Save channel B configuration */ |
| /********************************/ |
| |
| devpriv->s_ModuleInfo[b_ModulNbr]. |
| s_DigitalIOInfo. |
| b_ChannelBMode = b_ChannelBMode; |
| |
| /*****************************************/ |
| /* Set the channel A and B configuration */ |
| /*****************************************/ |
| |
| dw_WriteConfig = |
| (unsigned int) (b_ChannelAMode | |
| (b_ChannelBMode * 2)); |
| |
| /***************************/ |
| /* Write the configuration */ |
| /***************************/ |
| |
| outl(dw_WriteConfig, |
| devpriv->s_BoardInfos. |
| ui_Address + 4 + |
| (64 * b_ModulNbr)); |
| |
| } else { |
| /************************************************/ |
| /* Bi-directional channel B configuration error */ |
| /************************************************/ |
| DPRINTK("Bi-directional channel B configuration error\n"); |
| i_ReturnValue = -5; |
| } |
| |
| } else { |
| /************************************************/ |
| /* Bi-directional channel A configuration error */ |
| /************************************************/ |
| DPRINTK("Bi-directional channel A configuration error\n"); |
| i_ReturnValue = -4; |
| |
| } |
| |
| } else { |
| /******************************************/ |
| /* The module is not a digital I/O module */ |
| /******************************************/ |
| DPRINTK("The module is not a digital I/O module\n"); |
| i_ReturnValue = -3; |
| } |
| } /* end of Switch */ |
| printk("Return Value %d\n", i_ReturnValue); |
| return i_ReturnValue; |
| } |
| |
| /* |
| +----------------------------------------------------------------------------+ |
| | INPUT FUNCTIONS | |
| +----------------------------------------------------------------------------+ |
| */ |
| |
| /* |
| +----------------------------------------------------------------------------+ |
| |
| |INT i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev,comedi_subdevice |
| *s, struct comedi_insn *insn,unsigned int *data) |
| |
| +----------------------------------------------------------------------------+ |
| | Task : Read the status from selected digital I/O digital input| |
| | (b_InputChannel) | |
| +----------------------------------------------------------------------------| |
| |
| |
| | |
| | unsigned char_ b_ModulNbr CR_AREF(chanspec) : Selected module number | |
| | (0 to 3) | |
| | unsigned char_ b_InputChannel CR_CHAN(chanspec) : Selection from digital | |
| | input ( 0 to 6) | |
| | 0 : Channel C | |
| | 1 : Channel D | |
| | 2 : Channel E | |
| | 3 : Channel F | |
| | 4 : Channel G | |
| | 5 : Channel A | |
| | 6 : Channel B |
| |
| |
| | |
| +----------------------------------------------------------------------------+ |
| | Output Parameters : data[0] : Digital input channel | |
| | status | |
| | 0 : Channle is not active| |
| | 1 : Channle is active | |
| +----------------------------------------------------------------------------+ |
| | Return Value : 0: No error | |
| | -1: The handle parameter of the board is wrong | |
| | -2: The module parameter is wrong | |
| | -3: The module is not a digital I/O module | |
| | -4: The selected digital I/O digital input is wrong | |
| | -5: Digital I/O not initialised | |
| | -6: The digital channel A is used for output | |
| | -7: The digital channel B is used for output | |
| +----------------------------------------------------------------------------+ |
| */ |
| |
| /* _INT_ i_APCI1710_ReadDigitalIOChlValue (unsigned char_ b_BoardHandle, */ |
| /* |
| * unsigned char_ b_ModulNbr, unsigned char_ b_InputChannel, |
| * unsigned char *_ pb_ChannelStatus) |
| */ |
| static int i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev, |
| struct comedi_subdevice *s, |
| struct comedi_insn *insn, |
| unsigned int *data) |
| { |
| struct addi_private *devpriv = dev->private; |
| int i_ReturnValue = 0; |
| unsigned int dw_StatusReg; |
| unsigned char b_ModulNbr, b_InputChannel; |
| unsigned char *pb_ChannelStatus; |
| b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec); |
| b_InputChannel = (unsigned char) CR_CHAN(insn->chanspec); |
| data[0] = 0; |
| pb_ChannelStatus = (unsigned char *) &data[0]; |
| i_ReturnValue = insn->n; |
| |
| /**************************/ |
| /* Test the module number */ |
| /**************************/ |
| |
| if (b_ModulNbr < 4) { |
| /*******************************/ |
| /* Test if digital I/O counter */ |
| /*******************************/ |
| |
| if ((devpriv->s_BoardInfos. |
| dw_MolduleConfiguration[b_ModulNbr] & |
| 0xFFFF0000UL) == APCI1710_DIGITAL_IO) { |
| /******************************************/ |
| /* Test the digital imnput channel number */ |
| /******************************************/ |
| |
| if (b_InputChannel <= 6) { |
| /**********************************************/ |
| /* Test if the digital I/O module initialised */ |
| /**********************************************/ |
| |
| if (devpriv->s_ModuleInfo[b_ModulNbr]. |
| s_DigitalIOInfo.b_DigitalInit == 1) { |
| /**********************************/ |
| /* Test if channel A or channel B */ |
| /**********************************/ |
| |
| if (b_InputChannel > 4) { |
| /*********************/ |
| /* Test if channel A */ |
| /*********************/ |
| |
| if (b_InputChannel == 5) { |
| /***************************/ |
| /* Test the channel A mode */ |
| /***************************/ |
| |
| if (devpriv-> |
| s_ModuleInfo |
| [b_ModulNbr]. |
| s_DigitalIOInfo. |
| b_ChannelAMode |
| != 0) { |
| /********************************************/ |
| /* The digital channel A is used for output */ |
| /********************************************/ |
| |
| i_ReturnValue = |
| -6; |
| } |
| } /* if (b_InputChannel == 5) */ |
| else { |
| /***************************/ |
| /* Test the channel B mode */ |
| /***************************/ |
| |
| if (devpriv-> |
| s_ModuleInfo |
| [b_ModulNbr]. |
| s_DigitalIOInfo. |
| b_ChannelBMode |
| != 0) { |
| /********************************************/ |
| /* The digital channel B is used for output */ |
| /********************************************/ |
| |
| i_ReturnValue = |
| -7; |
| } |
| } /* if (b_InputChannel == 5) */ |
| } /* if (b_InputChannel > 4) */ |
| |
| /***********************/ |
| /* Test if error occur */ |
| /***********************/ |
| |
| if (i_ReturnValue >= 0) { |
| /**************************/ |
| /* Read all digital input */ |
| /**************************/ |
| |
| /* |
| * INPDW (ps_APCI1710Variable-> s_Board [b_BoardHandle]. |
| * s_BoardInfos. ui_Address + (64 * b_ModulNbr), &dw_StatusReg); |
| */ |
| |
| dw_StatusReg = |
| inl(devpriv-> |
| s_BoardInfos. |
| ui_Address + |
| (64 * b_ModulNbr)); |
| |
| *pb_ChannelStatus = |
| (unsigned char) ((dw_StatusReg ^ |
| 0x1C) >> |
| b_InputChannel) & 1; |
| |
| } /* if (i_ReturnValue == 0) */ |
| } else { |
| /*******************************/ |
| /* Digital I/O not initialised */ |
| /*******************************/ |
| DPRINTK("Digital I/O not initialised\n"); |
| i_ReturnValue = -5; |
| } |
| } else { |
| /********************************/ |
| /* Selected digital input error */ |
| /********************************/ |
| DPRINTK("Selected digital input error\n"); |
| i_ReturnValue = -4; |
| } |
| } else { |
| /******************************************/ |
| /* The module is not a digital I/O module */ |
| /******************************************/ |
| DPRINTK("The module is not a digital I/O module\n"); |
| i_ReturnValue = -3; |
| } |
| } else { |
| /***********************/ |
| /* Module number error */ |
| /***********************/ |
| DPRINTK("Module number error\n"); |
| i_ReturnValue = -2; |
| } |
| |
| return i_ReturnValue; |
| } |
| |
| /* |
| +----------------------------------------------------------------------------+ |
| | OUTPUT FUNCTIONS | |
| +----------------------------------------------------------------------------+ |
| */ |
| |
| /* |
| +----------------------------------------------------------------------------+ |
| | Function Name : int i_APCI1710_InsnWriteDigitalIOChlOnOff(comedi_device |
| |*dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
| |
| +----------------------------------------------------------------------------+ |
| | Task : Sets or resets the output witch has been passed with the | |
| | parameter b_Channel. Setting an output means setting | |
| | an ouput high. | |
| +----------------------------------------------------------------------------+ |
| | Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 | |
| | unsigned char_ b_ModulNbr (aref ) : Selected module number (0 to 3)| |
| | unsigned char_ b_OutputChannel (CR_CHAN) : Selection from digital output | |
| | channel (0 to 2) | |
| | 0 : Channel H | |
| | 1 : Channel A | |
| | 2 : Channel B | |
| +----------------------------------------------------------------------------+ |
| | Output Parameters : - | |
| +----------------------------------------------------------------------------+ |
| | Return Value : 0: No error | |
| | -1: The handle parameter of the board is wrong | |
| | -2: The module parameter is wrong | |
| | -3: The module is not a digital I/O module | |
| | -4: The selected digital output is wrong | |
| | -5: digital I/O not initialised see function | |
| | " i_APCI1710_InitDigitalIO" | |
| | -6: The digital channel A is used for input | |
| | -7: The digital channel B is used for input |
| -8: Digital Output Memory OFF. | |
| | Use previously the function | |
| | "i_APCI1710_SetDigitalIOMemoryOn". | |
| +----------------------------------------------------------------------------+ |
| */ |
| |
| /* |
| * _INT_ i_APCI1710_SetDigitalIOChlOn (unsigned char_ b_BoardHandle, |
| * unsigned char_ b_ModulNbr, unsigned char_ b_OutputChannel) |
| */ |
| static int i_APCI1710_InsnWriteDigitalIOChlOnOff(struct comedi_device *dev, |
| struct comedi_subdevice *s, |
| struct comedi_insn *insn, |
| unsigned int *data) |
| { |
| struct addi_private *devpriv = dev->private; |
| int i_ReturnValue = 0; |
| unsigned int dw_WriteValue = 0; |
| unsigned char b_ModulNbr, b_OutputChannel; |
| i_ReturnValue = insn->n; |
| b_ModulNbr = CR_AREF(insn->chanspec); |
| b_OutputChannel = CR_CHAN(insn->chanspec); |
| |
| /**************************/ |
| /* Test the module number */ |
| /**************************/ |
| |
| if (b_ModulNbr < 4) { |
| /*******************************/ |
| /* Test if digital I/O counter */ |
| /*******************************/ |
| |
| if ((devpriv->s_BoardInfos. |
| dw_MolduleConfiguration[b_ModulNbr] & |
| 0xFFFF0000UL) == APCI1710_DIGITAL_IO) { |
| /**********************************************/ |
| /* Test if the digital I/O module initialised */ |
| /**********************************************/ |
| |
| if (devpriv->s_ModuleInfo[b_ModulNbr]. |
| s_DigitalIOInfo.b_DigitalInit == 1) { |
| /******************************************/ |
| /* Test the digital output channel number */ |
| /******************************************/ |
| |
| switch (b_OutputChannel) { |
| /*************/ |
| /* Channel H */ |
| /*************/ |
| |
| case 0: |
| break; |
| |
| /*************/ |
| /* Channel A */ |
| /*************/ |
| |
| case 1: |
| if (devpriv->s_ModuleInfo[b_ModulNbr]. |
| s_DigitalIOInfo. |
| b_ChannelAMode != 1) { |
| /*******************************************/ |
| /* The digital channel A is used for input */ |
| /*******************************************/ |
| |
| i_ReturnValue = -6; |
| } |
| break; |
| |
| /*************/ |
| /* Channel B */ |
| /*************/ |
| |
| case 2: |
| if (devpriv->s_ModuleInfo[b_ModulNbr]. |
| s_DigitalIOInfo. |
| b_ChannelBMode != 1) { |
| /*******************************************/ |
| /* The digital channel B is used for input */ |
| /*******************************************/ |
| |
| i_ReturnValue = -7; |
| } |
| break; |
| |
| default: |
| /****************************************/ |
| /* The selected digital output is wrong */ |
| /****************************************/ |
| |
| i_ReturnValue = -4; |
| break; |
| } |
| |
| /***********************/ |
| /* Test if error occur */ |
| /***********************/ |
| |
| if (i_ReturnValue >= 0) { |
| |
| /*********************************/ |
| /* Test if set channel ON */ |
| /*********************************/ |
| if (data[0]) { |
| /*********************************/ |
| /* Test if output memory enabled */ |
| /*********************************/ |
| |
| if (devpriv-> |
| s_ModuleInfo |
| [b_ModulNbr]. |
| s_DigitalIOInfo. |
| b_OutputMemoryEnabled == |
| 1) { |
| dw_WriteValue = |
| devpriv-> |
| s_ModuleInfo |
| [b_ModulNbr]. |
| s_DigitalIOInfo. |
| dw_OutputMemory |
| | (1 << |
| b_OutputChannel); |
| |
| devpriv-> |
| s_ModuleInfo |
| [b_ModulNbr]. |
| s_DigitalIOInfo. |
| dw_OutputMemory |
| = dw_WriteValue; |
| } else { |
| dw_WriteValue = |
| 1 << |
| b_OutputChannel; |
| } |
| } /* set channel off */ |
| else { |
| if (devpriv-> |
| s_ModuleInfo |
| [b_ModulNbr]. |
| s_DigitalIOInfo. |
| b_OutputMemoryEnabled == |
| 1) { |
| dw_WriteValue = |
| devpriv-> |
| s_ModuleInfo |
| [b_ModulNbr]. |
| s_DigitalIOInfo. |
| dw_OutputMemory |
| & (0xFFFFFFFFUL |
| - |
| (1 << b_OutputChannel)); |
| |
| devpriv-> |
| s_ModuleInfo |
| [b_ModulNbr]. |
| s_DigitalIOInfo. |
| dw_OutputMemory |
| = dw_WriteValue; |
| } else { |
| /*****************************/ |
| /* Digital Output Memory OFF */ |
| /*****************************/ |
| /* +Use previously the function "i_APCI1710_SetDigitalIOMemoryOn" */ |
| i_ReturnValue = -8; |
| } |
| |
| } |
| /*******************/ |
| /* Write the value */ |
| /*******************/ |
| |
| /* OUTPDW (ps_APCI1710Variable-> |
| * s_Board [b_BoardHandle]. |
| * s_BoardInfos. ui_Address + (64 * b_ModulNbr), |
| * dw_WriteValue); |
| */ |
| */ |
| outl(dw_WriteValue, |
| devpriv->s_BoardInfos. |
| ui_Address + (64 * b_ModulNbr)); |
| } |
| } else { |
| /*******************************/ |
| /* Digital I/O not initialised */ |
| /*******************************/ |
| |
| i_ReturnValue = -5; |
| } |
| } else { |
| /******************************************/ |
| /* The module is not a digital I/O module */ |
| /******************************************/ |
| |
| i_ReturnValue = -3; |
| } |
| } else { |
| /***********************/ |
| /* Module number error */ |
| /***********************/ |
| |
| i_ReturnValue = -2; |
| } |
| |
| return i_ReturnValue; |
| } |
| |
| /* |
| +----------------------------------------------------------------------------+ |
| |
| |INT i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device *dev,comedi_subdevice |
| *s, struct comedi_insn *insn,unsigned int *data) |
| +----------------------------------------------------------------------------+ |
| | Task : write: |
| Sets or resets one or several outputs from port. | |
| | Setting an output means setting an output high. | |
| | If you have switched OFF the digital output memory | |
| | (OFF), all the other output are set to "0". |
| |
| | read: |
| Read the status from digital input port | |
| | from selected digital I/O module (b_ModulNbr) |
| +----------------------------------------------------------------------------+ |
| | Input Parameters : |
| unsigned char_ b_BoardHandle : Handle of board APCI-1710 | |
| | unsigned char_ b_ModulNbr CR_AREF(aref) : Selected module number (0 to 3)| |
| | unsigned char_ b_PortValue CR_CHAN(chanspec) : Output Value ( 0 To 7 ) |
| | data[0] read or write port |
| | data[1] if write then indicate ON or OFF |
| |
| | if read : data[1] will return port status. |
| +----------------------------------------------------------------------------+ |
| | Output Parameters : - | |
| +----------------------------------------------------------------------------+ |
| | Return Value : |
| |
| | INPUT : |
| |
| 0: No error | |
| | -1: The handle parameter of the board is wrong | |
| | -2: The module parameter is wrong | |
| | -3: The module is not a digital I/O module | |
| | -4: Digital I/O not initialised |
| |
| OUTPUT: 0: No error | |
| | -1: The handle parameter of the board is wrong | |
| | -2: The module parameter is wrong | |
| | -3: The module is not a digital I/O module | |
| | -4: Output value wrong | |
| | -5: digital I/O not initialised see function | |
| | " i_APCI1710_InitDigitalIO" | |
| | -6: The digital channel A is used for input | |
| | -7: The digital channel B is used for input |
| -8: Digital Output Memory OFF. | |
| | Use previously the function | |
| | "i_APCI1710_SetDigitalIOMemoryOn". | |
| +----------------------------------------------------------------------------+ |
| */ |
| |
| /* |
| * _INT_ i_APCI1710_SetDigitalIOPortOn (unsigned char_ |
| * b_BoardHandle, unsigned char_ b_ModulNbr, unsigned char_ |
| * b_PortValue) |
| */ |
| static int i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device *dev, |
| struct comedi_subdevice *s, |
| struct comedi_insn *insn, |
| unsigned int *data) |
| { |
| struct addi_private *devpriv = dev->private; |
| int i_ReturnValue = 0; |
| unsigned int dw_WriteValue = 0; |
| unsigned int dw_StatusReg; |
| unsigned char b_ModulNbr, b_PortValue; |
| unsigned char b_PortOperation, b_PortOnOFF; |
| |
| unsigned char *pb_PortValue; |
| |
| b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec); |
| b_PortOperation = (unsigned char) data[0]; /* Input or output */ |
| b_PortOnOFF = (unsigned char) data[1]; /* if output then On or Off */ |
| b_PortValue = (unsigned char) data[2]; /* if out put then Value */ |
| i_ReturnValue = insn->n; |
| pb_PortValue = (unsigned char *) &data[0]; |
| /* if input then read value */ |
| |
| switch (b_PortOperation) { |
| case APCI1710_INPUT: |
| /**************************/ |
| /* Test the module number */ |
| /**************************/ |
| |
| if (b_ModulNbr < 4) { |
| /*******************************/ |
| /* Test if digital I/O counter */ |
| /*******************************/ |
| |
| if ((devpriv->s_BoardInfos. |
| dw_MolduleConfiguration[b_ModulNbr] & |
| 0xFFFF0000UL) == APCI1710_DIGITAL_IO) { |
| /**********************************************/ |
| /* Test if the digital I/O module initialised */ |
| /**********************************************/ |
| |
| if (devpriv->s_ModuleInfo[b_ModulNbr]. |
| s_DigitalIOInfo.b_DigitalInit == 1) { |
| /**************************/ |
| /* Read all digital input */ |
| /**************************/ |
| |
| /* INPDW (ps_APCI1710Variable-> |
| * s_Board [b_BoardHandle]. |
| * s_BoardInfos. |
| * ui_Address + (64 * b_ModulNbr), |
| * &dw_StatusReg); |
| */ |
| |
| dw_StatusReg = |
| inl(devpriv->s_BoardInfos. |
| ui_Address + (64 * b_ModulNbr)); |
| *pb_PortValue = |
| (unsigned char) (dw_StatusReg ^ 0x1C); |
| |
| } else { |
| /*******************************/ |
| /* Digital I/O not initialised */ |
| /*******************************/ |
| |
| i_ReturnValue = -4; |
| } |
| } else { |
| /******************************************/ |
| /* The module is not a digital I/O module */ |
| /******************************************/ |
| |
| i_ReturnValue = -3; |
| } |
| } else { |
| /***********************/ |
| /* Module number error */ |
| /***********************/ |
| |
| i_ReturnValue = -2; |
| } |
| |
| break; |
| |
| case APCI1710_OUTPUT: |
| /**************************/ |
| /* Test the module number */ |
| /**************************/ |
| |
| if (b_ModulNbr < 4) { |
| /*******************************/ |
| /* Test if digital I/O counter */ |
| /*******************************/ |
| |
| if ((devpriv->s_BoardInfos. |
| dw_MolduleConfiguration[b_ModulNbr] & |
| 0xFFFF0000UL) == APCI1710_DIGITAL_IO) { |
| /**********************************************/ |
| /* Test if the digital I/O module initialised */ |
| /**********************************************/ |
| |
| if (devpriv->s_ModuleInfo[b_ModulNbr]. |
| s_DigitalIOInfo.b_DigitalInit == 1) { |
| /***********************/ |
| /* Test the port value */ |
| /***********************/ |
| |
| if (b_PortValue <= 7) { |
| /***********************************/ |
| /* Test the digital output channel */ |
| /***********************************/ |
| |
| /**************************/ |
| /* Test if channel A used */ |
| /**************************/ |
| |
| if ((b_PortValue & 2) == 2) { |
| if (devpriv-> |
| s_ModuleInfo |
| [b_ModulNbr]. |
| s_DigitalIOInfo. |
| b_ChannelAMode |
| != 1) { |
| /*******************************************/ |
| /* The digital channel A is used for input */ |
| /*******************************************/ |
| |
| i_ReturnValue = |
| -6; |
| } |
| } /* if ((b_PortValue & 2) == 2) */ |
| |
| /**************************/ |
| /* Test if channel B used */ |
| /**************************/ |
| |
| if ((b_PortValue & 4) == 4) { |
| if (devpriv-> |
| s_ModuleInfo |
| [b_ModulNbr]. |
| s_DigitalIOInfo. |
| b_ChannelBMode |
| != 1) { |
| /*******************************************/ |
| /* The digital channel B is used for input */ |
| /*******************************************/ |
| |
| i_ReturnValue = |
| -7; |
| } |
| } /* if ((b_PortValue & 4) == 4) */ |
| |
| /***********************/ |
| /* Test if error occur */ |
| /***********************/ |
| |
| if (i_ReturnValue >= 0) { |
| |
| /* if(data[1]) { */ |
| |
| switch (b_PortOnOFF) { |
| /*********************************/ |
| /* Test if set Port ON */ |
| /*********************************/ |
| |
| case APCI1710_ON: |
| |
| /*********************************/ |
| /* Test if output memory enabled */ |
| /*********************************/ |
| |
| if (devpriv-> |
| s_ModuleInfo |
| [b_ModulNbr]. |
| s_DigitalIOInfo. |
| b_OutputMemoryEnabled |
| == 1) { |
| dw_WriteValue |
| = |
| devpriv-> |
| s_ModuleInfo |
| [b_ModulNbr]. |
| s_DigitalIOInfo. |
| dw_OutputMemory |
| | |
| b_PortValue; |
| |
| devpriv-> |
| s_ModuleInfo |
| [b_ModulNbr]. |
| s_DigitalIOInfo. |
| dw_OutputMemory |
| = |
| dw_WriteValue; |
| } else { |
| dw_WriteValue |
| = |
| b_PortValue; |
| } |
| break; |
| |
| /* If Set PORT OFF */ |
| case APCI1710_OFF: |
| |
| /*********************************/ |
| /* Test if output memory enabled */ |
| /*********************************/ |
| |
| if (devpriv-> |
| s_ModuleInfo |
| [b_ModulNbr]. |
| s_DigitalIOInfo. |
| b_OutputMemoryEnabled |
| == 1) { |
| dw_WriteValue |
| = |
| devpriv-> |
| s_ModuleInfo |
| [b_ModulNbr]. |
| s_DigitalIOInfo. |
| dw_OutputMemory |
| & |
| (0xFFFFFFFFUL |
| - |
| b_PortValue); |
| |
| devpriv-> |
| s_ModuleInfo |
| [b_ModulNbr]. |
| s_DigitalIOInfo. |
| dw_OutputMemory |
| = |
| dw_WriteValue; |
| } else { |
| /*****************************/ |
| /* Digital Output Memory OFF */ |
| /*****************************/ |
| |
| i_ReturnValue |
| = |
| -8; |
| } |
| } /* switch */ |
| |
| /*******************/ |
| /* Write the value */ |
| /*******************/ |
| |
| /* OUTPDW (ps_APCI1710Variable-> |
| * s_Board [b_BoardHandle]. |
| * s_BoardInfos. |
| * ui_Address + (64 * b_ModulNbr), |
| * dw_WriteValue); */ |
| |
| outl(dw_WriteValue, |
| devpriv-> |
| s_BoardInfos. |
| ui_Address + |
| (64 * b_ModulNbr)); |
| } |
| } else { |
| /**********************/ |
| /* Output value wrong */ |
| /**********************/ |
| |
| i_ReturnValue = -4; |
| } |
| } else { |
| /*******************************/ |
| /* Digital I/O not initialised */ |
| /*******************************/ |
| |
| i_ReturnValue = -5; |
| } |
| } else { |
| /******************************************/ |
| /* The module is not a digital I/O module */ |
| /******************************************/ |
| |
| i_ReturnValue = -3; |
| } |
| } else { |
| /***********************/ |
| /* Module number error */ |
| /***********************/ |
| |
| i_ReturnValue = -2; |
| } |
| break; |
| |
| default: |
| i_ReturnValue = -9; |
| DPRINTK("NO INPUT/OUTPUT specified\n"); |
| } /* switch INPUT / OUTPUT */ |
| return i_ReturnValue; |
| } |