aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c')
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c861
1 files changed, 861 insertions, 0 deletions
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c
new file mode 100644
index 000000000000..3ac6a264ef54
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c
@@ -0,0 +1,861 @@
+/**
+@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 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 : API APCI1710 | Compiler : gcc |
+ | Module name : Inp_CPT.C | Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-----------------------------------------------------------------------+
+ | Description : APCI-1710 pulse encoder module |
+ | |
+ | |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ |----------|-----------|------------------------------------------------|
+ | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
+ | | | available |
+ +-----------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+
+#include "APCI1710_Inp_cpt.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_InitPulseEncoder |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_PulseEncoderNbr, |
+| BYTE_ b_InputLevelSelection, |
+| BYTE_ b_TriggerOutputAction, |
+| ULONG_ ul_StartValue) |
++----------------------------------------------------------------------------+
+| Task : Configure the pulse encoder operating mode selected via|
+| b_ModulNbr and b_PulseEncoderNbr. The pulse encoder |
+| after each pulse decrement the counter value from 1. |
+| |
+| You must calling this function be for you call any |
+| other function witch access of pulse encoders. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|
+| BYTE_ b_ModulNbr : Module number to |
+| configure (0 to 3) |
+| BYTE_ b_PulseEncoderNbr : Pulse encoder selection |
+| (0 to 3) |
+| BYTE_ b_InputLevelSelection : Input level selection |
+| (0 or 1) |
+| 0 : Set pulse encoder|
+| count the the low|
+| level pulse. |
+| 1 : Set pulse encoder|
+| count the the |
+| high level pulse.|
+| BYTE_ b_TriggerOutputAction : Digital TRIGGER output |
+| action |
+| 0 : No action |
+| 1 : Set the trigger |
+| output to "1" |
+| (high) after the |
+| passage from 1 to|
+| 0 from pulse |
+| encoder. |
+| 2 : Set the trigger |
+| output to "0" |
+| (low) after the |
+| passage from 1 to|
+| 0 from pulse |
+| encoder |
+| ULONG_ ul_StartValue : Pulse encoder start value|
+| (1 to 4294967295)
+ b_ModulNbr =(BYTE) CR_AREF(insn->chanspec);
+ b_PulseEncoderNbr =(BYTE) data[0];
+ b_InputLevelSelection =(BYTE) data[1];
+ b_TriggerOutputAction =(BYTE) data[2];
+ ul_StartValue =(ULONG) data[3];
+ |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The module is not a pulse encoder module |
+| -3: Pulse encoder selection is wrong |
+| -4: Input level selection is wrong |
+| -5: Digital TRIGGER output action selection is wrong |
+| -6: Pulse encoder start value is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnConfigInitPulseEncoder(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_IntRegister;
+
+ BYTE b_ModulNbr;
+ BYTE b_PulseEncoderNbr;
+ BYTE b_InputLevelSelection;
+ BYTE b_TriggerOutputAction;
+ ULONG ul_StartValue;
+
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_PulseEncoderNbr = (BYTE) data[0];
+ b_InputLevelSelection = (BYTE) data[1];
+ b_TriggerOutputAction = (BYTE) data[2];
+ ul_StartValue = (ULONG) data[3];
+
+ i_ReturnValue = insn->n;
+
+ /***********************************/
+ /* Test the selected module number */
+ /***********************************/
+
+ if (b_ModulNbr <= 3) {
+ /*************************/
+ /* Test if pulse encoder */
+ /*************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ APCI1710_PULSE_ENCODER) ==
+ APCI1710_PULSE_ENCODER) {
+ /******************************************/
+ /* Test the selected pulse encoder number */
+ /******************************************/
+
+ if (b_PulseEncoderNbr <= 3) {
+ /************************/
+ /* Test the input level */
+ /************************/
+
+ if ((b_InputLevelSelection == 0)
+ || (b_InputLevelSelection == 1)) {
+ /*******************************************/
+ /* Test the ouput TRIGGER action selection */
+ /*******************************************/
+
+ if ((b_TriggerOutputAction <= 2)
+ || (b_PulseEncoderNbr > 0)) {
+ if (ul_StartValue > 1) {
+
+ dw_IntRegister =
+ inl(devpriv->
+ s_BoardInfos.
+ ui_Address +
+ 20 +
+ (64 * b_ModulNbr));
+
+ /***********************/
+ /* Set the start value */
+ /***********************/
+
+ outl(ul_StartValue,
+ devpriv->
+ s_BoardInfos.
+ ui_Address +
+ (b_PulseEncoderNbr
+ * 4) +
+ (64 * b_ModulNbr));
+
+ /***********************/
+ /* Set the input level */
+ /***********************/
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister =
+ (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister &
+ (0xFFFFFFFFUL -
+ (1UL << (8 + b_PulseEncoderNbr)))) | ((1UL & (~b_InputLevelSelection)) << (8 + b_PulseEncoderNbr));
+
+ /*******************************/
+ /* Test if output trigger used */
+ /*******************************/
+
+ if ((b_TriggerOutputAction > 0) && (b_PulseEncoderNbr > 1)) {
+ /****************************/
+ /* Enable the output action */
+ /****************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister
+ | (1UL
+ << (4 + b_PulseEncoderNbr));
+
+ /*********************************/
+ /* Set the output TRIGGER action */
+ /*********************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister
+ =
+ (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister
+ &
+ (0xFFFFFFFFUL
+ -
+ (1UL << (12 + b_PulseEncoderNbr)))) | ((1UL & (b_TriggerOutputAction - 1)) << (12 + b_PulseEncoderNbr));
+ } else {
+ /*****************************/
+ /* Disable the output action */
+ /*****************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister
+ &
+ (0xFFFFFFFFUL
+ -
+ (1UL << (4 + b_PulseEncoderNbr)));
+ }
+
+ /*************************/
+ /* Set the configuration */
+ /*************************/
+
+ outl(devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister,
+ devpriv->
+ s_BoardInfos.
+ ui_Address +
+ 20 +
+ (64 * b_ModulNbr));
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ s_PulseEncoderInfo
+ [b_PulseEncoderNbr].
+ b_PulseEncoderInit
+ = 1;
+ } else {
+ /**************************************/
+ /* Pulse encoder start value is wrong */
+ /**************************************/
+
+ DPRINTK("Pulse encoder start value is wrong\n");
+ i_ReturnValue = -6;
+ }
+ } else {
+ /****************************************************/
+ /* Digital TRIGGER output action selection is wrong */
+ /****************************************************/
+
+ DPRINTK("Digital TRIGGER output action selection is wrong\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /**********************************/
+ /* Input level selection is wrong */
+ /**********************************/
+
+ DPRINTK("Input level selection is wrong\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /************************************/
+ /* Pulse encoder selection is wrong */
+ /************************************/
+
+ DPRINTK("Pulse encoder selection is wrong\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /********************************************/
+ /* The module is not a pulse encoder module */
+ /********************************************/
+
+ DPRINTK("The module is not a pulse encoder module\n");
+ i_ReturnValue = -2;
+ }
+ } else {
+ /********************************************/
+ /* The module is not a pulse encoder module */
+ /********************************************/
+
+ DPRINTK("The module is not a pulse encoder module\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_EnablePulseEncoder |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_PulseEncoderNbr, |
+| BYTE_ b_CycleSelection, |
+| BYTE_ b_InterruptHandling) |
++----------------------------------------------------------------------------+
+| Task : Enableor disable the selected pulse encoder (b_PulseEncoderNbr) |
+| from selected module (b_ModulNbr). Each input pulse |
+| decrement the pulse encoder counter value from 1. |
+| If you enabled the interrupt (b_InterruptHandling), a |
+| interrupt is generated when the pulse encoder has run |
+| down. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|
+| BYTE_ b_ModulNbr : Module number to |
+| configure (0 to 3) |
+| BYTE_ b_PulseEncoderNbr : Pulse encoder selection |
+| (0 to 3) |
+| BYTE_ b_CycleSelection : APCI1710_CONTINUOUS: |
+| Each time the |
+| counting value is set|
+| on "0", the pulse |
+| encoder load the |
+| start value after |
+| the next pulse. |
+| APCI1710_SINGLE: |
+| If the counter is set|
+| on "0", the pulse |
+| encoder is stopped. |
+| BYTE_ b_InterruptHandling : Interrupts can be |
+| generated, when the pulse|
+| encoder has run down. |
+| With this parameter the |
+| user decides if |
+| interrupts are used or |
+| not. |
+| APCI1710_ENABLE: |
+| Interrupts are enabled |
+| APCI1710_DISABLE: |
+| Interrupts are disabled
+
+ b_ModulNbr =(BYTE) CR_AREF(insn->chanspec);
+ b_Action =(BYTE) data[0];
+ b_PulseEncoderNbr =(BYTE) data[1];
+ b_CycleSelection =(BYTE) data[2];
+ b_InterruptHandling =(BYTE) data[3];|
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection is wrong |
+| -3: Pulse encoder selection is wrong |
+| -4: Pulse encoder not initialised. |
+| See function "i_APCI1710_InitPulseEncoder" |
+| -5: Cycle selection mode is wrong |
+| -6: Interrupt handling mode is wrong |
+| -7: Interrupt routine not installed. |
+| See function "i_APCI1710_SetBoardIntRoutineX" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnWriteEnableDisablePulseEncoder(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ BYTE b_ModulNbr;
+ BYTE b_PulseEncoderNbr;
+ BYTE b_CycleSelection;
+ BYTE b_InterruptHandling;
+ BYTE b_Action;
+
+ i_ReturnValue = insn->n;
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_Action = (BYTE) data[0];
+ b_PulseEncoderNbr = (BYTE) data[1];
+ b_CycleSelection = (BYTE) data[2];
+ b_InterruptHandling = (BYTE) data[3];
+
+ /***********************************/
+ /* Test the selected module number */
+ /***********************************/
+
+ if (b_ModulNbr <= 3) {
+ /******************************************/
+ /* Test the selected pulse encoder number */
+ /******************************************/
+
+ if (b_PulseEncoderNbr <= 3) {
+ /*************************************/
+ /* Test if pulse encoder initialised */
+ /*************************************/
+
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ s_PulseEncoderInfo[b_PulseEncoderNbr].
+ b_PulseEncoderInit == 1) {
+ switch (b_Action) {
+
+ case APCI1710_ENABLE:
+ /****************************/
+ /* Test the cycle selection */
+ /****************************/
+
+ if (b_CycleSelection ==
+ APCI1710_CONTINUOUS
+ || b_CycleSelection ==
+ APCI1710_SINGLE) {
+ /*******************************/
+ /* Test the interrupt handling */
+ /*******************************/
+
+ if (b_InterruptHandling ==
+ APCI1710_ENABLE
+ || b_InterruptHandling
+ == APCI1710_DISABLE) {
+ /******************************/
+ /* Test if interrupt not used */
+ /******************************/
+
+ if (b_InterruptHandling
+ ==
+ APCI1710_DISABLE)
+ {
+ /*************************/
+ /* Disable the interrupt */
+ /*************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister
+ &
+ (0xFFFFFFFFUL
+ -
+ (1UL << b_PulseEncoderNbr));
+ } else {
+
+ /************************/
+ /* Enable the interrupt */
+ /************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister
+ | (1UL
+ <<
+ b_PulseEncoderNbr);
+ devpriv->tsk_Current = current; // Save the current process task structure
+
+ }
+
+ if (i_ReturnValue >= 0) {
+ /***********************************/
+ /* Enable or disable the interrupt */
+ /***********************************/
+
+ outl(devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister,
+ devpriv->
+ s_BoardInfos.
+ ui_Address
+ + 20 +
+ (64 * b_ModulNbr));
+
+ /****************************/
+ /* Enable the pulse encoder */
+ /****************************/
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_ControlRegister
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_ControlRegister
+ | (1UL
+ <<
+ b_PulseEncoderNbr);
+
+ /**********************/
+ /* Set the cycle mode */
+ /**********************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_ControlRegister
+ =
+ (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_ControlRegister
+ &
+ (0xFFFFFFFFUL
+ -
+ (1 << (b_PulseEncoderNbr + 4)))) | ((b_CycleSelection & 1UL) << (4 + b_PulseEncoderNbr));
+
+ /****************************/
+ /* Enable the pulse encoder */
+ /****************************/
+
+ outl(devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_ControlRegister,
+ devpriv->
+ s_BoardInfos.
+ ui_Address
+ + 16 +
+ (64 * b_ModulNbr));
+ }
+ } else {
+ /************************************/
+ /* Interrupt handling mode is wrong */
+ /************************************/
+
+ DPRINTK("Interrupt handling mode is wrong\n");
+ i_ReturnValue = -6;
+ }
+ } else {
+ /*********************************/
+ /* Cycle selection mode is wrong */
+ /*********************************/
+
+ DPRINTK("Cycle selection mode is wrong\n");
+ i_ReturnValue = -5;
+ }
+ break;
+
+ case APCI1710_DISABLE:
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_ControlRegister =
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_ControlRegister &
+ (0xFFFFFFFFUL -
+ (1UL << b_PulseEncoderNbr));
+
+ /*****************************/
+ /* Disable the pulse encoder */
+ /*****************************/
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_ControlRegister,
+ devpriv->s_BoardInfos.
+ ui_Address + 16 +
+ (64 * b_ModulNbr));
+
+ break;
+ } // switch End
+
+ } else {
+ /*********************************/
+ /* Pulse encoder not initialised */
+ /*********************************/
+
+ DPRINTK("Pulse encoder not initialised\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /************************************/
+ /* Pulse encoder selection is wrong */
+ /************************************/
+
+ DPRINTK("Pulse encoder selection is wrong\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*****************************/
+ /* Module selection is wrong */
+ /*****************************/
+
+ DPRINTK("Module selection is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ReadPulseEncoderStatus |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_PulseEncoderNbr, |
+| PBYTE_ pb_Status) |
++----------------------------------------------------------------------------+
+| Task APCI1710_PULSEENCODER_READ : Reads the pulse encoder status
+ and valuefrom selected pulse |
+| encoder (b_PulseEncoderNbr) from selected module |
+| (b_ModulNbr). |
++----------------------------------------------------------------------------+
+ BYTE b_Type; data[0]
+ APCI1710_PULSEENCODER_WRITE
+ Writes a 32-bit value (ul_WriteValue) into the selected|
+| pulse encoder (b_PulseEncoderNbr) from selected module |
+| (b_ModulNbr). This operation set the new start pulse |
+| encoder value.
+ APCI1710_PULSEENCODER_READ
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|
+| CRAREF() BYTE_ b_ModulNbr : Module number to |
+| configure (0 to 3) |
+| data[1] BYTE_ b_PulseEncoderNbr : Pulse encoder selection |
+| (0 to 3)
+ APCI1710_PULSEENCODER_WRITE
+ data[2] ULONG_ ul_WriteValue : 32-bit value to be |
+| written |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_Status : Pulse encoder status. |
+| 0 : No overflow occur|
+| 1 : Overflow occur
+ PULONG_ pul_ReadValue : Pulse encoder value | |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection is wrong |
+| -3: Pulse encoder selection is wrong |
+| -4: Pulse encoder not initialised. |
+| See function "i_APCI1710_InitPulseEncoder" |
++----------------------------------------------------------------------------+
+*/
+
+/*_INT_ i_APCI1710_ReadPulseEncoderStatus (BYTE_ b_BoardHandle,
+ BYTE_ b_ModulNbr,
+ BYTE_ b_PulseEncoderNbr,
+
+ PBYTE_ pb_Status)
+ */
+INT i_APCI1710_InsnBitsReadWritePulseEncoder(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_StatusRegister;
+ BYTE b_ModulNbr;
+ BYTE b_PulseEncoderNbr;
+ PBYTE pb_Status;
+ BYTE b_Type;
+ PULONG pul_ReadValue;
+ ULONG ul_WriteValue;
+
+ i_ReturnValue = insn->n;
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_Type = (BYTE) data[0];
+ b_PulseEncoderNbr = (BYTE) data[1];
+ pb_Status = (PBYTE) & data[0];
+ pul_ReadValue = (PULONG) & data[1];
+
+ /***********************************/
+ /* Test the selected module number */
+ /***********************************/
+
+ if (b_ModulNbr <= 3) {
+ /******************************************/
+ /* Test the selected pulse encoder number */
+ /******************************************/
+
+ if (b_PulseEncoderNbr <= 3) {
+ /*************************************/
+ /* Test if pulse encoder initialised */
+ /*************************************/
+
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ s_PulseEncoderInfo[b_PulseEncoderNbr].
+ b_PulseEncoderInit == 1) {
+
+ switch (b_Type) {
+ case APCI1710_PULSEENCODER_READ:
+ /****************************/
+ /* Read the status register */
+ /****************************/
+
+ dw_StatusRegister =
+ inl(devpriv->s_BoardInfos.
+ ui_Address + 16 +
+ (64 * b_ModulNbr));
+
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_StatusRegister = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_StatusRegister |
+ dw_StatusRegister;
+
+ *pb_Status =
+ (BYTE) (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_StatusRegister >> (1 +
+ b_PulseEncoderNbr)) & 1;
+
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_StatusRegister =
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_StatusRegister &
+ (0xFFFFFFFFUL - (1 << (1 +
+ b_PulseEncoderNbr)));
+
+ /******************/
+ /* Read the value */
+ /******************/
+
+ *pul_ReadValue =
+ inl(devpriv->s_BoardInfos.
+ ui_Address +
+ (4 * b_PulseEncoderNbr) +
+ (64 * b_ModulNbr));
+ break;
+
+ case APCI1710_PULSEENCODER_WRITE:
+ ul_WriteValue = (ULONG) data[2];
+ /*******************/
+ /* Write the value */
+ /*******************/
+
+ outl(ul_WriteValue,
+ devpriv->s_BoardInfos.
+ ui_Address +
+ (4 * b_PulseEncoderNbr) +
+ (64 * b_ModulNbr));
+
+ } //end of switch
+ } else {
+ /*********************************/
+ /* Pulse encoder not initialised */
+ /*********************************/
+
+ DPRINTK("Pulse encoder not initialised\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /************************************/
+ /* Pulse encoder selection is wrong */
+ /************************************/
+
+ DPRINTK("Pulse encoder selection is wrong\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*****************************/
+ /* Module selection is wrong */
+ /*****************************/
+
+ DPRINTK("Module selection is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+INT i_APCI1710_InsnReadInterruptPulseEncoder(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+
+ data[0] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].b_OldModuleMask;
+ data[1] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].ul_OldInterruptMask;
+ data[2] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
+
+ /***************************/
+ /* Increment the read FIFO */
+ /***************************/
+
+ devpriv->s_InterruptParameters.
+ ui_Read = (devpriv->
+ s_InterruptParameters.ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
+
+ return insn->n;
+
+}