| /** |
| @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 : 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 | |
| | (unsigned char_ b_BoardHandle, | |
| | unsigned char_ b_ModulNbr, | |
| | unsigned char_ b_PulseEncoderNbr, | |
| | unsigned char_ b_InputLevelSelection, | |
| | unsigned char_ 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 : unsigned char_ b_BoardHandle : Handle of board APCI-1710| |
| | unsigned char_ b_ModulNbr : Module number to | |
| | configure (0 to 3) | |
| | unsigned char_ b_PulseEncoderNbr : Pulse encoder selection | |
| | (0 to 3) | |
| | unsigned char_ 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.| |
| | unsigned char_ 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 =(unsigned char) CR_AREF(insn->chanspec); |
| b_PulseEncoderNbr =(unsigned char) data[0]; |
| b_InputLevelSelection =(unsigned char) data[1]; |
| b_TriggerOutputAction =(unsigned char) data[2]; |
| ul_StartValue =(unsigned int) 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; |
| unsigned int dw_IntRegister; |
| |
| unsigned char b_ModulNbr; |
| unsigned char b_PulseEncoderNbr; |
| unsigned char b_InputLevelSelection; |
| unsigned char b_TriggerOutputAction; |
| unsigned int ul_StartValue; |
| |
| b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec); |
| b_PulseEncoderNbr = (unsigned char) data[0]; |
| b_InputLevelSelection = (unsigned char) data[1]; |
| b_TriggerOutputAction = (unsigned char) data[2]; |
| ul_StartValue = (unsigned int) 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 | |
| | (unsigned char_ b_BoardHandle, | |
| | unsigned char_ b_ModulNbr, | |
| | unsigned char_ b_PulseEncoderNbr, | |
| | unsigned char_ b_CycleSelection, | |
| | unsigned char_ 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 : unsigned char_ b_BoardHandle : Handle of board APCI-1710| |
| | unsigned char_ b_ModulNbr : Module number to | |
| | configure (0 to 3) | |
| | unsigned char_ b_PulseEncoderNbr : Pulse encoder selection | |
| | (0 to 3) | |
| | unsigned char_ 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. | |
| | unsigned char_ 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 =(unsigned char) CR_AREF(insn->chanspec); |
| b_Action =(unsigned char) data[0]; |
| b_PulseEncoderNbr =(unsigned char) data[1]; |
| b_CycleSelection =(unsigned char) data[2]; |
| b_InterruptHandling =(unsigned char) 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; |
| unsigned char b_ModulNbr; |
| unsigned char b_PulseEncoderNbr; |
| unsigned char b_CycleSelection; |
| unsigned char b_InterruptHandling; |
| unsigned char b_Action; |
| |
| i_ReturnValue = insn->n; |
| b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec); |
| b_Action = (unsigned char) data[0]; |
| b_PulseEncoderNbr = (unsigned char) data[1]; |
| b_CycleSelection = (unsigned char) data[2]; |
| b_InterruptHandling = (unsigned char) 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 | |
| | (unsigned char_ b_BoardHandle, | |
| | unsigned char_ b_ModulNbr, | |
| | unsigned char_ b_PulseEncoderNbr, | |
| | unsigned char *_ pb_Status) | |
| +----------------------------------------------------------------------------+ |
| | Task APCI1710_PULSEENCODER_READ : Reads the pulse encoder status |
| and valuefrom selected pulse | |
| | encoder (b_PulseEncoderNbr) from selected module | |
| | (b_ModulNbr). | |
| +----------------------------------------------------------------------------+ |
| unsigned char 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 : unsigned char_ b_BoardHandle : Handle of board APCI-1710| |
| | CRAREF() unsigned char_ b_ModulNbr : Module number to | |
| | configure (0 to 3) | |
| | data[1] unsigned char_ b_PulseEncoderNbr : Pulse encoder selection | |
| | (0 to 3) |
| APCI1710_PULSEENCODER_WRITE |
| data[2] ULONG_ ul_WriteValue : 32-bit value to be | |
| | written | |
| +----------------------------------------------------------------------------+ |
| | Output Parameters : unsigned char *_ 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 (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
| unsigned char_ b_PulseEncoderNbr, |
| |
| unsigned char *_ 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; |
| unsigned int dw_StatusRegister; |
| unsigned char b_ModulNbr; |
| unsigned char b_PulseEncoderNbr; |
| unsigned char *pb_Status; |
| unsigned char b_Type; |
| unsigned int *pul_ReadValue; |
| unsigned int ul_WriteValue; |
| |
| i_ReturnValue = insn->n; |
| b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec); |
| b_Type = (unsigned char) data[0]; |
| b_PulseEncoderNbr = (unsigned char) data[1]; |
| pb_Status = (unsigned char *) &data[0]; |
| pul_ReadValue = (unsigned int *) &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 = |
| (unsigned char) (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 = (unsigned int) 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; |
| |
| } |