aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c')
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c3642
1 files changed, 3642 insertions, 0 deletions
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
new file mode 100644
index 000000000000..1ff66bee548d
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
@@ -0,0 +1,3642 @@
+/**
+@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 : APCI-3200 | Compiler : GCC |
+ | Module name : hwdrv_apci3200.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-------------------------------+---------------------------------------+
+ | Description : Hardware Layer Acces For APCI-3200 |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +----------+-----------+------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | 02.07.04 | J. Krauth | Modification from the driver in order to |
+ | | | correct some errors when using several boards. |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+ | 26.10.04 | J. Krauth | - Update for COMEDI 0.7.68 |
+ | | | - Read eeprom value |
+ | | | - Append APCI-3300 |
+ +----------+-----------+------------------------------------------------+
+*/
+
+/*
+ +----------------------------------------------------------------------------+
+ | Included files |
+ +----------------------------------------------------------------------------+
+*/
+#include "hwdrv_apci3200.h"
+//Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+#include "addi_amcc_S5920.h"
+//#define PRINT_INFO
+
+//End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+//BEGIN JK 06.07.04: Management of sevrals boards
+/*
+ INT i_CJCAvailable=1;
+ INT i_CJCPolarity=0;
+ INT i_CJCGain=2;//changed from 0 to 2
+ INT i_InterruptFlag=0;
+ INT i_ADDIDATAPolarity;
+ INT i_ADDIDATAGain;
+ INT i_AutoCalibration=0; //: auto calibration
+ INT i_ADDIDATAConversionTime;
+ INT i_ADDIDATAConversionTimeUnit;
+ INT i_ADDIDATAType;
+ INT i_ChannelNo;
+ INT i_ChannelCount=0;
+ INT i_ScanType;
+ INT i_FirstChannel;
+ INT i_LastChannel;
+ INT i_Sum=0;
+ INT i_Offset;
+ UINT ui_Channel_num=0;
+ static int i_Count=0;
+ INT i_Initialised=0;
+ UINT ui_InterruptChannelValue[96]; //Buffer
+*/
+str_BoardInfos s_BoardInfos[100]; // 100 will be the max number of boards to be used
+//END JK 06.07.04: Management of sevrals boards
+
+//Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+/*+----------------------------------------------------------------------------+*/
+/*| Function Name : INT i_AddiHeaderRW_ReadEeprom |*/
+/*| (INT i_NbOfWordsToRead, |*/
+/*| DWORD dw_PCIBoardEepromAddress, |*/
+/*| WORD w_EepromStartAddress, |*/
+/*| PWORD pw_DataRead) |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Task : Read word from the 5920 eeprom. |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Input Parameters : INT i_NbOfWordsToRead : Nbr. of word to read |*/
+/*| DWORD dw_PCIBoardEepromAddress : Address of the eeprom |*/
+/*| WORD w_EepromStartAddress : Eeprom strat address |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Output Parameters : PWORD pw_DataRead : Read data |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Return Value : - |*/
+/*+----------------------------------------------------------------------------+*/
+
+INT i_AddiHeaderRW_ReadEeprom(INT i_NbOfWordsToRead,
+ DWORD dw_PCIBoardEepromAddress,
+ WORD w_EepromStartAddress, PWORD pw_DataRead)
+{
+ DWORD dw_eeprom_busy = 0;
+ INT i_Counter = 0;
+ INT i_WordCounter;
+ INT i;
+ BYTE pb_ReadByte[1];
+ BYTE b_ReadLowByte = 0;
+ BYTE b_ReadHighByte = 0;
+ BYTE b_SelectedAddressLow = 0;
+ BYTE b_SelectedAddressHigh = 0;
+ WORD w_ReadWord = 0;
+
+ for (i_WordCounter = 0; i_WordCounter < i_NbOfWordsToRead;
+ i_WordCounter++) {
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ for (i_Counter = 0; i_Counter < 2; i_Counter++) {
+ b_SelectedAddressLow = (w_EepromStartAddress + i_Counter) % 256; //Read the low 8 bit part
+ b_SelectedAddressHigh = (w_EepromStartAddress + i_Counter) / 256; //Read the high 8 bit part
+
+ //Select the load low address mode
+ outb(NVCMD_LOAD_LOW,
+ dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+ 3);
+
+ //Wait on busy
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ //Load the low address
+ outb(b_SelectedAddressLow,
+ dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+ 2);
+
+ //Wait on busy
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ //Select the load high address mode
+ outb(NVCMD_LOAD_HIGH,
+ dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+ 3);
+
+ //Wait on busy
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ //Load the high address
+ outb(b_SelectedAddressHigh,
+ dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+ 2);
+
+ //Wait on busy
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ //Select the READ mode
+ outb(NVCMD_BEGIN_READ,
+ dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+ 3);
+
+ //Wait on busy
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ //Read data into the EEPROM
+ *pb_ReadByte =
+ inb(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR + 2);
+
+ //Wait on busy
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ //Select the upper address part
+ if (i_Counter == 0) {
+ b_ReadLowByte = pb_ReadByte[0];
+ } else {
+ b_ReadHighByte = pb_ReadByte[0];
+ }
+
+ //Sleep
+ for (i = 0; i < 10000; i++) ;
+
+ }
+ w_ReadWord =
+ (b_ReadLowByte | (((unsigned short)b_ReadHighByte) *
+ 256));
+
+ pw_DataRead[i_WordCounter] = w_ReadWord;
+
+ w_EepromStartAddress += 2; // to read the next word
+
+ } // for (...) i_NbOfWordsToRead
+ return (0);
+}
+
+/*+----------------------------------------------------------------------------+*/
+/*| Function Name : void v_GetAPCI3200EepromCalibrationValue (void) |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Task : Read calibration value from the APCI-3200 eeprom. |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Input Parameters : - |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Output Parameters : - |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Return Value : - |*/
+/*+----------------------------------------------------------------------------+*/
+
+void v_GetAPCI3200EepromCalibrationValue(DWORD dw_PCIBoardEepromAddress,
+ str_BoardInfos * BoardInformations)
+{
+ WORD w_AnalogInputMainHeaderAddress;
+ WORD w_AnalogInputComponentAddress;
+ WORD w_NumberOfModuls = 0;
+ WORD w_CurrentSources[2];
+ WORD w_ModulCounter = 0;
+ WORD w_FirstHeaderSize = 0;
+ WORD w_NumberOfInputs = 0;
+ WORD w_CJCFlag = 0;
+ WORD w_NumberOfGainValue = 0;
+ WORD w_SingleHeaderAddress = 0;
+ WORD w_SingleHeaderSize = 0;
+ WORD w_Input = 0;
+ WORD w_GainFactorAddress = 0;
+ WORD w_GainFactorValue[2];
+ WORD w_GainIndex = 0;
+ WORD w_GainValue = 0;
+
+ /*****************************************/
+ /** Get the Analog input header address **/
+ /*****************************************/
+ i_AddiHeaderRW_ReadEeprom(1, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress, 0x116, //w_EepromStartAddress: Analog input header address
+ &w_AnalogInputMainHeaderAddress);
+
+ /*******************************************/
+ /** Compute the real analog input address **/
+ /*******************************************/
+ w_AnalogInputMainHeaderAddress = w_AnalogInputMainHeaderAddress + 0x100;
+
+ /******************************/
+ /** Get the number of moduls **/
+ /******************************/
+ i_AddiHeaderRW_ReadEeprom(1, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress, w_AnalogInputMainHeaderAddress + 0x02, //w_EepromStartAddress: Number of conponment
+ &w_NumberOfModuls);
+
+ for (w_ModulCounter = 0; w_ModulCounter < w_NumberOfModuls;
+ w_ModulCounter++) {
+ /***********************************/
+ /** Compute the component address **/
+ /***********************************/
+ w_AnalogInputComponentAddress =
+ w_AnalogInputMainHeaderAddress +
+ (w_FirstHeaderSize * w_ModulCounter) + 0x04;
+
+ /****************************/
+ /** Read first header size **/
+ /****************************/
+ i_AddiHeaderRW_ReadEeprom(1, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress, // Address of the first header
+ &w_FirstHeaderSize);
+
+ w_FirstHeaderSize = w_FirstHeaderSize >> 4;
+
+ /***************************/
+ /** Read number of inputs **/
+ /***************************/
+ i_AddiHeaderRW_ReadEeprom(1, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 0x06, // Number of inputs for the first modul
+ &w_NumberOfInputs);
+
+ w_NumberOfInputs = w_NumberOfInputs >> 4;
+
+ /***********************/
+ /** Read the CJC flag **/
+ /***********************/
+ i_AddiHeaderRW_ReadEeprom(1, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 0x08, // CJC flag
+ &w_CJCFlag);
+
+ w_CJCFlag = (w_CJCFlag >> 3) & 0x1; // Get only the CJC flag
+
+ /*******************************/
+ /** Read number of gain value **/
+ /*******************************/
+ i_AddiHeaderRW_ReadEeprom(1, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 0x44, // Number of gain value
+ &w_NumberOfGainValue);
+
+ w_NumberOfGainValue = w_NumberOfGainValue & 0xFF;
+
+ /***********************************/
+ /** Compute single header address **/
+ /***********************************/
+ w_SingleHeaderAddress =
+ w_AnalogInputComponentAddress + 0x46 +
+ (((w_NumberOfGainValue / 16) + 1) * 2) +
+ (6 * w_NumberOfGainValue) +
+ (4 * (((w_NumberOfGainValue / 16) + 1) * 2));
+
+ /********************************************/
+ /** Read current sources value for input 1 **/
+ /********************************************/
+ i_AddiHeaderRW_ReadEeprom(1, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress, w_SingleHeaderAddress, //w_EepromStartAddress: Single header address
+ &w_SingleHeaderSize);
+
+ w_SingleHeaderSize = w_SingleHeaderSize >> 4;
+
+ /*************************************/
+ /** Read gain factor for the module **/
+ /*************************************/
+ w_GainFactorAddress = w_AnalogInputComponentAddress;
+
+ for (w_GainIndex = 0; w_GainIndex < w_NumberOfGainValue;
+ w_GainIndex++) {
+ /************************************/
+ /** Read gain value for the module **/
+ /************************************/
+ i_AddiHeaderRW_ReadEeprom(1, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 70 + (2 * (1 + (w_NumberOfGainValue / 16))) + (0x02 * w_GainIndex), // Gain value
+ &w_GainValue);
+
+ BoardInformations->s_Module[w_ModulCounter].
+ w_GainValue[w_GainIndex] = w_GainValue;
+
+# ifdef PRINT_INFO
+ printk("\n Gain value = %d",
+ BoardInformations->s_Module[w_ModulCounter].
+ w_GainValue[w_GainIndex]);
+# endif
+
+ /*************************************/
+ /** Read gain factor for the module **/
+ /*************************************/
+ i_AddiHeaderRW_ReadEeprom(2, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 70 + ((2 * w_NumberOfGainValue) + (2 * (1 + (w_NumberOfGainValue / 16)))) + (0x04 * w_GainIndex), // Gain factor
+ w_GainFactorValue);
+
+ BoardInformations->s_Module[w_ModulCounter].
+ ul_GainFactor[w_GainIndex] =
+ (w_GainFactorValue[1] << 16) +
+ w_GainFactorValue[0];
+
+# ifdef PRINT_INFO
+ printk("\n w_GainFactorValue [%d] = %lu", w_GainIndex,
+ BoardInformations->s_Module[w_ModulCounter].
+ ul_GainFactor[w_GainIndex]);
+# endif
+ }
+
+ /***************************************************************/
+ /** Read current source value for each channels of the module **/
+ /***************************************************************/
+ for (w_Input = 0; w_Input < w_NumberOfInputs; w_Input++) {
+ /********************************************/
+ /** Read current sources value for input 1 **/
+ /********************************************/
+ i_AddiHeaderRW_ReadEeprom(2, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress,
+ (w_Input * w_SingleHeaderSize) +
+ w_SingleHeaderAddress + 0x0C, w_CurrentSources);
+
+ /************************************/
+ /** Save the current sources value **/
+ /************************************/
+ BoardInformations->s_Module[w_ModulCounter].
+ ul_CurrentSource[w_Input] =
+ (w_CurrentSources[0] +
+ ((w_CurrentSources[1] & 0xFFF) << 16));
+
+# ifdef PRINT_INFO
+ printk("\n Current sources [%d] = %lu", w_Input,
+ BoardInformations->s_Module[w_ModulCounter].
+ ul_CurrentSource[w_Input]);
+# endif
+ }
+
+ /***************************************/
+ /** Read the CJC current source value **/
+ /***************************************/
+ i_AddiHeaderRW_ReadEeprom(2, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress,
+ (w_Input * w_SingleHeaderSize) + w_SingleHeaderAddress +
+ 0x0C, w_CurrentSources);
+
+ /************************************/
+ /** Save the current sources value **/
+ /************************************/
+ BoardInformations->s_Module[w_ModulCounter].
+ ul_CurrentSourceCJC =
+ (w_CurrentSources[0] +
+ ((w_CurrentSources[1] & 0xFFF) << 16));
+
+# ifdef PRINT_INFO
+ printk("\n Current sources CJC = %lu",
+ BoardInformations->s_Module[w_ModulCounter].
+ ul_CurrentSourceCJC);
+# endif
+ }
+}
+
+INT i_APCI3200_GetChannelCalibrationValue(struct comedi_device * dev,
+ unsigned int ui_Channel_num, unsigned int * CJCCurrentSource,
+ unsigned int * ChannelCurrentSource, unsigned int * ChannelGainFactor)
+{
+ int i_DiffChannel = 0;
+ int i_Module = 0;
+
+#ifdef PRINT_INFO
+ printk("\n Channel = %u", ui_Channel_num);
+#endif
+
+ //Test if single or differential mode
+ if (s_BoardInfos[dev->minor].i_ConnectionType == 1) {
+ //if diff
+
+ if ((ui_Channel_num >= 0) && (ui_Channel_num <= 1))
+ i_DiffChannel = ui_Channel_num, i_Module = 0;
+ else if ((ui_Channel_num >= 2) && (ui_Channel_num <= 3))
+ i_DiffChannel = ui_Channel_num - 2, i_Module = 1;
+ else if ((ui_Channel_num >= 4) && (ui_Channel_num <= 5))
+ i_DiffChannel = ui_Channel_num - 4, i_Module = 2;
+ else if ((ui_Channel_num >= 6) && (ui_Channel_num <= 7))
+ i_DiffChannel = ui_Channel_num - 6, i_Module = 3;
+
+ } else {
+ // if single
+ if ((ui_Channel_num == 0) || (ui_Channel_num == 1))
+ i_DiffChannel = 0, i_Module = 0;
+ else if ((ui_Channel_num == 2) || (ui_Channel_num == 3))
+ i_DiffChannel = 1, i_Module = 0;
+ else if ((ui_Channel_num == 4) || (ui_Channel_num == 5))
+ i_DiffChannel = 0, i_Module = 1;
+ else if ((ui_Channel_num == 6) || (ui_Channel_num == 7))
+ i_DiffChannel = 1, i_Module = 1;
+ else if ((ui_Channel_num == 8) || (ui_Channel_num == 9))
+ i_DiffChannel = 0, i_Module = 2;
+ else if ((ui_Channel_num == 10) || (ui_Channel_num == 11))
+ i_DiffChannel = 1, i_Module = 2;
+ else if ((ui_Channel_num == 12) || (ui_Channel_num == 13))
+ i_DiffChannel = 0, i_Module = 3;
+ else if ((ui_Channel_num == 14) || (ui_Channel_num == 15))
+ i_DiffChannel = 1, i_Module = 3;
+ }
+
+ //Test if thermocouple or RTD mode
+ *CJCCurrentSource =
+ s_BoardInfos[dev->minor].s_Module[i_Module].ul_CurrentSourceCJC;
+#ifdef PRINT_INFO
+ printk("\n CJCCurrentSource = %lu", *CJCCurrentSource);
+#endif
+
+ *ChannelCurrentSource =
+ s_BoardInfos[dev->minor].s_Module[i_Module].
+ ul_CurrentSource[i_DiffChannel];
+#ifdef PRINT_INFO
+ printk("\n ChannelCurrentSource = %lu", *ChannelCurrentSource);
+#endif
+ // }
+ // }
+
+ //Channle gain factor
+ *ChannelGainFactor =
+ s_BoardInfos[dev->minor].s_Module[i_Module].
+ ul_GainFactor[s_BoardInfos[dev->minor].i_ADDIDATAGain];
+#ifdef PRINT_INFO
+ printk("\n ChannelGainFactor = %lu", *ChannelGainFactor);
+#endif
+ //End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+ return (0);
+}
+
+//End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_ReadDigitalInput |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Read value of the selected channel or port |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | UINT ui_NoOfChannels : No Of Channels To read for Port
+ Channel Numberfor single channel
+ | UINT data[0] : 0: Read single channel
+ 1: Read port value
+ data[1] Port number
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- data[0] :Read status value
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+
+INT i_APCI3200_ReadDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Temp = 0;
+ UINT ui_NoOfChannel = 0;
+ ui_NoOfChannel = CR_CHAN(insn->chanspec);
+ ui_Temp = data[0];
+ *data = inl(devpriv->i_IobaseReserved);
+
+ if (ui_Temp == 0) {
+ *data = (*data >> ui_NoOfChannel) & 0x1;
+ } //if (ui_Temp==0)
+ else {
+ if (ui_Temp == 1) {
+ if (data[1] < 0 || data[1] > 1) {
+ printk("\nThe port number is in error\n");
+ return -EINVAL;
+ } //if(data[1] < 0 || data[1] >1)
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ *data = (*data >> (2 * data[1])) & 0x3;
+ break;
+ case 3:
+ *data = (*data & 15);
+ break;
+ default:
+ comedi_error(dev, " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+ } //switch(ui_NoOfChannels)
+ } //if (ui_Temp==1)
+ else {
+ printk("\nSpecified channel not supported \n");
+ } //elseif (ui_Temp==1)
+ }
+ return insn->n;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_ConfigDigitalOutput |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Configures The Digital Output Subdevice. |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | data[0] :1 Memory enable
+ 0 Memory Disable
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+int i_APCI3200_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ if ((data[0] != 0) && (data[0] != 1)) {
+ comedi_error(dev,
+ "Not a valid Data !!! ,Data should be 1 or 0\n");
+ return -EINVAL;
+ } //if ( (data[0]!=0) && (data[0]!=1) )
+ if (data[0]) {
+ devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
+ } // if (data[0])
+ else {
+ devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
+ } //else if (data[0])
+ return insn->n;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_WriteDigitalOutput |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : writes To the digital Output Subdevice |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | struct comedi_subdevice *s : Subdevice Pointer |
+ | struct comedi_insn *insn : Insn Structure Pointer |
+ | unsigned int *data : Data Pointer contains |
+ | configuration parameters as below |
+ | data[0] :Value to output
+ data[1] : 0 o/p single channel
+ 1 o/p port
+ data[2] : port no
+ data[3] :0 set the digital o/p on
+ 1 set the digital o/p off
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+INT i_APCI3200_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Temp = 0, ui_Temp1 = 0;
+ UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
+ if (devpriv->b_OutputMemoryStatus) {
+ ui_Temp = inl(devpriv->i_IobaseAddon);
+
+ } //if(devpriv->b_OutputMemoryStatus )
+ else {
+ ui_Temp = 0;
+ } //if(devpriv->b_OutputMemoryStatus )
+ if (data[3] == 0) {
+ if (data[1] == 0) {
+ data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
+ outl(data[0], devpriv->i_IobaseAddon);
+ } //if(data[1]==0)
+ else {
+ if (data[1] == 1) {
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ data[0] =
+ (data[0] << (2 *
+ data[2])) | ui_Temp;
+ break;
+ case 3:
+ data[0] = (data[0] | ui_Temp);
+ break;
+ } //switch(ui_NoOfChannels)
+
+ outl(data[0], devpriv->i_IobaseAddon);
+ } // if(data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } //else if(data[1]==1)
+ } //elseif(data[1]==0)
+ } //if(data[3]==0)
+ else {
+ if (data[3] == 1) {
+ if (data[1] == 0) {
+ data[0] = ~data[0] & 0x1;
+ ui_Temp1 = 1;
+ ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] = (data[0] << ui_NoOfChannel) ^ 0xf;
+ data[0] = data[0] & ui_Temp;
+ outl(data[0], devpriv->i_IobaseAddon);
+ } //if(data[1]==0)
+ else {
+ if (data[1] == 1) {
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ data[0] = ~data[0] & 0x3;
+ ui_Temp1 = 3;
+ ui_Temp1 =
+ ui_Temp1 << 2 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (2 *
+ data
+ [2])) ^
+ 0xf) & ui_Temp;
+
+ break;
+ case 3:
+ break;
+
+ default:
+ comedi_error(dev,
+ " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+ } //switch(ui_NoOfChannels)
+
+ outl(data[0], devpriv->i_IobaseAddon);
+ } // if(data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } //else if(data[1]==1)
+ } //elseif(data[1]==0)
+ } //if(data[3]==1);
+ else {
+ printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ } //if else data[3]==1)
+ } //if else data[3]==0)
+ return insn->n;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_ReadDigitalOutput |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Read value of the selected channel or port |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | UINT ui_NoOfChannels : No Of Channels To read |
+ | UINT *data : Data Pointer to read status |
+ data[0] :0 read single channel
+ 1 read port value
+ data[1] port no
+
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+INT i_APCI3200_ReadDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Temp;
+ UINT ui_NoOfChannel;
+ ui_NoOfChannel = CR_CHAN(insn->chanspec);
+ ui_Temp = data[0];
+ *data = inl(devpriv->i_IobaseAddon);
+ if (ui_Temp == 0) {
+ *data = (*data >> ui_NoOfChannel) & 0x1;
+ } // if (ui_Temp==0)
+ else {
+ if (ui_Temp == 1) {
+ if (data[1] < 0 || data[1] > 1) {
+ printk("\nThe port selection is in error\n");
+ return -EINVAL;
+ } //if(data[1] <0 ||data[1] >1)
+ switch (ui_NoOfChannel) {
+ case 2:
+ *data = (*data >> (2 * data[1])) & 3;
+ break;
+
+ case 3:
+ break;
+
+ default:
+ comedi_error(dev, " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+ break;
+ } // switch(ui_NoOfChannels)
+ } // if (ui_Temp==1)
+ else {
+ printk("\nSpecified channel not supported \n");
+ } // else if (ui_Temp==1)
+ } // else if (ui_Temp==0)
+ return insn->n;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : INT i_APCI3200_ConfigAnalogInput |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Configures The Analog Input Subdevice |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | struct comedi_subdevice *s : Subdevice Pointer |
+ | struct comedi_insn *insn : Insn Structure Pointer |
+ | unsigned int *data : Data Pointer contains |
+ | configuration parameters as below |
+ | |
+ | data[0]
+ | 0:Normal AI |
+ | 1:RTD |
+ | 2:THERMOCOUPLE |
+ | data[1] : Gain To Use |
+ | |
+ | data[2] : Polarity
+ | 0:Bipolar |
+ | 1:Unipolar |
+ | |
+ | data[3] : Offset Range
+ | |
+ | data[4] : Coupling
+ | 0:DC Coupling |
+ | 1:AC Coupling |
+ | |
+ | data[5] :Differential/Single
+ | 0:Single |
+ | 1:Differential |
+ | |
+ | data[6] :TimerReloadValue
+ | |
+ | data[7] :ConvertingTimeUnit
+ | |
+ | data[8] :0 Analog voltage measurement
+ 1 Resistance measurement
+ 2 Temperature measurement
+ | data[9] :Interrupt
+ | 0:Disable
+ | 1:Enable
+ data[10] :Type of Thermocouple
+ | data[11] : 0: single channel
+ Module Number
+ |
+ | data[12]
+ | 0:Single Read
+ | 1:Read more channel
+ 2:Single scan
+ | 3:Continous Scan
+ data[13] :Number of channels to read
+ | data[14] :RTD connection type
+ :0:RTD not used
+ 1:RTD 2 wire connection
+ 2:RTD 3 wire connection
+ 3:RTD 4 wire connection
+ | |
+ | |
+ | |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+INT i_APCI3200_ConfigAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ UINT ul_Config = 0, ul_Temp = 0;
+ UINT ui_ChannelNo = 0;
+ UINT ui_Dummy = 0;
+ INT i_err = 0;
+
+ //Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+#ifdef PRINT_INFO
+ INT i = 0, i2 = 0;
+#endif
+ //End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ // Initialize the structure
+ if (s_BoardInfos[dev->minor].b_StructInitialized != 1) {
+ s_BoardInfos[dev->minor].i_CJCAvailable = 1;
+ s_BoardInfos[dev->minor].i_CJCPolarity = 0;
+ s_BoardInfos[dev->minor].i_CJCGain = 2; //changed from 0 to 2
+ s_BoardInfos[dev->minor].i_InterruptFlag = 0;
+ s_BoardInfos[dev->minor].i_AutoCalibration = 0; //: auto calibration
+ s_BoardInfos[dev->minor].i_ChannelCount = 0;
+ s_BoardInfos[dev->minor].i_Sum = 0;
+ s_BoardInfos[dev->minor].ui_Channel_num = 0;
+ s_BoardInfos[dev->minor].i_Count = 0;
+ s_BoardInfos[dev->minor].i_Initialised = 0;
+ s_BoardInfos[dev->minor].b_StructInitialized = 1;
+
+ //Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ s_BoardInfos[dev->minor].i_ConnectionType = 0;
+ //End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+ //Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ memset(s_BoardInfos[dev->minor].s_Module, 0,
+ sizeof(s_BoardInfos[dev->minor].s_Module[MAX_MODULE]));
+
+ v_GetAPCI3200EepromCalibrationValue(devpriv->i_IobaseAmcc,
+ &s_BoardInfos[dev->minor]);
+
+#ifdef PRINT_INFO
+ for (i = 0; i < MAX_MODULE; i++) {
+ printk("\n s_Module[%i].ul_CurrentSourceCJC = %lu", i,
+ s_BoardInfos[dev->minor].s_Module[i].
+ ul_CurrentSourceCJC);
+
+ for (i2 = 0; i2 < 5; i2++) {
+ printk("\n s_Module[%i].ul_CurrentSource [%i] = %lu", i, i2, s_BoardInfos[dev->minor].s_Module[i].ul_CurrentSource[i2]);
+ }
+
+ for (i2 = 0; i2 < 8; i2++) {
+ printk("\n s_Module[%i].ul_GainFactor [%i] = %lu", i, i2, s_BoardInfos[dev->minor].s_Module[i].ul_GainFactor[i2]);
+ }
+
+ for (i2 = 0; i2 < 8; i2++) {
+ printk("\n s_Module[%i].w_GainValue [%i] = %u",
+ i, i2,
+ s_BoardInfos[dev->minor].s_Module[i].
+ w_GainValue[i2]);
+ }
+ }
+#endif
+ //End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ }
+
+ if (data[0] != 0 && data[0] != 1 && data[0] != 2) {
+ printk("\nThe selection of acquisition type is in error\n");
+ i_err++;
+ } //if(data[0]!=0 && data[0]!=1 && data[0]!=2)
+ if (data[0] == 1) {
+ if (data[14] != 0 && data[14] != 1 && data[14] != 2
+ && data[14] != 4) {
+ printk("\n Error in selection of RTD connection type\n");
+ i_err++;
+ } //if(data[14]!=0 && data[14]!=1 && data[14]!=2 && data[14]!=4)
+ } //if(data[0]==1 )
+ if (data[1] < 0 || data[1] > 7) {
+ printk("\nThe selection of gain is in error\n");
+ i_err++;
+ } // if(data[1]<0 || data[1]>7)
+ if (data[2] != 0 && data[2] != 1) {
+ printk("\nThe selection of polarity is in error\n");
+ i_err++;
+ } //if(data[2]!=0 && data[2]!=1)
+ if (data[3] != 0) {
+ printk("\nThe selection of offset range is in error\n");
+ i_err++;
+ } // if(data[3]!=0)
+ if (data[4] != 0 && data[4] != 1) {
+ printk("\nThe selection of coupling is in error\n");
+ i_err++;
+ } //if(data[4]!=0 && data[4]!=1)
+ if (data[5] != 0 && data[5] != 1) {
+ printk("\nThe selection of single/differential mode is in error\n");
+ i_err++;
+ } //if(data[5]!=0 && data[5]!=1)
+ if (data[8] != 0 && data[8] != 1 && data[2] != 2) {
+ printk("\nError in selection of functionality\n");
+ } //if(data[8]!=0 && data[8]!=1 && data[2]!=2)
+ if (data[12] == 0 || data[12] == 1) {
+ if (data[6] != 20 && data[6] != 40 && data[6] != 80
+ && data[6] != 160) {
+ printk("\nThe selection of conversion time reload value is in error\n");
+ i_err++;
+ } // if (data[6]!=20 && data[6]!=40 && data[6]!=80 && data[6]!=160 )
+ if (data[7] != 2) {
+ printk("\nThe selection of conversion time unit is in error\n");
+ i_err++;
+ } // if(data[7]!=2)
+ }
+ if (data[9] != 0 && data[9] != 1) {
+ printk("\nThe selection of interrupt enable is in error\n");
+ i_err++;
+ } //if(data[9]!=0 && data[9]!=1)
+ if (data[11] < 0 || data[11] > 4) {
+ printk("\nThe selection of module is in error\n");
+ i_err++;
+ } //if(data[11] <0 || data[11]>1)
+ if (data[12] < 0 || data[12] > 3) {
+ printk("\nThe selection of singlechannel/scan selection is in error\n");
+ i_err++;
+ } //if(data[12] < 0 || data[12]> 3)
+ if (data[13] < 0 || data[13] > 16) {
+ printk("\nThe selection of number of channels is in error\n");
+ i_err++;
+ } // if(data[13] <0 ||data[13] >15)
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ /*
+ i_ChannelCount=data[13];
+ i_ScanType=data[12];
+ i_ADDIDATAPolarity = data[2];
+ i_ADDIDATAGain=data[1];
+ i_ADDIDATAConversionTime=data[6];
+ i_ADDIDATAConversionTimeUnit=data[7];
+ i_ADDIDATAType=data[0];
+ */
+
+ // Save acquisition configuration for the actual board
+ s_BoardInfos[dev->minor].i_ChannelCount = data[13];
+ s_BoardInfos[dev->minor].i_ScanType = data[12];
+ s_BoardInfos[dev->minor].i_ADDIDATAPolarity = data[2];
+ s_BoardInfos[dev->minor].i_ADDIDATAGain = data[1];
+ s_BoardInfos[dev->minor].i_ADDIDATAConversionTime = data[6];
+ s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit = data[7];
+ s_BoardInfos[dev->minor].i_ADDIDATAType = data[0];
+ //Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ s_BoardInfos[dev->minor].i_ConnectionType = data[5];
+ //End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ //END JK 06.07.04: Management of sevrals boards
+
+ //Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ memset(s_BoardInfos[dev->minor].ui_ScanValueArray, 0, (7 + 12) * sizeof(unsigned int)); // 7 is the maximal number of channels
+ //End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+
+ //BEGIN JK 02.07.04 : This while can't be do, it block the process when using severals boards
+ //while(i_InterruptFlag==1)
+ while (s_BoardInfos[dev->minor].i_InterruptFlag == 1) {
+#ifndef MSXBOX
+ udelay(1);
+#else
+ // In the case where the driver is compiled for the MSX-Box
+ // we used a printk to have a little delay because udelay
+ // seems to be broken under the MSX-Box.
+ // This solution hat to be studied.
+ printk("");
+#endif
+ }
+ //END JK 02.07.04 : This while can't be do, it block the process when using severals boards
+
+ ui_ChannelNo = CR_CHAN(insn->chanspec); // get the channel
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_ChannelNo=ui_ChannelNo;
+ //ui_Channel_num =ui_ChannelNo;
+
+ s_BoardInfos[dev->minor].i_ChannelNo = ui_ChannelNo;
+ s_BoardInfos[dev->minor].ui_Channel_num = ui_ChannelNo;
+
+ //END JK 06.07.04: Management of sevrals boards
+
+ if (data[5] == 0) {
+ if (ui_ChannelNo < 0 || ui_ChannelNo > 15) {
+ printk("\nThe Selection of the channel is in error\n");
+ i_err++;
+ } // if(ui_ChannelNo<0 || ui_ChannelNo>15)
+ } //if(data[5]==0)
+ else {
+ if (data[14] == 2) {
+ if (ui_ChannelNo < 0 || ui_ChannelNo > 3) {
+ printk("\nThe Selection of the channel is in error\n");
+ i_err++;
+ } // if(ui_ChannelNo<0 || ui_ChannelNo>3)
+ } //if(data[14]==2)
+ else {
+ if (ui_ChannelNo < 0 || ui_ChannelNo > 7) {
+ printk("\nThe Selection of the channel is in error\n");
+ i_err++;
+ } // if(ui_ChannelNo<0 || ui_ChannelNo>7)
+ } //elseif(data[14]==2)
+ } //elseif(data[5]==0)
+ if (data[12] == 0 || data[12] == 1) {
+ switch (data[5]) {
+ case 0:
+ if (ui_ChannelNo >= 0 && ui_ChannelNo <= 3) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=0;
+ s_BoardInfos[dev->minor].i_Offset = 0;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if(ui_ChannelNo >=0 && ui_ChannelNo <=3)
+ if (ui_ChannelNo >= 4 && ui_ChannelNo <= 7) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=64;
+ s_BoardInfos[dev->minor].i_Offset = 64;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if(ui_ChannelNo >=4 && ui_ChannelNo <=7)
+ if (ui_ChannelNo >= 8 && ui_ChannelNo <= 11) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=128;
+ s_BoardInfos[dev->minor].i_Offset = 128;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if(ui_ChannelNo >=8 && ui_ChannelNo <=11)
+ if (ui_ChannelNo >= 12 && ui_ChannelNo <= 15) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=192;
+ s_BoardInfos[dev->minor].i_Offset = 192;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if(ui_ChannelNo >=12 && ui_ChannelNo <=15)
+ break;
+ case 1:
+ if (data[14] == 2) {
+ if (ui_ChannelNo == 0) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=0;
+ s_BoardInfos[dev->minor].i_Offset = 0;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if(ui_ChannelNo ==0 )
+ if (ui_ChannelNo == 1) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=0;
+ s_BoardInfos[dev->minor].i_Offset = 64;
+ //END JK 06.07.04: Management of sevrals boards
+ } // if(ui_ChannelNo ==1)
+ if (ui_ChannelNo == 2) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=128;
+ s_BoardInfos[dev->minor].i_Offset = 128;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if(ui_ChannelNo ==2 )
+ if (ui_ChannelNo == 3) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=192;
+ s_BoardInfos[dev->minor].i_Offset = 192;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if(ui_ChannelNo ==3)
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_ChannelNo=0;
+ s_BoardInfos[dev->minor].i_ChannelNo = 0;
+ //END JK 06.07.04: Management of sevrals boards
+ ui_ChannelNo = 0;
+ break;
+ } //if(data[14]==2)
+ if (ui_ChannelNo >= 0 && ui_ChannelNo <= 1) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=0;
+ s_BoardInfos[dev->minor].i_Offset = 0;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if(ui_ChannelNo >=0 && ui_ChannelNo <=1)
+ if (ui_ChannelNo >= 2 && ui_ChannelNo <= 3) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_ChannelNo=i_ChannelNo-2;
+ //i_Offset=64;
+ s_BoardInfos[dev->minor].i_ChannelNo =
+ s_BoardInfos[dev->minor].i_ChannelNo -
+ 2;
+ s_BoardInfos[dev->minor].i_Offset = 64;
+ //END JK 06.07.04: Management of sevrals boards
+ ui_ChannelNo = ui_ChannelNo - 2;
+ } //if(ui_ChannelNo >=2 && ui_ChannelNo <=3)
+ if (ui_ChannelNo >= 4 && ui_ChannelNo <= 5) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_ChannelNo=i_ChannelNo-4;
+ //i_Offset=128;
+ s_BoardInfos[dev->minor].i_ChannelNo =
+ s_BoardInfos[dev->minor].i_ChannelNo -
+ 4;
+ s_BoardInfos[dev->minor].i_Offset = 128;
+ //END JK 06.07.04: Management of sevrals boards
+ ui_ChannelNo = ui_ChannelNo - 4;
+ } //if(ui_ChannelNo >=4 && ui_ChannelNo <=5)
+ if (ui_ChannelNo >= 6 && ui_ChannelNo <= 7) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_ChannelNo=i_ChannelNo-6;
+ //i_Offset=192;
+ s_BoardInfos[dev->minor].i_ChannelNo =
+ s_BoardInfos[dev->minor].i_ChannelNo -
+ 6;
+ s_BoardInfos[dev->minor].i_Offset = 192;
+ //END JK 06.07.04: Management of sevrals boards
+ ui_ChannelNo = ui_ChannelNo - 6;
+ } //if(ui_ChannelNo >=6 && ui_ChannelNo <=7)
+ break;
+
+ default:
+ printk("\n This selection of polarity does not exist\n");
+ i_err++;
+ } //switch(data[2])
+ } //if(data[12]==0 || data[12]==1)
+ else {
+ switch (data[11]) {
+ case 1:
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=0;
+ s_BoardInfos[dev->minor].i_Offset = 0;
+ //END JK 06.07.04: Management of sevrals boards
+ break;
+ case 2:
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=64;
+ s_BoardInfos[dev->minor].i_Offset = 64;
+ //END JK 06.07.04: Management of sevrals boards
+ break;
+ case 3:
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=128;
+ s_BoardInfos[dev->minor].i_Offset = 128;
+ //END JK 06.07.04: Management of sevrals boards
+ break;
+ case 4:
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=192;
+ s_BoardInfos[dev->minor].i_Offset = 192;
+ //END JK 06.07.04: Management of sevrals boards
+ break;
+ default:
+ printk("\nError in module selection\n");
+ i_err++;
+ } // switch(data[11])
+ } // elseif(data[12]==0 || data[12]==1)
+ if (i_err) {
+ i_APCI3200_Reset(dev);
+ return -EINVAL;
+ }
+ //if(i_ScanType!=1)
+ if (s_BoardInfos[dev->minor].i_ScanType != 1) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Count=0;
+ //i_Sum=0;
+ s_BoardInfos[dev->minor].i_Count = 0;
+ s_BoardInfos[dev->minor].i_Sum = 0;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if(i_ScanType!=1)
+
+ ul_Config =
+ data[1] | (data[2] << 6) | (data[5] << 7) | (data[3] << 8) |
+ (data[4] << 9);
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //END JK 06.07.04: Management of sevrals boards
+ /*********************************/
+ /* Write the channel to configure */
+ /*********************************/
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //outl(0 | ui_ChannelNo , devpriv->iobase+i_Offset + 0x4);
+ outl(0 | ui_ChannelNo,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x4);
+ //END JK 06.07.04: Management of sevrals boards
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //END JK 06.07.04: Management of sevrals boards
+ /**************************/
+ /* Reset the configuration */
+ /**************************/
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //outl(0 , devpriv->iobase+i_Offset + 0x0);
+ outl(0, devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x0);
+ //END JK 06.07.04: Management of sevrals boards
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //END JK 06.07.04: Management of sevrals boards
+
+ /***************************/
+ /* Write the configuration */
+ /***************************/
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //outl(ul_Config , devpriv->iobase+i_Offset + 0x0);
+ outl(ul_Config,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x0);
+ //END JK 06.07.04: Management of sevrals boards
+
+ /***************************/
+ /*Reset the calibration bit */
+ /***************************/
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //ul_Temp = inl(devpriv->iobase+i_Offset + 12);
+ ul_Temp = inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+ //END JK 06.07.04: Management of sevrals boards
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //END JK 06.07.04: Management of sevrals boards
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //outl((ul_Temp & 0xFFF9FFFF) , devpriv->iobase+.i_Offset + 12);
+ outl((ul_Temp & 0xFFF9FFFF),
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+ //END JK 06.07.04: Management of sevrals boards
+
+ if (data[9] == 1) {
+ devpriv->tsk_Current = current;
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_InterruptFlag=1;
+ s_BoardInfos[dev->minor].i_InterruptFlag = 1;
+ //END JK 06.07.04: Management of sevrals boards
+ } // if(data[9]==1)
+ else {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_InterruptFlag=0;
+ s_BoardInfos[dev->minor].i_InterruptFlag = 0;
+ //END JK 06.07.04: Management of sevrals boards
+ } //else if(data[9]==1)
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Initialised=1;
+ s_BoardInfos[dev->minor].i_Initialised = 1;
+ //END JK 06.07.04: Management of sevrals boards
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //if(i_ScanType==1)
+ if (s_BoardInfos[dev->minor].i_ScanType == 1)
+ //END JK 06.07.04: Management of sevrals boards
+ {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Sum=i_Sum+1;
+ s_BoardInfos[dev->minor].i_Sum =
+ s_BoardInfos[dev->minor].i_Sum + 1;
+ //END JK 06.07.04: Management of sevrals boards
+
+ insn->unused[0] = 0;
+ i_APCI3200_ReadAnalogInput(dev, s, insn, &ui_Dummy);
+ }
+
+ return insn->n;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_ReadAnalogInput |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Read value of the selected channel |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | UINT ui_NoOfChannels : No Of Channels To read |
+ | UINT *data : Data Pointer to read status |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ | data[0] : Digital Value Of Input |
+ | data[1] : Calibration Offset Value |
+ | data[2] : Calibration Gain Value
+ | data[3] : CJC value
+ | data[4] : CJC offset value
+ | data[5] : CJC gain value
+ | Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ | data[6] : CJC current source from eeprom
+ | data[7] : Channel current source from eeprom
+ | data[8] : Channle gain factor from eeprom
+ | End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+INT i_APCI3200_ReadAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_DummyValue = 0;
+ int i_ConvertCJCCalibration;
+ int i = 0;
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //if(i_Initialised==0)
+ if (s_BoardInfos[dev->minor].i_Initialised == 0)
+ //END JK 06.07.04: Management of sevrals boards
+ {
+ i_APCI3200_Reset(dev);
+ return -EINVAL;
+ } //if(i_Initialised==0);
+
+#ifdef PRINT_INFO
+ printk("\n insn->unused[0] = %i", insn->unused[0]);
+#endif
+
+ switch (insn->unused[0]) {
+ case 0:
+
+ i_APCI3200_Read1AnalogInputChannel(dev, s, insn,
+ &ui_DummyValue);
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //ui_InterruptChannelValue[i_Count+0]=ui_DummyValue;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->minor].
+ i_Count + 0] = ui_DummyValue;
+ //END JK 06.07.04: Management of sevrals boards
+
+ //Begin JK 25.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ i_APCI3200_GetChannelCalibrationValue(dev,
+ s_BoardInfos[dev->minor].ui_Channel_num,
+ &s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->minor].
+ i_Count + 6],
+ &s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->minor].
+ i_Count + 7],
+ &s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->minor].
+ i_Count + 8]);
+
+#ifdef PRINT_INFO
+ printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+6] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 6]);
+
+ printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+7] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 7]);
+
+ printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+8] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 8]);
+#endif
+
+ //End JK 25.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE) && (i_CJCAvailable==1))
+ if ((s_BoardInfos[dev->minor].i_ADDIDATAType == 2)
+ && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE)
+ && (s_BoardInfos[dev->minor].i_CJCAvailable == 1))
+ //END JK 06.07.04: Management of sevrals boards
+ {
+ i_APCI3200_ReadCJCValue(dev, &ui_DummyValue);
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //ui_InterruptChannelValue[i_Count + 3]=ui_DummyValue;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->
+ minor].i_Count + 3] = ui_DummyValue;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE))
+ else {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //ui_InterruptChannelValue[i_Count + 3]=0;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->
+ minor].i_Count + 3] = 0;
+ //END JK 06.07.04: Management of sevrals boards
+ } //elseif((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE) && (i_CJCAvailable==1))
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //if (( i_AutoCalibration == FALSE) && (i_InterruptFlag == FALSE))
+ if ((s_BoardInfos[dev->minor].i_AutoCalibration == FALSE)
+ && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE))
+ //END JK 06.07.04: Management of sevrals boards
+ {
+ i_APCI3200_ReadCalibrationOffsetValue(dev,
+ &ui_DummyValue);
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //ui_InterruptChannelValue[i_Count + 1]=ui_DummyValue;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->
+ minor].i_Count + 1] = ui_DummyValue;
+ //END JK 06.07.04: Management of sevrals boards
+ i_APCI3200_ReadCalibrationGainValue(dev,
+ &ui_DummyValue);
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //ui_InterruptChannelValue[i_Count + 2]=ui_DummyValue;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->
+ minor].i_Count + 2] = ui_DummyValue;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if (( i_AutoCalibration == FALSE) && (i_InterruptFlag == FALSE))
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)&& (i_CJCAvailable==1))
+ if ((s_BoardInfos[dev->minor].i_ADDIDATAType == 2)
+ && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE)
+ && (s_BoardInfos[dev->minor].i_CJCAvailable == 1))
+ //END JK 06.07.04: Management of sevrals boards
+ {
+ /**********************************************************/
+ /*Test if the Calibration channel must be read for the CJC */
+ /**********************************************************/
+ /**********************************/
+ /*Test if the polarity is the same */
+ /**********************************/
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //if(i_CJCPolarity!=i_ADDIDATAPolarity)
+ if (s_BoardInfos[dev->minor].i_CJCPolarity !=
+ s_BoardInfos[dev->minor].i_ADDIDATAPolarity)
+ //END JK 06.07.04: Management of sevrals boards
+ {
+ i_ConvertCJCCalibration = 1;
+ } //if(i_CJCPolarity!=i_ADDIDATAPolarity)
+ else {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //if(i_CJCGain==i_ADDIDATAGain)
+ if (s_BoardInfos[dev->minor].i_CJCGain ==
+ s_BoardInfos[dev->minor].i_ADDIDATAGain)
+ //END JK 06.07.04: Management of sevrals boards
+ {
+ i_ConvertCJCCalibration = 0;
+ } //if(i_CJCGain==i_ADDIDATAGain)
+ else {
+ i_ConvertCJCCalibration = 1;
+ } //elseif(i_CJCGain==i_ADDIDATAGain)
+ } //elseif(i_CJCPolarity!=i_ADDIDATAPolarity)
+ if (i_ConvertCJCCalibration == 1) {
+ i_APCI3200_ReadCJCCalOffset(dev,
+ &ui_DummyValue);
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //ui_InterruptChannelValue[i_Count+4]=ui_DummyValue;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos
+ [dev->minor].i_Count + 4] =
+ ui_DummyValue;
+ //END JK 06.07.04: Management of sevrals boards
+
+ i_APCI3200_ReadCJCCalGain(dev, &ui_DummyValue);
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //ui_InterruptChannelValue[i_Count+5]=ui_DummyValue;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos
+ [dev->minor].i_Count + 5] =
+ ui_DummyValue;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if(i_ConvertCJCCalibration==1)
+ else {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //ui_InterruptChannelValue[i_Count+4]=0;
+ //ui_InterruptChannelValue[i_Count+5]=0;
+
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos
+ [dev->minor].i_Count + 4] = 0;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos
+ [dev->minor].i_Count + 5] = 0;
+ //END JK 06.07.04: Management of sevrals boards
+ } //elseif(i_ConvertCJCCalibration==1)
+ } //if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE))
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //if(i_ScanType!=1)
+ if (s_BoardInfos[dev->minor].i_ScanType != 1) {
+ //i_Count=0;
+ s_BoardInfos[dev->minor].i_Count = 0;
+ } //if(i_ScanType!=1)
+ else {
+ //i_Count=i_Count +6;
+ //Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ //s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count +6;
+ s_BoardInfos[dev->minor].i_Count =
+ s_BoardInfos[dev->minor].i_Count + 9;
+ //End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ } //else if(i_ScanType!=1)
+
+ //if((i_ScanType==1) &&(i_InterruptFlag==1))
+ if ((s_BoardInfos[dev->minor].i_ScanType == 1)
+ && (s_BoardInfos[dev->minor].i_InterruptFlag == 1)) {
+ //i_Count=i_Count-6;
+ //Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ //s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count-6;
+ s_BoardInfos[dev->minor].i_Count =
+ s_BoardInfos[dev->minor].i_Count - 9;
+ //End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ }
+ //if(i_ScanType==0)
+ if (s_BoardInfos[dev->minor].i_ScanType == 0) {
+ /*
+ data[0]= ui_InterruptChannelValue[0];
+ data[1]= ui_InterruptChannelValue[1];
+ data[2]= ui_InterruptChannelValue[2];
+ data[3]= ui_InterruptChannelValue[3];
+ data[4]= ui_InterruptChannelValue[4];
+ data[5]= ui_InterruptChannelValue[5];
+ */
+#ifdef PRINT_INFO
+ printk("\n data[0]= s_BoardInfos [dev->minor].ui_InterruptChannelValue[0];");
+#endif
+ data[0] =
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[0];
+ data[1] =
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[1];
+ data[2] =
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[2];
+ data[3] =
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[3];
+ data[4] =
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[4];
+ data[5] =
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[5];
+
+ //Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ //printk("\n 0 - i_APCI3200_GetChannelCalibrationValue data [6] = %lu, data [7] = %lu, data [8] = %lu", data [6], data [7], data [8]);
+ i_APCI3200_GetChannelCalibrationValue(dev,
+ s_BoardInfos[dev->minor].ui_Channel_num,
+ &data[6], &data[7], &data[8]);
+ //End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ }
+ break;
+ case 1:
+
+ for (i = 0; i < insn->n; i++) {
+ //data[i]=ui_InterruptChannelValue[i];
+ data[i] =
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[i];
+ }
+
+ //i_Count=0;
+ //i_Sum=0;
+ //if(i_ScanType==1)
+ s_BoardInfos[dev->minor].i_Count = 0;
+ s_BoardInfos[dev->minor].i_Sum = 0;
+ if (s_BoardInfos[dev->minor].i_ScanType == 1) {
+ //i_Initialised=0;
+ //i_InterruptFlag=0;
+ s_BoardInfos[dev->minor].i_Initialised = 0;
+ s_BoardInfos[dev->minor].i_InterruptFlag = 0;
+ //END JK 06.07.04: Management of sevrals boards
+ }
+ break;
+ default:
+ printk("\nThe parameters passed are in error\n");
+ i_APCI3200_Reset(dev);
+ return -EINVAL;
+ } //switch(insn->unused[0])
+
+ return insn->n;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_Read1AnalogInputChannel |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Read value of the selected channel |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | UINT ui_NoOfChannel : Channel No to read |
+ | UINT *data : Data Pointer to read status |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ | data[0] : Digital Value read |
+ |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+INT i_APCI3200_Read1AnalogInputChannel(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_EOC = 0;
+ UINT ui_ChannelNo = 0;
+ UINT ui_CommandRegister = 0;
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //ui_ChannelNo=i_ChannelNo;
+ ui_ChannelNo = s_BoardInfos[dev->minor].i_ChannelNo;
+
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ /*********************************/
+ /* Write the channel to configure */
+ /*********************************/
+ //Begin JK 20.10.2004: Bad channel value is used when using differential mode
+ //outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4);
+ //outl(0 | s_BoardInfos [dev->minor].ui_Channel_num , devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 0x4);
+ outl(0 | s_BoardInfos[dev->minor].i_ChannelNo,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x4);
+ //End JK 20.10.2004: Bad channel value is used when using differential mode
+
+ /*******************************/
+ /* Set the convert timing unit */
+ /*******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+
+ //outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
+
+ /**************************/
+ /* Set the convert timing */
+ /**************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+
+ //outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
+
+ /**************************************************************************/
+ /* Set the start end stop index to the selected channel and set the start */
+ /**************************************************************************/
+
+ ui_CommandRegister = ui_ChannelNo | (ui_ChannelNo << 8) | 0x80000;
+
+ /*********************************/
+ /*Test if the interrupt is enable */
+ /*********************************/
+
+ //if (i_InterruptFlag == ADDIDATA_ENABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
+ /************************/
+ /* Enable the interrupt */
+ /************************/
+ ui_CommandRegister = ui_CommandRegister | 0x00100000;
+ } //if (i_InterruptFlag == ADDIDATA_ENABLE)
+
+ /******************************/
+ /* Write the command register */
+ /******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+
+ //outl(ui_CommandRegister, devpriv->iobase+i_Offset + 8);
+ outl(ui_CommandRegister,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+
+ /*****************************/
+ /*Test if interrupt is enable */
+ /*****************************/
+ //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+ do {
+ /*************************/
+ /*Read the EOC Status bit */
+ /*************************/
+
+ //ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1;
+ ui_EOC = inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 20) & 1;
+
+ } while (ui_EOC != 1);
+
+ /***************************************/
+ /* Read the digital value of the input */
+ /***************************************/
+
+ //data[0] = inl (devpriv->iobase+i_Offset + 28);
+ data[0] =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 28);
+ //END JK 06.07.04: Management of sevrals boards
+
+ } // if (i_InterruptFlag == ADDIDATA_DISABLE)
+ return 0;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_ReadCalibrationOffsetValue |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Read calibration offset value of the selected channel|
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | UINT *data : Data Pointer to read status |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ | data[0] : Calibration offset Value |
+ |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device * dev, UINT * data)
+{
+ UINT ui_Temp = 0, ui_EOC = 0;
+ UINT ui_CommandRegister = 0;
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ /*********************************/
+ /* Write the channel to configure */
+ /*********************************/
+ //Begin JK 20.10.2004: This seems not necessary !
+ //outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4);
+ //outl(0 | s_BoardInfos [dev->minor].ui_Channel_num , devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 0x4);
+ //End JK 20.10.2004: This seems not necessary !
+
+ /*******************************/
+ /* Set the convert timing unit */
+ /*******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
+ /**************************/
+ /* Set the convert timing */
+ /**************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
+ /*****************************/
+ /*Read the calibration offset */
+ /*****************************/
+ //ui_Temp = inl(devpriv->iobase+i_Offset + 12);
+ ui_Temp = inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+
+ /*********************************/
+ /*Configure the Offset Conversion */
+ /*********************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl((ui_Temp | 0x00020000), devpriv->iobase+i_Offset + 12);
+ outl((ui_Temp | 0x00020000),
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+ /*******************************/
+ /*Initialise ui_CommandRegister */
+ /*******************************/
+
+ ui_CommandRegister = 0;
+
+ /*********************************/
+ /*Test if the interrupt is enable */
+ /*********************************/
+
+ //if (i_InterruptFlag == ADDIDATA_ENABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
+
+ /**********************/
+ /*Enable the interrupt */
+ /**********************/
+
+ ui_CommandRegister = ui_CommandRegister | 0x00100000;
+
+ } //if (i_InterruptFlag == ADDIDATA_ENABLE)
+
+ /**********************/
+ /*Start the conversion */
+ /**********************/
+ ui_CommandRegister = ui_CommandRegister | 0x00080000;
+
+ /***************************/
+ /*Write the command regiter */
+ /***************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(ui_CommandRegister, devpriv->iobase+i_Offset + 8);
+ outl(ui_CommandRegister,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+
+ /*****************************/
+ /*Test if interrupt is enable */
+ /*****************************/
+
+ //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+
+ do {
+ /*******************/
+ /*Read the EOC flag */
+ /*******************/
+
+ //ui_EOC = inl (devpriv->iobase+i_Offset + 20) & 1;
+ ui_EOC = inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 20) & 1;
+
+ } while (ui_EOC != 1);
+
+ /**************************************************/
+ /*Read the digital value of the calibration Offset */
+ /**************************************************/
+
+ //data[0] = inl(devpriv->iobase+i_Offset+ 28);
+ data[0] =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 28);
+ } //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ return 0;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_ReadCalibrationGainValue |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Read calibration gain value of the selected channel |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | UINT *data : Data Pointer to read status |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ | data[0] : Calibration gain Value Of Input |
+ |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+int i_APCI3200_ReadCalibrationGainValue(struct comedi_device * dev, UINT * data)
+{
+ UINT ui_EOC = 0;
+ INT ui_CommandRegister = 0;
+
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ /*********************************/
+ /* Write the channel to configure */
+ /*********************************/
+ //Begin JK 20.10.2004: This seems not necessary !
+ //outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4);
+ //outl(0 | s_BoardInfos [dev->minor].ui_Channel_num , devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 0x4);
+ //End JK 20.10.2004: This seems not necessary !
+
+ /***************************/
+ /*Read the calibration gain */
+ /***************************/
+ /*******************************/
+ /* Set the convert timing unit */
+ /*******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
+ /**************************/
+ /* Set the convert timing */
+ /**************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
+ /*******************************/
+ /*Configure the Gain Conversion */
+ /*******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(0x00040000 , devpriv->iobase+i_Offset + 12);
+ outl(0x00040000,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+
+ /*******************************/
+ /*Initialise ui_CommandRegister */
+ /*******************************/
+
+ ui_CommandRegister = 0;
+
+ /*********************************/
+ /*Test if the interrupt is enable */
+ /*********************************/
+
+ //if (i_InterruptFlag == ADDIDATA_ENABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
+
+ /**********************/
+ /*Enable the interrupt */
+ /**********************/
+
+ ui_CommandRegister = ui_CommandRegister | 0x00100000;
+
+ } //if (i_InterruptFlag == ADDIDATA_ENABLE)
+
+ /**********************/
+ /*Start the conversion */
+ /**********************/
+
+ ui_CommandRegister = ui_CommandRegister | 0x00080000;
+ /***************************/
+ /*Write the command regiter */
+ /***************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(ui_CommandRegister , devpriv->iobase+i_Offset + 8);
+ outl(ui_CommandRegister,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+
+ /*****************************/
+ /*Test if interrupt is enable */
+ /*****************************/
+
+ //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+
+ do {
+
+ /*******************/
+ /*Read the EOC flag */
+ /*******************/
+
+ //ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1;
+ ui_EOC = inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 20) & 1;
+
+ } while (ui_EOC != 1);
+
+ /************************************************/
+ /*Read the digital value of the calibration Gain */
+ /************************************************/
+
+ //data[0] = inl(devpriv->iobase+i_Offset + 28);
+ data[0] =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 28);
+
+ } //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ return 0;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_ReadCJCValue |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Read CJC value of the selected channel |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | UINT *data : Data Pointer to read status |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ | data[0] : CJC Value |
+ |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+
+int i_APCI3200_ReadCJCValue(struct comedi_device * dev, unsigned int * data)
+{
+ UINT ui_EOC = 0;
+ INT ui_CommandRegister = 0;
+
+ /******************************/
+ /*Set the converting time unit */
+ /******************************/
+
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+
+ //outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
+ /**************************/
+ /* Set the convert timing */
+ /**************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+
+ //outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
+
+ /******************************/
+ /*Configure the CJC Conversion */
+ /******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+
+ //outl( 0x00000400 , devpriv->iobase+i_Offset + 4);
+ outl(0x00000400,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4);
+ /*******************************/
+ /*Initialise dw_CommandRegister */
+ /*******************************/
+ ui_CommandRegister = 0;
+ /*********************************/
+ /*Test if the interrupt is enable */
+ /*********************************/
+ //if (i_InterruptFlag == ADDIDATA_ENABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
+ /**********************/
+ /*Enable the interrupt */
+ /**********************/
+ ui_CommandRegister = ui_CommandRegister | 0x00100000;
+ }
+
+ /**********************/
+ /*Start the conversion */
+ /**********************/
+
+ ui_CommandRegister = ui_CommandRegister | 0x00080000;
+
+ /***************************/
+ /*Write the command regiter */
+ /***************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(ui_CommandRegister , devpriv->iobase+i_Offset + 8);
+ outl(ui_CommandRegister,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+
+ /*****************************/
+ /*Test if interrupt is enable */
+ /*****************************/
+
+ //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+ do {
+
+ /*******************/
+ /*Read the EOC flag */
+ /*******************/
+
+ //ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1;
+ ui_EOC = inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 20) & 1;
+
+ } while (ui_EOC != 1);
+
+ /***********************************/
+ /*Read the digital value of the CJC */
+ /***********************************/
+
+ //data[0] = inl(devpriv->iobase+i_Offset + 28);
+ data[0] =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 28);
+
+ } //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ return 0;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_ReadCJCCalOffset |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Read CJC calibration offset value of the selected channel
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | UINT *data : Data Pointer to read status |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ | data[0] : CJC calibration offset Value
+ |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+int i_APCI3200_ReadCJCCalOffset(struct comedi_device * dev, unsigned int * data)
+{
+ UINT ui_EOC = 0;
+ INT ui_CommandRegister = 0;
+ /*******************************************/
+ /*Read calibration offset value for the CJC */
+ /*******************************************/
+ /*******************************/
+ /* Set the convert timing unit */
+ /*******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
+ /**************************/
+ /* Set the convert timing */
+ /**************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
+ /******************************/
+ /*Configure the CJC Conversion */
+ /******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(0x00000400 , devpriv->iobase+i_Offset + 4);
+ outl(0x00000400,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4);
+ /*********************************/
+ /*Configure the Offset Conversion */
+ /*********************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(0x00020000, devpriv->iobase+i_Offset + 12);
+ outl(0x00020000,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+ /*******************************/
+ /*Initialise ui_CommandRegister */
+ /*******************************/
+ ui_CommandRegister = 0;
+ /*********************************/
+ /*Test if the interrupt is enable */
+ /*********************************/
+
+ //if (i_InterruptFlag == ADDIDATA_ENABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
+ /**********************/
+ /*Enable the interrupt */
+ /**********************/
+ ui_CommandRegister = ui_CommandRegister | 0x00100000;
+
+ }
+
+ /**********************/
+ /*Start the conversion */
+ /**********************/
+ ui_CommandRegister = ui_CommandRegister | 0x00080000;
+ /***************************/
+ /*Write the command regiter */
+ /***************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(ui_CommandRegister,devpriv->iobase+i_Offset + 8);
+ outl(ui_CommandRegister,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+ //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+ do {
+ /*******************/
+ /*Read the EOC flag */
+ /*******************/
+ //ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1;
+ ui_EOC = inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 20) & 1;
+ } while (ui_EOC != 1);
+
+ /**************************************************/
+ /*Read the digital value of the calibration Offset */
+ /**************************************************/
+ //data[0] = inl(devpriv->iobase+i_Offset + 28);
+ data[0] =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 28);
+ } //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ return 0;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_ReadCJCGainValue |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Read CJC calibration gain value
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | UINT ui_NoOfChannels : No Of Channels To read |
+ | UINT *data : Data Pointer to read status |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ | data[0] : CJC calibration gain value
+ |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+int i_APCI3200_ReadCJCCalGain(struct comedi_device * dev, unsigned int * data)
+{
+ UINT ui_EOC = 0;
+ INT ui_CommandRegister = 0;
+ /*******************************/
+ /* Set the convert timing unit */
+ /*******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
+ /**************************/
+ /* Set the convert timing */
+ /**************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
+ /******************************/
+ /*Configure the CJC Conversion */
+ /******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(0x00000400,devpriv->iobase+i_Offset + 4);
+ outl(0x00000400,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4);
+ /*******************************/
+ /*Configure the Gain Conversion */
+ /*******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(0x00040000,devpriv->iobase+i_Offset + 12);
+ outl(0x00040000,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+
+ /*******************************/
+ /*Initialise dw_CommandRegister */
+ /*******************************/
+ ui_CommandRegister = 0;
+ /*********************************/
+ /*Test if the interrupt is enable */
+ /*********************************/
+ //if (i_InterruptFlag == ADDIDATA_ENABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
+ /**********************/
+ /*Enable the interrupt */
+ /**********************/
+ ui_CommandRegister = ui_CommandRegister | 0x00100000;
+ }
+ /**********************/
+ /*Start the conversion */
+ /**********************/
+ ui_CommandRegister = ui_CommandRegister | 0x00080000;
+ /***************************/
+ /*Write the command regiter */
+ /***************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(ui_CommandRegister ,devpriv->iobase+i_Offset + 8);
+ outl(ui_CommandRegister,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+ //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+ do {
+ /*******************/
+ /*Read the EOC flag */
+ /*******************/
+ //ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1;
+ ui_EOC = inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 20) & 1;
+ } while (ui_EOC != 1);
+ /************************************************/
+ /*Read the digital value of the calibration Gain */
+ /************************************************/
+ //data[0] = inl (devpriv->iobase+i_Offset + 28);
+ data[0] =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 28);
+ } //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ return 0;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_InsnBits_AnalogInput_Test |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Tests the Selected Anlog Input Channel |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | struct comedi_subdevice *s : Subdevice Pointer |
+ | struct comedi_insn *insn : Insn Structure Pointer |
+ | unsigned int *data : Data Pointer contains |
+ | configuration parameters as below |
+ |
+ |
+ | data[0] : 0 TestAnalogInputShortCircuit
+ | 1 TestAnalogInputConnection |
+
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ | data[0] : Digital value obtained |
+ | data[1] : calibration offset |
+ | data[2] : calibration gain |
+ | |
+ | |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+
+INT i_APCI3200_InsnBits_AnalogInput_Test(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Configuration = 0;
+ INT i_Temp; //,i_TimeUnit;
+ //if(i_Initialised==0)
+
+ if (s_BoardInfos[dev->minor].i_Initialised == 0) {
+ i_APCI3200_Reset(dev);
+ return -EINVAL;
+ } //if(i_Initialised==0);
+ if (data[0] != 0 && data[0] != 1) {
+ printk("\nError in selection of functionality\n");
+ i_APCI3200_Reset(dev);
+ return -EINVAL;
+ } //if(data[0]!=0 && data[0]!=1)
+
+ if (data[0] == 1) //Perform Short Circuit TEST
+ {
+ /**************************/
+ /*Set the short-cicuit bit */
+ /**************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].
+ i_Offset + 12) >> 19) & 1) !=
+ 1) ;
+ //outl((0x00001000 |i_ChannelNo) , devpriv->iobase+i_Offset + 4);
+ outl((0x00001000 | s_BoardInfos[dev->minor].i_ChannelNo),
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 4);
+ /*************************/
+ /*Set the time unit to ns */
+ /*************************/
+ /* i_TimeUnit= i_ADDIDATAConversionTimeUnit;
+ i_ADDIDATAConversionTimeUnit= 1; */
+ //i_Temp= i_InterruptFlag ;
+ i_Temp = s_BoardInfos[dev->minor].i_InterruptFlag;
+ //i_InterruptFlag = ADDIDATA_DISABLE;
+ s_BoardInfos[dev->minor].i_InterruptFlag = ADDIDATA_DISABLE;
+ i_APCI3200_Read1AnalogInputChannel(dev, s, insn, data);
+ //if(i_AutoCalibration == FALSE)
+ if (s_BoardInfos[dev->minor].i_AutoCalibration == FALSE) {
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].
+ i_Offset +
+ 12) >> 19) & 1) != 1) ;
+
+ //outl((0x00001000 |i_ChannelNo) , devpriv->iobase+i_Offset + 4);
+ outl((0x00001000 | s_BoardInfos[dev->minor].
+ i_ChannelNo),
+ devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 4);
+ data++;
+ i_APCI3200_ReadCalibrationOffsetValue(dev, data);
+ data++;
+ i_APCI3200_ReadCalibrationGainValue(dev, data);
+ }
+ } else {
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].
+ i_Offset + 12) >> 19) & 1) !=
+ 1) ;
+ //outl((0x00000800|i_ChannelNo) , devpriv->iobase+i_Offset + 4);
+ outl((0x00000800 | s_BoardInfos[dev->minor].i_ChannelNo),
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 4);
+ //ui_Configuration = inl(devpriv->iobase+i_Offset + 0);
+ ui_Configuration =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 0);
+ /*************************/
+ /*Set the time unit to ns */
+ /*************************/
+ /* i_TimeUnit= i_ADDIDATAConversionTimeUnit;
+ i_ADDIDATAConversionTimeUnit= 1; */
+ //i_Temp= i_InterruptFlag ;
+ i_Temp = s_BoardInfos[dev->minor].i_InterruptFlag;
+ //i_InterruptFlag = ADDIDATA_DISABLE;
+ s_BoardInfos[dev->minor].i_InterruptFlag = ADDIDATA_DISABLE;
+ i_APCI3200_Read1AnalogInputChannel(dev, s, insn, data);
+ //if(i_AutoCalibration == FALSE)
+ if (s_BoardInfos[dev->minor].i_AutoCalibration == FALSE) {
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].
+ i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl((0x00000800|i_ChannelNo) , devpriv->iobase+i_Offset + 4);
+ outl((0x00000800 | s_BoardInfos[dev->minor].
+ i_ChannelNo),
+ devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 4);
+ data++;
+ i_APCI3200_ReadCalibrationOffsetValue(dev, data);
+ data++;
+ i_APCI3200_ReadCalibrationGainValue(dev, data);
+ }
+ }
+ //i_InterruptFlag=i_Temp ;
+ s_BoardInfos[dev->minor].i_InterruptFlag = i_Temp;
+ //printk("\ni_InterruptFlag=%d\n",i_InterruptFlag);
+ return insn->n;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_InsnWriteReleaseAnalogInput |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Resets the channels |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | struct comedi_subdevice *s : Subdevice Pointer |
+ | struct comedi_insn *insn : Insn Structure Pointer |
+ | unsigned int *data : Data Pointer
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+
+INT i_APCI3200_InsnWriteReleaseAnalogInput(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ i_APCI3200_Reset(dev);
+ return insn->n;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function name :int i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev|
+ | ,struct comedi_subdevice *s,struct comedi_cmd *cmd) |
+ | |
+ +----------------------------------------------------------------------------+
+ | Task : Test validity for a command for cyclic anlog input |
+ | acquisition |
+ | |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev |
+ | struct comedi_subdevice *s |
+ | struct comedi_cmd *cmd |
+ | |
+ |
+ | |
+ | |
+ | |
+ +----------------------------------------------------------------------------+
+ | Return Value :0 |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+
+int i_APCI3200_CommandTestAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+
+ int err = 0;
+ int tmp; // divisor1,divisor2;
+ UINT ui_ConvertTime = 0;
+ UINT ui_ConvertTimeBase = 0;
+ UINT ui_DelayTime = 0;
+ UINT ui_DelayTimeBase = 0;
+ INT i_Triggermode = 0;
+ INT i_TriggerEdge = 0;
+ INT i_NbrOfChannel = 0;
+ INT i_Cpt = 0;
+ double d_ConversionTimeForAllChannels = 0.0;
+ double d_SCANTimeNewUnit = 0.0;
+ // step 1: make sure trigger sources are trivially valid
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW | TRIG_EXT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_FOLLOW;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+ //if(i_InterruptFlag==0)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) {
+ err++;
+ // printk("\nThe interrupt should be enabled\n");
+ }
+ if (err) {
+ i_APCI3200_Reset(dev);
+ return 1;
+ }
+
+ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) {
+ err++;
+ }
+ if (cmd->start_src == TRIG_EXT) {
+ i_TriggerEdge = cmd->start_arg & 0xFFFF;
+ i_Triggermode = cmd->start_arg >> 16;
+ if (i_TriggerEdge < 1 || i_TriggerEdge > 3) {
+ err++;
+ printk("\nThe trigger edge selection is in error\n");
+ }
+ if (i_Triggermode != 2) {
+ err++;
+ printk("\nThe trigger mode selection is in error\n");
+ }
+ }
+
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_FOLLOW)
+ err++;
+
+ if (cmd->convert_src != TRIG_TIMER)
+ err++;
+
+ if (cmd->scan_end_src != TRIG_COUNT) {
+ cmd->scan_end_src = TRIG_COUNT;
+ err++;
+ }
+
+ if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
+ err++;
+
+ if (err) {
+ i_APCI3200_Reset(dev);
+ return 2;
+ }
+ //i_FirstChannel=cmd->chanlist[0];
+ s_BoardInfos[dev->minor].i_FirstChannel = cmd->chanlist[0];
+ //i_LastChannel=cmd->chanlist[1];
+ s_BoardInfos[dev->minor].i_LastChannel = cmd->chanlist[1];
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ ui_ConvertTime = cmd->convert_arg & 0xFFFF;
+ ui_ConvertTimeBase = cmd->convert_arg >> 16;
+ if (ui_ConvertTime != 20 && ui_ConvertTime != 40
+ && ui_ConvertTime != 80 && ui_ConvertTime != 160)
+ {
+ printk("\nThe selection of conversion time reload value is in error\n");
+ err++;
+ } // if (ui_ConvertTime!=20 && ui_ConvertTime!=40 && ui_ConvertTime!=80 && ui_ConvertTime!=160 )
+ if (ui_ConvertTimeBase != 2) {
+ printk("\nThe selection of conversion time unit is in error\n");
+ err++;
+ } //if(ui_ConvertTimeBase!=2)
+ } else {
+ ui_ConvertTime = 0;
+ ui_ConvertTimeBase = 0;
+ }
+ if (cmd->scan_begin_src == TRIG_FOLLOW) {
+ ui_DelayTime = 0;
+ ui_DelayTimeBase = 0;
+ } //if(cmd->scan_begin_src==TRIG_FOLLOW)
+ else {
+ ui_DelayTime = cmd->scan_begin_arg & 0xFFFF;
+ ui_DelayTimeBase = cmd->scan_begin_arg >> 16;
+ if (ui_DelayTimeBase != 2 && ui_DelayTimeBase != 3) {
+ err++;
+ printk("\nThe Delay time base selection is in error\n");
+ }
+ if (ui_DelayTime < 1 && ui_DelayTime > 1023) {
+ err++;
+ printk("\nThe Delay time value is in error\n");
+ }
+ if (err) {
+ i_APCI3200_Reset(dev);
+ return 3;
+ }
+ fpu_begin();
+ d_SCANTimeNewUnit = (double)ui_DelayTime;
+ //i_NbrOfChannel= i_LastChannel-i_FirstChannel + 4;
+ i_NbrOfChannel =
+ s_BoardInfos[dev->minor].i_LastChannel -
+ s_BoardInfos[dev->minor].i_FirstChannel + 4;
+ /**********************************************************/
+ /*calculate the total conversion time for all the channels */
+ /**********************************************************/
+ d_ConversionTimeForAllChannels =
+ (double)((double)ui_ConvertTime /
+ (double)i_NbrOfChannel);
+
+ /*******************************/
+ /*Convert the frequence in time */
+ /*******************************/
+ d_ConversionTimeForAllChannels =
+ (double)1.0 / d_ConversionTimeForAllChannels;
+ ui_ConvertTimeBase = 3;
+ /***********************************/
+ /*Test if the time unit is the same */
+ /***********************************/
+
+ if (ui_DelayTimeBase <= ui_ConvertTimeBase) {
+
+ for (i_Cpt = 0;
+ i_Cpt < (ui_ConvertTimeBase - ui_DelayTimeBase);
+ i_Cpt++) {
+
+ d_ConversionTimeForAllChannels =
+ d_ConversionTimeForAllChannels * 1000;
+ d_ConversionTimeForAllChannels =
+ d_ConversionTimeForAllChannels + 1;
+ }
+ } else {
+ for (i_Cpt = 0;
+ i_Cpt < (ui_DelayTimeBase - ui_ConvertTimeBase);
+ i_Cpt++) {
+ d_SCANTimeNewUnit = d_SCANTimeNewUnit * 1000;
+
+ }
+ }
+
+ if (d_ConversionTimeForAllChannels >= d_SCANTimeNewUnit) {
+
+ printk("\nSCAN Delay value cannot be used\n");
+ /*********************************/
+ /*SCAN Delay value cannot be used */
+ /*********************************/
+ err++;
+ }
+ fpu_end();
+ } //else if(cmd->scan_begin_src==TRIG_FOLLOW)
+
+ if (err) {
+ i_APCI3200_Reset(dev);
+ return 4;
+ }
+
+ return 0;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function name :int i_APCI3200_StopCyclicAcquisition(struct comedi_device *dev,|
+ | struct comedi_subdevice *s)|
+ | |
+ +----------------------------------------------------------------------------+
+ | Task : Stop the acquisition |
+ | |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev |
+ | struct comedi_subdevice *s |
+ | |
+ +----------------------------------------------------------------------------+
+ | Return Value :0 |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+
+int i_APCI3200_StopCyclicAcquisition(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ UINT ui_Configuration = 0;
+ //i_InterruptFlag=0;
+ //i_Initialised=0;
+ //i_Count=0;
+ //i_Sum=0;
+ s_BoardInfos[dev->minor].i_InterruptFlag = 0;
+ s_BoardInfos[dev->minor].i_Initialised = 0;
+ s_BoardInfos[dev->minor].i_Count = 0;
+ s_BoardInfos[dev->minor].i_Sum = 0;
+
+ /*******************/
+ /*Read the register */
+ /*******************/
+ //ui_Configuration = inl(devpriv->iobase+i_Offset + 8);
+ ui_Configuration =
+ inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+ /*****************************/
+ /*Reset the START and IRQ bit */
+ /*****************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl((ui_Configuration & 0xFFE7FFFF),devpriv->iobase+i_Offset + 8);
+ outl((ui_Configuration & 0xFFE7FFFF),
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+ return 0;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function name : int i_APCI3200_CommandAnalogInput(struct comedi_device *dev, |
+ | struct comedi_subdevice *s) |
+ | |
+ +----------------------------------------------------------------------------+
+ | Task : Does asynchronous acquisition |
+ | Determines the mode 1 or 2. |
+ | |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev |
+ | struct comedi_subdevice *s |
+ | |
+ | |
+ +----------------------------------------------------------------------------+
+ | Return Value : |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+
+int i_APCI3200_CommandAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ UINT ui_Configuration = 0;
+ //INT i_CurrentSource = 0;
+ UINT ui_Trigger = 0;
+ UINT ui_TriggerEdge = 0;
+ UINT ui_Triggermode = 0;
+ UINT ui_ScanMode = 0;
+ UINT ui_ConvertTime = 0;
+ UINT ui_ConvertTimeBase = 0;
+ UINT ui_DelayTime = 0;
+ UINT ui_DelayTimeBase = 0;
+ UINT ui_DelayMode = 0;
+ //i_FirstChannel=cmd->chanlist[0];
+ //i_LastChannel=cmd->chanlist[1];
+ s_BoardInfos[dev->minor].i_FirstChannel = cmd->chanlist[0];
+ s_BoardInfos[dev->minor].i_LastChannel = cmd->chanlist[1];
+ if (cmd->start_src == TRIG_EXT) {
+ ui_Trigger = 1;
+ ui_TriggerEdge = cmd->start_arg & 0xFFFF;
+ ui_Triggermode = cmd->start_arg >> 16;
+ } //if(cmd->start_src==TRIG_EXT)
+ else {
+ ui_Trigger = 0;
+ } //elseif(cmd->start_src==TRIG_EXT)
+
+ if (cmd->stop_src == TRIG_COUNT) {
+ ui_ScanMode = 0;
+ } // if (cmd->stop_src==TRIG_COUNT)
+ else {
+ ui_ScanMode = 2;
+ } //else if (cmd->stop_src==TRIG_COUNT)
+
+ if (cmd->scan_begin_src == TRIG_FOLLOW) {
+ ui_DelayTime = 0;
+ ui_DelayTimeBase = 0;
+ ui_DelayMode = 0;
+ } //if(cmd->scan_begin_src==TRIG_FOLLOW)
+ else {
+ ui_DelayTime = cmd->scan_begin_arg & 0xFFFF;
+ ui_DelayTimeBase = cmd->scan_begin_arg >> 16;
+ ui_DelayMode = 1;
+ } //else if(cmd->scan_begin_src==TRIG_FOLLOW)
+ // printk("\nui_DelayTime=%u\n",ui_DelayTime);
+ // printk("\nui_DelayTimeBase=%u\n",ui_DelayTimeBase);
+ if (cmd->convert_src == TRIG_TIMER) {
+ ui_ConvertTime = cmd->convert_arg & 0xFFFF;
+ ui_ConvertTimeBase = cmd->convert_arg >> 16;
+ } else {
+ ui_ConvertTime = 0;
+ ui_ConvertTimeBase = 0;
+ }
+
+ // if(i_ADDIDATAType ==1 || ((i_ADDIDATAType==2)))
+ // {
+ /**************************************************/
+ /*Read the old configuration of the current source */
+ /**************************************************/
+ //ui_Configuration = inl(devpriv->iobase+i_Offset + 12);
+ ui_Configuration =
+ inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+ /***********************************************/
+ /*Write the configuration of the current source */
+ /***********************************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl((ui_Configuration & 0xFFC00000 ), devpriv->iobase+i_Offset +12);
+ outl((ui_Configuration & 0xFFC00000),
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+ // }
+ ui_Configuration = 0;
+ // printk("\nfirstchannel=%u\n",i_FirstChannel);
+ // printk("\nlastchannel=%u\n",i_LastChannel);
+ // printk("\nui_Trigger=%u\n",ui_Trigger);
+ // printk("\nui_TriggerEdge=%u\n",ui_TriggerEdge);
+ // printk("\nui_Triggermode=%u\n",ui_Triggermode);
+ // printk("\nui_DelayMode=%u\n",ui_DelayMode);
+ // printk("\nui_ScanMode=%u\n",ui_ScanMode);
+
+ //ui_Configuration = i_FirstChannel |(i_LastChannel << 8)| 0x00100000 |
+ ui_Configuration =
+ s_BoardInfos[dev->minor].i_FirstChannel | (s_BoardInfos[dev->
+ minor].
+ i_LastChannel << 8) | 0x00100000 | (ui_Trigger << 24) |
+ (ui_TriggerEdge << 25) | (ui_Triggermode << 27) | (ui_DelayMode
+ << 18) | (ui_ScanMode << 16);
+
+ /*************************/
+ /*Write the Configuration */
+ /*************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl( ui_Configuration, devpriv->iobase+i_Offset + 0x8);
+ outl(ui_Configuration,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x8);
+ /***********************/
+ /*Write the Delay Value */
+ /***********************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(ui_DelayTime,devpriv->iobase+i_Offset + 40);
+ outl(ui_DelayTime,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 40);
+ /***************************/
+ /*Write the Delay time base */
+ /***************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(ui_DelayTimeBase,devpriv->iobase+i_Offset + 44);
+ outl(ui_DelayTimeBase,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 44);
+ /*********************************/
+ /*Write the conversion time value */
+ /*********************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(ui_ConvertTime,devpriv->iobase+i_Offset + 32);
+ outl(ui_ConvertTime,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
+
+ /********************************/
+ /*Write the conversion time base */
+ /********************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(ui_ConvertTimeBase,devpriv->iobase+i_Offset + 36);
+ outl(ui_ConvertTimeBase,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
+ /*******************/
+ /*Read the register */
+ /*******************/
+ //ui_Configuration = inl(devpriv->iobase+i_Offset + 4);
+ ui_Configuration =
+ inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4);
+ /******************/
+ /*Set the SCAN bit */
+ /******************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+
+ //outl(((ui_Configuration & 0x1E0FF) | 0x00002000),devpriv->iobase+i_Offset + 4);
+ outl(((ui_Configuration & 0x1E0FF) | 0x00002000),
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4);
+ /*******************/
+ /*Read the register */
+ /*******************/
+ ui_Configuration = 0;
+ //ui_Configuration = inl(devpriv->iobase+i_Offset + 8);
+ ui_Configuration =
+ inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+
+ /*******************/
+ /*Set the START bit */
+ /*******************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl((ui_Configuration | 0x00080000),devpriv->iobase+i_Offset + 8);
+ outl((ui_Configuration | 0x00080000),
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+ return 0;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_Reset(struct comedi_device *dev) |
+ | |
+ +----------------------------------------------------------------------------+
+ | Task :Resets the registers of the card |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ +----------------------------------------------------------------------------+
+ | Return Value : |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+
+int i_APCI3200_Reset(struct comedi_device * dev)
+{
+ INT i_Temp;
+ DWORD dw_Dummy;
+ //i_InterruptFlag=0;
+ //i_Initialised==0;
+ //i_Count=0;
+ //i_Sum=0;
+
+ s_BoardInfos[dev->minor].i_InterruptFlag = 0;
+ s_BoardInfos[dev->minor].i_Initialised = 0;
+ s_BoardInfos[dev->minor].i_Count = 0;
+ s_BoardInfos[dev->minor].i_Sum = 0;
+ s_BoardInfos[dev->minor].b_StructInitialized = 0;
+
+ outl(0x83838383, devpriv->i_IobaseAmcc + 0x60);
+
+ // Enable the interrupt for the controler
+ dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38);
+ outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38);
+ outl(0, devpriv->i_IobaseAddon); //Resets the output
+ /***************/
+ /*Empty the buffer */
+ /**************/
+ for (i_Temp = 0; i_Temp <= 95; i_Temp++) {
+ //ui_InterruptChannelValue[i_Temp]=0;
+ s_BoardInfos[dev->minor].ui_InterruptChannelValue[i_Temp] = 0;
+ } //for(i_Temp=0;i_Temp<=95;i_Temp++)
+ /*****************************/
+ /*Reset the START and IRQ bit */
+ /*****************************/
+ for (i_Temp = 0; i_Temp <= 192;) {
+ while (((inl(devpriv->iobase + i_Temp + 12) >> 19) & 1) != 1) ;
+ outl(0, devpriv->iobase + i_Temp + 8);
+ i_Temp = i_Temp + 64;
+ } //for(i_Temp=0;i_Temp<=192;i_Temp+64)
+ return 0;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : static void v_APCI3200_Interrupt |
+ | (int irq , void *d) |
+ +----------------------------------------------------------------------------+
+ | Task : Interrupt processing Routine |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : int irq : irq number |
+ | void *d : void pointer |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+void v_APCI3200_Interrupt(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ UINT ui_StatusRegister = 0;
+ UINT ui_ChannelNumber = 0;
+ INT i_CalibrationFlag = 0;
+ INT i_CJCFlag = 0;
+ UINT ui_DummyValue = 0;
+ UINT ui_DigitalTemperature = 0;
+ UINT ui_DigitalInput = 0;
+ int i_ConvertCJCCalibration;
+
+ //BEGIN JK TEST
+ int i_ReturnValue = 0;
+ //END JK TEST
+
+ //printk ("\n i_ScanType = %i i_ADDIDATAType = %i", s_BoardInfos [dev->minor].i_ScanType, s_BoardInfos [dev->minor].i_ADDIDATAType);
+
+ //switch(i_ScanType)
+ switch (s_BoardInfos[dev->minor].i_ScanType) {
+ case 0:
+ case 1:
+ //switch(i_ADDIDATAType)
+ switch (s_BoardInfos[dev->minor].i_ADDIDATAType) {
+ case 0:
+ case 1:
+
+ /************************************/
+ /*Read the interrupt status register */
+ /************************************/
+ //ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16);
+ ui_StatusRegister =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 16);
+ if ((ui_StatusRegister & 0x2) == 0x2) {
+ //i_CalibrationFlag = ((inl(devpriv->iobase+i_Offset + 12) & 0x00060000) >> 17);
+ i_CalibrationFlag =
+ ((inl(devpriv->iobase +
+ s_BoardInfos[dev->
+ minor].
+ i_Offset +
+ 12) & 0x00060000) >>
+ 17);
+ /*************************/
+ /*Read the channel number */
+ /*************************/
+ //ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24);
+
+ /*************************************/
+ /*Read the digital analog input value */
+ /*************************************/
+ //ui_DigitalInput = inl(devpriv->iobase+i_Offset + 28);
+ ui_DigitalInput =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 28);
+
+ /***********************************************/
+ /* Test if the value read is the channel value */
+ /***********************************************/
+ if (i_CalibrationFlag == 0) {
+ //ui_InterruptChannelValue[i_Count + 0] = ui_DigitalInput;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->minor].
+ i_Count + 0] = ui_DigitalInput;
+
+ //Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ /*
+ printk("\n 1 - i_APCI3200_GetChannelCalibrationValue (dev, s_BoardInfos %i", ui_ChannelNumber);
+ i_APCI3200_GetChannelCalibrationValue (dev, s_BoardInfos [dev->minor].ui_Channel_num,
+ &s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count + 6],
+ &s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count + 7],
+ &s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count + 8]);
+ */
+ //End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+ /******************************************************/
+ /*Start the conversion of the calibration offset value */
+ /******************************************************/
+ i_APCI3200_ReadCalibrationOffsetValue
+ (dev, &ui_DummyValue);
+ } //if (i_CalibrationFlag == 0)
+ /**********************************************************/
+ /* Test if the value read is the calibration offset value */
+ /**********************************************************/
+
+ if (i_CalibrationFlag == 1) {
+
+ /******************/
+ /* Save the value */
+ /******************/
+
+ //ui_InterruptChannelValue[i_Count + 1] = ui_DigitalInput;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->minor].
+ i_Count + 1] = ui_DigitalInput;
+
+ /******************************************************/
+ /* Start the conversion of the calibration gain value */
+ /******************************************************/
+ i_APCI3200_ReadCalibrationGainValue(dev,
+ &ui_DummyValue);
+ } //if (i_CalibrationFlag == 1)
+ /******************************************************/
+ /*Test if the value read is the calibration gain value */
+ /******************************************************/
+
+ if (i_CalibrationFlag == 2) {
+
+ /****************/
+ /*Save the value */
+ /****************/
+ //ui_InterruptChannelValue[i_Count + 2] = ui_DigitalInput;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->minor].
+ i_Count + 2] = ui_DigitalInput;
+ //if(i_ScanType==1)
+ if (s_BoardInfos[dev->minor].
+ i_ScanType == 1) {
+
+ //i_InterruptFlag=0;
+ s_BoardInfos[dev->minor].
+ i_InterruptFlag = 0;
+ //i_Count=i_Count + 6;
+ //Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ //s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count + 6;
+ s_BoardInfos[dev->minor].
+ i_Count =
+ s_BoardInfos[dev->
+ minor].i_Count + 9;
+ //End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ } //if(i_ScanType==1)
+ else {
+ //i_Count=0;
+ s_BoardInfos[dev->minor].
+ i_Count = 0;
+ } //elseif(i_ScanType==1)
+ //if(i_ScanType!=1)
+ if (s_BoardInfos[dev->minor].
+ i_ScanType != 1) {
+ i_ReturnValue = send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
+ } //if(i_ScanType!=1)
+ else {
+ //if(i_ChannelCount==i_Sum)
+ if (s_BoardInfos[dev->minor].
+ i_ChannelCount ==
+ s_BoardInfos[dev->
+ minor].i_Sum) {
+ send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
+ }
+ } //if(i_ScanType!=1)
+ } //if (i_CalibrationFlag == 2)
+ } // if ((ui_StatusRegister & 0x2) == 0x2)
+
+ break;
+
+ case 2:
+ /************************************/
+ /*Read the interrupt status register */
+ /************************************/
+
+ //ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16);
+ ui_StatusRegister =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 16);
+ /*************************/
+ /*Test if interrupt occur */
+ /*************************/
+
+ if ((ui_StatusRegister & 0x2) == 0x2) {
+
+ //i_CJCFlag = ((inl(devpriv->iobase+i_Offset + 4) & 0x00000400) >> 10);
+ i_CJCFlag =
+ ((inl(devpriv->iobase +
+ s_BoardInfos[dev->
+ minor].
+ i_Offset +
+ 4) & 0x00000400) >> 10);
+
+ //i_CalibrationFlag = ((inl(devpriv->iobase+i_Offset + 12) & 0x00060000) >> 17);
+ i_CalibrationFlag =
+ ((inl(devpriv->iobase +
+ s_BoardInfos[dev->
+ minor].
+ i_Offset +
+ 12) & 0x00060000) >>
+ 17);
+
+ /*************************/
+ /*Read the channel number */
+ /*************************/
+
+ //ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24);
+ ui_ChannelNumber =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 24);
+ //Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ s_BoardInfos[dev->minor].ui_Channel_num =
+ ui_ChannelNumber;
+ //End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+ /************************************/
+ /*Read the digital temperature value */
+ /************************************/
+ //ui_DigitalTemperature = inl(devpriv->iobase+i_Offset + 28);
+ ui_DigitalTemperature =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 28);
+
+ /*********************************************/
+ /*Test if the value read is the channel value */
+ /*********************************************/
+
+ if ((i_CalibrationFlag == 0)
+ && (i_CJCFlag == 0)) {
+ //ui_InterruptChannelValue[i_Count + 0]=ui_DigitalTemperature;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->minor].
+ i_Count + 0] =
+ ui_DigitalTemperature;
+
+ /*********************************/
+ /*Start the conversion of the CJC */
+ /*********************************/
+ i_APCI3200_ReadCJCValue(dev,
+ &ui_DummyValue);
+
+ } //if ((i_CalibrationFlag == 0) && (i_CJCFlag == 0))
+
+ /*****************************************/
+ /*Test if the value read is the CJC value */
+ /*****************************************/
+
+ if ((i_CJCFlag == 1)
+ && (i_CalibrationFlag == 0)) {
+ //ui_InterruptChannelValue[i_Count + 3]=ui_DigitalTemperature;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->minor].
+ i_Count + 3] =
+ ui_DigitalTemperature;
+
+ /******************************************************/
+ /*Start the conversion of the calibration offset value */
+ /******************************************************/
+ i_APCI3200_ReadCalibrationOffsetValue
+ (dev, &ui_DummyValue);
+ } // if ((i_CJCFlag == 1) && (i_CalibrationFlag == 0))
+
+ /********************************************************/
+ /*Test if the value read is the calibration offset value */
+ /********************************************************/
+
+ if ((i_CalibrationFlag == 1)
+ && (i_CJCFlag == 0)) {
+ //ui_InterruptChannelValue[i_Count + 1]=ui_DigitalTemperature;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->minor].
+ i_Count + 1] =
+ ui_DigitalTemperature;
+
+ /****************************************************/
+ /*Start the conversion of the calibration gain value */
+ /****************************************************/
+ i_APCI3200_ReadCalibrationGainValue(dev,
+ &ui_DummyValue);
+
+ } //if ((i_CalibrationFlag == 1) && (i_CJCFlag == 0))
+
+ /******************************************************/
+ /*Test if the value read is the calibration gain value */
+ /******************************************************/
+
+ if ((i_CalibrationFlag == 2)
+ && (i_CJCFlag == 0)) {
+ //ui_InterruptChannelValue[i_Count + 2]=ui_DigitalTemperature;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->minor].
+ i_Count + 2] =
+ ui_DigitalTemperature;
+
+ /**********************************************************/
+ /*Test if the Calibration channel must be read for the CJC */
+ /**********************************************************/
+
+ /*Test if the polarity is the same */
+ /**********************************/
+ //if(i_CJCPolarity!=i_ADDIDATAPolarity)
+ if (s_BoardInfos[dev->minor].
+ i_CJCPolarity !=
+ s_BoardInfos[dev->minor].
+ i_ADDIDATAPolarity) {
+ i_ConvertCJCCalibration = 1;
+ } //if(i_CJCPolarity!=i_ADDIDATAPolarity)
+ else {
+ //if(i_CJCGain==i_ADDIDATAGain)
+ if (s_BoardInfos[dev->minor].
+ i_CJCGain ==
+ s_BoardInfos[dev->
+ minor].
+ i_ADDIDATAGain) {
+ i_ConvertCJCCalibration
+ = 0;
+ } //if(i_CJCGain==i_ADDIDATAGain)
+ else {
+ i_ConvertCJCCalibration
+ = 1;
+ } //elseif(i_CJCGain==i_ADDIDATAGain)
+ } //elseif(i_CJCPolarity!=i_ADDIDATAPolarity)
+ if (i_ConvertCJCCalibration == 1) {
+ /****************************************************************/
+ /*Start the conversion of the calibration gain value for the CJC */
+ /****************************************************************/
+ i_APCI3200_ReadCJCCalOffset(dev,
+ &ui_DummyValue);
+
+ } //if(i_ConvertCJCCalibration==1)
+ else {
+ //ui_InterruptChannelValue[i_Count + 4]=0;
+ //ui_InterruptChannelValue[i_Count + 5]=0;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->
+ minor].i_Count +
+ 4] = 0;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->
+ minor].i_Count +
+ 5] = 0;
+ } //elseif(i_ConvertCJCCalibration==1)
+ } //else if ((i_CalibrationFlag == 2) && (i_CJCFlag == 0))
+
+ /********************************************************************/
+ /*Test if the value read is the calibration offset value for the CJC */
+ /********************************************************************/
+
+ if ((i_CalibrationFlag == 1)
+ && (i_CJCFlag == 1)) {
+ //ui_InterruptChannelValue[i_Count + 4]=ui_DigitalTemperature;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->minor].
+ i_Count + 4] =
+ ui_DigitalTemperature;
+
+ /****************************************************************/
+ /*Start the conversion of the calibration gain value for the CJC */
+ /****************************************************************/
+ i_APCI3200_ReadCJCCalGain(dev,
+ &ui_DummyValue);
+
+ } //if ((i_CalibrationFlag == 1) && (i_CJCFlag == 1))
+
+ /******************************************************************/
+ /*Test if the value read is the calibration gain value for the CJC */
+ /******************************************************************/
+
+ if ((i_CalibrationFlag == 2)
+ && (i_CJCFlag == 1)) {
+ //ui_InterruptChannelValue[i_Count + 5]=ui_DigitalTemperature;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->minor].
+ i_Count + 5] =
+ ui_DigitalTemperature;
+
+ //if(i_ScanType==1)
+ if (s_BoardInfos[dev->minor].
+ i_ScanType == 1) {
+
+ //i_InterruptFlag=0;
+ s_BoardInfos[dev->minor].
+ i_InterruptFlag = 0;
+ //i_Count=i_Count + 6;
+ //Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ //s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count + 6;
+ s_BoardInfos[dev->minor].
+ i_Count =
+ s_BoardInfos[dev->
+ minor].i_Count + 9;
+ //End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ } //if(i_ScanType==1)
+ else {
+ //i_Count=0;
+ s_BoardInfos[dev->minor].
+ i_Count = 0;
+ } //elseif(i_ScanType==1)
+
+ //if(i_ScanType!=1)
+ if (s_BoardInfos[dev->minor].
+ i_ScanType != 1) {
+ send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
+ } //if(i_ScanType!=1)
+ else {
+ //if(i_ChannelCount==i_Sum)
+ if (s_BoardInfos[dev->minor].
+ i_ChannelCount ==
+ s_BoardInfos[dev->
+ minor].i_Sum) {
+ send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
+
+ } //if(i_ChannelCount==i_Sum)
+ } //else if(i_ScanType!=1)
+ } //if ((i_CalibrationFlag == 2) && (i_CJCFlag == 1))
+
+ } //else if ((ui_StatusRegister & 0x2) == 0x2)
+ break;
+ } //switch(i_ADDIDATAType)
+ break;
+ case 2:
+ case 3:
+ i_APCI3200_InterruptHandleEos(dev);
+ break;
+ } //switch(i_ScanType)
+ return;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function name :int i_APCI3200_InterruptHandleEos(struct comedi_device *dev) |
+ | |
+ | |
+ +----------------------------------------------------------------------------+
+ | Task : . |
+ | This function copies the acquired data(from FIFO) |
+ | to Comedi buffer. |
+ | |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev |
+ | |
+ | |
+ +----------------------------------------------------------------------------+
+ | Return Value : 0 |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+int i_APCI3200_InterruptHandleEos(struct comedi_device * dev)
+{
+ UINT ui_StatusRegister = 0;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+
+ //BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ //comedi_async *async = s->async;
+ //UINT *data;
+ //data=async->data+async->buf_int_ptr;//new samples added from here onwards
+ int n = 0, i = 0;
+ //END JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+
+ /************************************/
+ /*Read the interrupt status register */
+ /************************************/
+ //ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16);
+ ui_StatusRegister =
+ inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 16);
+
+ /*************************/
+ /*Test if interrupt occur */
+ /*************************/
+
+ if ((ui_StatusRegister & 0x2) == 0x2) {
+ /*************************/
+ /*Read the channel number */
+ /*************************/
+ //ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24);
+ //BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ //This value is not used
+ //ui_ChannelNumber = inl(devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 24);
+ s->async->events = 0;
+ //END JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+
+ /*************************************/
+ /*Read the digital Analog Input value */
+ /*************************************/
+
+ //data[i_Count] = inl(devpriv->iobase+i_Offset + 28);
+ //Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ //data[s_BoardInfos [dev->minor].i_Count] = inl(devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 28);
+ s_BoardInfos[dev->minor].ui_ScanValueArray[s_BoardInfos[dev->
+ minor].i_Count] =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 28);
+ //End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+
+ //if((i_Count == (i_LastChannel-i_FirstChannel+3)))
+ if ((s_BoardInfos[dev->minor].i_Count ==
+ (s_BoardInfos[dev->minor].i_LastChannel -
+ s_BoardInfos[dev->minor].
+ i_FirstChannel + 3))) {
+
+ //Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ s_BoardInfos[dev->minor].i_Count++;
+
+ for (i = s_BoardInfos[dev->minor].i_FirstChannel;
+ i <= s_BoardInfos[dev->minor].i_LastChannel;
+ i++) {
+ i_APCI3200_GetChannelCalibrationValue(dev, i,
+ &s_BoardInfos[dev->minor].
+ ui_ScanValueArray[s_BoardInfos[dev->
+ minor].i_Count + ((i -
+ s_BoardInfos
+ [dev->minor].
+ i_FirstChannel)
+ * 3)],
+ &s_BoardInfos[dev->minor].
+ ui_ScanValueArray[s_BoardInfos[dev->
+ minor].i_Count + ((i -
+ s_BoardInfos
+ [dev->minor].
+ i_FirstChannel)
+ * 3) + 1],
+ &s_BoardInfos[dev->minor].
+ ui_ScanValueArray[s_BoardInfos[dev->
+ minor].i_Count + ((i -
+ s_BoardInfos
+ [dev->minor].
+ i_FirstChannel)
+ * 3) + 2]);
+ }
+
+ //End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+ //i_Count=-1;
+
+ s_BoardInfos[dev->minor].i_Count = -1;
+
+ //async->buf_int_count+=(i_LastChannel-i_FirstChannel+4)*sizeof(UINT);
+ //Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ //async->buf_int_count+=(s_BoardInfos [dev->minor].i_LastChannel-s_BoardInfos [dev->minor].i_FirstChannel+4)*sizeof(UINT);
+ //End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ //async->buf_int_ptr+=(i_LastChannel-i_FirstChannel+4)*sizeof(UINT);
+ //Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ //async->buf_int_ptr+=(s_BoardInfos [dev->minor].i_LastChannel-s_BoardInfos [dev->minor].i_FirstChannel+4)*sizeof(UINT);
+ //comedi_eos(dev,s);
+
+ // Set the event type (Comedi Buffer End Of Scan)
+ s->async->events |= COMEDI_CB_EOS;
+
+ // Test if enougth memory is available and allocate it for 7 values
+ //n = comedi_buf_write_alloc(s->async, 7*sizeof(unsigned int));
+ n = comedi_buf_write_alloc(s->async,
+ (7 + 12) * sizeof(unsigned int));
+
+ // If not enougth memory available, event is set to Comedi Buffer Errror
+ if (n > ((7 + 12) * sizeof(unsigned int))) {
+ printk("\ncomedi_buf_write_alloc n = %i", n);
+ s->async->events |= COMEDI_CB_ERROR;
+ }
+ // Write all 7 scan values in the comedi buffer
+ comedi_buf_memcpy_to(s->async, 0,
+ (unsigned int *) s_BoardInfos[dev->minor].
+ ui_ScanValueArray, (7 + 12) * sizeof(unsigned int));
+
+ // Update comedi buffer pinters indexes
+ comedi_buf_write_free(s->async,
+ (7 + 12) * sizeof(unsigned int));
+
+ // Send events
+ comedi_event(dev, s);
+ //End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+
+ //BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ //
+ //if (s->async->buf_int_ptr>=s->async->data_len) // for buffer rool over
+ // {
+ // /* buffer rollover */
+ // s->async->buf_int_ptr=0;
+ // comedi_eobuf(dev,s);
+ // }
+ //End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ }
+ //i_Count++;
+ s_BoardInfos[dev->minor].i_Count++;
+ }
+ //i_InterruptFlag=0;
+ s_BoardInfos[dev->minor].i_InterruptFlag = 0;
+ return 0;
+}