--- /dev/null
+/*\r
+ +-----------------------------------------------------------------------+\r
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |\r
+ +-----------------------------------------------------------------------+\r
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |\r
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |\r
+ +-----------------------------------------------------------------------+\r
+ | Project : API APCI1710 | Compiler : BORLANDC/MICROSOFT C |\r
+ | Module name : 82X54.C | Version : 3.1 / 6.0 |\r
+ +-------------------------------+---------------------------------------+\r
+ | Author : S.WEBER | Date : 29.06.98 |\r
+ +-----------------------------------------------------------------------+\r
+ | Description : APCI-1710 82X54 timer module |\r
+ | |\r
+ | |\r
+ +-----------------------------------------------------------------------+\r
+ | UPDATES |\r
+ +-----------------------------------------------------------------------+\r
+ | Date | Author | Description of updates |\r
+ +----------+-----------+------------------------------------------------+\r
+ | 29/06/98 | S. Weber | Digital input / output implementation |\r
+ |----------|-----------|------------------------------------------------|\r
+ | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |\r
+ | | | available |\r
+ +-----------------------------------------------------------------------+\r
+ | | | |\r
+ | | | |\r
+ +-----------------------------------------------------------------------+\r
+*/\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Included files |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+\r
+#include "APCI1710_82x54.h"\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_InitTimer |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_TimerNbr, |\r
+| BYTE_ b_TimerMode, |\r
+| ULONG_ ul_ReloadValue, |\r
+| BYTE_ b_InputClockSelection, |\r
+| BYTE_ b_InputClockLevel, |\r
+| BYTE_ b_OutputLevel, |\r
+| BYTE_ b_HardwareGateLevel)\r
+INT i_InsnConfig_InitTimer(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data)\r
+| \r
++----------------------------------------------------------------------------+\r
+| Task : Configure the Timer (b_TimerNbr) operating mode |\r
+| (b_TimerMode) from selected module (b_ModulNbr). |\r
+| You must calling this function be for you call any |\r
+| other function witch access of the timer. |\r
+| |\r
+| |\r
+| Timer mode description table |\r
+| |\r
+|+--------+-----------------------------+--------------+--------------------+|\r
+||Selected+ Mode description +u_ReloadValue | Hardware gate input||\r
+|| mode | | description | action ||\r
+|+--------+-----------------------------+--------------+--------------------+|\r
+|| |Mode 0 is typically used | | ||\r
+|| |for event counting. After | | ||\r
+|| |the initialisation, OUT | | ||\r
+|| |is initially low, and | | ||\r
+|| 0 |will remain low until the |Start counting| Hardware gate ||\r
+|| |counter reaches zero. | value | ||\r
+|| |OUT then goes high and | | ||\r
+|| |remains high until a new | | ||\r
+|| |count is written. See | | ||\r
+|| |"i_APCI1710_WriteTimerValue" | | ||\r
+|| |function. | | ||\r
+|+--------+-----------------------------+--------------+--------------------+|\r
+|| |Mode 1 is similar to mode 0 | | ||\r
+|| |except for the gate input | | ||\r
+|| 1 |action. The gate input is not|Start counting| Hardware trigger ||\r
+|| |used for enabled or disabled | value | ||\r
+|| |the timer. | | ||\r
+|| |The gate input is used for | | ||\r
+|| |triggered the timer. | | ||\r
+|+--------+-----------------------------+--------------+--------------------+|\r
+|| |This mode functions like a | | ||\r
+|| |divide-by-ul_ReloadValue | | ||\r
+|| |counter. It is typically used| | ||\r
+|| |to generate a real time clock| | ||\r
+|| |interrupt. OUT will initially| | ||\r
+|| 2 |be high after the | Division | Hardware gate ||\r
+|| |initialisation. When the | factor | ||\r
+|| |initial count has decremented| | ||\r
+|| |to 1, OUT goes low for one | | ||\r
+|| |CLK pule. OUT then goes high | | ||\r
+|| |again, the counter reloads | | ||\r
+|| |the initial count | | ||\r
+|| |(ul_ReloadValue) and the | | ||\r
+|| |process is repeated. | | ||\r
+|| |This action can generated a | | ||\r
+|| |interrupt. See function | | ||\r
+|| |"i_APCI1710_SetBoardInt- | | ||\r
+|| |RoutineX" | | ||\r
+|| |and "i_APCI1710_EnableTimer" | | ||\r
+|+--------+-----------------------------+--------------+--------------------+|\r
+|| |Mode 3 is typically used for | | ||\r
+|| |baud rate generation. This | | ||\r
+|| |mode is similar to mode 2 | | ||\r
+|| |except for the duty cycle of | | ||\r
+|| 3 |OUT. OUT will initially be | Division | Hardware gate ||\r
+|| |high after the initialisation| factor | ||\r
+|| |When half the initial count | | ||\r
+|| |(ul_ReloadValue) has expired,| | ||\r
+|| |OUT goes low for the | | ||\r
+|| |remainder of the count. The | | ||\r
+|| |mode is periodic; the | | ||\r
+|| |sequence above is repeated | | ||\r
+|| |indefinitely. | | ||\r
+|+--------+-----------------------------+--------------+--------------------+|\r
+|| |OUT will be initially high | | ||\r
+|| |after the initialisation. | | ||\r
+|| |When the initial count | | ||\r
+|| 4 |expires OUT will go low for |Start counting| Hardware gate ||\r
+|| |one CLK pulse and then go | value | ||\r
+|| |high again. | | ||\r
+|| |The counting sequences is | | ||\r
+|| |triggered by writing a new | | ||\r
+|| |value. See | | ||\r
+|| |"i_APCI1710_WriteTimerValue" | | ||\r
+|| |function. If a new count is | | ||\r
+|| |written during counting, | | ||\r
+|| |it will be loaded on the | | ||\r
+|| |next CLK pulse | | ||\r
+|+--------+-----------------------------+--------------+--------------------+|\r
+|| |Mode 5 is similar to mode 4 | | ||\r
+|| |except for the gate input | | ||\r
+|| |action. The gate input is not| | ||\r
+|| 5 |used for enabled or disabled |Start counting| Hardware trigger ||\r
+|| |the timer. The gate input is | value | ||\r
+|| |used for triggered the timer.| | ||\r
+|+--------+-----------------------------+--------------+--------------------+|\r
+| |\r
+| |\r
+| |\r
+| Input clock selection table |\r
+| |\r
+| +--------------------------------+------------------------------------+ |\r
+| | b_InputClockSelection | Description | |\r
+| | parameter | | |\r
+| +--------------------------------+------------------------------------+ |\r
+| | APCI1710_PCI_BUS_CLOCK | For the timer input clock, the PCI | |\r
+| | | bus clock / 4 is used. This PCI bus| |\r
+| | | clock can be 30MHz or 33MHz. For | |\r
+| | | Timer 0 only this selection are | |\r
+| | | available. | |\r
+| +--------------------------------+------------------------------------+ |\r
+| | APCI1710_ FRONT_CONNECTOR_INPUT| Of the front connector you have the| |\r
+| | | possibility to inject a input clock| |\r
+| | | for Timer 1 or Timer 2. The source | |\r
+| | | from this clock can eat the output | |\r
+| | | clock from Timer 0 or any other | |\r
+| | | clock source. | |\r
+| +--------------------------------+------------------------------------+ |\r
+| |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board |\r
+| APCI-1710 |\r
+| BYTE_ b_ModulNbr : Module number to |\r
+| configure (0 to 3) |\r
+| BYTE_ b_TimerNbr : Timer number to |\r
+| configure (0 to 2) |\r
+| BYTE_ b_TimerMode : Timer mode selection |\r
+| (0 to 5) |\r
+| 0: Interrupt on terminal|\r
+| count |\r
+| 1: Hardware |\r
+| retriggerable one- |\r
+| shot |\r
+| 2: Rate generator |\r
+| 3: Square wave mode |\r
+| 4: Software triggered |\r
+| strobe |\r
+| 5: Hardware triggered |\r
+| strobe |\r
+| See timer mode |\r
+| description table. |\r
+| ULONG_ ul_ReloadValue : Start counting value |\r
+| or division factor |\r
+| See timer mode |\r
+| description table. |\r
+| BYTE_ b_InputClockSelection : Selection from input |\r
+| timer clock. |\r
+| See input clock |\r
+| selection table. |\r
+| BYTE_ b_InputClockLevel : Selection from input |\r
+| clock level. |\r
+| 0 : Low active |\r
+| (Input inverted) |\r
+| 1 : High active |\r
+| BYTE_ b_OutputLevel, : Selection from output |\r
+| clock level. |\r
+| 0 : Low active |\r
+| 1 : High active |\r
+| (Output inverted) |\r
+| BYTE_ b_HardwareGateLevel : Selection from |\r
+| hardware gate level. |\r
+| 0 : Low active |\r
+| (Input inverted) |\r
+| 1 : High active |\r
+| If you will not used |\r
+| the hardware gate set |\r
+| this value to 0. \r
+|b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);\r
+ b_TimerNbr = (BYTE) CR_CHAN(insn->chanspec);\r
+ b_TimerMode = (BYTE) data[0];\r
+ ul_ReloadValue = (ULONG) data[1];\r
+ b_InputClockSelection =(BYTE) data[2];\r
+ b_InputClockLevel =(BYTE) data[3];\r
+ b_OutputLevel =(BYTE) data[4];\r
+ b_HardwareGateLevel =(BYTE) data[5];\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: Module selection wrong |\r
+| -3: Timer selection wrong |\r
+| -4: The module is not a TIMER module |\r
+| -5: Timer mode selection is wrong |\r
+| -6: Input timer clock selection is wrong |\r
+| -7: Selection from input clock level is wrong |\r
+| -8: Selection from output clock level is wrong |\r
+| -9: Selection from hardware gate level is wrong |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+
+INT i_APCI1710_InsnConfigInitTimer(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data)\r
+ {\r
+\r
+ INT i_ReturnValue = 0; \r
+ BYTE b_ModulNbr;\r
+ BYTE b_TimerNbr;\r
+ BYTE b_TimerMode;\r
+ ULONG ul_ReloadValue;\r
+ BYTE b_InputClockSelection;\r
+ BYTE b_InputClockLevel;\r
+ BYTE b_OutputLevel;\r
+ BYTE b_HardwareGateLevel;\r
+\r
+ i_ReturnValue=insn->n;\r
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);\r
+ b_TimerNbr = (BYTE) CR_CHAN(insn->chanspec);\r
+ b_TimerMode = (BYTE) data[0];\r
+ ul_ReloadValue = (ULONG) data[1];\r
+ b_InputClockSelection =(BYTE) data[2];\r
+ b_InputClockLevel =(BYTE) data[3];\r
+ b_OutputLevel =(BYTE) data[4];\r
+ b_HardwareGateLevel =(BYTE) data[5];\r
+\r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /***********************/\r
+ /* Test if 82X54 timer */\r
+ /***********************/\r
+\r
+ if ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER)\r
+ {\r
+ /*************************/\r
+ /* Test the timer number */\r
+ /*************************/\r
+\r
+ if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))\r
+ {\r
+ /***********************/\r
+ /* Test the timer mode */\r
+ /***********************/\r
+\r
+ if ((b_TimerMode >= 0) && (b_TimerMode <= 5))\r
+ {\r
+ /*********************************/\r
+ /* Test te imput clock selection */\r
+ /*********************************/\r
+\r
+ if (((b_TimerNbr == 0) && (b_InputClockSelection == 0)) ||\r
+ ((b_TimerNbr != 0) && ((b_InputClockSelection == 0) || (b_InputClockSelection == 1))))\r
+ {\r
+ /****************************************/\r
+ /* Test the input clock level selection */\r
+ /****************************************/\r
+\r
+ if ((b_InputClockLevel == 0) || (b_InputClockLevel == 1))\r
+ {\r
+ /*****************************************/\r
+ /* Test the output clock level selection */\r
+ /*****************************************/\r
+\r
+ if ((b_OutputLevel == 0) || (b_OutputLevel == 1))\r
+ {\r
+ /******************************************/\r
+ /* Test the hardware gate level selection */\r
+ /******************************************/\r
+\r
+ if ((b_HardwareGateLevel == 0) || (b_HardwareGateLevel == 1))\r
+ {\r
+ /*********************/\r
+ /* Initialisation OK */\r
+ /*********************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_82X54ModuleInfo.\r
+ s_82X54TimerInfo [b_TimerNbr].\r
+ b_82X54Init = 1;\r
+\r
+ /**********************************/\r
+ /* Save the input clock selection */\r
+ /**********************************/\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_82X54ModuleInfo.\r
+ s_82X54TimerInfo [b_TimerNbr].\r
+ b_InputClockSelection = b_InputClockSelection;\r
+\r
+ /******************************/\r
+ /* Save the input clock level */\r
+ /******************************/\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_82X54ModuleInfo.\r
+ s_82X54TimerInfo [b_TimerNbr].\r
+ b_InputClockLevel = ~b_InputClockLevel & 1;\r
+\r
+ /*************************/\r
+ /* Save the output level */\r
+ /*************************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_82X54ModuleInfo.\r
+ s_82X54TimerInfo [b_TimerNbr].\r
+ b_OutputLevel = ~b_OutputLevel & 1;\r
+\r
+ /***********************/\r
+ /* Save the gate level */\r
+ /***********************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_82X54ModuleInfo.\r
+ s_82X54TimerInfo [b_TimerNbr].\r
+ b_HardwareGateLevel = b_HardwareGateLevel;\r
+\r
+ /****************************************************/\r
+ /* Set the configuration word and disable the timer */\r
+ /****************************************************/\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_82X54ModuleInfo.\r
+ s_82X54TimerInfo [b_TimerNbr].\r
+ dw_ConfigurationWord = (DWORD) (((b_HardwareGateLevel << 0) & 0x1) |\r
+ ((b_InputClockLevel << 1) & 0x2) |\r
+ (((~b_OutputLevel & 1) << 2) & 0x4) |\r
+ ((b_InputClockSelection << 4) & 0x10));\r
+\r
+
+ outl(devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_82X54ModuleInfo.s_82X54TimerInfo [b_TimerNbr].\r
+ dw_ConfigurationWord, devpriv->s_BoardInfos.\r
+ ui_Address + 32 + (b_TimerNbr * 4) + (64 * b_ModulNbr));\r
+\r
+ /******************************/\r
+ /* Initialise the 82X54 Timer */\r
+ /******************************/\r
+\r
+
+ outl((DWORD) b_TimerMode,devpriv->s_BoardInfos.\r
+ ui_Address + 16 + (b_TimerNbr * 4) + (64 * b_ModulNbr));\r
+\r
+ /**************************/\r
+ /* Write the reload value */\r
+ /**************************/\r
+\r
+
+ outl(ul_ReloadValue,devpriv->s_BoardInfos.\r
+ ui_Address + 0 + (b_TimerNbr * 4) + (64 * b_ModulNbr));\r
+\r
+ } // if ((b_HardwareGateLevel == 0) || (b_HardwareGateLevel == 1))\r
+ else\r
+ {\r
+ /***********************************************/\r
+ /* Selection from hardware gate level is wrong */\r
+ /***********************************************/\r
+\r DPRINTK("Selection from hardware gate level is wrong\n");
+ i_ReturnValue = -9;\r
+ } // if ((b_HardwareGateLevel == 0) || (b_HardwareGateLevel == 1))\r
+ } // if ((b_OutputLevel == 0) || (b_OutputLevel == 1))\r
+ else\r
+ {\r
+ /**********************************************/\r
+ /* Selection from output clock level is wrong */\r
+ /**********************************************/\r
+\r DPRINTK("Selection from output clock level is wrong\n");
+ i_ReturnValue = -8;\r
+ } // if ((b_OutputLevel == 0) || (b_OutputLevel == 1))\r
+ } // if ((b_InputClockLevel == 0) || (b_InputClockLevel == 1))\r
+ else\r
+ {\r
+ /*********************************************/\r
+ /* Selection from input clock level is wrong */\r
+ /*********************************************/\r
+\r DPRINTK("Selection from input clock level is wrong\n");
+ i_ReturnValue = -7;\r
+ } // if ((b_InputClockLevel == 0) || (b_InputClockLevel == 1))\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Input timer clock selection is wrong */\r
+ /****************************************/\r
+\r DPRINTK("Input timer clock selection is wrong\n");
+ i_ReturnValue = -6;\r
+ }\r
+ } // if ((b_TimerMode >= 0) && (b_TimerMode <= 5))\r
+ else\r
+ {\r
+ /*********************************/\r
+ /* Timer mode selection is wrong */\r
+ /*********************************/\r
+\r DPRINTK("Timer mode selection is wrong\n");
+ i_ReturnValue = -5;\r
+ } // if ((b_TimerMode >= 0) && (b_TimerMode <= 5))\r
+ } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))\r
+ else\r
+ {\r
+ /*************************/\r
+ /* Timer selection wrong */\r
+ /*************************/\r
+\r DPRINTK("Timer selection wrong\n");
+ i_ReturnValue = -3;\r
+ } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))\r
+ }\r
+ else\r
+ {\r
+ /************************************/\r
+ /* The module is not a TIMER module */\r
+ /************************************/\r
+\r DPRINTK("The module is not a TIMER module\n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***********************/\r
+ /* Module number error */\r
+ /***********************/\r
+\r DPRINTK("Module number error\n");
+ i_ReturnValue = -2;\r
+ }\r
+
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_EnableTimer |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_TimerNbr, |\r
+| BYTE_ b_InterruptEnable) \r
+INT i_APCI1710_InsnWriteEnableDisableTimer(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data) |\r
++----------------------------------------------------------------------------+\r
+| Task : Enable OR Disable the Timer (b_TimerNbr) from selected module |\r
+| (b_ModulNbr). You must calling the |\r
+| "i_APCI1710_InitTimer" function be for you call this |\r
+| function. If you enable the timer interrupt, the timer |\r
+| generate a interrupt after the timer value reach |\r
+| the zero. See function "i_APCI1710_SetBoardIntRoutineX"|\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board |\r
+| APCI-1710 |\r
+| BYTE_ b_ModulNbr : Selected module number |\r
+| (0 to 3) |\r
+| BYTE_ b_TimerNbr : Timer number to enable |\r
+| (0 to 2) |\r
+| BYTE_ b_InterruptEnable : Enable or disable the |\r
+| timer interrupt. |\r
+| APCI1710_ENABLE : |\r
+| Enable the timer interrupt |\r
+| APCI1710_DISABLE : |\r
+| Disable the timer interrupt|\r
+i_ReturnValue=insn->n;\r
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);\r
+ b_TimerNbr = (BYTE) CR_CHAN(insn->chanspec);\r
+ b_ActionType = (BYTE) data[0]; // enable disable \r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: Module selection wrong |\r
+| -3: Timer selection wrong |\r
+| -4: The module is not a TIMER module |\r
+| -5: Timer not initialised see function |\r
+| "i_APCI1710_InitTimer" |\r
+| -6: Interrupt parameter is wrong |\r
+| -7: Interrupt function not initialised. |\r
+| See function "i_APCI1710_SetBoardIntRoutineX" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_InsnWriteEnableDisableTimer(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ DWORD dw_DummyRead;\r
+ BYTE b_ModulNbr;\r
+ BYTE b_TimerNbr;\r
+ BYTE b_ActionType;\r
+ BYTE b_InterruptEnable;\r
+\r
+ i_ReturnValue=insn->n;\r
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);\r
+ b_TimerNbr = (BYTE) CR_CHAN(insn->chanspec);\r
+ b_ActionType = (BYTE) data[0]; // enable disable \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /***********************/\r
+ /* Test if 82X54 timer */\r
+ /***********************/\r
+\r
+ if ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER)\r
+ {\r
+ /*************************/\r
+ /* Test the timer number */\r
+ /*************************/\r
+\r
+ if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))\r
+ {\r
+ /*****************************/\r
+ /* Test if timer initialised */\r
+ /*****************************/\r
+\r
+ if (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_82X54ModuleInfo.\r
+ s_82X54TimerInfo [b_TimerNbr].\r
+ b_82X54Init == 1)\r
+ {\r
+\r
+ switch(b_ActionType)\r
+ { \r
+ case APCI1710_ENABLE:\r
+\r
+ b_InterruptEnable = (BYTE) data[1];\r
+ /********************************/\r
+ /* Test the interrupt selection */\r
+ /********************************/\r
+\r
+ if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE))\r
+ {\r
+ if (b_InterruptEnable == APCI1710_ENABLE)\r
+ {\r
+
+ dw_DummyRead=inl(devpriv->s_BoardInfos.\r
+ ui_Address + 12 + (b_TimerNbr * 4) + (64 * b_ModulNbr));\r
+\r
+ /************************/\r
+ /* Enable the interrupt */\r
+ /************************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_82X54ModuleInfo.\r
+ s_82X54TimerInfo [b_TimerNbr].\r
+ dw_ConfigurationWord = devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_82X54ModuleInfo.\r
+ s_82X54TimerInfo [b_TimerNbr].\r
+ dw_ConfigurationWord | 0x8;\r
+\r
+ \r
+ outl(devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_82X54ModuleInfo.\r
+ s_82X54TimerInfo [b_TimerNbr].\r
+ dw_ConfigurationWord,devpriv->s_BoardInfos.\r
+ ui_Address + 32 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+ devpriv->tsk_Current=current; // Save the current process task structure\r
+ \r
+
+ } // if (b_InterruptEnable == APCI1710_ENABLE)\r
+ else\r
+ {\r
+ /*************************/\r
+ /* Disable the interrupt */\r
+ /*************************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_82X54ModuleInfo.\r
+ s_82X54TimerInfo [b_TimerNbr].\r
+ dw_ConfigurationWord = devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_82X54ModuleInfo.\r
+ s_82X54TimerInfo [b_TimerNbr].\r
+ dw_ConfigurationWord & 0xF7;\r
+\r
+ \r
+ outl(devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_82X54ModuleInfo.\r
+ s_82X54TimerInfo [b_TimerNbr].\r
+ dw_ConfigurationWord,devpriv->s_BoardInfos.\r
+ ui_Address + 32 + (b_TimerNbr * 4) + (64 * b_ModulNbr));\r
+\r
+ /***************************/\r
+ /* Save the interrupt flag */\r
+ /***************************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_82X54ModuleInfo.\r
+ b_InterruptMask = devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_82X54ModuleInfo.\r
+ b_InterruptMask & (0xFF - (1 << b_TimerNbr));\r
+ } // if (b_InterruptEnable == APCI1710_ENABLE)\r
+\r
+ /***********************/\r
+ /* Test if error occur */\r
+ /***********************/\r
+\r
+ if (i_ReturnValue >= 0)\r
+ {\r
+ /***************************/\r
+ /* Save the interrupt flag */\r
+ /***************************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_82X54ModuleInfo.\r
+ b_InterruptMask = devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_82X54ModuleInfo.\r
+ b_InterruptMask | ((1 & b_InterruptEnable) << b_TimerNbr);\r
+\r
+\r
+ /********************/\r
+ /* Enable the timer */\r
+ /********************/\r
+\r
+ \r
+ outl(1,devpriv->s_BoardInfos.\r
+ ui_Address + 44 + (b_TimerNbr * 4) + (64 * b_ModulNbr));\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /********************************/\r
+ /* Interrupt parameter is wrong */\r
+ /********************************/\r
+\r DPRINTK("\n");
+ i_ReturnValue = -6;\r
+ }\r
+ break;\r
+ case APCI1710_DISABLE:\r
+ /***************************/\r
+ /* Test the interrupt flag */\r
+ /***************************/\r
+\r
+ if (((devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_82X54ModuleInfo.\r
+ b_InterruptMask >> b_TimerNbr) & 1) == 1)\r
+ {\r
+ /*************************/\r
+ /* Disable the interrupt */\r
+ /*************************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_82X54ModuleInfo.\r
+ s_82X54TimerInfo [b_TimerNbr].\r
+ dw_ConfigurationWord = devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_82X54ModuleInfo.\r
+ s_82X54TimerInfo [b_TimerNbr].\r
+ dw_ConfigurationWord & 0xF7;\r
+\r
+ \r
+ outl(devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_82X54ModuleInfo.\r
+ s_82X54TimerInfo [b_TimerNbr].\r
+ dw_ConfigurationWord,devpriv->s_BoardInfos.\r
+ ui_Address + 32 + (b_TimerNbr * 4) + (64 * b_ModulNbr));\r
+\r
+ /***************************/\r
+ /* Save the interrupt flag */\r
+ /***************************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_82X54ModuleInfo.\r
+ b_InterruptMask = devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_82X54ModuleInfo.b_InterruptMask & (0xFF - (1 << b_TimerNbr));\r
+ }\r
+\r
+ /*********************/\r
+ /* Disable the timer */\r
+ /*********************/\r
+\r
+
+ outl(0,devpriv->s_BoardInfos.\r
+ ui_Address + 44 + (b_TimerNbr * 4) + (64 * b_ModulNbr));\r
+ break; \r
+ }// Switch end\r
+ }\r
+ else\r
+ {\r
+ /**************************************/\r
+ /* Timer not initialised see function */\r
+ /**************************************/\r
+\r DPRINTK("Timer not initialised see function\n");
+ i_ReturnValue = -5;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************/\r
+ /* Timer selection wrong */\r
+ /*************************/\r
+\r DPRINTK("Timer selection wrong\n");
+ i_ReturnValue = -3;\r
+ } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))\r
+ }\r
+ else\r
+ {\r
+ /************************************/\r
+ /* The module is not a TIMER module */\r
+ /************************************/\r
+\r DPRINTK("The module is not a TIMER module\n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***********************/\r
+ /* Module number error */\r
+ /***********************/\r
+\r DPRINTK("Module number error\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+ \r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_ReadAllTimerValue |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| PULONG_ pul_TimerValueArray)\r
+INT i_APCI1710_InsnReadAllTimerValue(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data) |\r
++----------------------------------------------------------------------------+\r
+| Task : Return the all timer values from selected timer |\r
+| module (b_ModulNbr). |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board |\r
+| APCI-1710 |\r
+| BYTE_ b_ModulNbr : Selected module number |\r
+| (0 to 3) |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : PULONG_ pul_TimerValueArray : Timer value array. |\r
+| Element 0 contain the timer 0 value. |\r
+| Element 1 contain the timer 1 value. |\r
+| Element 2 contain the timer 2 value. |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: Module selection wrong |\r
+| -3: The module is not a TIMER module |\r
+| -4: Timer 0 not initialised see function |\r
+| "i_APCI1710_InitTimer" |\r
+| -5: Timer 1 not initialised see function |\r
+| "i_APCI1710_InitTimer" |\r
+| -6: Timer 2 not initialised see function |\r
+| "i_APCI1710_InitTimer" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_InsnReadAllTimerValue(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ BYTE b_ModulNbr,b_ReadType;\r
+ PULONG pul_TimerValueArray;\r
+\r
+ b_ModulNbr=CR_AREF(insn->chanspec);\r
+ b_ReadType=CR_CHAN(insn->chanspec);
+ pul_TimerValueArray=(PULONG) data;\r
+ i_ReturnValue=insn->n;\r
+
+ switch(b_ReadType)
+ {
+ case APCI1710_TIMER_READINTERRUPT:
+
+
+ data[0]=devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Read].b_OldModuleMask;
+ data[1]=devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Read].ul_OldInterruptMask;
+ data[2]=devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Read].ul_OldCounterLatchValue;
+
+
+ /**************************/
+ /* Increment the read FIFO */
+ /***************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Read = (devpriv->
+ s_InterruptParameters.
+ ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
+
+ break;
+\r
+ case APCI1710_TIMER_READALLTIMER:
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /***********************/\r
+ /* Test if 82X54 timer */\r
+ /***********************/\r
+\r
+ if ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER)\r
+ {\r
+ /********************************/\r
+ /* Test if timer 0 iniutialised */\r
+ /********************************/\r
+\r
+ if (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_82X54ModuleInfo.\r
+ s_82X54TimerInfo [0].\r
+ b_82X54Init == 1)\r
+ {\r
+ /********************************/\r
+ /* Test if timer 1 iniutialised */\r
+ /********************************/\r
+\r
+ if (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_82X54ModuleInfo.\r
+ s_82X54TimerInfo [1].\r
+ b_82X54Init == 1)\r
+ {\r
+ /********************************/\r
+ /* Test if timer 2 iniutialised */\r
+ /********************************/\r
+\r
+ if (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_82X54ModuleInfo.\r
+ s_82X54TimerInfo [2].\r
+ b_82X54Init == 1)\r
+ {\r
+ /*********************/\r
+ /* Latch all counter */\r
+ /*********************/\r
+\r
+
+ outl(0x17,devpriv->s_BoardInfos.\r
+ ui_Address + 12 + (64 * b_ModulNbr));\r
+\r
+ /**************************/\r
+ /* Read the timer 0 value */\r
+ /**************************/\r
+\r
+
+ pul_TimerValueArray [0]=inl(devpriv->s_BoardInfos.\r
+ ui_Address + 0 + (64 * b_ModulNbr));\r
+\r
+ /**************************/\r
+ /* Read the timer 1 value */\r
+ /**************************/\r
+\r
+
+ pul_TimerValueArray [1]=inl(devpriv->s_BoardInfos.\r
+ ui_Address + 4 + (64 * b_ModulNbr));\r
+\r
+ /**************************/\r
+ /* Read the timer 2 value */\r
+ /**************************/\r
+\r
+
+ pul_TimerValueArray [2]=inl(devpriv->s_BoardInfos.\r
+ ui_Address + 8 + (64 * b_ModulNbr));\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Timer 2 not initialised see function */\r
+ /****************************************/\r
+\r DPRINTK("Timer 2 not initialised see function\n");
+ i_ReturnValue = -6;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Timer 1 not initialised see function */\r
+ /****************************************/\r
+\r DPRINTK("Timer 1 not initialised see function\n");
+ i_ReturnValue = -5;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Timer 0 not initialised see function */\r
+ /****************************************/\r
+\r DPRINTK("Timer 0 not initialised see function\n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /************************************/\r
+ /* The module is not a TIMER module */\r
+ /************************************/\r
+\r DPRINTK("The module is not a TIMER module\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***********************/\r
+ /* Module number error */\r
+ /***********************/\r
+\r DPRINTK("Module number error\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r }// End of Switch
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+
+/*
++----------------------------------------------------------------------------+
+| Function Name :INT i_APCI1710_InsnBitsTimer(comedi_device *dev,
+comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Read write functions for Timer |
++----------------------------------------------------------------------------+
+| Input Parameters :
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnBitsTimer(comedi_device *dev,comedi_subdevice *s,
+comedi_insn *insn,lsampl_t *data)
+{
+ BYTE b_BitsType;
+ INT i_ReturnValue=0;
+ b_BitsType=data[0];
+
+ switch(b_BitsType)
+ {
+ case APCI1710_TIMER_READVALUE:
+ i_ReturnValue=i_APCI1710_ReadTimerValue (dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (BYTE) CR_CHAN(insn->chanspec),
+ (PULONG) &data[0]);
+ break;
+
+ case APCI1710_TIMER_GETOUTPUTLEVEL:
+ i_ReturnValue=i_APCI1710_GetTimerOutputLevel (dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (BYTE) CR_CHAN(insn->chanspec),
+ (PBYTE) &data[0]);
+ break;
+
+ case APCI1710_TIMER_GETPROGRESSSTATUS:
+ i_ReturnValue=i_APCI1710_GetTimerProgressStatus (dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (BYTE) CR_CHAN(insn->chanspec),
+ (PBYTE) &data[0]);
+ break;
+
+ case APCI1710_TIMER_WRITEVALUE:
+ i_ReturnValue=i_APCI1710_WriteTimerValue (dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (BYTE) CR_CHAN(insn->chanspec),
+ (ULONG) data[1]);
+
+ break;
+
+ default:
+ printk("Bits Config Parameter Wrong\n");
+ i_ReturnValue=-1;
+ }
+
+ if(i_ReturnValue>=0) i_ReturnValue =insn->n;
+ return (i_ReturnValue);
+}
+
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ReadTimerValue |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_TimerNbr, |
+| PULONG_ pul_TimerValue) |
++----------------------------------------------------------------------------+
+| Task : Return the timer value from selected digital timer |
+| (b_TimerNbr) from selected timer module (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board |
+| APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number |
+| (0 to 3) |
+| BYTE_ b_TimerNbr : Timer number to read |
+| (0 to 2) |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pul_TimerValue : Timer value |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: Timer selection wrong |
+| -4: The module is not a TIMER module |
+| -5: Timer not initialised see function |
+| "i_APCI1710_InitTimer" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_ReadTimerValue (comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_TimerNbr,
+ PULONG pul_TimerValue)
+ {
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4)
+ {
+ /***********************/
+ /* Test if 82X54 timer */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER)
+ {
+ /*************************/
+ /* Test the timer number */
+ /*************************/
+
+ if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
+ {
+ /*****************************/
+ /* Test if timer initialised */
+ /*****************************/
+
+ if (devpriv->
+ s_ModuleInfo [b_ModulNbr].
+ s_82X54ModuleInfo.
+ s_82X54TimerInfo [b_TimerNbr].
+ b_82X54Init == 1)
+ {
+ /*************************/
+ /* Latch the timer value */
+ /*************************/
+
+
+ outl((2 << b_TimerNbr) | 0xD0,devpriv->s_BoardInfos.
+ ui_Address + 12 + (64 * b_ModulNbr));
+
+ /**************************/
+ /* Read the counter value */
+ /**************************/
+
+
+ *pul_TimerValue=inl(devpriv->s_BoardInfos.
+ ui_Address + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+ }
+ else
+ {
+ /**************************************/
+ /* Timer not initialised see function */
+ /**************************************/
+ DPRINTK("Timer not initialised see function\n");
+ i_ReturnValue = -5;
+ }
+ }
+ else
+ {
+ /*************************/
+ /* Timer selection wrong */
+ /*************************/
+ DPRINTK("Timer selection wrong\n");
+ i_ReturnValue = -3;
+ } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
+ }
+ else
+ {
+ /************************************/
+ /* The module is not a TIMER module */
+ /************************************/
+ DPRINTK("The module is not a TIMER module\n");
+ i_ReturnValue = -4;
+ }
+ }
+ else
+ {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+ }
+
+
+ /*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_GetTimerOutputLevel |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_TimerNbr, |
+| PBYTE_ pb_OutputLevel) |
++----------------------------------------------------------------------------+
+| Task : Return the output signal level (pb_OutputLevel) from |
+| selected digital timer (b_TimerNbr) from selected timer|
+| module (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board |
+| APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number |
+| (0 to 3) |
+| BYTE_ b_TimerNbr : Timer number to test |
+| (0 to 2) |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_OutputLevel : Output signal level |
+| 0 : The output is low |
+| 1 : The output is high |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: Timer selection wrong |
+| -4: The module is not a TIMER module |
+| -5: Timer not initialised see function |
+| "i_APCI1710_InitTimer" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetTimerOutputLevel (comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_TimerNbr,
+ PBYTE pb_OutputLevel)
+ {
+ INT i_ReturnValue = 0;
+ DWORD dw_TimerStatus;
+
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4)
+ {
+ /***********************/
+ /* Test if 82X54 timer */
+ /***********************/
+
+ if ((devpriv->
+ s_BoardInfos.
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER)
+ {
+ /*************************/
+ /* Test the timer number */
+ /*************************/
+
+ if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
+ {
+ /*****************************/
+ /* Test if timer initialised */
+ /*****************************/
+
+ if (devpriv->
+ s_ModuleInfo [b_ModulNbr].
+ s_82X54ModuleInfo.
+ s_82X54TimerInfo [b_TimerNbr].
+ b_82X54Init == 1)
+ {
+ /*************************/
+ /* Latch the timer value */
+ /*************************/
+
+ outl((2 << b_TimerNbr) | 0xE0,devpriv->s_BoardInfos.
+ ui_Address + 12 + (64 * b_ModulNbr));
+
+ /*************************/
+ /* Read the timer status */
+ /*************************/
+
+
+ dw_TimerStatus=inl(devpriv->s_BoardInfos.
+ ui_Address + 16 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+
+ *pb_OutputLevel = (BYTE) (((dw_TimerStatus >> 7) & 1) ^ devpriv->
+ s_ModuleInfo [b_ModulNbr].
+ s_82X54ModuleInfo.
+ s_82X54TimerInfo [b_TimerNbr].
+ b_OutputLevel);
+ }
+ else
+ {
+ /**************************************/
+ /* Timer not initialised see function */
+ /**************************************/
+ DPRINTK("Timer not initialised see function\n");
+ i_ReturnValue = -5;
+ }
+ }
+ else
+ {
+ /*************************/
+ /* Timer selection wrong */
+ /*************************/
+ DPRINTK("Timer selection wrong\n");
+ i_ReturnValue = -3;
+ } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
+ }
+ else
+ {
+ /************************************/
+ /* The module is not a TIMER module */
+ /************************************/
+ DPRINTK("The module is not a TIMER module\n");
+ i_ReturnValue = -4;
+ }
+ }
+ else
+ {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+ }
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_GetTimerProgressStatus |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_TimerNbr, |
+| PBYTE_ pb_TimerStatus) |
++----------------------------------------------------------------------------+
+| Task : Return the progress status (pb_TimerStatus) from |
+| selected digital timer (b_TimerNbr) from selected timer|
+| module (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board |
+| APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number |
+| (0 to 3) |
+| BYTE_ b_TimerNbr : Timer number to test |
+| (0 to 2) |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_TimerStatus : Output signal level |
+| 0 : Timer not in progress |
+| 1 : Timer in progress |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: Timer selection wrong |
+| -4: The module is not a TIMER module |
+| -5: Timer not initialised see function |
+| "i_APCI1710_InitTimer" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetTimerProgressStatus (comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_TimerNbr,
+ PBYTE pb_TimerStatus)
+ {
+ INT i_ReturnValue = 0;
+ DWORD dw_TimerStatus;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4)
+ {
+ /***********************/
+ /* Test if 82X54 timer */
+ /***********************/
+
+ if ((devpriv->
+ s_BoardInfos.
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER)
+ {
+ /*************************/
+ /* Test the timer number */
+ /*************************/
+
+ if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
+ {
+ /*****************************/
+ /* Test if timer initialised */
+ /*****************************/
+
+ if (devpriv->
+ s_ModuleInfo [b_ModulNbr].
+ s_82X54ModuleInfo.
+ s_82X54TimerInfo [b_TimerNbr].
+ b_82X54Init == 1)
+ {
+ /*************************/
+ /* Latch the timer value */
+ /*************************/
+
+
+ outl((2 << b_TimerNbr) | 0xE0,devpriv->s_BoardInfos.
+ ui_Address + 12 + (64 * b_ModulNbr));
+
+ /*************************/
+ /* Read the timer status */
+ /*************************/
+
+
+ dw_TimerStatus=inl(devpriv->s_BoardInfos.
+ ui_Address + 16 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+
+ *pb_TimerStatus = (BYTE) ((dw_TimerStatus) >> 8) & 1;
+ printk("ProgressStatus : %d",*pb_TimerStatus);
+ }
+ else
+ {
+ /**************************************/
+ /* Timer not initialised see function */
+ /**************************************/
+
+ i_ReturnValue = -5;
+ }
+ }
+ else
+ {
+ /*************************/
+ /* Timer selection wrong */
+ /*************************/
+
+ i_ReturnValue = -3;
+ } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
+ }
+ else
+ {
+ /************************************/
+ /* The module is not a TIMER module */
+ /************************************/
+
+ i_ReturnValue = -4;
+ }
+ }
+ else
+ {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+ }
+
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_WriteTimerValue |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_TimerNbr, |
+| ULONG_ ul_WriteValue) |
++----------------------------------------------------------------------------+
+| Task : Write the value (ul_WriteValue) into the selected timer|
+| (b_TimerNbr) from selected timer module (b_ModulNbr). |
+| The action in depend of the time mode selection. |
+| See timer mode description table. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board |
+| APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number |
+| (0 to 3) |
+| BYTE_ b_TimerNbr : Timer number to write |
+| (0 to 2) |
+| ULONG_ ul_WriteValue : Value to write |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: Timer selection wrong |
+| -4: The module is not a TIMER module |
+| -5: Timer not initialised see function |
+| "i_APCI1710_InitTimer" |
++----------------------------------------------------------------------------+
+*/
+
+ INT i_APCI1710_WriteTimerValue (comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_TimerNbr,
+ ULONG ul_WriteValue)
+ {
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4)
+ {
+ /***********************/
+ /* Test if 82X54 timer */
+ /***********************/
+
+ if ((devpriv->
+ s_BoardInfos.
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER)
+ {
+ /*************************/
+ /* Test the timer number */
+ /*************************/
+
+ if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
+ {
+ /*****************************/
+ /* Test if timer initialised */
+ /*****************************/
+
+ if (devpriv->
+ s_ModuleInfo [b_ModulNbr].
+ s_82X54ModuleInfo.
+ s_82X54TimerInfo [b_TimerNbr].
+ b_82X54Init == 1)
+ {
+ /*******************/
+ /* Write the value */
+ /*******************/
+
+
+ outl(ul_WriteValue,devpriv->s_BoardInfos.
+ ui_Address + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+ }
+ else
+ {
+ /**************************************/
+ /* Timer not initialised see function */
+ /**************************************/
+ DPRINTK("Timer not initialised see function\n");
+ i_ReturnValue = -5;
+ }
+ }
+ else
+ {
+ /*************************/
+ /* Timer selection wrong */
+ /*************************/
+ DPRINTK("Timer selection wrong\n");
+ i_ReturnValue = -3;
+ } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
+ }
+ else
+ {
+ /************************************/
+ /* The module is not a TIMER module */
+ /************************************/
+ DPRINTK("The module is not a TIMER module\n");
+ i_ReturnValue = -4;
+ }
+ }
+ else
+ {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+ }
+
+\r
+\r
+\r
+\r
--- /dev/null
+\r
+\r
+#define APCI1710_PCI_BUS_CLOCK 0\r
+#define APCI1710_FRONT_CONNECTOR_INPUT 1\r
+#define APCI1710_TIMER_READVALUE 0\r
+#define APCI1710_TIMER_GETOUTPUTLEVEL 1\r
+#define APCI1710_TIMER_GETPROGRESSSTATUS 2\r
+#define APCI1710_TIMER_WRITEVALUE 3\r
+
+#define APCI1710_TIMER_READINTERRUPT 1
+#define APCI1710_TIMER_READALLTIMER 2
+
+/*\r
++----------------------------------------------------------------------------+\r
+| 82X54 TIMER INISIALISATION FUNCTION |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+\r
+\r
+INT i_APCI1710_InsnConfigInitTimer(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data);\r
+\r
+
+\r
+INT i_APCI1710_InsnWriteEnableDisableTimer(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data);\r
+/*\r
++----------------------------------------------------------------------------+\r
+| 82X54 READ FUNCTION |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_InsnReadAllTimerValue(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data);\r
+\r
+
+INT i_APCI1710_InsnBitsTimer(comedi_device *dev,comedi_subdevice *s,
+comedi_insn *insn,lsampl_t *data);
+
+/*
++----------------------------------------------------------------------------+
+| 82X54 READ & WRITE FUNCTION |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1710_ReadTimerValue (comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_TimerNbr,
+ PULONG pul_TimerValue);
+
+INT i_APCI1710_GetTimerOutputLevel (comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_TimerNbr,
+ PBYTE pb_OutputLevel);
+
+INT i_APCI1710_GetTimerProgressStatus (comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_TimerNbr,
+ PBYTE pb_TimerStatus);
+
+/*
++----------------------------------------------------------------------------+
+| 82X54 WRITE FUNCTION |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1710_WriteTimerValue (comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_TimerNbr,
+ ULONG ul_WriteValue);
\ No newline at end of file
--- /dev/null
+/*\r
+ +-----------------------------------------------------------------------+\r
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |\r
+ +-----------------------------------------------------------------------+\r
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |\r
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |\r
+ +-----------------------------------------------------------------------+\r
+ | Project : API APCI1710 | Compiler : BORLANDC/MICROSOFT C |\r
+ | Module name : CHRONO.C | Version : 3.1 / 6.0 |\r
+ +-------------------------------+---------------------------------------+\r
+ | Author : S.WEBER | Date : 06.07.98 |\r
+ +-----------------------------------------------------------------------+\r
+ | Description : APCI-1710 chronometer module |\r
+ | |\r
+ | |\r
+ +-----------------------------------------------------------------------+\r
+ | UPDATES |\r
+ +-----------------------------------------------------------------------+\r
+ | Date | Author | Description of updates |\r
+ +----------+-----------+------------------------------------------------+\r
+ | 29/06/98 | S. Weber | Digital input / output implementation |\r
+ |----------|-----------|------------------------------------------------|\r
+ | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |\r
+ | | | available |\r
+ +-----------------------------------------------------------------------+\r
+ | | | |\r
+ | | | |\r
+ +-----------------------------------------------------------------------+\r
+*/\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Included files |\r
++----------------------------------------------------------------------------+\r
+*/\r
+#include "APCI1710_Chrono.h"\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_InitChrono |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_ChronoMode, |\r
+| BYTE_ b_PCIInputClock, |\r
+| BYTE_ b_TimingUnit, |\r
+| ULONG_ ul_TimingInterval, |\r
+| PULONG_ pul_RealTimingInterval) \r
+
++----------------------------------------------------------------------------+\r
+| Task : Configure the chronometer operating mode (b_ChronoMode)|\r
+| from selected module (b_ModulNbr). |\r
+| The ul_TimingInterval and ul_TimingUnit determine the |\r
+| timing base for the measurement. |\r
+| The pul_RealTimingInterval return the real timing |\r
+| value. You must calling this function be for you call |\r
+| any other function witch access of the chronometer. |\r
+| |\r
+| Witch this functionality from the APCI-1710 you have |\r
+| the possibility to measure the timing witch two event. |\r
+| |\r
+| The mode 0 and 1 is appropriate for period measurement.|\r
+| The mode 2 and 3 is appropriate for frequent |\r
+| measurement. |\r
+| The mode 4 to 7 is appropriate for measuring the timing|\r
+| between two event. |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr CR_AREF(insn->chanspec) : Module number to configure |\r
+| (0 to 3) |\r
+| BYTE_ b_ChronoMode data[0] : Chronometer action mode |\r
+| (0 to 7). |\r
+| BYTE_ b_PCIInputClock data[1] : Selection from PCI bus clock|\r
+| - APCI1710_30MHZ : |\r
+| The PC have a PCI bus |\r
+| clock from 30 MHz |\r
+| - APCI1710_33MHZ : |\r
+| The PC have a PCI bus |\r
+| clock from 33 MHz |\r
+| - APCI1710_40MHZ |\r
+| The APCI-1710 have a |\r
+| integrated 40Mhz |\r
+| quartz. |\r
+| BYTE_ b_TimingUnit data[2] : Base timing unity (0 to 4) |\r
+| 0 : ns |\r
+| 1 : µs |\r
+| 2 : ms |\r
+| 3 : s |\r
+| 4 : mn |\r
+| ULONG_ ul_TimingInterval : data[3] Base timing value. |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : PULONG_ pul_RealTimingInterval : Real base timing |\r
+| value. \r
+| data[0]\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: Module selection wrong |\r
+| -3: The module is not a Chronometer module |\r
+| -4: Chronometer mode selection is wrong |\r
+| -5: The selected PCI input clock is wrong |\r
+| -6: Timing unity selection is wrong |\r
+| -7: Base timing selection is wrong |\r
+| -8: You can not used the 40MHz clock selection wich |\r
+| this board |\r
+| -9: You can not used the 40MHz clock selection wich |\r
+| this CHRONOS version |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+
+\r
+INT i_APCI1710_InsnConfigInitChrono(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ ULONG ul_TimerValue,ul_TimingInterval,ul_RealTimingInterval;\r
+ double d_RealTimingInterval;\r
+ DWORD dw_ModeArray [8] = {0x01, 0x05, 0x00, 0x04, 0x02, 0x0E, 0x0A, 0x06};\r
+ BYTE b_ModulNbr,b_ChronoMode,b_PCIInputClock,b_TimingUnit;\r
+\r PULONG pul_RealTimingInterval;
+
+ b_ModulNbr = CR_AREF(insn->chanspec);\r
+ b_ChronoMode = (BYTE) data[0];\r
+ b_PCIInputClock = (BYTE) data[1];\r
+ b_TimingUnit = (BYTE) data[2];\r
+ ul_TimingInterval = (ULONG) data[3]; \r
+ i_ReturnValue = insn->n;\r
+\r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /***********************/\r
+ /* Test if chronometer */\r
+ /***********************/\r
+\r
+ if ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_CHRONOMETER)\r
+ {\r
+ /*****************************/\r
+ /* Test the chronometer mode */\r
+ /*****************************/\r
+\r
+ if (b_ChronoMode >= 0 && b_ChronoMode <= 7)\r
+ {\r
+ /**************************/\r
+ /* Test the PCI bus clock */\r
+ /**************************/\r
+\r
+ if ((b_PCIInputClock == APCI1710_30MHZ) ||\r
+ (b_PCIInputClock == APCI1710_33MHZ) ||\r
+ (b_PCIInputClock == APCI1710_40MHZ))\r
+ {\r
+ /*************************/\r
+ /* Test the timing unity */\r
+ /*************************/\r
+\r
+ if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))\r
+ {\r
+ /**********************************/\r
+ /* Test the base timing selection */\r
+ /**********************************/\r
+\r
+ if (((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 66) && (ul_TimingInterval <= 0xFFFFFFFFUL)) ||\r
+ ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 143165576UL)) ||\r
+ ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 143165UL)) ||\r
+ ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 143UL)) ||\r
+ ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 2UL)) ||\r
+ ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 60) && (ul_TimingInterval <= 0xFFFFFFFFUL)) ||\r
+ ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 130150240UL)) ||\r
+ ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 130150UL)) ||\r
+ ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 130UL)) ||\r
+ ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 2UL)) ||\r
+ ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 50) && (ul_TimingInterval <= 0xFFFFFFFFUL)) ||\r
+ ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 107374182UL)) ||\r
+ ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 107374UL)) ||\r
+ ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 107UL)) ||\r
+ ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 1UL)))\r
+ {\r
+ /**************************/\r
+ /* Test the board version */\r
+ /**************************/\r
+\r
+ if ((b_PCIInputClock == APCI1710_40MHZ) && (devpriv->s_BoardInfos.\r
+ b_BoardVersion > 0) ||\r
+ (b_PCIInputClock != APCI1710_40MHZ))\r
+ {\r
+ /************************/\r
+ /* Test the TOR version */\r
+ /************************/\r
+\r
+ if ((b_PCIInputClock == APCI1710_40MHZ) && ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF) >= 0x3131) ||\r
+ (b_PCIInputClock != APCI1710_40MHZ))\r
+ {\r
+ /****************************************/\r
+ /* Calculate the timer 0 division fator */\r
+ /****************************************/\r
+\r
+ switch (b_TimingUnit)\r
+ {\r
+ /******/\r
+ /* ns */\r
+ /******/\r
+\r
+ case 0:\r
+ \r
+ /******************/\r
+ /* Timer 0 factor */\r
+ /******************/\r
+\r
+ ul_TimerValue = (ULONG) (ul_TimingInterval * (0.001 * b_PCIInputClock));\r
+\r
+ /*******************/\r
+ /* Round the value */\r
+ /*******************/\r
+\r
+ if ((double) ((double) ul_TimingInterval * (0.001 * (double) b_PCIInputClock)) >= ((double) ((double) ul_TimerValue + 0.5)))\r
+ {\r
+ ul_TimerValue = ul_TimerValue + 1;\r
+ }\r
+\r
+ /*****************************/\r
+ /* Calculate the real timing */\r
+ /*****************************/\r
+\r
+ ul_RealTimingInterval = (ULONG) (ul_TimerValue / (0.001 * (double) b_PCIInputClock));\r
+ d_RealTimingInterval = (double) ul_TimerValue / (0.001 * (double) b_PCIInputClock);\r
+\r
+ if ((double) ((double) ul_TimerValue / (0.001 * (double) b_PCIInputClock)) >= (double) ((double) *pul_RealTimingInterval + 0.5))\r
+ {\r
+ ul_RealTimingInterval = ul_RealTimingInterval + 1;\r
+ }\r
+\r
+ ul_TimingInterval = ul_TimingInterval - 1;\r
+ ul_TimerValue = ul_TimerValue - 2;\r
+ if (b_PCIInputClock != APCI1710_40MHZ)\r
+ {\r
+ ul_TimerValue = (ULONG) ((double) (ul_TimerValue) * 0.99392);\r
+ }\r
+ \r
+ break;\r
+\r
+ /******/\r
+ /* æs */\r
+ /******/\r
+\r
+ case 1:\r
+ \r
+ /******************/\r
+ /* Timer 0 factor */\r
+ /******************/\r
+\r
+ ul_TimerValue = (ULONG) (ul_TimingInterval * (1.0 * b_PCIInputClock));\r
+\r
+ /*******************/\r
+ /* Round the value */\r
+ /*******************/\r
+\r
+ if ((double) ((double) ul_TimingInterval * (1.0 * (double) b_PCIInputClock)) >= ((double) ((double) ul_TimerValue + 0.5)))\r
+ {\r
+ ul_TimerValue = ul_TimerValue + 1;\r
+ }\r
+\r
+ /*****************************/\r
+ /* Calculate the real timing */\r
+ /*****************************/\r
+\r
+ ul_RealTimingInterval = (ULONG) (ul_TimerValue / (1.0 * (double) b_PCIInputClock));\r
+ d_RealTimingInterval = (double) ul_TimerValue / ((double) 1.0 * (double) b_PCIInputClock);\r
+\r
+ if ((double) ((double) ul_TimerValue / (1.0 * (double) b_PCIInputClock)) >= (double) ((double) *pul_RealTimingInterval + 0.5))\r
+ {\r
+ ul_RealTimingInterval = ul_RealTimingInterval + 1;\r
+ }\r
+\r
+ ul_TimingInterval = ul_TimingInterval - 1;\r
+ ul_TimerValue = ul_TimerValue - 2;\r
+ if (b_PCIInputClock != APCI1710_40MHZ)\r
+ {\r
+ ul_TimerValue = (ULONG) ((double) (ul_TimerValue) * 0.99392);\r
+ }\r
+ \r
+\r
+ break;\r
+\r
+ /******/\r
+ /* ms */\r
+ /******/\r
+\r
+ case 2:\r
+ \r
+ /******************/\r
+ /* Timer 0 factor */\r
+ /******************/\r
+\r
+ ul_TimerValue = ul_TimingInterval * (1000 * b_PCIInputClock);\r
+\r
+ /*******************/\r
+ /* Round the value */\r
+ /*******************/\r
+\r
+ if ((double) ((double) ul_TimingInterval * (1000.0 * (double) b_PCIInputClock)) >= ((double) ((double) ul_TimerValue + 0.5)))\r
+ {\r
+ ul_TimerValue = ul_TimerValue + 1;\r
+ }\r
+\r
+ /*****************************/\r
+ /* Calculate the real timing */\r
+ /*****************************/\r
+\r
+ ul_RealTimingInterval = (ULONG) (ul_TimerValue / (1000.0 * (double) b_PCIInputClock));\r
+ d_RealTimingInterval = (double) ul_TimerValue / (1000.0 * (double) b_PCIInputClock);\r
+\r
+ if ((double) ((double) ul_TimerValue / (1000.0 * (double) b_PCIInputClock)) >= (double) ((double) *pul_RealTimingInterval + 0.5))\r
+ {\r
+ ul_RealTimingInterval = ul_RealTimingInterval + 1;\r
+ }\r
+\r
+ ul_TimingInterval = ul_TimingInterval - 1;\r
+ ul_TimerValue = ul_TimerValue - 2;\r
+ if (b_PCIInputClock != APCI1710_40MHZ)\r
+ {\r
+ ul_TimerValue = (ULONG) ((double) (ul_TimerValue) * 0.99392);\r
+ }\r
+ \r
+ break;\r
+\r
+ /*****/\r
+ /* s */\r
+ /*****/\r
+\r
+ case 3:\r
+ \r
+ /******************/\r
+ /* Timer 0 factor */\r
+ /******************/\r
+\r
+ ul_TimerValue = (ULONG) (ul_TimingInterval * (1000000.0 * b_PCIInputClock));\r
+\r
+ /*******************/\r
+ /* Round the value */\r
+ /*******************/\r
+\r
+ if ((double) ((double) ul_TimingInterval * (1000000.0 * (double) b_PCIInputClock)) >= ((double) ((double) ul_TimerValue + 0.5)))\r
+ {\r
+ ul_TimerValue = ul_TimerValue + 1;\r
+ }\r
+\r
+ /*****************************/\r
+ /* Calculate the real timing */\r
+ /*****************************/\r
+\r
+ ul_RealTimingInterval = (ULONG) (ul_TimerValue / (1000000.0 * (double) b_PCIInputClock));\r
+ d_RealTimingInterval = (double) ul_TimerValue / (1000000.0 * (double) b_PCIInputClock);\r
+\r
+ if ((double) ((double) ul_TimerValue / (1000000.0 * (double) b_PCIInputClock)) >= (double) ((double) *pul_RealTimingInterval + 0.5))\r
+ {\r
+ ul_RealTimingInterval = ul_RealTimingInterval + 1;\r
+ }\r
+\r
+ ul_TimingInterval = ul_TimingInterval - 1;\r
+ ul_TimerValue = ul_TimerValue - 2;\r
+ if (b_PCIInputClock != APCI1710_40MHZ)\r
+ {\r
+ ul_TimerValue = (ULONG) ((double) (ul_TimerValue) * 0.99392);\r
+ }\r
+ \r
+\r
+ break;\r
+\r
+ /******/\r
+ /* mn */\r
+ /******/\r
+\r
+ case 4:\r
+ \r
+ /******************/\r
+ /* Timer 0 factor */\r
+ /******************/\r
+\r
+ ul_TimerValue = (ULONG) ((ul_TimingInterval * 60) * (1000000.0 * b_PCIInputClock));\r
+\r
+ /*******************/\r
+ /* Round the value */\r
+ /*******************/\r
+\r
+ if ((double) ((double) (ul_TimingInterval * 60.0) * (1000000.0 * (double) b_PCIInputClock)) >= ((double) ((double) ul_TimerValue + 0.5)))\r
+ {\r
+ ul_TimerValue = ul_TimerValue + 1;\r
+ }\r
+\r
+ /*****************************/\r
+ /* Calculate the real timing */\r
+ /*****************************/\r
+\r
+ ul_RealTimingInterval = (ULONG) (ul_TimerValue / (1000000.0 * (double) b_PCIInputClock)) / 60;\r
+ d_RealTimingInterval = ((double) ul_TimerValue / (0.001 * (double) b_PCIInputClock)) / 60.0;\r
+\r
+ if ((double) (((double) ul_TimerValue / (1000000.0 * (double) b_PCIInputClock)) / 60.0) >= (double) ((double) *pul_RealTimingInterval + 0.5))\r
+ {\r
+ ul_RealTimingInterval = ul_RealTimingInterval + 1;\r
+ }\r
+\r
+ ul_TimingInterval = ul_TimingInterval - 1;\r
+ ul_TimerValue = ul_TimerValue - 2;\r
+ if (b_PCIInputClock != APCI1710_40MHZ)\r
+ {\r
+ ul_TimerValue = (ULONG) ((double) (ul_TimerValue) * 0.99392);\r
+ }\r
+ \r
+\r
+ break;\r
+ }\r
+\r
+ /****************************/\r
+ /* Save the PCI input clock */\r
+ /****************************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_ChronoModuleInfo.\r
+ b_PCIInputClock = b_PCIInputClock;\r
+\r
+ /*************************/\r
+ /* Save the timing unity */\r
+ /*************************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_ChronoModuleInfo.\r
+ b_TimingUnit = b_TimingUnit;\r
+\r
+ /************************/\r
+ /* Save the base timing */\r
+ /************************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_ChronoModuleInfo.\r
+ d_TimingInterval = d_RealTimingInterval;\r
+\r
+ /****************************/\r
+ /* Set the chronometer mode */\r
+ /****************************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_ChronoModuleInfo.\r
+ dw_ConfigReg = dw_ModeArray [b_ChronoMode];\r
+\r
+ /***********************/\r
+ /* Test if 40 MHz used */\r
+ /***********************/\r
+\r
+ if (b_PCIInputClock == APCI1710_40MHZ)\r
+ {\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_ChronoModuleInfo.\r
+ dw_ConfigReg = devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_ChronoModuleInfo.\r
+ dw_ConfigReg | 0x80;\r
+ }\r
+\r
+ outl(devpriv->s_ModuleInfo [b_ModulNbr].s_ChronoModuleInfo.\r
+ dw_ConfigReg,devpriv->s_BoardInfos.\r
+ ui_Address + 16 + (64 * b_ModulNbr));\r
+\r
+ /***********************/\r
+ /* Write timer 0 value */\r
+ /***********************/\r
+\r
+
+ outl(ul_TimerValue,devpriv->s_BoardInfos.\r
+ ui_Address + (64 * b_ModulNbr));\r
+\r
+ /*********************/\r
+ /* Chronometer init. */\r
+ /*********************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_ChronoModuleInfo.\r
+ b_ChronoInit = 1;\r
+ }\r
+ else\r
+ {\r
+ /***********************************************/\r
+ /* TOR version error for 40MHz clock selection */\r
+ /***********************************************/\r
+\r DPRINTK("TOR version error for 40MHz clock selection\n");
+ i_ReturnValue = -9;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /**************************************************************/\r
+ /* You can not used the 40MHz clock selection wich this board */\r
+ /**************************************************************/\r
+\r DPRINTK("You can not used the 40MHz clock selection wich this board\n");
+ i_ReturnValue = -8;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /**********************************/\r
+ /* Base timing selection is wrong */\r
+ /**********************************/\r
+\r DPRINTK("Base timing selection is wrong\n");
+ i_ReturnValue = -7;\r
+ }\r
+ } // if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))\r
+ else\r
+ {\r
+ /***********************************/\r
+ /* Timing unity selection is wrong */\r
+ /***********************************/\r
+\r DPRINTK("Timing unity selection is wrong\n");
+ i_ReturnValue = -6;\r
+ } // if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))\r
+ } // if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ))\r
+ else\r
+ {\r
+ /*****************************************/\r
+ /* The selected PCI input clock is wrong */\r
+ /*****************************************/\r
+\r DPRINTK("The selected PCI input clock is wrong\n");
+ i_ReturnValue = -5;\r
+ } // if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ))\r
+ } // if (b_ChronoMode >= 0 && b_ChronoMode <= 7)\r
+ else\r
+ {\r
+ /***************************************/\r
+ /* Chronometer mode selection is wrong */\r
+ /***************************************/\r
+ \rDPRINTK("Chronometer mode selection is wrong\n");
+ i_ReturnValue = -4;\r
+ } // if (b_ChronoMode >= 0 && b_ChronoMode <= 7)\r
+ }\r
+ else\r
+ {\r
+ /******************************************/\r
+ /* The module is not a Chronometer module */\r
+ /******************************************/\r
+\r DPRINTK("The module is not a Chronometer module\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***********************/\r
+ /* Module number error */\r
+ /***********************/\r
+\r DPRINTK("Module number error\n");
+ i_ReturnValue = -2;\r
+ }\r
+ data[0] = ul_RealTimingInterval;\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_EnableChrono |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_CycleMode, |\r
+| BYTE_ b_InterruptEnable)\r
+INT i_APCI1710_InsnWriteEnableDisableChrono(comedi_device *dev,\r
+comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) |\r
++----------------------------------------------------------------------------+\r
+| Task : Enable the chronometer from selected module |\r
+| (b_ModulNbr). You must calling the |\r
+| "i_APCI1710_InitChrono" function be for you call this |\r
+| function. |\r
+| If you enable the chronometer interrupt, the |\r
+| chronometer generate a interrupt after the stop signal.|\r
+| See function "i_APCI1710_SetBoardIntRoutineX" and the |\r
+| Interrupt mask description chapter from this manual. |\r
+| The b_CycleMode parameter determine if you will |\r
+| measured a single or more cycle. \r
+\r
+| Disable the chronometer from selected module |\r
+| (b_ModulNbr). If you disable the chronometer after a |\r
+| start signal occur and you restart the chronometer |\r
+| witch the " i_APCI1710_EnableChrono" function, if no |\r
+| stop signal occur this start signal is ignored. \r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr CR_AREF(chanspec) : Selected module number (0 to 3) |\r
+ data[0] ENABle/Disable chrono\r
+| BYTE_ b_CycleMode : Selected the chronometer |\r
+| data[1] acquisition mode |\r
+| BYTE_ b_InterruptEnable : Enable or disable the |\r
+| data[2] chronometer interrupt. |\r
+| APCI1710_ENABLE: |\r
+| Enable the chronometer |\r
+| interrupt |\r
+| APCI1710_DISABLE: |\r
+| Disable the chronometer |\r
+| interrupt |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: Module selection wrong |\r
+| -3: The module is not a Chronometer module |\r
+| -4: Chronometer not initialised see function |\r
+| "i_APCI1710_InitChrono" |\r
+| -5: Chronometer acquisition mode cycle is wrong |\r
+| -6: Interrupt parameter is wrong |\r
+| -7: Interrupt function not initialised. |\r
+| See function "i_APCI1710_SetBoardIntRoutineX" \r
+ -8: data[0] wrong input |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r\r
+INT i_APCI1710_InsnWriteEnableDisableChrono(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ BYTE b_ModulNbr,b_CycleMode,b_InterruptEnable,b_Action;\r
+ b_ModulNbr = CR_AREF(insn->chanspec);\r
+ b_Action =(BYTE) data[0];
+ b_CycleMode =(BYTE) data[1];\r
+ b_InterruptEnable =(BYTE) data[2];\r
+ i_ReturnValue = insn->n;\r
+
+\r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /***********************/\r
+ /* Test if chronometer */\r
+ /***********************/\r
+\r
+ if ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_CHRONOMETER)\r
+ {\r
+ /***********************************/\r
+ /* Test if chronometer initialised */\r
+ /***********************************/\r
+\r
+ if (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_ChronoModuleInfo.\r
+ b_ChronoInit == 1)\r
+ {\r
+\r
+\r
+ switch(b_Action)\r
+ {\r
+ \r
+ case APCI1710_ENABLE :\r
+
+ /*********************************/\r
+ /* Test the cycle mode parameter */\r
+ /*********************************/\r
+\r
+ if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS))\r
+ {\r
+ /***************************/\r
+ /* Test the interrupt flag */\r
+ /***************************/\r
+\r
+ if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE))\r
+ {\r
+
+
+ /***************************/\r
+ /* Save the interrupt flag */\r
+ /***************************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_ChronoModuleInfo.\r
+ b_InterruptMask = b_InterruptEnable;\r
+\r
+ /***********************/\r
+ /* Save the cycle mode */\r
+ /***********************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_ChronoModuleInfo.\r
+ b_CycleMode = b_CycleMode;\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_ChronoModuleInfo.\r
+ dw_ConfigReg = (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_ChronoModuleInfo.\r
+ dw_ConfigReg & 0x8F) |\r
+ ((1 & b_InterruptEnable) << 5) |\r
+ ((1 & b_CycleMode) << 6) |\r
+ 0x10 ;\r
+\r
+ /*****************************/\r
+ /* Test if interrupt enabled */\r
+ /*****************************/\r
+\r
+ if (b_InterruptEnable == APCI1710_ENABLE)\r
+ {\r
+ /****************************/\r
+ /* Clear the interrupt flag */\r
+ /****************************/\r
+\r
+ \r
+ outl(devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_ChronoModuleInfo.dw_ConfigReg, devpriv->s_BoardInfos.\r
+ ui_Address + 32 + (64 * b_ModulNbr));\r
+ devpriv->tsk_Current=current; // Save the current process task structure
+ }\r
+\r
+ /***********************************/\r
+ /* Enable or disable the interrupt */\r
+ /* Enable the chronometer */\r
+ /***********************************/\r
+
+ outl(devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_ChronoModuleInfo.dw_ConfigReg,devpriv->s_BoardInfos.\r
+ ui_Address + 16 + (64 * b_ModulNbr));\r
+\r
+ /*************************/\r
+ /* Clear status register */\r
+ /*************************/\r
+\r
+
+ outl(0,devpriv->s_BoardInfos.ui_Address + 36 + (64 * b_ModulNbr));\r
+ \r
+ } // if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE))\r
+ else\r
+ {\r
+ /********************************/\r
+ /* Interrupt parameter is wrong */\r
+ /********************************/\r
+\r DPRINTK("Interrupt parameter is wrong\n");
+ i_ReturnValue = -6;\r
+ } // if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE))\r
+ } // if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS))\r
+ else\r
+ {\r
+ /***********************************************/\r
+ /* Chronometer acquisition mode cycle is wrong */\r
+ /***********************************************/\r
+\r DPRINTK("Chronometer acquisition mode cycle is wrong\n");
+ i_ReturnValue = -5;\r
+ } // if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS))\r
+ break;\r
+\r
+ case APCI1710_DISABLE :\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_ChronoModuleInfo.\r
+ b_InterruptMask = 0;\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_ChronoModuleInfo.\r
+ dw_ConfigReg = devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_ChronoModuleInfo.\r
+ dw_ConfigReg & 0x2F;\r
+\r
+ /***************************/\r
+ /* Disable the interrupt */\r
+ /* Disable the chronometer */\r
+ /***************************/\r
+\r
+
+ outl(devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_ChronoModuleInfo.dw_ConfigReg, devpriv->s_BoardInfos.\r
+ ui_Address + 16 + (64 * b_ModulNbr));\r
+\r
+ /***************************/\r
+ /* Test if continuous mode */\r
+ /***************************/\r
+\r
+ if (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_ChronoModuleInfo.b_CycleMode == APCI1710_CONTINUOUS)\r
+ {\r
+ /*************************/\r
+ /* Clear status register */\r
+ /*************************/\r
+\r
+
+ outl(0,devpriv->s_BoardInfos.ui_Address + 36 + (64 * b_ModulNbr));\r
+ }\r
+ break;\r
+
+ default:\r
+ DPRINTK("Inputs wrong! Enable or Disable chrono\n");\r
+ i_ReturnValue = -8;\r
+ } // switch ENABLE/DISABLE\r
+ }\r
+ else\r
+ {\r
+ /*******************************/\r
+ /* Chronometer not initialised */\r
+ /*******************************/\r
+\r DPRINTK("Chronometer not initialised\n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /******************************************/\r
+ /* The module is not a Chronometer module */\r
+ /******************************************/\r
+\r DPRINTK("The module is not a Chronometer module\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***********************/\r
+ /* Module number error */\r
+ /***********************/\r
+\r DPRINTK("Module number error\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+\r
+\r
+/*
++----------------------------------------------------------------------------+
+| Function Name :INT i_APCI1710_InsnReadChrono(comedi_device *dev,comedi_subdevice *s,
+comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Read functions for Timer |
++----------------------------------------------------------------------------+
+| Input Parameters :
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnReadChrono(comedi_device *dev,comedi_subdevice *s,
+comedi_insn *insn,lsampl_t *data)
+{
+ BYTE b_ReadType;
+ INT i_ReturnValue=insn->n;
+
+ b_ReadType=CR_CHAN(insn->chanspec);
+
+ switch(b_ReadType)
+ {
+ case APCI1710_CHRONO_PROGRESS_STATUS:
+ i_ReturnValue=i_APCI1710_GetChronoProgressStatus (dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (PBYTE) &data[0]);
+ break;
+
+ case APCI1710_CHRONO_READVALUE:
+ i_ReturnValue=i_APCI1710_ReadChronoValue (dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (UINT) insn->unused[0],
+ (PBYTE) &data[0],
+ (PULONG) &data[1]);
+ break;
+
+ case APCI1710_CHRONO_CONVERTVALUE:
+ i_ReturnValue=i_APCI1710_ConvertChronoValue (dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (ULONG) insn->unused[0],
+ (PULONG) &data[0],
+ (PBYTE) &data[1],
+ (PBYTE) &data[2],
+ (PUINT) &data[3],
+ (PUINT) &data[4],
+ (PUINT) &data[5]);
+ break;
+
+ case APCI1710_CHRONO_READINTERRUPT:
+ printk("In Chrono Read Interrupt\n");
+
+ data[0]=devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Read].b_OldModuleMask;
+ data[1]=devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Read].ul_OldInterruptMask;
+ data[2]=devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Read].ul_OldCounterLatchValue;
+
+
+ /**************************/
+ /* Increment the read FIFO */
+ /***************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Read = (devpriv->
+ s_InterruptParameters.
+ ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
+ break;
+
+ default:
+ printk("ReadType Parameter wrong\n");
+ }
+
+ if(i_ReturnValue>=0) i_ReturnValue =insn->n;
+ return (i_ReturnValue);
+
+}
+
+
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_GetChronoProgressStatus |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| PBYTE_ pb_ChronoStatus) |
++----------------------------------------------------------------------------+
+| Task : Return the chronometer status (pb_ChronoStatus) from |
+| selected chronometer module (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pb_ChronoStatus : Return the chronometer |
+| status. |
+| 0 : Measurement not started.|
+| No start signal occur. |
+| 1 : Measurement started. |
+| A start signal occur. |
+| 2 : Measurement stopped. |
+| A stop signal occur. |
+| The measurement is |
+| terminate. |
+| 3: A overflow occur. You |
+| must change the base |
+| timing witch the |
+| function |
+| "i_APCI1710_InitChrono" |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a Chronometer module |
+| -4: Chronometer not initialised see function |
+| "i_APCI1710_InitChrono" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetChronoProgressStatus (comedi_device *dev,
+ BYTE b_ModulNbr,
+ PBYTE pb_ChronoStatus)
+ {
+ INT i_ReturnValue = 0;
+ DWORD dw_Status;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4)
+ {
+ /***********************/
+ /* Test if chronometer */
+ /***********************/
+
+ if ((devpriv->
+ s_BoardInfos.
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_CHRONOMETER)
+ {
+ /***********************************/
+ /* Test if chronometer initialised */
+ /***********************************/
+
+ if (devpriv->
+ s_ModuleInfo [b_ModulNbr].
+ s_ChronoModuleInfo.
+ b_ChronoInit == 1)
+ {
+
+ dw_Status=inl(devpriv->s_BoardInfos.
+ ui_Address + 8 + (64 * b_ModulNbr));
+
+ /********************/
+ /* Test if overflow */
+ /********************/
+
+ if ((dw_Status & 8) == 8)
+ {
+ /******************/
+ /* Overflow occur */
+ /******************/
+
+ *pb_ChronoStatus = 3;
+ } // if ((dw_Status & 8) == 8)
+ else
+ {
+ /*******************************/
+ /* Test if measurement stopped */
+ /*******************************/
+
+ if ((dw_Status & 2) == 2)
+ {
+ /***********************/
+ /* A stop signal occur */
+ /***********************/
+
+ *pb_ChronoStatus = 2;
+ } // if ((dw_Status & 2) == 2)
+ else
+ {
+ /*******************************/
+ /* Test if measurement started */
+ /*******************************/
+
+ if ((dw_Status & 1) == 1)
+ {
+ /************************/
+ /* A start signal occur */
+ /************************/
+
+ *pb_ChronoStatus = 1;
+ } // if ((dw_Status & 1) == 1)
+ else
+ {
+ /***************************/
+ /* Measurement not started */
+ /***************************/
+
+ *pb_ChronoStatus = 0;
+ } // if ((dw_Status & 1) == 1)
+ } // if ((dw_Status & 2) == 2)
+ } // if ((dw_Status & 8) == 8)
+ }
+ else
+ {
+ /*******************************/
+ /* Chronometer not initialised */
+ /*******************************/
+ DPRINTK("Chronometer not initialised\n");
+ i_ReturnValue = -4;
+ }
+ }
+ else
+ {
+ /******************************************/
+ /* The module is not a Chronometer module */
+ /******************************************/
+ DPRINTK("The module is not a Chronometer module\n");
+ i_ReturnValue = -3;
+ }
+ }
+ else
+ {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+ }
+
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ReadChronoValue |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| UINT_ ui_TimeOut, |
+| PBYTE_ pb_ChronoStatus, |
+| PULONG_ pul_ChronoValue) |
++----------------------------------------------------------------------------+
+| Task : Return the chronometer status (pb_ChronoStatus) and the|
+| timing value (pul_ChronoValue) after a stop signal |
+| occur from selected chronometer module (b_ModulNbr). |
+| This function are only avaible if you have disabled |
+| the interrupt functionality. See function |
+| "i_APCI1710_EnableChrono" and the Interrupt mask |
+| description chapter. |
+| You can test the chronometer status witch the |
+| "i_APCI1710_GetChronoProgressStatus" function. |
+| |
+| The returned value from pul_ChronoValue parameter is |
+| not real measured timing. |
+| You must used the "i_APCI1710_ConvertChronoValue" |
+| function or make this operation for calculate the |
+| timing: |
+| |
+| Timing = pul_ChronoValue * pul_RealTimingInterval. |
+| |
+| pul_RealTimingInterval is the returned parameter from |
+| "i_APCI1710_InitChrono" function and the time unity is |
+| the b_TimingUnit from "i_APCI1710_InitChrono" function|
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pb_ChronoStatus : Return the chronometer |
+| status. |
+| 0 : Measurement not started.|
+| No start signal occur. |
+| 1 : Measurement started. |
+| A start signal occur. |
+| 2 : Measurement stopped. |
+| A stop signal occur. |
+| The measurement is |
+| terminate. |
+| 3: A overflow occur. You |
+| must change the base |
+| timing witch the |
+| function |
+| "i_APCI1710_InitChrono" |
+| PULONG pul_ChronoValue : Chronometer timing value. |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a Chronometer module |
+| -4: Chronometer not initialised see function |
+| "i_APCI1710_InitChrono" |
+| -5: Timeout parameter is wrong (0 to 65535) |
+| -6: Interrupt routine installed. You can not read |
+| directly the chronometer measured timing. |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_ReadChronoValue (comedi_device *dev,
+ BYTE b_ModulNbr,
+ UINT ui_TimeOut,
+ PBYTE pb_ChronoStatus,
+ PULONG pul_ChronoValue)
+ {
+ INT i_ReturnValue = 0;
+ DWORD dw_Status;
+ DWORD dw_TimeOut = 0;
+
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4)
+ {
+ /***********************/
+ /* Test if chronometer */
+ /***********************/
+
+ if ((devpriv->
+ s_BoardInfos.
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_CHRONOMETER)
+ {
+ /***********************************/
+ /* Test if chronometer initialised */
+ /***********************************/
+
+ if (devpriv->
+ s_ModuleInfo [b_ModulNbr].
+ s_ChronoModuleInfo.
+ b_ChronoInit == 1)
+ {
+ /*****************************/
+ /* Test the timout parameter */
+ /*****************************/
+
+ if ((ui_TimeOut >= 0) && (ui_TimeOut <= 65535UL))
+ {
+
+ for (;;)
+ {
+ /*******************/
+ /* Read the status */
+ /*******************/
+
+
+ dw_Status=inl(devpriv->s_BoardInfos.
+ ui_Address + 8 + (64 * b_ModulNbr));
+
+
+ /********************/
+ /* Test if overflow */
+ /********************/
+
+ if ((dw_Status & 8) == 8)
+ {
+ /******************/
+ /* Overflow occur */
+ /******************/
+
+ *pb_ChronoStatus = 3;
+
+ /***************************/
+ /* Test if continuous mode */
+ /***************************/
+
+ if (devpriv->s_ModuleInfo [b_ModulNbr].
+ s_ChronoModuleInfo.
+ b_CycleMode == APCI1710_CONTINUOUS)
+ {
+ /*************************/
+ /* Clear status register */
+ /*************************/
+
+
+ outl(0,devpriv->s_BoardInfos.
+ ui_Address + 36 + (64 * b_ModulNbr));
+ }
+
+ break;
+ } // if ((dw_Status & 8) == 8)
+ else
+ {
+ /*******************************/
+ /* Test if measurement stopped */
+ /*******************************/
+
+ if ((dw_Status & 2) == 2)
+ {
+ /***********************/
+ /* A stop signal occur */
+ /***********************/
+
+ *pb_ChronoStatus = 2;
+
+ /***************************/
+ /* Test if continnous mode */
+ /***************************/
+
+ if (devpriv->
+ s_ModuleInfo [b_ModulNbr].
+ s_ChronoModuleInfo.
+ b_CycleMode == APCI1710_CONTINUOUS)
+ {
+ /*************************/
+ /* Clear status register */
+ /*************************/
+
+
+ outl(0,devpriv->s_BoardInfos.
+ ui_Address + 36 + (64 * b_ModulNbr));
+ }
+ break;
+ } // if ((dw_Status & 2) == 2)
+ else
+ {
+ /*******************************/
+ /* Test if measurement started */
+ /*******************************/
+
+ if ((dw_Status & 1) == 1)
+ {
+ /************************/
+ /* A start signal occur */
+ /************************/
+
+ *pb_ChronoStatus = 1;
+ } // if ((dw_Status & 1) == 1)
+ else
+ {
+ /***************************/
+ /* Measurement not started */
+ /***************************/
+
+ *pb_ChronoStatus = 0;
+ } // if ((dw_Status & 1) == 1)
+ } // if ((dw_Status & 2) == 2)
+ } // if ((dw_Status & 8) == 8)
+
+ if (dw_TimeOut == ui_TimeOut)
+ {
+ /*****************/
+ /* Timeout occur */
+ /*****************/
+
+ break;
+ }
+ else
+ {
+ /*************************/
+ /* Increment the timeout */
+ /*************************/
+
+ dw_TimeOut = dw_TimeOut + 1;
+ mdelay(1000);
+
+ }
+ } // for (;;)
+
+ /*****************************/
+ /* Test if stop signal occur */
+ /*****************************/
+
+ if (*pb_ChronoStatus == 2)
+ {
+ /**********************************/
+ /* Read the measured timing value */
+ /**********************************/
+
+
+ *pul_ChronoValue= inl(devpriv->s_BoardInfos.
+ ui_Address + 4 + (64 * b_ModulNbr));
+
+ if (*pul_ChronoValue != 0)
+ {
+ *pul_ChronoValue = *pul_ChronoValue - 1;
+ }
+ }
+ else
+ {
+ /*************************/
+ /* Test if timeout occur */
+ /*************************/
+
+ if ((*pb_ChronoStatus != 3) && (dw_TimeOut == ui_TimeOut) && (ui_TimeOut != 0))
+ {
+ /*****************/
+ /* Timeout occur */
+ /*****************/
+
+ *pb_ChronoStatus = 4;
+ }
+ }
+
+ }
+ else
+ {
+ /******************************/
+ /* Timeout parameter is wrong */
+ /******************************/
+ DPRINTK("Timeout parameter is wrong\n");
+ i_ReturnValue = -5;
+ }
+ }
+ else
+ {
+ /*******************************/
+ /* Chronometer not initialised */
+ /*******************************/
+ DPRINTK("Chronometer not initialised\n");
+ i_ReturnValue = -4;
+ }
+ }
+ else
+ {
+ /******************************************/
+ /* The module is not a Chronometer module */
+ /******************************************/
+ DPRINTK("The module is not a Chronometer module\n");
+ i_ReturnValue = -3;
+ }
+ }
+ else
+ {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+ }
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ConvertChronoValue |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| ULONG_ ul_ChronoValue, |
+| PULONG_ pul_Hour, |
+| PBYTE_ pb_Minute, |
+| PBYTE_ pb_Second, |
+| PUINT_ pui_MilliSecond, |
+| PUINT_ pui_MicroSecond, |
+| PUINT_ pui_NanoSecond) |
++----------------------------------------------------------------------------+
+| Task : Convert the chronometer measured timing |
+| (ul_ChronoValue) in to h, mn, s, ms, µs, ns. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3)|
+| ULONG_ ul_ChronoValue : Measured chronometer timing |
+| value. |
+| See"i_APCI1710_ReadChronoValue"|
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pul_Hour : Chronometer timing hour |
+| PBYTE_ pb_Minute : Chronometer timing minute |
+| PBYTE_ pb_Second : Chronometer timing second |
+| PUINT_ pui_MilliSecond : Chronometer timing mini |
+| second |
+| PUINT_ pui_MicroSecond : Chronometer timing micro |
+| second |
+| PUINT_ pui_NanoSecond : Chronometer timing nano |
+| second |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a Chronometer module |
+| -4: Chronometer not initialised see function |
+| "i_APCI1710_InitChrono" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_ConvertChronoValue (comedi_device *dev,
+ BYTE b_ModulNbr,
+ ULONG ul_ChronoValue,
+ PULONG pul_Hour,
+ PBYTE pb_Minute,
+ PBYTE pb_Second,
+ PUINT pui_MilliSecond,
+ PUINT pui_MicroSecond,
+ PUINT pui_NanoSecond)
+ {
+ INT i_ReturnValue = 0;
+ double d_Hour;
+ double d_Minute;
+ double d_Second;
+ double d_MilliSecond;
+ double d_MicroSecond;
+ double d_NanoSecond;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4)
+ {
+ /***********************/
+ /* Test if chronometer */
+ /***********************/
+
+ if ((devpriv->
+ s_BoardInfos.
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_CHRONOMETER)
+ {
+ /***********************************/
+ /* Test if chronometer initialised */
+ /***********************************/
+
+ if (devpriv->
+ s_ModuleInfo [b_ModulNbr].
+ s_ChronoModuleInfo.
+ b_ChronoInit == 1)
+ {
+
+ d_Hour = (double) ul_ChronoValue * (double) devpriv->
+ s_ModuleInfo [b_ModulNbr].
+ s_ChronoModuleInfo.
+ d_TimingInterval;
+
+ switch (devpriv->
+ s_ModuleInfo [b_ModulNbr].
+ s_ChronoModuleInfo.
+ b_TimingUnit)
+ {
+ case 0:
+ d_Hour = d_Hour / (double) 1000.0;
+
+ case 1:
+ d_Hour = d_Hour / (double) 1000.0;
+
+ case 2:
+ d_Hour = d_Hour / (double) 1000.0;
+
+ case 3:
+ d_Hour = d_Hour / (double) 60.0;
+
+ case 4:
+ /**********************/
+ /* Calculate the hour */
+ /**********************/
+
+ d_Hour = d_Hour / (double) 60.0;
+ *pul_Hour = (ULONG) d_Hour;
+
+ /************************/
+ /* Calculate the minute */
+ /************************/
+
+ d_Minute = d_Hour - *pul_Hour;
+ d_Minute = d_Minute * 60;
+ *pb_Minute = (BYTE) d_Minute;
+
+ /************************/
+ /* Calculate the second */
+ /************************/
+
+ d_Second = d_Minute - *pb_Minute;
+ d_Second = d_Second * 60;
+ *pb_Second = (BYTE) d_Second;
+
+ /*****************************/
+ /* Calculate the mini second */
+ /*****************************/
+
+ d_MilliSecond = d_Second - *pb_Second;
+ d_MilliSecond = d_MilliSecond * 1000;
+ *pui_MilliSecond = (UINT) d_MilliSecond;
+
+ /******************************/
+ /* Calculate the micro second */
+ /******************************/
+
+ d_MicroSecond = d_MilliSecond - *pui_MilliSecond;
+ d_MicroSecond = d_MicroSecond * 1000;
+ *pui_MicroSecond = (UINT) d_MicroSecond;
+
+ /******************************/
+ /* Calculate the micro second */
+ /******************************/
+
+ d_NanoSecond = d_MicroSecond - *pui_MicroSecond;
+ d_NanoSecond = d_NanoSecond * 1000;
+ *pui_NanoSecond = (UINT) d_NanoSecond;
+ break;
+ }
+
+ }
+ else
+ {
+ /*******************************/
+ /* Chronometer not initialised */
+ /*******************************/
+ DPRINTK("Chronometer not initialised\n");
+ i_ReturnValue = -4;
+ }
+ }
+ else
+ {
+ /******************************************/
+ /* The module is not a Chronometer module */
+ /******************************************/
+ DPRINTK("The module is not a Chronometer module\n");
+ i_ReturnValue = -3;
+ }
+ }
+ else
+ {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+ }
+\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : INT i_APCI1710_InsnBitsChronoDigitalIO(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data) |\r
++----------------------------------------------------------------------------+\r
+| Task : Sets the output witch has been passed with the |\r
+| parameter b_Channel. Setting an output means setting an|\r
+| output high. |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Selected module number (0 to 3)|\r
+| BYTE_ b_OutputChannel : Selection from digital output |\r
+| CR_CHAN() channel (0 to 2) |\r
+| 0 : Channel H |\r
+| 1 : Channel A |\r
+| 2 : Channel B |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: Module selection wrong |\r
+| -3: The module is not a Chronometer module |\r
+| -4: The selected digital output is wrong |\r
+| -5: Chronometer not initialised see function |\r
+| "i_APCI1710_InitChrono" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_SetChronoChlOff |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_OutputChannel) |\r
++----------------------------------------------------------------------------+\r
+| Task : Resets the output witch has been passed with the |\r
+| parameter b_Channel. Resetting an output means setting |\r
+| an output low. |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 \r
+ data[0] : Chl ON, Chl OFF , Chl Read , Port Read \r
+ \r
+| BYTE_ b_ModulNbr CR_AREF : Selected module number (0 to 3)|\r
+| BYTE_ b_OutputChannel CR_CHAN : Selection from digital output |\r
+| channel (0 to 2) |\r
+| 0 : Channel H |\r
+| 1 : Channel A |\r
+| 2 : Channel B |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: Module selection wrong |\r
+| -3: The module is not a Chronometer module |\r
+| -4: The selected digital output is wrong |\r
+| -5: Chronometer not initialised see function |\r
+| "i_APCI1710_InitChrono" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_ReadChronoChlValue |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_InputChannel, |\r
+| PBYTE_ pb_ChannelStatus) |\r
++----------------------------------------------------------------------------+\r
+| Task : Return the status from selected digital input |\r
+| (b_InputChannel) from selected chronometer |\r
+| module (b_ModulNbr). |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Selected module number (0 to 3)|\r
+| BYTE_ b_InputChannel : Selection from digital input |\r
+| channel (0 to 2) |\r
+| CR_CHAN() 0 : Channel E |\r
+| 1 : Channel F |\r
+| 2 : Channel G |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : PBYTE_ pb_ChannelStatus : Digital input channel status.|\r
+| data[0] 0 : Channel is not active |\r
+| 1 : Channel is active |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: Module selection wrong |\r
+| -3: The module is not a Chronometer module |\r
+| -4: The selected digital input is wrong |\r
+| -5: Chronometer not initialised see function |\r
+| "i_APCI1710_InitChrono" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_ReadChronoPortValue |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| PBYTE_ pb_PortValue) |\r
++----------------------------------------------------------------------------+\r
+| Task : Return the status from digital inputs port from |\r
+| selected (b_ModulNbr) chronometer module. |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Selected module number (0 to 3)|\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : PBYTE_ pb_PortValue : Digital inputs port status. \r
+| data[0]\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: Module selection wrong |\r
+| -3: The module is not a Chronometer module |\r
+| -4: Chronometer not initialised see function |\r
+| "i_APCI1710_InitChrono" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+
+\r
+INT i_APCI1710_InsnBitsChronoDigitalIO(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ BYTE b_ModulNbr,b_OutputChannel,b_InputChannel,b_IOType;
+ DWORD dw_Status;
+ PBYTE pb_ChannelStatus;
+ PBYTE pb_PortValue;\r
+ \r
+ b_ModulNbr = CR_AREF(insn->chanspec);\r
+ i_ReturnValue = insn->n;\r
+ b_IOType = (BYTE) data[0];\r
+ \r
+\r
+
+\r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /***********************/\r
+ /* Test if chronometer */\r
+ /***********************/\r
+\r
+ if ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_CHRONOMETER)\r
+ {\r
+ /***********************************/\r
+ /* Test if chronometer initialised */\r
+ /***********************************/\r
+\r
+ if (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_ChronoModuleInfo.\r
+ b_ChronoInit == 1)\r
+ {\r
+ /***********************************/\r
+ /* Test the digital output channel */\r
+ /***********************************/\r
+ switch(b_IOType)\r
+ {\r
+\r
+ case APCI1710_CHRONO_SET_CHANNELOFF:\r
+\r
+ b_OutputChannel = (BYTE) CR_CHAN(insn->chanspec);\r
+ if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2))\r
+ {\r
+
+ outl(0,devpriv->s_BoardInfos.ui_Address + 20 + (b_OutputChannel * 4) + (64 * b_ModulNbr));\r
+ } // if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2))\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* The selected digital output is wrong */\r
+ /****************************************/\r
+\r DPRINTK("The selected digital output is wrong\n");
+ i_ReturnValue = -4;\r
+\r
+ } // if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2))\r
+\r
+ break;\r
+\r
+ case APCI1710_CHRONO_SET_CHANNELON:\r
+\r
+ b_OutputChannel = (BYTE) CR_CHAN(insn->chanspec);\r
+ if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2))\r
+ {\r
+
+ outl(1,devpriv->s_BoardInfos.ui_Address + 20 + (b_OutputChannel * 4) + (64 * b_ModulNbr));\r
+ } // if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2))\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* The selected digital output is wrong */\r
+ /****************************************/\r
+\r DPRINTK("The selected digital output is wrong\n");
+ i_ReturnValue = -4;\r
+\r
+ } // if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2))\r
+\r
+ break;\r
+ \r
+ case APCI1710_CHRONO_READ_CHANNEL :\r
+ /**********************************/\r
+ /* Test the digital input channel */\r
+ /**********************************/\r
+ pb_ChannelStatus = (PBYTE) &data[0];\r
+ b_InputChannel = (BYTE) CR_CHAN(insn->chanspec);\r
+ \r
+ if ((b_InputChannel >= 0) && (b_InputChannel <= 2))\r
+ {\r
+ \r
+ dw_Status = inl(devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr));\r
+\r
+ *pb_ChannelStatus = (BYTE) (((dw_Status >> b_InputChannel) & 1) ^ 1);\r
+ } // if ((b_InputChannel >= 0) && (b_InputChannel <= 2))\r
+ else\r
+ {\r
+ /***************************************/\r
+ /* The selected digital input is wrong */\r
+ /***************************************/\r
+\r DPRINTK("The selected digital input is wrong\n");
+ i_ReturnValue = -4;\r
+ } // if ((b_InputChannel >= 0) && (b_InputChannel <= 2))\r
+\r
+ break;\r
+\r
+ case APCI1710_CHRONO_READ_PORT :\r
+\r
+ pb_PortValue = (PBYTE) &data[0];\r
+\r
+
+ dw_Status = inl(devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr));\r
+\r
+ *pb_PortValue = (BYTE) ((dw_Status & 0x7) ^ 7);\r
+ break;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*******************************/\r
+ /* Chronometer not initialised */\r
+ /*******************************/\r
+\r DPRINTK("Chronometer not initialised\n");
+ i_ReturnValue = -5;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /******************************************/\r
+ /* The module is not a Chronometer module */\r
+ /******************************************/\r
+\r DPRINTK("The module is not a Chronometer module\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***********************/\r
+ /* Module number error */\r
+ /***********************/\r
+\r DPRINTK("Module number error\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+}\r
+\r
--- /dev/null
+\r\r
+\r
+\r
+#define APCI1710_30MHZ 30\r
+#define APCI1710_33MHZ 33\r
+#define APCI1710_40MHZ 40\r
+
+\r
+#define APCI1710_SINGLE 0\r
+#define APCI1710_CONTINUOUS 1\r
+\r
+\r
+#define APCI1710_CHRONO_PROGRESS_STATUS 0\r
+#define APCI1710_CHRONO_READVALUE 1\r
+#define APCI1710_CHRONO_CONVERTVALUE 2\r
+#define APCI1710_CHRONO_READINTERRUPT 3
+\r
+#define APCI1710_CHRONO_SET_CHANNELON 0\r
+#define APCI1710_CHRONO_SET_CHANNELOFF 1\r
+#define APCI1710_CHRONO_READ_CHANNEL 2\r
+#define APCI1710_CHRONO_READ_PORT 3\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| CHRONOMETER INISIALISATION FUNCTION |\r
++----------------------------------------------------------------------------+\r */\r
+\r
+INT i_APCI1710_InsnConfigInitChrono(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data);\r
+\r
+INT i_APCI1710_InsnWriteEnableDisableChrono(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data);\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| CHRONOMETER READ FUNCTION |\r
++----------------------------------------------------------------------------+\r
+*/\r
+
+INT i_APCI1710_InsnReadChrono(comedi_device *dev,comedi_subdevice *s,
+comedi_insn *insn,lsampl_t *data);
+
+
+INT i_APCI1710_GetChronoProgressStatus (comedi_device *dev,
+ BYTE b_ModulNbr,
+ PBYTE pb_ChronoStatus);
+
+INT i_APCI1710_ReadChronoValue (comedi_device *dev,
+ BYTE b_ModulNbr,
+ UINT ui_TimeOut,
+ PBYTE pb_ChronoStatus,
+ PULONG pul_ChronoValue);
+
+INT i_APCI1710_ConvertChronoValue (comedi_device *dev,
+ BYTE b_ModulNbr,
+ ULONG ul_ChronoValue,
+ PULONG pul_Hour,
+ PBYTE pb_Minute,
+ PBYTE pb_Second,
+ PUINT pui_MilliSecond,
+ PUINT pui_MicroSecond,
+ PUINT pui_NanoSecond);
+
+
+\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| CHRONOMETER DIGITAL INPUT OUTPUT FUNCTION |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_InsnBitsChronoDigitalIO(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data);\r
+\r
+\r
--- /dev/null
+/*\r
+ +-----------------------------------------------------------------------+\r
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |\r
+ +-----------------------------------------------------------------------+\r
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |\r
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |\r
+ +-----------------------------------------------------------------------+\r
+ | Project : API APCI1710 | Compiler : BORLANDC/MICROSOFT C |\r
+ | Module name : DIG_IO.C | Version : 3.1 / 6.0 |\r
+ +-------------------------------+---------------------------------------+\r
+ | Author : S.WEBER | Date : 16.06.98 |\r
+ +-----------------------------------------------------------------------+\r
+ | Description : APCI-1710 digital I/O module |\r
+ | |\r
+ | |\r
+ +-----------------------------------------------------------------------+\r
+ | UPDATES |\r
+ +-----------------------------------------------------------------------+\r
+ | Date | Author | Description of updates |\r
+ +----------+-----------+------------------------------------------------+\r
+ | 16/06/98 | S. Weber | Digital input / output implementation |\r
+ |----------|-----------|------------------------------------------------|\r
+ | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |\r
+ | | | available |\r
+ +-----------------------------------------------------------------------+\r
+ | | | |\r
+ | | | |\r
+ +-----------------------------------------------------------------------+\r
+*/\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Included files |\r
++----------------------------------------------------------------------------+\r
+*/\r
+#include "APCI1710_Dig_io.h"\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : INT i_APCI1710_InsnConfigDigitalIO(comedi_device *dev, |\r
+| comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)|\r
++----------------------------------------------------------------------------+\r
+| Task : Configure the digital I/O operating mode from selected |\r
+| module (b_ModulNbr). You must calling this function be|\r
+| for you call any other function witch access of digital|\r
+| I/O. |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : |\r
+| BYTE_ b_ModulNbr data[0]: Module number to |\r
+| configure (0 to 3) |\r
+| BYTE_ b_ChannelAMode data[1] : Channel A mode selection |\r
+| 0 : Channel used for digital |\r
+| input |\r
+| 1 : Channel used for digital |\r
+| output |\r
+| BYTE_ b_ChannelBMode data[2] : Channel B mode selection |\r
+| 0 : Channel used for digital |\r
+| input |\r
+| 1 : Channel used for digital |\r
+| output | \r
+ data[0] memory on/off\r
+Activates and deactivates the digital output memory. \r
+ After having |\r
+| called up this function with memory on,the output you have previously|\r
+| activated with the function are not reset\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: The module parameter is wrong |\r
+| -3: The module is not a digital I/O module |\r
+| -4: Bi-directional channel A configuration error |\r
+| -5: Bi-directional channel B configuration error |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_InsnConfigDigitalIO(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data)\r
+ {\r
+ BYTE b_ModulNbr,b_ChannelAMode,b_ChannelBMode ;
+ BYTE b_MemoryOnOff,b_ConfigType;\r
+ INT i_ReturnValue = 0;\r
+ DWORD dw_WriteConfig = 0;\r
+
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_ConfigType\r = (BYTE) data[0];// Memory or Init
+ b_ChannelAMode = (BYTE) data[1];\r
+ b_ChannelBMode = (BYTE) data[2];\r
+ b_MemoryOnOff = (BYTE) data[1]; // if memory operation
+ i_ReturnValue = insn->n;\r
+
+
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr >= 4)\r
+ {\r
+ DPRINTK("Module Number invalid\n");\r
+ i_ReturnValue = -2;
+ return i_ReturnValue; \r
+ } \r
+ switch(b_ConfigType)
+ {
+ case APCI1710_DIGIO_MEMORYONOFF:
+\r
+ if(b_MemoryOnOff) // If Memory ON\r
+ {\r
+ /****************************/\r
+ /* Set the output memory on */\r
+ /****************************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_DigitalIOInfo.\r
+ b_OutputMemoryEnabled = 1;\r
+\r
+ /***************************/\r
+ /* Clear the output memory */\r
+ /***************************/\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_DigitalIOInfo.\r
+ dw_OutputMemory = 0;\r
+ }\r
+ else // If memory off\r
+ {\r
+ /*****************************/\r
+ /* Set the output memory off */\r
+ /*****************************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_DigitalIOInfo.\r
+ b_OutputMemoryEnabled = 0; \r
+ }\r
+ break;
+
+ case APCI1710_DIGIO_INIT:
+
+ /*******************************/\r
+ /* Test if digital I/O counter */\r
+ /*******************************/\r
+\r
+ if((devpriv->s_BoardInfos.dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_DIGITAL_IO)\r
+ {\r
+\r
+ /***************************************************/\r
+ /* Test the bi-directional channel A configuration */\r
+ /***************************************************/\r
+ \r
+ if ((b_ChannelAMode == 0) || (b_ChannelAMode == 1))\r
+ {\r
+ /***************************************************/\r
+ /* Test the bi-directional channel B configuration */\r
+ /***************************************************/\r
+\r
+ if ((b_ChannelBMode == 0) || (b_ChannelBMode == 1))\r
+ {\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_DigitalIOInfo.\r
+ b_DigitalInit = 1;\r
+\r
+ /********************************/\r
+ /* Save channel A configuration */\r
+ /********************************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_DigitalIOInfo.\r
+ b_ChannelAMode = b_ChannelAMode;\r
+\r
+ /********************************/\r
+ /* Save channel B configuration */\r
+ /********************************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_DigitalIOInfo.\r
+ b_ChannelBMode = b_ChannelBMode;\r
+\r
+ /*****************************************/\r
+ /* Set the channel A and B configuration */\r
+ /*****************************************/\r
+\r
+\r
+ dw_WriteConfig = (DWORD) (b_ChannelAMode | (b_ChannelBMode * 2));\r
+\r
+ /***************************/\r
+ /* Write the configuration */\r
+ /***************************/\r
+\r
+ outl(dw_WriteConfig,devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr));\r
+\r
+ }\r
+ else\r
+ {\r
+ /************************************************/\r
+ /* Bi-directional channel B configuration error */\r
+ /************************************************/ \r
+ DPRINTK("Bi-directional channel B configuration error\n"); \r
+ i_ReturnValue = -5; \r
+ } \r
+\r
+ }\r
+ else\r
+ {\r
+ /************************************************/\r
+ /* Bi-directional channel A configuration error */\r
+ /************************************************/\r
+ DPRINTK("Bi-directional channel A configuration error\n"); \r
+ i_ReturnValue = -4; \r
+ \r
+ } \r
+\r
+ }\r
+ else\r
+ {\r
+ /******************************************/\r
+ /* The module is not a digital I/O module */\r
+ /******************************************/\r
+ DPRINTK("The module is not a digital I/O module\n"); \r
+ i_ReturnValue = -3;\r
+ }
+ } // end of Switch
+ printk("Return Value %d\n",i_ReturnValue); \r
+ return i_ReturnValue;\r
+}\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| INPUT FUNCTIONS |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+\r
+|INT i_APCI1710_InsnReadDigitalIOChlValue(comedi_device *dev,comedi_subdevice \r
+*s, comedi_insn *insn,lsampl_t *data)\r
+\r
++----------------------------------------------------------------------------+\r
+| Task : Read the status from selected digital I/O digital input|\r
+| (b_InputChannel) |\r
++----------------------------------------------------------------------------|\r
+\r
+ \r
+|\r
+| BYTE_ b_ModulNbr CR_AREF(chanspec) : Selected module number |\r
+| (0 to 3) |\r
+| BYTE_ b_InputChannel CR_CHAN(chanspec) : Selection from digital |\r
+| input ( 0 to 6) |\r
+| 0 : Channel C |\r
+| 1 : Channel D |\r
+| 2 : Channel E |\r
+| 3 : Channel F |\r
+| 4 : Channel G |\r
+| 5 : Channel A |\r
+| 6 : Channel B \r
+\r
+ \r
+ |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : data[0] : Digital input channel |\r
+| status |\r
+| 0 : Channle is not active|\r
+| 1 : Channle is active |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: The module parameter is wrong |\r
+| -3: The module is not a digital I/O module |\r
+| -4: The selected digital I/O digital input is wrong |\r
+| -5: Digital I/O not initialised |\r
+| -6: The digital channel A is used for output |\r
+| -7: The digital channel B is used for output |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+//_INT_ i_APCI1710_ReadDigitalIOChlValue (BYTE_ b_BoardHandle,\r
+// BYTE_ b_ModulNbr,\r
+// BYTE_ b_InputChannel,\r
+//\r
+// PBYTE_ pb_ChannelStatus)\r
+INT i_APCI1710_InsnReadDigitalIOChlValue(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data)\r
+{\r
+ INT i_ReturnValue = 0;\r
+ DWORD dw_StatusReg;\r
+ BYTE b_ModulNbr,b_InputChannel;\r
+ PBYTE pb_ChannelStatus;
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);\r
+ b_InputChannel = (BYTE) CR_CHAN(insn->chanspec);
+ data[0]=0;\r
+ pb_ChannelStatus= (PBYTE) &data[0];
+ i_ReturnValue = insn->n;\r
+\r
+\r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if digital I/O counter */\r
+ /*******************************/\r
+\r
+ if ((devpriv->s_BoardInfos.dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_DIGITAL_IO)\r
+ {\r
+ /******************************************/\r
+ /* Test the digital imnput channel number */\r
+ /******************************************/\r
+\r
+ if ((b_InputChannel >= 0) && (b_InputChannel <= 6))\r
+ {\r
+ /**********************************************/\r
+ /* Test if the digital I/O module initialised */\r
+ /**********************************************/\r
+\r
+ if (devpriv->s_ModuleInfo[b_ModulNbr].s_DigitalIOInfo.b_DigitalInit == 1)\r
+ {\r
+ /**********************************/\r
+ /* Test if channel A or channel B */\r
+ /**********************************/\r
+\r
+ if (b_InputChannel > 4)\r
+ {\r
+ /*********************/\r
+ /* Test if channel A */\r
+ /*********************/\r
+\r
+ if (b_InputChannel == 5)\r
+ {\r
+ /***************************/\r
+ /* Test the channel A mode */\r
+ /***************************/\r
+\r
+ if (devpriv->s_ModuleInfo [b_ModulNbr].s_DigitalIOInfo.b_ChannelAMode != 0)\r
+ {\r
+ /********************************************/\r
+ /* The digital channel A is used for output */\r
+ /********************************************/\r
+\r
+ i_ReturnValue = -6;\r
+ }\r
+ } // if (b_InputChannel == 5)\r
+ else\r
+ {\r
+ /***************************/\r
+ /* Test the channel B mode */\r
+ /***************************/\r
+\r
+ if (devpriv->s_ModuleInfo [b_ModulNbr].s_DigitalIOInfo.b_ChannelBMode != 0)\r
+ {\r
+ /********************************************/\r
+ /* The digital channel B is used for output */\r
+ /********************************************/\r
+\r
+ i_ReturnValue = -7;\r
+ }\r
+ } // if (b_InputChannel == 5)\r
+ } // if (b_InputChannel > 4)\r
+\r
+ /***********************/\r
+ /* Test if error occur */\r
+ /***********************/\r
+\r
+ if (i_ReturnValue >= 0)\r
+ {\r
+ /**************************/\r
+ /* Read all digital input */\r
+ /**************************/\r
+\r
+ //INPDW (ps_APCI1710Variable->\r
+ // s_Board [b_BoardHandle].\r
+ // s_BoardInfos.\r
+ // ui_Address + (64 * b_ModulNbr),\r
+ // &dw_StatusReg);\r
+\r
+ dw_StatusReg = inl(devpriv->s_BoardInfos.ui_Address + (64 * b_ModulNbr));\r
+\r
+ *pb_ChannelStatus = (BYTE) ((dw_StatusReg ^ 0x1C) >> b_InputChannel) & 1;\r
+
+ } // if (i_ReturnValue == 0)\r
+ }\r
+ else\r
+ {\r
+ /*******************************/\r
+ /* Digital I/O not initialised */\r
+ /*******************************/\r
+ DPRINTK("Digital I/O not initialised\n");\r
+ i_ReturnValue = -5;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /********************************/\r
+ /* Selected digital input error */\r
+ /********************************/\r
+ DPRINTK("Selected digital input error\n"); \r
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /******************************************/\r
+ /* The module is not a digital I/O module */\r
+ /******************************************/\r
+ DPRINTK("The module is not a digital I/O module\n"); \r
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***********************/\r
+ /* Module number error */\r
+ /***********************/\r
+ DPRINTK("Module number error\n"); \r
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| OUTPUT FUNCTIONS |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : INT i_APCI1710_InsnWriteDigitalIOChlOnOff(comedi_device \r
+|*dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)\r
+\r
++----------------------------------------------------------------------------+\r
+| Task : Sets or resets the output witch has been passed with the |\r
+| parameter b_Channel. Setting an output means setting |\r
+| an ouput high. |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr (aref ) : Selected module number (0 to 3)|\r
+| BYTE_ b_OutputChannel (CR_CHAN) : Selection from digital output |\r
+| channel (0 to 2) |\r
+| 0 : Channel H |\r
+| 1 : Channel A |\r
+| 2 : Channel B |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: The module parameter is wrong |\r
+| -3: The module is not a digital I/O module |\r
+| -4: The selected digital output is wrong |\r
+| -5: digital I/O not initialised see function |\r
+| " i_APCI1710_InitDigitalIO" |\r
+| -6: The digital channel A is used for input |\r
+| -7: The digital channel B is used for input \r
+ -8: Digital Output Memory OFF. |\r
+| Use previously the function |\r
+| "i_APCI1710_SetDigitalIOMemoryOn". |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+//_INT_ i_APCI1710_SetDigitalIOChlOn (BYTE_ b_BoardHandle,\r
+// BYTE_ b_ModulNbr,\r
+// BYTE_ b_OutputChannel)\r
+INT i_APCI1710_InsnWriteDigitalIOChlOnOff(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ DWORD dw_WriteValue;\r
+ BYTE b_ModulNbr,b_OutputChannel;\r
+ i_ReturnValue = insn->n; \r
+ b_ModulNbr = CR_AREF(insn->chanspec); \r
+ b_OutputChannel = CR_CHAN(insn->chanspec); \r
+ \r
+
+\r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if digital I/O counter */\r
+ /*******************************/\r
+\r
+ if ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_DIGITAL_IO)\r
+ {\r
+ /**********************************************/\r
+ /* Test if the digital I/O module initialised */\r
+ /**********************************************/\r
+\r
+ if (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_DigitalIOInfo.\r
+ b_DigitalInit == 1)\r
+ {\r
+ /******************************************/\r
+ /* Test the digital output channel number */\r
+ /******************************************/\r
+\r
+ switch (b_OutputChannel)\r
+ {\r
+ /*************/\r
+ /* Channel H */\r
+ /*************/\r
+\r
+ case 0:\r
+ break;\r
+\r
+ /*************/\r
+ /* Channel A */\r
+ /*************/\r
+\r
+ case 1:\r
+ if (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_DigitalIOInfo.\r
+ b_ChannelAMode != 1)\r
+ {\r
+ /*******************************************/\r
+ /* The digital channel A is used for input */\r
+ /*******************************************/\r
+\r
+ i_ReturnValue = -6;\r
+ }\r
+ break;\r
+\r
+ /*************/\r
+ /* Channel B */\r
+ /*************/\r
+\r
+ case 2:\r
+ if (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_DigitalIOInfo.\r
+ b_ChannelBMode != 1)\r
+ {\r
+ /*******************************************/\r
+ /* The digital channel B is used for input */\r
+ /*******************************************/\r
+\r
+ i_ReturnValue = -7;\r
+ }\r
+ break;\r
+\r
+ default :\r
+ /****************************************/\r
+ /* The selected digital output is wrong */\r
+ /****************************************/\r
+\r
+ i_ReturnValue = -4;\r
+ break;\r
+ }\r
+\r
+ /***********************/\r
+ /* Test if error occur */\r
+ /***********************/\r
+\r
+ if (i_ReturnValue >= 0)\r
+ {\r
+ \r
+ \r
+ /*********************************/\r
+ /* Test if set channel ON */\r
+ /*********************************/ \r
+ if(data[0])\r
+ { \r
+ /*********************************/\r
+ /* Test if output memory enabled */\r
+ /*********************************/\r
+\r
+ if (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_DigitalIOInfo.\r
+ b_OutputMemoryEnabled == 1)\r
+ {\r
+ dw_WriteValue = devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_DigitalIOInfo.\r
+ dw_OutputMemory | (1 << b_OutputChannel);\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_DigitalIOInfo.\r
+ dw_OutputMemory = dw_WriteValue;\r
+ }\r
+ else\r
+ {\r
+ dw_WriteValue = 1 << b_OutputChannel;\r
+ }\r
+ } // set channel off\r
+ else\r
+ {\r
+ if (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_DigitalIOInfo.\r
+ b_OutputMemoryEnabled == 1)\r
+ {\r
+ dw_WriteValue = devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_DigitalIOInfo.\r
+ dw_OutputMemory & (0xFFFFFFFFUL - (1 << b_OutputChannel));\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].s_DigitalIOInfo.dw_OutputMemory = dw_WriteValue;\r
+ }\r
+ else\r
+ {\r
+ /*****************************/\r
+ /* Digital Output Memory OFF */\r
+ /*****************************/\r
+ // +Use previously the function "i_APCI1710_SetDigitalIOMemoryOn"\r
+ i_ReturnValue = -8;\r
+ }\r
+\r
+ }\r
+ /*******************/\r
+ /* Write the value */\r
+ /*******************/\r
+\r
+ //OUTPDW (ps_APCI1710Variable->\r
+ // s_Board [b_BoardHandle].\r
+ // s_BoardInfos.\r
+ // ui_Address + (64 * b_ModulNbr),\r
+ // dw_WriteValue);\r
+ outl(dw_WriteValue,devpriv->s_BoardInfos.ui_Address + (64 * b_ModulNbr));\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*******************************/\r
+ /* Digital I/O not initialised */\r
+ /*******************************/\r
+\r
+ i_ReturnValue = -5;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /******************************************/\r
+ /* The module is not a digital I/O module */\r
+ /******************************************/\r
+\r
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***********************/\r
+ /* Module number error */\r
+ /***********************/\r
+\r
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+ \r
+|INT i_APCI1710_InsnBitsDigitalIOPortOnOff(comedi_device *dev,comedi_subdevice \r
+ *s, comedi_insn *insn,lsampl_t *data)\r
++----------------------------------------------------------------------------+\r
+| Task : write:\r
+ Sets or resets one or several outputs from port. |\r
+| Setting an output means setting an output high. |\r
+| If you have switched OFF the digital output memory |\r
+| (OFF), all the other output are set to "0". \r
+\r
+| read:\r
+ Read the status from digital input port |\r
+| from selected digital I/O module (b_ModulNbr) \r
++----------------------------------------------------------------------------+\r
+| Input Parameters : \r
+ BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr CR_AREF(aref) : Selected module number (0 to 3)|\r
+| BYTE_ b_PortValue CR_CHAN(chanspec) : Output Value ( 0 To 7 ) \r
+| data[0] read or write port\r
+ data[1] if write then indicate ON or OFF\r
+\r
+ if read : data[1] will return port status.\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value :\r
+\r
+ INPUT :\r
+ \r
+ 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: The module parameter is wrong |\r
+| -3: The module is not a digital I/O module |\r
+| -4: Digital I/O not initialised \r
+\r
+ OUTPUT: 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: The module parameter is wrong |\r
+| -3: The module is not a digital I/O module |\r
+| -4: Output value wrong |\r
+| -5: digital I/O not initialised see function |\r
+| " i_APCI1710_InitDigitalIO" |\r
+| -6: The digital channel A is used for input |\r
+| -7: The digital channel B is used for input \r
+ -8: Digital Output Memory OFF. |\r
+| Use previously the function |\r
+| "i_APCI1710_SetDigitalIOMemoryOn". |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+//_INT_ i_APCI1710_SetDigitalIOPortOn (BYTE_ b_BoardHandle,\r
+// BYTE_ b_ModulNbr,\r
+// BYTE_ b_PortValue)\r
+INT i_APCI1710_InsnBitsDigitalIOPortOnOff(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ DWORD dw_WriteValue,dw_StatusReg;\r
+ BYTE b_ModulNbr,b_PortValue;
+ BYTE b_PortOperation,b_PortOnOFF;
+\r PBYTE pb_PortValue;
+
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);\r
+ b_PortOperation = (BYTE) data[0];// Input or output
+ b_PortOnOFF = (BYTE) data[1];// if output then On or Off
+ b_PortValue = (BYTE) data[2];// if out put then Value\r
+ i_ReturnValue = insn->n;\r
+ pb_PortValue = (PBYTE) &data[0];\r// if input then read value
+
+\r
+\r
+ switch(b_PortOperation)\r
+ {\r
+ case APCI1710_INPUT :\r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if digital I/O counter */\r
+ /*******************************/\r
+\r
+ if ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_DIGITAL_IO)\r
+ {\r
+ /**********************************************/\r
+ /* Test if the digital I/O module initialised */\r
+ /**********************************************/\r
+\r
+ if (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_DigitalIOInfo.b_DigitalInit == 1)\r
+ {\r
+ /**************************/\r
+ /* Read all digital input */\r
+ /**************************/\r
+\r
+ //INPDW (ps_APCI1710Variable->\r
+ // s_Board [b_BoardHandle].\r
+ // s_BoardInfos.\r
+ // ui_Address + (64 * b_ModulNbr),\r
+ // &dw_StatusReg);\r
+\r
+ dw_StatusReg=inl(devpriv->s_BoardInfos.ui_Address + (64 * b_ModulNbr));\r
+ *pb_PortValue = (BYTE) (dw_StatusReg ^ 0x1C);\r
+
+ }\r
+ else\r
+ {\r
+ /*******************************/\r
+ /* Digital I/O not initialised */\r
+ /*******************************/\r
+\r
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /******************************************/\r
+ /* The module is not a digital I/O module */\r
+ /******************************************/\r
+\r
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***********************/\r
+ /* Module number error */\r
+ /***********************/\r
+\r
+ i_ReturnValue = -2;\r
+ }\r
+ \r
+ break;\r
+\r
+ case APCI1710_OUTPUT :\r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if digital I/O counter */\r
+ /*******************************/\r
+\r
+ if ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_DIGITAL_IO)\r
+ {\r
+ /**********************************************/\r
+ /* Test if the digital I/O module initialised */\r
+ /**********************************************/\r
+\r
+ if (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_DigitalIOInfo.\r
+ b_DigitalInit == 1)\r
+ {\r
+ /***********************/\r
+ /* Test the port value */\r
+ /***********************/\r
+\r
+ if ((b_PortValue >= 0) && (b_PortValue <= 7))\r
+ {\r
+ /***********************************/\r
+ /* Test the digital output channel */\r
+ /***********************************/\r
+\r
+ /**************************/\r
+ /* Test if channel A used */\r
+ /**************************/\r
+\r
+ if ((b_PortValue & 2) == 2)\r
+ {\r
+ if (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_DigitalIOInfo.\r
+ b_ChannelAMode != 1)\r
+ {\r
+ /*******************************************/\r
+ /* The digital channel A is used for input */\r
+ /*******************************************/\r
+\r
+ i_ReturnValue = -6;\r
+ }\r
+ } // if ((b_PortValue & 2) == 2)\r
+\r
+ /**************************/\r
+ /* Test if channel B used */\r
+ /**************************/\r
+\r
+ if ((b_PortValue & 4) == 4)\r
+ {\r
+ if (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_DigitalIOInfo.\r
+ b_ChannelBMode != 1)\r
+ {\r
+ /*******************************************/\r
+ /* The digital channel B is used for input */\r
+ /*******************************************/\r
+\r
+ i_ReturnValue = -7;\r
+ }\r
+ } // if ((b_PortValue & 4) == 4)\r
+\r
+ /***********************/\r
+ /* Test if error occur */\r
+ /***********************/\r
+\r
+ if (i_ReturnValue >= 0)\r
+ {\r
+ \r
+ //if(data[1])\r
+ //{\r
+ switch(b_PortOnOFF)\r
+ { \r
+ /*********************************/\r
+ /* Test if set Port ON */\r
+ /*********************************/\r
+\r
+ case APCI1710_ON :\r
+\r
+ /*********************************/\r
+ /* Test if output memory enabled */\r
+ /*********************************/\r
+\r
+ if (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_DigitalIOInfo.\r
+ b_OutputMemoryEnabled == 1)\r
+ {\r
+ dw_WriteValue = devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_DigitalIOInfo.\r
+ dw_OutputMemory | b_PortValue;\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_DigitalIOInfo.dw_OutputMemory = dw_WriteValue;\r
+ }\r
+ else\r
+ {\r
+ dw_WriteValue = b_PortValue;\r
+ }\r
+ break;\r
+\r
+ // If Set PORT OFF \r
+ case APCI1710_OFF:\r
+ \r
+ /*********************************/\r
+ /* Test if output memory enabled */\r
+ /*********************************/\r
+\r
+ if (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_DigitalIOInfo.b_OutputMemoryEnabled == 1)\r
+ {\r
+ dw_WriteValue = devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_DigitalIOInfo.\r
+ dw_OutputMemory & (0xFFFFFFFFUL - b_PortValue);\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_DigitalIOInfo.\r
+ dw_OutputMemory = dw_WriteValue;\r
+ }\r
+ else\r
+ {\r
+ /*****************************/\r
+ /* Digital Output Memory OFF */\r
+ /*****************************/\r
+\r
+ i_ReturnValue = -8;\r
+ }\r
+ } // switch\r
+\r
+ /*******************/\r
+ /* Write the value */\r
+ /*******************/\r
+\r
+ // OUTPDW (ps_APCI1710Variable->\r
+ // s_Board [b_BoardHandle].\r
+ // s_BoardInfos.\r
+ // ui_Address + (64 * b_ModulNbr),\r
+ // dw_WriteValue);\r
+ outl(dw_WriteValue,devpriv->s_BoardInfos.ui_Address + (64 * b_ModulNbr));\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /**********************/\r
+ /* Output value wrong */\r
+ /**********************/\r
+\r
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*******************************/\r
+ /* Digital I/O not initialised */\r
+ /*******************************/\r
+\r
+ i_ReturnValue = -5;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /******************************************/\r
+ /* The module is not a digital I/O module */\r
+ /******************************************/\r
+\r
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***********************/\r
+ /* Module number error */\r
+ /***********************/\r
+\r
+ i_ReturnValue = -2;\r
+ }\r
+ break;\r
+\r
+ default:\r
+ i_ReturnValue = -9;\r
+ DPRINTK("NO INPUT/OUTPUT specified\n");\r
+ } //switch INPUT / OUTPUT\r
+ return (i_ReturnValue);\r
+}\r
+\r
+\r
+\r
--- /dev/null
+\r
+\r
+\r
+#define APCI1710_ON 1 // Digital Output ON or OFF\r
+#define APCI1710_OFF 0\r
+\r
+\r
+#define APCI1710_INPUT 0 // Digital I/O\r
+#define APCI1710_OUTPUT 1\r
+\r
+#define APCI1710_DIGIO_MEMORYONOFF 0x10 //
+#define APCI1710_DIGIO_INIT 0x11\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| DIGITAL I/O INISIALISATION FUNCTION |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+\r
+ INT i_APCI1710_InsnConfigDigitalIO(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data);\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| INPUT OUTPUT FUNCTIONS |\r
++----------------------------------------------------------------------------+\r
+*/\r
+INT i_APCI1710_InsnReadDigitalIOChlValue(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data);\r
+\r
+INT i_APCI1710_InsnWriteDigitalIOChlOnOff(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data);\r
+\r
+INT i_APCI1710_InsnBitsDigitalIOPortOnOff(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data);\r
+\r
--- /dev/null
+/*\r
+ +-----------------------------------------------------------------------+\r
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |\r
+ +-----------------------------------------------------------------------+\r
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |\r
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |\r
+ +-----------------------------------------------------------------------+\r
+ | Project : API APCI1710 | Compiler : BORLANDC/MICROSOFT C |\r
+ | Module name : INC_CPT.C | Version : 3.1 / 6.0 |\r
+ +-------------------------------+---------------------------------------+\r
+ | Author : S.WEBER | Date : 08.01.98 |\r
+ +-----------------------------------------------------------------------+\r
+ | Description : APCI-1710 incremental counter module |\r
+ | |\r
+ | |\r
+ +-----------------------------------------------------------------------+\r
+ | UPDATES |\r
+ +-----------------------------------------------------------------------+\r
+ | Date | Author | Description of updates |\r
+ +----------+-----------+------------------------------------------------+\r
+ | | | |\r
+ |----------|-----------|------------------------------------------------|\r
+ | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |\r
+ | | | available |\r
+ +-----------------------------------------------------------------------+\r
+ | 29/06/01 | Guinot C. | - 1100/0231 -> 0701/0232 |\r
+ | | | See i_APCI1710_DisableFrequencyMeasurement |\r
+ +-----------------------------------------------------------------------+\r
+*/\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Included files |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+\r
+#include "APCI1710_INCCPT.h"\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| INT i_APCI1710_InsnConfigINCCPT(comedi_device *dev,comedi_subdevice *s,\r
+comedi_insn *insn,lsampl_t *data)\r
+\r
++----------------------------------------------------------------------------+\r
+| Task : Configuration function for INC_CPT |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : | \r
++----------------------------------------------------------------------------+\r
+| Output Parameters : *data\r
++----------------------------------------------------------------------------+\r
+| Return Value : |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+\r
+INT i_APCI1710_InsnConfigINCCPT(comedi_device *dev,comedi_subdevice *s,\r
+comedi_insn *insn,lsampl_t *data)\r
+{ \r
+ UINT ui_ConfigType; \r
+ INT i_ReturnValue = 0;\r
+ ui_ConfigType=CR_CHAN(insn->chanspec);\r
+\r devpriv->tsk_Current=current; // Save the current process task structure
+ switch(ui_ConfigType)\r
+ {\r
+ case APCI1710_INCCPT_INITCOUNTER : \r
+ i_ReturnValue =i_APCI1710_InitCounter (dev,\r
+ CR_AREF(insn->chanspec),\r
+ (BYTE) data[0],\r
+ (BYTE) data[1],\r
+ (BYTE) data[2],\r
+ (BYTE) data[3],\r
+ (BYTE) data[4]);\r
+ break;\r
+\r
+ case APCI1710_INCCPT_COUNTERAUTOTEST:\r
+ i_ReturnValue =i_APCI1710_CounterAutoTest (dev,\r
+ (PBYTE) &data[0]);\r
+ break;\r
+\r
+ case APCI1710_INCCPT_INITINDEX:\r
+ i_ReturnValue =i_APCI1710_InitIndex (dev,\r
+ CR_AREF(insn->chanspec),\r
+ (BYTE) data[0],\r
+ (BYTE) data[1],\r
+ (BYTE) data[2],\r
+ (BYTE) data[3]);\r
+ break;\r
+\r
+ case APCI1710_INCCPT_INITREFERENCE:\r
+ i_ReturnValue =i_APCI1710_InitReference (dev,\r
+ CR_AREF(insn->chanspec),\r
+ (BYTE) data[0]);\r
+ break;\r
+\r
+ case APCI1710_INCCPT_INITEXTERNALSTROBE: \r
+ i_ReturnValue =i_APCI1710_InitExternalStrobe (dev,\r
+ CR_AREF(insn->chanspec),\r
+ (BYTE) data[0],\r
+ (BYTE) data[1]);\r
+ break;\r
+\r
+ case APCI1710_INCCPT_INITCOMPARELOGIC:\r
+ i_ReturnValue =i_APCI1710_InitCompareLogic (dev,\r
+ CR_AREF(insn->chanspec),\r
+ (UINT) data[0]);\r
+ break;\r
+\r
+ case APCI1710_INCCPT_INITFREQUENCYMEASUREMENT:\r
+ i_ReturnValue =i_APCI1710_InitFrequencyMeasurement (dev,\r
+ CR_AREF(insn->chanspec),\r
+ (BYTE) data[0],\r
+ (BYTE) data[1],\r
+ (ULONG) data[2],\r
+ (PULONG) &data[0]);\r
+ break;\r
+\r
+ default: \r
+ printk("Insn Config : Config Parameter Wrong\n");\r
+\r
+ }\r
+\r
+ if(i_ReturnValue>=0) i_ReturnValue =insn->n;\r
+ return (i_ReturnValue);\r
+}\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_InitCounter |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_CounterRange, |\r
+| BYTE_ b_FirstCounterModus, |\r
+| BYTE_ b_FirstCounterOption, |\r
+| BYTE_ b_SecondCounterModus, |\r
+| BYTE_ b_SecondCounterOption) |\r
++----------------------------------------------------------------------------+\r
+| Task : Configure the counter operating mode from selected |\r
+| module (b_ModulNbr). You must calling this function be |\r
+| for you call any other function witch access of |\r
+| counters. |\r
+| |\r
+| Counter range |\r
+| ------------- |\r
+| +------------------------------------+-----------------------------------+ |\r
+| | Parameter Passed value | Description | |\r
+| |------------------------------------+-----------------------------------| |\r
+| |b_ModulNbr APCI1710_16BIT_COUNTER | The module is configured for | |\r
+| | | two 16-bit counter. | |\r
+| | | - b_FirstCounterModus and | |\r
+| | | b_FirstCounterOption | |\r
+| | | configure the first 16 bit | |\r
+| | | counter. | |\r
+| | | - b_SecondCounterModus and | |\r
+| | | b_SecondCounterOption | |\r
+| | | configure the second 16 bit | |\r
+| | | counter. | |\r
+| |------------------------------------+-----------------------------------| |\r
+| |b_ModulNbr APCI1710_32BIT_COUNTER | The module is configured for one | |\r
+| | | 32-bit counter. | |\r
+| | | - b_FirstCounterModus and | |\r
+| | | b_FirstCounterOption | |\r
+| | | configure the 32 bit counter. | |\r
+| | | - b_SecondCounterModus and | |\r
+| | | b_SecondCounterOption | |\r
+| | | are not used and have no | |\r
+| | | importance. | |\r
+| +------------------------------------+-----------------------------------+ |\r
+| |\r
+| Counter operating mode |\r
+| ---------------------- |\r
+| |\r
+| +--------------------+-------------------------+-------------------------+ |\r
+| | Parameter | Passed value | Description | |\r
+| |--------------------+-------------------------+-------------------------| |\r
+| |b_FirstCounterModus | APCI1710_QUADRUPLE_MODE | In the quadruple mode, | |\r
+| | or | | the edge analysis | |\r
+| |b_SecondCounterModus| | circuit generates a | |\r
+| | | | counting pulse from | |\r
+| | | | each edge of 2 signals | |\r
+| | | | which are phase shifted | |\r
+| | | | in relation to each | |\r
+| | | | other. | |\r
+| |--------------------+-------------------------+-------------------------| |\r
+| |b_FirstCounterModus | APCI1710_DOUBLE_MODE | Functions in the same | |\r
+| | or | | way as the quadruple | |\r
+| |b_SecondCounterModus| | mode, except that only | |\r
+| | | | two of the four edges | |\r
+| | | | are analysed per | |\r
+| | | | period | |\r
+| |--------------------+-------------------------+-------------------------| |\r
+| |b_FirstCounterModus | APCI1710_SIMPLE_MODE | Functions in the same | |\r
+| | or | | way as the quadruple | |\r
+| |b_SecondCounterModus| | mode, except that only | |\r
+| | | | one of the four edges | |\r
+| | | | is analysed per | |\r
+| | | | period. | |\r
+| |--------------------+-------------------------+-------------------------| |\r
+| |b_FirstCounterModus | APCI1710_DIRECT_MODE | In the direct mode the | |\r
+| | or | | both edge analysis | |\r
+| |b_SecondCounterModus| | circuits are inactive. | |\r
+| | | | The inputs A, B in the | |\r
+| | | | 32-bit mode or A, B and | |\r
+| | | | C, D in the 16-bit mode | |\r
+| | | | represent, each, one | |\r
+| | | | clock pulse gate circuit| |\r
+| | | | There by frequency and | |\r
+| | | | pulse duration | |\r
+| | | | measurements can be | |\r
+| | | | performed. | |\r
+| +--------------------+-------------------------+-------------------------+ |\r
+| |\r
+| |\r
+| IMPORTANT! |\r
+| If you have configured the module for two 16-bit counter, a mixed |\r
+| mode with a counter in quadruple/double/single mode |\r
+| and the other counter in direct mode is not possible! |\r
+| |\r
+| |\r
+| Counter operating option for quadruple/double/simple mode |\r
+| --------------------------------------------------------- |\r
+| |\r
+| +----------------------+-------------------------+------------------------+|\r
+| | Parameter | Passed value | Description ||\r
+| |----------------------+-------------------------+------------------------||\r
+| |b_FirstCounterOption | APCI1710_HYSTERESIS_ON | In both edge analysis ||\r
+| | or | | circuits is available ||\r
+| |b_SecondCounterOption | | one hysteresis circuit.||\r
+| | | | It suppresses each ||\r
+| | | | time the first counting||\r
+| | | | pulse after a change ||\r
+| | | | of rotation. ||\r
+| |----------------------+-------------------------+------------------------||\r
+| |b_FirstCounterOption | APCI1710_HYSTERESIS_OFF | The first counting ||\r
+| | or | | pulse is not suppress ||\r
+| |b_SecondCounterOption | | after a change of ||\r
+| | | | rotation. ||\r
+| +----------------------+-------------------------+------------------------+|\r
+| |\r
+| |\r
+| IMPORTANT! |\r
+| This option are only avaible if you have selected the direct mode. |\r
+| |\r
+| |\r
+| Counter operating option for direct mode |\r
+| ---------------------------------------- |\r
+| |\r
+| +----------------------+--------------------+----------------------------+ |\r
+| | Parameter | Passed value | Description | |\r
+| |----------------------+--------------------+----------------------------| |\r
+| |b_FirstCounterOption | APCI1710_INCREMENT | The counter increment for | |\r
+| | or | | each counting pulse | |\r
+| |b_SecondCounterOption | | | |\r
+| |----------------------+--------------------+----------------------------| |\r
+| |b_FirstCounterOption | APCI1710_DECREMENT | The counter decrement for | |\r
+| | or | | each counting pulse | |\r
+| |b_SecondCounterOption | | | |\r
+| +----------------------+--------------------+----------------------------+ |\r
+| |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|\r
+| BYTE_ b_ModulNbr : Module number to |\r
+| configure (0 to 3) |\r
+| BYTE_ b_CounterRange : Selection form counter |\r
+| range. |\r
+| BYTE_ b_FirstCounterModus : First counter operating |\r
+| mode. |\r
+| BYTE_ b_FirstCounterOption : First counter option. |\r
+| BYTE_ b_SecondCounterModus : Second counter operating |\r
+| mode. |\r
+| BYTE_ b_SecondCounterOption : Second counter option. |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: The module is not a counter module |\r
+| -3: The selected counter range is wrong. |\r
+| -4: The selected first counter operating mode is wrong. |\r
+| -5: The selected first counter operating option is wrong|\r
+| -6: The selected second counter operating mode is wrong.|\r
+| -7: The selected second counter operating option is |\r
+| wrong. |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+\r
+\r
+\r
+\r
+INT i_APCI1710_InitCounter (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ BYTE b_CounterRange,\r
+ BYTE b_FirstCounterModus,\r
+ BYTE b_FirstCounterOption,\r
+ BYTE b_SecondCounterModus,\r
+ BYTE b_SecondCounterOption)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ \r
+ /*******************************/\r
+ /* Test if incremental counter */\r
+ /*******************************/\r
+\r
+ if ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_INCREMENTAL_COUNTER)\r
+ {\r
+ /**************************/\r
+ /* Test the counter range */\r
+ /**************************/\r
+\r
+ if (b_CounterRange == APCI1710_16BIT_COUNTER || b_CounterRange == APCI1710_32BIT_COUNTER)\r
+ {\r
+ /********************************/\r
+ /* Test the first counter modus */\r
+ /********************************/\r
+\r
+ if (b_FirstCounterModus == APCI1710_QUADRUPLE_MODE ||\r
+ b_FirstCounterModus == APCI1710_DOUBLE_MODE ||\r
+ b_FirstCounterModus == APCI1710_SIMPLE_MODE ||\r
+ b_FirstCounterModus == APCI1710_DIRECT_MODE)\r
+ {\r
+ /*********************************/\r
+ /* Test the first counter option */\r
+ /*********************************/\r
+\r
+ if ((b_FirstCounterModus == APCI1710_DIRECT_MODE &&\r
+ (b_FirstCounterOption == APCI1710_INCREMENT ||\r
+ b_FirstCounterOption == APCI1710_DECREMENT)) ||\r
+ (b_FirstCounterModus != APCI1710_DIRECT_MODE &&\r
+ (b_FirstCounterOption == APCI1710_HYSTERESIS_ON ||\r
+ b_FirstCounterOption == APCI1710_HYSTERESIS_OFF)))\r
+ {\r
+ /**************************/\r
+ /* Test if 16-bit counter */\r
+ /**************************/\r
+\r
+ if (b_CounterRange == APCI1710_16BIT_COUNTER)\r
+ {\r
+ /*********************************/\r
+ /* Test the second counter modus */\r
+ /*********************************/\r
+\r
+ if ((b_FirstCounterModus != APCI1710_DIRECT_MODE &&\r
+ (b_SecondCounterModus == APCI1710_QUADRUPLE_MODE ||\r
+ b_SecondCounterModus == APCI1710_DOUBLE_MODE ||\r
+ b_SecondCounterModus == APCI1710_SIMPLE_MODE)) ||\r
+ (b_FirstCounterModus == APCI1710_DIRECT_MODE &&\r
+ b_SecondCounterModus == APCI1710_DIRECT_MODE))\r
+ {\r
+ /**********************************/\r
+ /* Test the second counter option */\r
+ /**********************************/\r
+\r
+ if ((b_SecondCounterModus == APCI1710_DIRECT_MODE &&\r
+ (b_SecondCounterOption == APCI1710_INCREMENT ||\r
+ b_SecondCounterOption == APCI1710_DECREMENT)) ||\r
+ (b_SecondCounterModus != APCI1710_DIRECT_MODE &&\r
+ (b_SecondCounterOption == APCI1710_HYSTERESIS_ON ||\r
+ b_SecondCounterOption == APCI1710_HYSTERESIS_OFF)))\r
+ {\r
+ i_ReturnValue = 0;\r
+ }\r
+ else\r
+ {\r
+ /*********************************************************/\r
+ /* The selected second counter operating option is wrong */\r
+ /*********************************************************/\r
+\r DPRINTK("The selected second counter operating option is wrong\n");
+ i_ReturnValue = -7;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*******************************************************/\r
+ /* The selected second counter operating mode is wrong */\r
+ /*******************************************************/\r
+\r DPRINTK("The selected second counter operating mode is wrong\n");
+ i_ReturnValue = -6;\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /********************************************************/\r
+ /* The selected first counter operating option is wrong */\r
+ /********************************************************/\r
+\r DPRINTK("The selected first counter operating option is wrong\n");
+ i_ReturnValue = -5;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /******************************************************/\r
+ /* The selected first counter operating mode is wrong */\r
+ /******************************************************/\r
+ DPRINTK("The selected first counter operating mode is wrong\n");\r
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***************************************/\r
+ /* The selected counter range is wrong */\r
+ /***************************************/\r
+\r DPRINTK("The selected counter range is wrong\n");
+ i_ReturnValue = -3;\r
+ }\r
+\r
+ /*************************/\r
+ /* Test if a error occur */\r
+ /*************************/\r
+\r
+ if (i_ReturnValue == 0)\r
+ {\r
+ /**************************/\r
+ /* Test if 16-Bit counter */\r
+ /**************************/\r
+\r
+ if (b_CounterRange == APCI1710_32BIT_COUNTER)\r
+ {\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister1 = b_CounterRange |\r
+ b_FirstCounterModus |\r
+ b_FirstCounterOption;\r
+ }\r
+ else\r
+ {\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister1 = b_CounterRange |\r
+ (b_FirstCounterModus & 0x5) |\r
+ (b_FirstCounterOption & 0x20) |\r
+ (b_SecondCounterModus & 0xA) |\r
+ (b_SecondCounterOption & 0x40);\r
+\r
+ /***********************/\r
+ /* Test if direct mode */\r
+ /***********************/\r
+\r
+ if (b_FirstCounterModus == APCI1710_DIRECT_MODE)\r
+ {\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister1 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister1 | APCI1710_DIRECT_MODE;\r
+ }\r
+ }\r
+\r
+ /***************************/\r
+ /* Write the configuration */\r
+ /***************************/\r
+\r
+
+ outl(devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ dw_ModeRegister1_2_3_4,\r
+ devpriv->s_BoardInfos.\r
+ ui_Address + 20 + (64 * b_ModulNbr));\r
+\r
+\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit = 1;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /**************************************/\r
+ /* The module is not a counter module */\r
+ /**************************************/\r
+\r DPRINTK("The module is not a counter module\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_CounterAutoTest |\r
+| (BYTE_ b_BoardHandle, |\r
+| PBYTE_ pb_TestStatus) |\r
++----------------------------------------------------------------------------+\r
+| Task : A test mode is intended for testing the component and |\r
+| the connected periphery. All the 8-bit counter chains |\r
+| are operated internally as down counters. |\r
+| Independently from the external signals, |\r
+| all the four 8-bit counter chains are decremented in |\r
+| parallel by each negative clock pulse edge of CLKX. |\r
+| |\r
+| Counter auto test conclusion |\r
+| ---------------------------- |\r
+| +-----------------+-----------------------------+ |\r
+| | pb_TestStatus | Error description | |\r
+| | mask | | |\r
+| |-----------------+-----------------------------| |\r
+| | 0000 | No error detected | |\r
+| |-----------------|-----------------------------| |\r
+| | 0001 | Error detected of counter 0 | |\r
+| |-----------------|-----------------------------| |\r
+| | 0010 | Error detected of counter 1 | |\r
+| |-----------------|-----------------------------| |\r
+| | 0100 | Error detected of counter 2 | |\r
+| |-----------------|-----------------------------| |\r
+| | 1000 | Error detected of counter 3 | |\r
+| +-----------------+-----------------------------+ |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 | |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : PBYTE_ pb_TestStatus : Auto test conclusion. See table|\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: No counter module found |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_CounterAutoTest (comedi_device *dev,PBYTE pb_TestStatus)\r
+ {\r
+ BYTE b_ModulCpt = 0;\r
+ INT i_ReturnValue = 0;\r
+ DWORD dw_LathchValue;\r
+ \r
+ \r
+ *pb_TestStatus = 0;\r
+\r
+ /********************************/\r
+ /* Test if counter module found */\r
+ /********************************/\r
+\r
+ if ((devpriv->\r
+ s_BoardInfos.\r
+ dw_MolduleConfiguration [0] & 0xFFFF0000UL) == APCI1710_INCREMENTAL_COUNTER ||\r
+ (devpriv->\r
+ s_BoardInfos.\r
+ dw_MolduleConfiguration [1] & 0xFFFF0000UL) == APCI1710_INCREMENTAL_COUNTER ||\r
+ (devpriv->\r
+ s_BoardInfos.\r
+ dw_MolduleConfiguration [2] & 0xFFFF0000UL) == APCI1710_INCREMENTAL_COUNTER||\r
+ (devpriv->\r
+ s_BoardInfos.\r
+ dw_MolduleConfiguration [3] & 0xFFFF0000UL) == APCI1710_INCREMENTAL_COUNTER)\r
+ {\r
+ for (b_ModulCpt = 0; b_ModulCpt < 4 ; b_ModulCpt ++)\r
+ {\r
+ /*******************************/\r
+ /* Test if incremental counter */\r
+ /*******************************/\r
+\r
+ if ((devpriv->\r
+ s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulCpt] & 0xFFFF0000UL) == APCI1710_INCREMENTAL_COUNTER)\r
+ {\r
+ /******************/\r
+ /* Start the test */\r
+ /******************/\r
+\r
+
+ outl(3,devpriv->s_BoardInfos.\r
+ ui_Address + 16 + (64 * b_ModulCpt));\r
+\r
+ /*********************/\r
+ /* Tatch the counter */\r
+ /*********************/\r
+\r
+
+ outl(1,devpriv->s_BoardInfos.\r
+ ui_Address + (64 * b_ModulCpt));\r
+\r
+ /************************/\r
+ /* Read the latch value */\r
+ /************************/\r
+\r
+
+ dw_LathchValue=inl(devpriv->s_BoardInfos.\r
+ ui_Address + 4 + (64 * b_ModulCpt));\r
+\r
+ if ((dw_LathchValue & 0xFF) != ((dw_LathchValue >> 8) & 0xFF) &&\r
+ (dw_LathchValue & 0xFF) != ((dw_LathchValue >> 16) & 0xFF) &&\r
+ (dw_LathchValue & 0xFF) != ((dw_LathchValue >> 24) & 0xFF))\r
+ {\r
+ *pb_TestStatus = *pb_TestStatus | (1 << b_ModulCpt);\r
+ }\r
+\r
+ /*****************/\r
+ /* Stop the test */\r
+ /*****************/\r
+\r
+ \r
+ outl(0,devpriv->s_BoardInfos.\r
+ ui_Address + 16 + (64 * b_ModulCpt));\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***************************/\r
+ /* No counter module found */\r
+ /***************************/\r
+\r DPRINTK("No counter module found\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_InitIndex (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_ReferenceAction, |\r
+| BYTE_ b_IndexOperation, |\r
+| BYTE_ b_AutoMode, |\r
+| BYTE_ b_InterruptEnable) |\r
++----------------------------------------------------------------------------+\r
+| Task : Initialise the index corresponding to the selected |\r
+| module (b_ModulNbr). If a INDEX flag occur, you have |\r
+| the possibility to clear the 32-Bit counter or to latch|\r
+| the current 32-Bit value in to the first latch |\r
+| register. The b_IndexOperation parameter give the |\r
+| possibility to choice the INDEX action. |\r
+| If you have enabled the automatic mode, each INDEX |\r
+| action is cleared automatically, else you must read |\r
+| the index status ("i_APCI1710_ReadIndexStatus") |\r
+| after each INDEX action. |\r
+| |\r
+| |\r
+| Index action |\r
+| ------------ |\r
+| |\r
+| +------------------------+------------------------------------+ |\r
+| | b_IndexOperation | Operation | |\r
+| |------------------------+------------------------------------| |\r
+| |APCI1710_LATCH_COUNTER | After a index signal, the counter | |\r
+| | | value (32-Bit) is latched in to | |\r
+| | | the first latch register | |\r
+| |------------------------|------------------------------------| |\r
+| |APCI1710_CLEAR_COUNTER | After a index signal, the counter | |\r
+| | | value is cleared (32-Bit) | |\r
+| +------------------------+------------------------------------+ |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Module number to configure |\r
+| (0 to 3) |\r
+| BYTE_ b_ReferenceAction : Determine if the reference |\r
+| must set or no for the |\r
+| acceptance from index |\r
+| APCI1710_ENABLE : |\r
+| Reference must be set for |\r
+| accepted the index |\r
+| APCI1710_DISABLE : |\r
+| Reference have not |\r
+| importance |\r
+| BYTE_ b_IndexOperation : Index operating mode. |\r
+| See table. |\r
+| BYTE_ b_AutoMode : Enable or disable the |\r
+| automatic index reset. |\r
+| APCI1710_ENABLE : |\r
+| Enable the automatic mode |\r
+| APCI1710_DISABLE : |\r
+| Disable the automatic mode |\r
+| BYTE_ b_InterruptEnable : Enable or disable the |\r
+| interrupt. |\r
+| APCI1710_ENABLE : |\r
+| Enable the interrupt |\r
+| APCI1710_DISABLE : |\r
+| Disable the interrupt |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: No counter module found |\r
+| -3: Counter not initialised see function |\r
+| "i_APCI1710_InitCounter" |\r
+| -4 The reference action parameter is wrong |\r
+| -5: The index operating mode parameter is wrong |\r
+| -6: The auto mode parameter is wrong |\r
+| -7: Interrupt parameter is wrong |\r
+| -8: Interrupt function not initialised. |\r
+| See function "i_APCI1710_SetBoardIntRoutineX" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_InitIndex (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ BYTE b_ReferenceAction,\r
+ BYTE b_IndexOperation,\r
+ BYTE b_AutoMode,\r
+ BYTE b_InterruptEnable)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ \r
+\r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+ /********************************/\r
+ /* Test the reference parameter */\r
+ /********************************/\r
+\r
+ if (b_ReferenceAction == APCI1710_ENABLE ||\r
+ b_ReferenceAction == APCI1710_DISABLE)\r
+ {\r
+ /****************************/\r
+ /* Test the index parameter */\r
+ /****************************/\r
+\r
+ if (b_IndexOperation == APCI1710_HIGH_EDGE_LATCH_COUNTER ||\r
+ b_IndexOperation == APCI1710_LOW_EDGE_LATCH_COUNTER ||\r
+ b_IndexOperation == APCI1710_HIGH_EDGE_CLEAR_COUNTER ||\r
+ b_IndexOperation == APCI1710_LOW_EDGE_CLEAR_COUNTER ||\r
+ b_IndexOperation == APCI1710_HIGH_EDGE_LATCH_AND_CLEAR_COUNTER ||\r
+ b_IndexOperation == APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER)\r
+ {\r
+ /********************************/\r
+ /* Test the auto mode parameter */\r
+ /********************************/\r
+\r
+ if (b_AutoMode == APCI1710_ENABLE ||\r
+ b_AutoMode == APCI1710_DISABLE)\r
+ {\r
+ /***************************/\r
+ /* Test the interrupt mode */\r
+ /***************************/\r
+\r
+ if (b_InterruptEnable == APCI1710_ENABLE ||\r
+ b_InterruptEnable == APCI1710_DISABLE)\r
+ {\r
+ \r
+ /************************************/\r
+ /* Makte the configuration commando */\r
+ /************************************/\r
+\r
+ if (b_ReferenceAction == APCI1710_ENABLE)\r
+ {\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister2 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister2 | APCI1710_ENABLE_INDEX_ACTION;\r
+ }\r
+ else\r
+ {\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister2 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister2 & APCI1710_DISABLE_INDEX_ACTION;\r
+ }\r
+\r
+ /****************************************/\r
+ /* Test if low level latch or/and clear */\r
+ /****************************************/\r
+\r
+ if (b_IndexOperation == APCI1710_LOW_EDGE_LATCH_COUNTER ||\r
+ b_IndexOperation == APCI1710_LOW_EDGE_CLEAR_COUNTER ||\r
+ b_IndexOperation == APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER)\r
+ {\r
+ /*************************************/\r
+ /* Set the index level to low (DQ26) */\r
+ /*************************************/\r
+\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister4 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister4 | APCI1710_SET_LOW_INDEX_LEVEL;\r
+ }\r
+ else\r
+ {\r
+ /**************************************/\r
+ /* Set the index level to high (DQ26) */\r
+ /**************************************/\r
+\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister4 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister4 & APCI1710_SET_HIGH_INDEX_LEVEL;\r
+ }\r
+\r
+ /***********************************/\r
+ /* Test if latch and clear counter */\r
+ /***********************************/\r
+\r
+ if (b_IndexOperation == APCI1710_HIGH_EDGE_LATCH_AND_CLEAR_COUNTER ||\r
+ b_IndexOperation == APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER)\r
+ {\r
+ /***************************************/\r
+ /* Set the latch and clear flag (DQ27) */\r
+ /***************************************/\r
+\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister4 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister4 | APCI1710_ENABLE_LATCH_AND_CLEAR;\r
+ } // if (b_IndexOperation == APCI1710_HIGH_EDGE_LATCH_AND_CLEAR_COUNTER || b_IndexOperation == APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER)\r
+ else\r
+ {\r
+ /*****************************************/\r
+ /* Clear the latch and clear flag (DQ27) */\r
+ /*****************************************/\r
+\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister4 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister4 & APCI1710_DISABLE_LATCH_AND_CLEAR;\r
+\r
+ /*************************/\r
+ /* Test if latch counter */\r
+ /*************************/\r
+\r
+ if (b_IndexOperation == APCI1710_HIGH_EDGE_LATCH_COUNTER ||\r
+ b_IndexOperation == APCI1710_LOW_EDGE_LATCH_COUNTER)\r
+ {\r
+ /*********************************/\r
+ /* Enable the latch from counter */\r
+ /*********************************/\r
+\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister2 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister2 | APCI1710_INDEX_LATCH_COUNTER;\r
+ }\r
+ else\r
+ {\r
+ /*********************************/\r
+ /* Enable the clear from counter */\r
+ /*********************************/\r
+\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister2 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister2 & (~APCI1710_INDEX_LATCH_COUNTER);\r
+ }\r
+ } // // if (b_IndexOperation == APCI1710_HIGH_EDGE_LATCH_AND_CLEAR_COUNTER || b_IndexOperation == APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER)\r
+\r
+\r
+ if (b_AutoMode == APCI1710_DISABLE)\r
+ {\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister2 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister2 | APCI1710_INDEX_AUTO_MODE;\r
+ }\r
+ else\r
+ {\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister2 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister2 & (~APCI1710_INDEX_AUTO_MODE);\r
+ }\r
+\r
+ if (b_InterruptEnable == APCI1710_ENABLE)\r
+ {\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister3 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister3 | APCI1710_ENABLE_INDEX_INT;\r
+ }\r
+ else\r
+ {\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister3 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister3 & APCI1710_DISABLE_INDEX_INT;\r
+ }\r
+\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_IndexInit = 1;\r
+ \r
+ }\r
+ else\r
+ {\r
+ /********************************/\r
+ /* Interrupt parameter is wrong */\r
+ /********************************/\r
+ DPRINTK("Interrupt parameter is wrong\n"); \r
+ i_ReturnValue = -7;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /************************************/\r
+ /* The auto mode parameter is wrong */\r
+ /************************************/\r
+\r DPRINTK("The auto mode parameter is wrong\n");
+ i_ReturnValue = -6;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***********************************************/\r
+ /* The index operating mode parameter is wrong */\r
+ /***********************************************/\r
+\r DPRINTK("The index operating mode parameter is wrong\n");
+ i_ReturnValue = -5;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*******************************************/\r
+ /* The reference action parameter is wrong */\r
+ /*******************************************/\r
+\r DPRINTK("The reference action parameter is wrong\n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_InitReference |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_ReferenceLevel) |\r
++----------------------------------------------------------------------------+\r
+| Task : Initialise the reference corresponding to the selected |\r
+| module (b_ModulNbr). |\r
+| |\r
+| Reference level |\r
+| --------------- |\r
+| +--------------------+-------------------------+ |\r
+| | b_ReferenceLevel | Operation | |\r
+| +--------------------+-------------------------+ |\r
+| | APCI1710_LOW | Reference occur if "0" | |\r
+| |--------------------|-------------------------| |\r
+| | APCI1710_HIGH | Reference occur if "1" | |\r
+| +--------------------+-------------------------+ |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Module number to configure |\r
+| (0 to 3) |\r
+| BYTE_ b_ReferenceLevel : Reference level. |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: The selected module number parameter is wrong |\r
+| -3: Counter not initialised see function |\r
+| "i_APCI1710_InitCounter" |\r
+| -4: Reference level parameter is wrong |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_InitReference (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ BYTE b_ReferenceLevel)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+ /**************************************/\r
+ /* Test the reference level parameter */\r
+ /**************************************/\r
+\r
+ if (b_ReferenceLevel == 0 ||\r
+ b_ReferenceLevel == 1)\r
+ {\r
+ if (b_ReferenceLevel == 1)\r
+ {\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister2 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister2 | APCI1710_REFERENCE_HIGH;\r
+ }\r
+ else\r
+ {\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister2 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister2 & APCI1710_REFERENCE_LOW;\r
+ }\r
+\r
+
+ outl(devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ dw_ModeRegister1_2_3_4,devpriv->s_BoardInfos.\r
+ ui_Address + 20 + (64 * b_ModulNbr));\r
+\r
+\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_ReferenceInit = 1;\r
+ }\r
+ else\r
+ {\r
+ /**************************************/\r
+ /* Reference level parameter is wrong */\r
+ /**************************************/\r
+\r DPRINTK("Reference level parameter is wrong\n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+\r
+ \r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_InitExternalStrobe |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_ExternalStrobe, |\r
+| BYTE_ b_ExternalStrobeLevel) |\r
++----------------------------------------------------------------------------+\r
+| Task : Initialises the external strobe level corresponding to |\r
+| the selected module (b_ModulNbr). |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Module number to configure |\r
+| (0 to 3) |\r
+| BYTE_ b_ExternalStrobe : External strobe selection |\r
+| 0 : External strobe A |\r
+| 1 : External strobe B |\r
+| BYTE_ b_ExternalStrobeLevel : External strobe level |\r
+| APCI1710_LOW : |\r
+| External latch occurs if "0" |\r
+| APCI1710_HIGH : |\r
+| External latch occurs if "1" |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: The selected module number is wrong |\r
+| -3: Counter not initialised. |\r
+| See function "i_APCI1710_InitCounter" |\r
+| -4: External strobe selection is wrong |\r
+| -5: External strobe level parameter is wrong |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_InitExternalStrobe (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ BYTE b_ExternalStrobe,\r
+ BYTE b_ExternalStrobeLevel)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ \r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+ /**************************************/\r
+ /* Test the external strobe selection */\r
+ /**************************************/\r
+\r
+ if (b_ExternalStrobe == 0 || b_ExternalStrobe == 1)\r
+ {\r
+ /******************/\r
+ /* Test the level */\r
+ /******************/\r
+\r
+ if ((b_ExternalStrobeLevel == APCI1710_HIGH) ||\r
+ ((b_ExternalStrobeLevel == APCI1710_LOW && (devpriv->\r
+ s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF) >= 0x3135)))\r
+ {\r
+ /*****************/\r
+ /* Set the level */\r
+ /*****************/\r
+\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister4 = (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister4 & (0xFF - (0x10 << b_ExternalStrobe))) |\r
+ ((b_ExternalStrobeLevel^1) << (4 + b_ExternalStrobe));\r
+ }\r
+ else\r
+ {\r
+ /********************************************/\r
+ /* External strobe level parameter is wrong */\r
+ /********************************************/\r
+\r DPRINTK("External strobe level parameter is wrong\n");
+ i_ReturnValue = -5;\r
+ }\r
+ } // if (b_ExternalStrobe == 0 || b_ExternalStrobe == 1)\r
+ else\r
+ {\r
+ /**************************************/\r
+ /* External strobe selection is wrong */\r
+ /**************************************/\r
+\r DPRINTK("External strobe selection is wrong\n");
+ i_ReturnValue = -4;\r
+ } // if (b_ExternalStrobe == 0 || b_ExternalStrobe == 1)\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+ /*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_InitCompareLogic |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| UINT_ ui_CompareValue) |\r
++----------------------------------------------------------------------------+\r
+| Task : Set the 32-Bit compare value. At that moment that the |\r
+| incremental counter arrive to the compare value |\r
+| (ui_CompareValue) a interrupt is generated. |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Module number to configure |\r
+| (0 to 3) |\r
+| UINT_ ui_CompareValue : 32-Bit compare value |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : -\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: No counter module found |\r
+| -3: Counter not initialised see function |\r
+| "i_APCI1710_InitCounter" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_InitCompareLogic (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ UINT ui_CompareValue)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ \r
+\r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+ \r
+ outl(ui_CompareValue,devpriv->s_BoardInfos.\r
+ ui_Address + 28 + (64 * b_ModulNbr));\r
+\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CompareLogicInit = 1;\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_InitFrequencyMeasurement |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_PCIInputClock, |\r
+| BYTE_ b_TimingUnity, |\r
+| ULONG_ ul_TimingInterval, |\r
+| PULONG_ pul_RealTimingInterval) |\r
++----------------------------------------------------------------------------+\r
+| Task : Sets the time for the frequency measurement. |\r
+| Configures the selected TOR incremental counter of the |\r
+| selected module (b_ModulNbr). The ul_TimingInterval and|\r
+| ul_TimingUnity determine the time base for the |\r
+| measurement. The pul_RealTimingInterval returns the |\r
+| real time value. You must call up this function before |\r
+| you call up any other function which gives access to |\r
+| the frequency measurement. |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Number of the module to be |\r
+| configured (0 to 3) |\r
+| BYTE_ b_PCIInputClock : Selection of the PCI bus |\r
+| clock |\r
+| - APCI1710_30MHZ : |\r
+| The PC has a PCI bus clock |\r
+| of 30 MHz |\r
+| - APCI1710_33MHZ : |\r
+| The PC has a PCI bus clock |\r
+| of 33 MHz |\r
+| BYTE_ b_TimingUnity : Base time unit (0 to 2) |\r
+| 0 : ns |\r
+| 1 : æs |\r
+| 2 : ms |\r
+| ULONG_ ul_TimingInterval: Base time value. |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : PULONG_ pul_RealTimingInterval : Real base time value. |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: The selected module number is wrong |\r
+| -3: Counter not initialised see function |\r
+| "i_APCI1710_InitCounter" |\r
+| -4: The selected PCI input clock is wrong |\r
+| -5: Timing unity selection is wrong |\r
+| -6: Base timing selection is wrong |\r
+| -7: 40MHz quartz not on board |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_InitFrequencyMeasurement (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ BYTE b_PCIInputClock,\r
+ BYTE b_TimingUnity,\r
+ ULONG ul_TimingInterval,\r
+ PULONG pul_RealTimingInterval)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ ULONG ul_TimerValue;\r
+ double d_RealTimingInterval;\r
+ DWORD dw_Status = 0;\r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+ /**************************/\r
+ /* Test the PCI bus clock */\r
+ /**************************/\r
+\r
+ if ((b_PCIInputClock == APCI1710_30MHZ) ||\r
+ (b_PCIInputClock == APCI1710_33MHZ) ||\r
+ (b_PCIInputClock == APCI1710_40MHZ))\r
+ {\r
+ /************************/\r
+ /* Test the timing unit */\r
+ /************************/\r
+\r
+ if ((b_TimingUnity >= 0) && (b_TimingUnity <= 2))\r
+ {\r
+ /**********************************/\r
+ /* Test the base timing selection */\r
+ /**********************************/\r
+\r
+ if (((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnity == 0) && (ul_TimingInterval >= 266) && (ul_TimingInterval <= 8738133UL)) ||\r
+ ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnity == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 8738UL)) ||\r
+ ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnity == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 8UL)) ||\r
+ ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnity == 0) && (ul_TimingInterval >= 242) && (ul_TimingInterval <= 7943757UL)) ||\r
+ ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnity == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 7943UL)) ||\r
+ ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnity == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 7UL)) ||\r
+ ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnity == 0) && (ul_TimingInterval >= 200) && (ul_TimingInterval <= 6553500UL)) ||\r
+ ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnity == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 6553UL)) ||\r
+ ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnity == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 6UL)))\r
+ {\r
+ /**********************/\r
+ /* Test if 40MHz used */\r
+ /**********************/\r
+\r
+ if (b_PCIInputClock == APCI1710_40MHZ)\r
+ {\r
+ /******************************/\r
+ /* Test if firmware >= Rev1.5 */\r
+ /******************************/\r
+\r
+ if ((devpriv->\r
+ s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF) >= 0x3135)\r
+ {\r
+ /*********************************/\r
+ /* Test if 40MHz quartz on board */\r
+ /*********************************/\r
+\r
+ /*INPDW (ps_APCI1710Variable->\r
+ s_Board [b_BoardHandle].\r
+ s_BoardInfos.\r
+ ui_Address + 36 + (64 * b_ModulNbr), &dw_Status);*/\r
+ dw_Status=inl(devpriv->s_BoardInfos.\r
+ ui_Address + 36 + (64 * b_ModulNbr));\r
+\r
+ /******************************/\r
+ /* Test the quartz flag (DQ0) */\r
+ /******************************/\r
+\r
+ if ((dw_Status & 1) != 1)\r
+ {\r
+ /*****************************/\r
+ /* 40MHz quartz not on board */\r
+ /*****************************/\r
+\r DPRINTK("40MHz quartz not on board\n");
+ i_ReturnValue = -7;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*****************************/\r
+ /* 40MHz quartz not on board */\r
+ /*****************************/\r
+ DPRINTK("40MHz quartz not on board\n");\r
+ i_ReturnValue = -7;\r
+ }\r
+ } // if (b_PCIInputClock == APCI1710_40MHZ)\r
+\r
+ /***************************/\r
+ /* Test if not error occur */\r
+ /***************************/\r
+\r
+ if (i_ReturnValue == 0)\r
+ {\r
+ /****************************/\r
+ /* Test the INC_CPT version */\r
+ /****************************/\r
+\r
+ if ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF) >= 0x3131)\r
+ {\r
+
+ /**********************/\r
+ /* Test if 40MHz used */\r
+ /**********************/\r
+\r
+ if (b_PCIInputClock == APCI1710_40MHZ)\r
+ {\r
+ /*********************************/\r
+ /* Enable the 40MHz quarz (DQ30) */\r
+ /*********************************/\r
+\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister4 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister4 | APCI1710_ENABLE_40MHZ_FREQUENCY;\r
+ } // if (b_PCIInputClock == APCI1710_40MHZ)\r
+ else\r
+ {\r
+ /**********************************/\r
+ /* Disable the 40MHz quarz (DQ30) */\r
+ /**********************************/\r
+\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister4 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister4 & APCI1710_DISABLE_40MHZ_FREQUENCY;\r
+\r
+ } // if (b_PCIInputClock == APCI1710_40MHZ)\r
+
+\r
+ /********************************/\r
+ /* Calculate the division fator */\r
+ /********************************/\r
+\r
+ switch (b_TimingUnity)\r
+ {\r
+ /******/\r
+ /* ns */\r
+ /******/\r
+\r
+ case 0:\r
+ \r
+ /******************/\r
+ /* Timer 0 factor */\r
+ /******************/\r
+\r
+ ul_TimerValue = (ULONG) (ul_TimingInterval * (0.00025 * b_PCIInputClock));\r
+\r
+ /*******************/\r
+ /* Round the value */\r
+ /*******************/\r
+\r
+ if ((double) ((double) ul_TimingInterval * (0.00025 * (double) b_PCIInputClock)) >= ((double) ((double) ul_TimerValue + 0.5)))\r
+ {\r
+ ul_TimerValue = ul_TimerValue + 1;\r
+ }\r
+\r
+ /*****************************/\r
+ /* Calculate the real timing */\r
+ /*****************************/\r
+\r
+ *pul_RealTimingInterval = (ULONG) (ul_TimerValue / (0.00025 * (double) b_PCIInputClock));\r
+ d_RealTimingInterval = (double) ul_TimerValue / (0.00025 * (double) b_PCIInputClock);\r
+\r
+ if ((double) ((double) ul_TimerValue / (0.00025 * (double) b_PCIInputClock)) >= (double) ((double) *pul_RealTimingInterval + 0.5))\r
+ {\r
+ *pul_RealTimingInterval = *pul_RealTimingInterval + 1;\r
+ }\r
+\r
+ ul_TimingInterval = ul_TimingInterval - 1;\r
+ ul_TimerValue = ul_TimerValue - 2;\r
+ \r
+ break;\r
+\r
+ /******/\r
+ /* æs */\r
+ /******/\r
+\r
+ case 1:\r
+ \r
+ /******************/\r
+ /* Timer 0 factor */\r
+ /******************/\r
+\r
+ ul_TimerValue = (ULONG) (ul_TimingInterval * (0.25 * b_PCIInputClock));\r
+\r
+ /*******************/\r
+ /* Round the value */\r
+ /*******************/\r
+\r
+ if ((double) ((double) ul_TimingInterval * (0.25 * (double) b_PCIInputClock)) >= ((double) ((double) ul_TimerValue + 0.5)))\r
+ {\r
+ ul_TimerValue = ul_TimerValue + 1;\r
+ }\r
+\r
+ /*****************************/\r
+ /* Calculate the real timing */\r
+ /*****************************/\r
+\r
+ *pul_RealTimingInterval = (ULONG) (ul_TimerValue / (0.25 * (double) b_PCIInputClock));\r
+ d_RealTimingInterval = (double) ul_TimerValue / ((double) 0.25 * (double) b_PCIInputClock);\r
+\r
+ if ((double) ((double) ul_TimerValue / (0.25 * (double) b_PCIInputClock)) >= (double) ((double) *pul_RealTimingInterval + 0.5))\r
+ {\r
+ *pul_RealTimingInterval = *pul_RealTimingInterval + 1;\r
+ }\r
+\r
+ ul_TimingInterval = ul_TimingInterval - 1;\r
+ ul_TimerValue = ul_TimerValue - 2;\r
+ \r
+\r
+ break;\r
+\r
+ /******/\r
+ /* ms */\r
+ /******/\r
+\r
+ case 2:\r
+ \r
+ /******************/\r
+ /* Timer 0 factor */\r
+ /******************/\r
+\r
+ ul_TimerValue = ul_TimingInterval * (250.0 * b_PCIInputClock);\r
+\r
+ /*******************/\r
+ /* Round the value */\r
+ /*******************/\r
+\r
+ if ((double) ((double) ul_TimingInterval * (250.0 * (double) b_PCIInputClock)) >= ((double) ((double) ul_TimerValue + 0.5)))\r
+ {\r
+ ul_TimerValue = ul_TimerValue + 1;\r
+ }\r
+\r
+ /*****************************/\r
+ /* Calculate the real timing */\r
+ /*****************************/\r
+\r
+ *pul_RealTimingInterval = (ULONG) (ul_TimerValue / (250.0 * (double) b_PCIInputClock));\r
+ d_RealTimingInterval = (double) ul_TimerValue / (250.0 * (double) b_PCIInputClock);\r
+\r
+ if ((double) ((double) ul_TimerValue / (250.0 * (double) b_PCIInputClock)) >= (double) ((double) *pul_RealTimingInterval + 0.5))\r
+ {\r
+ *pul_RealTimingInterval = *pul_RealTimingInterval + 1;\r
+ }\r
+\r
+ ul_TimingInterval = ul_TimingInterval - 1;\r
+ ul_TimerValue = ul_TimerValue - 2;\r
+ \r
+ break;\r
+ }\r
+\r
+ /*************************/\r
+ /* Write the timer value */\r
+ /*************************/\r
+\r
+ \r
+ outl(ul_TimerValue,devpriv->s_BoardInfos.\r
+ ui_Address + 32 + (64 * b_ModulNbr));\r
+\r
+ /*******************************/\r
+ /* Set the initialisation flag */\r
+ /*******************************/\r
+\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_FrequencyMeasurementInit = 1;\r
+ }\r
+ else\r
+ {\r
+ /***************************/\r
+ /* Counter not initialised */\r
+ /***************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ } // if (i_ReturnValue == 0)\r
+ }\r
+ else\r
+ {\r
+ /**********************************/\r
+ /* Base timing selection is wrong */\r
+ /**********************************/\r
+\r DPRINTK("Base timing selection is wrong\n");
+ i_ReturnValue = -6;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***********************************/\r
+ /* Timing unity selection is wrong */\r
+ /***********************************/\r
+\r DPRINTK("Timing unity selection is wrong\n");
+ i_ReturnValue = -5;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*****************************************/\r
+ /* The selected PCI input clock is wrong */\r
+ /*****************************************/\r
+\r DPRINTK("The selected PCI input clock is wrong\n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+/*########################################################################### */\r
+\r
+ //INSN BITS\r
+/*########################################################################### */\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name :INT i_APCI1710_InsnBitsINCCPT(comedi_device *dev,comedi_subdevice *s,\r
+comedi_insn *insn,lsampl_t *data) |\r
++----------------------------------------------------------------------------+\r
+| Task : Set & Clear Functions for INC_CPT |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : \r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : \r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+\r
+INT i_APCI1710_InsnBitsINCCPT(comedi_device *dev,comedi_subdevice *s,\r
+comedi_insn *insn,lsampl_t *data)\r
+{\r
+ UINT ui_BitsType;\r
+ INT i_ReturnValue=0;\r
+ ui_BitsType=CR_CHAN(insn->chanspec);\r
+ devpriv->tsk_Current=current; // Save the current process task structure
+\r
+ switch(ui_BitsType)\r
+ {\r
+ case APCI1710_INCCPT_CLEARCOUNTERVALUE:\r
+ i_ReturnValue=i_APCI1710_ClearCounterValue (dev,\r
+ (BYTE) CR_AREF(insn->chanspec));\r
+ break;\r
+\r
+ case APCI1710_INCCPT_CLEARALLCOUNTERVALUE:\r
+ i_ReturnValue=i_APCI1710_ClearAllCounterValue (dev);\r
+ break;\r
+\r
+ case APCI1710_INCCPT_SETINPUTFILTER:\r
+ i_ReturnValue=i_APCI1710_SetInputFilter (dev,\r
+ (BYTE) CR_AREF(insn->chanspec),\r
+ (BYTE) data[0],\r
+ (BYTE) data[1]);\r
+ break;\r
+\r
+ case APCI1710_INCCPT_LATCHCOUNTER:\r
+ i_ReturnValue=i_APCI1710_LatchCounter (dev,\r
+ (BYTE) CR_AREF(insn->chanspec),\r
+ (BYTE) data[0]);\r
+ break;\r
+\r
+ case APCI1710_INCCPT_SETINDEXANDREFERENCESOURCE:\r
+ i_ReturnValue=i_APCI1710_SetIndexAndReferenceSource (dev,\r
+ (BYTE) CR_AREF(insn->chanspec),\r
+ (BYTE) data[0]);\r
+ break;\r
+\r
+ case APCI1710_INCCPT_SETDIGITALCHLON:\r
+ i_ReturnValue=i_APCI1710_SetDigitalChlOn (dev,\r
+ (BYTE) CR_AREF(insn->chanspec));\r
+ break;\r
+\r
+ case APCI1710_INCCPT_SETDIGITALCHLOFF:\r
+ i_ReturnValue=i_APCI1710_SetDigitalChlOff (dev,\r
+ (BYTE) CR_AREF(insn->chanspec));\r
+ break;\r
+\r
+ default:\r
+ printk("Bits Config Parameter Wrong\n");\r
+ }\r
+\r
+ if(i_ReturnValue>=0) i_ReturnValue =insn->n;\r
+ return (i_ReturnValue);\r
+}\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_ClearCounterValue |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr) |\r
++----------------------------------------------------------------------------+\r
+| Task : Clear the counter value from selected module |\r
+| (b_ModulNbr). |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Module number to configure |\r
+| (0 to 3) |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: The selected module number parameter is wrong |\r
+| -3: Counter not initialised see function |\r
+| "i_APCI1710_InitCounter" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_ClearCounterValue (comedi_device *dev,\r
+ BYTE b_ModulNbr)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+ /*********************/\r
+ /* Clear the counter */\r
+ /*********************/\r
+\r
+ \r
+ outl(1,devpriv->s_BoardInfos.\r
+ ui_Address + 16 + (64 * b_ModulNbr));\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_ClearAllCounterValue |\r
+| (BYTE_ b_BoardHandle) |\r
++----------------------------------------------------------------------------+\r
+| Task : Clear all counter value. |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: No counter module found |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_ClearAllCounterValue (comedi_device *dev)\r
+ {\r
+ BYTE b_ModulCpt = 0;\r
+ INT i_ReturnValue = 0;\r
+ \r
+\r
+ /********************************/\r
+ /* Test if counter module found */\r
+ /********************************/\r
+\r
+ if ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [0] & 0xFFFF0000UL) == APCI1710_INCREMENTAL_COUNTER ||\r
+ (devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [1] & 0xFFFF0000UL) == APCI1710_INCREMENTAL_COUNTER ||\r
+ (devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [2] & 0xFFFF0000UL) == APCI1710_INCREMENTAL_COUNTER ||\r
+ (devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [3] & 0xFFFF0000UL) == APCI1710_INCREMENTAL_COUNTER)\r
+ {\r
+ for (b_ModulCpt = 0; b_ModulCpt < 4 ; b_ModulCpt ++)\r
+ {\r
+ /*******************************/\r
+ /* Test if incremental counter */\r
+ /*******************************/\r
+\r
+ if ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulCpt] & 0xFFFF0000UL) == APCI1710_INCREMENTAL_COUNTER)\r
+ {\r
+ /*********************/\r
+ /* Clear the counter */\r
+ /*********************/\r
+\r
+ \r
+ outl(1,devpriv->s_BoardInfos.\r
+ ui_Address + 16 + (64 * b_ModulCpt));\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***************************/\r
+ /* No counter module found */\r
+ /***************************/\r
+\r DPRINTK("No counter module found\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_SetInputFilter |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_Module, |\r
+| BYTE_ b_PCIInputClock, |\r
+| BYTE_ b_Filter) |\r
++----------------------------------------------------------------------------+\r
+| Task : Disable or enable the software filter from selected |\r
+| module (b_ModulNbr). b_Filter determine the filter time|\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Number of the module to be |\r
+| configured (0 to 3) |\r
+| BYTE_ b_PCIInputClock : Selection of the PCI bus |\r
+| clock |\r
+| - APCI1710_30MHZ : |\r
+| The PC has a PCI bus clock |\r
+| of 30 MHz |\r
+| - APCI1710_33MHZ : |\r
+| The PC has a PCI bus clock |\r
+| of 33 MHz |\r
+| - APCI1710_40MHZ : |\r
+| The APCI1710 has a 40MHz |\r
+| quartz |\r
+| BYTE_ b_Filter : Filter selection |\r
+| |\r
+| 30 MHz |\r
+| ------ |\r
+| 0: Software filter not used |\r
+| 1: Filter from 266ns (3.750000MHz) |\r
+| 2: Filter from 400ns (2.500000MHz) |\r
+| 3: Filter from 533ns (1.876170MHz) |\r
+| 4: Filter from 666ns (1.501501MHz) |\r
+| 5: Filter from 800ns (1.250000MHz) |\r
+| 6: Filter from 933ns (1.071800MHz) |\r
+| 7: Filter from 1066ns (0.938080MHz) |\r
+| 8: Filter from 1200ns (0.833333MHz) |\r
+| 9: Filter from 1333ns (0.750000MHz) |\r
+| 10: Filter from 1466ns (0.682100MHz) |\r
+| 11: Filter from 1600ns (0.625000MHz) |\r
+| 12: Filter from 1733ns (0.577777MHz) |\r
+| 13: Filter from 1866ns (0.535900MHz) |\r
+| 14: Filter from 2000ns (0.500000MHz) |\r
+| 15: Filter from 2133ns (0.468800MHz) |\r
+| |\r
+| 33 MHz |\r
+| ------ |\r
+| 0: Software filter not used |\r
+| 1: Filter from 242ns (4.125000MHz) |\r
+| 2: Filter from 363ns (2.754820MHz) |\r
+| 3: Filter from 484ns (2.066115MHz) |\r
+| 4: Filter from 605ns (1.652892MHz) |\r
+| 5: Filter from 726ns (1.357741MHz) |\r
+| 6: Filter from 847ns (1.180637MHz) |\r
+| 7: Filter from 968ns (1.033055MHz) |\r
+| 8: Filter from 1089ns (0.918273MHz) |\r
+| 9: Filter from 1210ns (0.826446MHz) |\r
+| 10: Filter from 1331ns (0.751314MHz) |\r
+| 11: Filter from 1452ns (0.688705MHz) |\r
+| 12: Filter from 1573ns (0.635727MHz) |\r
+| 13: Filter from 1694ns (0.590318MHz) |\r
+| 14: Filter from 1815ns (0.550964MHz) |\r
+| 15: Filter from 1936ns (0.516528MHz) |\r
+| |\r
+| 40 MHz |\r
+| ------ |\r
+| 0: Software filter not used |\r
+| 1: Filter from 200ns (5.000000MHz) |\r
+| 2: Filter from 300ns (3.333333MHz) |\r
+| 3: Filter from 400ns (2.500000MHz) |\r
+| 4: Filter from 500ns (2.000000MHz) |\r
+| 5: Filter from 600ns (1.666666MHz) |\r
+| 6: Filter from 700ns (1.428500MHz) |\r
+| 7: Filter from 800ns (1.250000MHz) |\r
+| 8: Filter from 900ns (1.111111MHz) |\r
+| 9: Filter from 1000ns (1.000000MHz) |\r
+| 10: Filter from 1100ns (0.909090MHz) |\r
+| 11: Filter from 1200ns (0.833333MHz) |\r
+| 12: Filter from 1300ns (0.769200MHz) |\r
+| 13: Filter from 1400ns (0.714200MHz) |\r
+| 14: Filter from 1500ns (0.666666MHz) |\r
+| 15: Filter from 1600ns (0.625000MHz) |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: The selected module number is wrong |\r
+| -3: The module is not a counter module |\r
+| -4: The selected PCI input clock is wrong |\r
+| -5: The selected filter value is wrong |\r
+| -6: 40MHz quartz not on board |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_SetInputFilter (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ BYTE b_PCIInputClock,\r
+ BYTE b_Filter)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ DWORD dw_Status = 0;\r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if incremental counter */\r
+ /*******************************/\r
+\r
+ if ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_INCREMENTAL_COUNTER)\r
+ {\r
+ /******************************/\r
+ /* Test if firmware >= Rev1.5 */\r
+ /******************************/\r
+\r
+ if ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF) >= 0x3135)\r
+ {\r
+ /**************************/\r
+ /* Test the PCI bus clock */\r
+ /**************************/\r
+\r
+ if ((b_PCIInputClock == APCI1710_30MHZ) ||\r
+ (b_PCIInputClock == APCI1710_33MHZ) ||\r
+ (b_PCIInputClock == APCI1710_40MHZ))\r
+ {\r
+ /*************************/\r
+ /* Test the filter value */\r
+ /*************************/\r
+\r
+ if (b_Filter < 16)\r
+ {\r
+ /**********************/\r
+ /* Test if 40MHz used */\r
+ /**********************/\r
+\r
+ if (b_PCIInputClock == APCI1710_40MHZ)\r
+ {\r
+ /*********************************/\r
+ /* Test if 40MHz quartz on board */\r
+ /*********************************/\r
+\r
+
+ dw_Status= inl(devpriv->s_BoardInfos.\r
+ ui_Address + 36 + (64 * b_ModulNbr));\r
+\r
+ /******************************/\r
+ /* Test the quartz flag (DQ0) */\r
+ /******************************/\r
+\r
+ if ((dw_Status & 1) != 1)\r
+ {\r
+ /*****************************/\r
+ /* 40MHz quartz not on board */\r
+ /*****************************/\r
+\r DPRINTK("40MHz quartz not on board\n");
+ i_ReturnValue = -6;\r
+ }\r
+ } // if (b_PCIInputClock == APCI1710_40MHZ)\r
+\r
+ /***************************/\r
+ /* Test if error not occur */\r
+ /***************************/\r
+\r
+ if (i_ReturnValue == 0)\r
+ {\r
+ /**********************/\r
+ /* Test if 40MHz used */\r
+ /**********************/\r
+\r
+ if (b_PCIInputClock == APCI1710_40MHZ)\r
+ {\r
+ /*********************************/\r
+ /* Enable the 40MHz quarz (DQ31) */\r
+ /*********************************/\r
+\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister4 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister4 | APCI1710_ENABLE_40MHZ_FILTER;\r
+\r
+ } // if (b_PCIInputClock == APCI1710_40MHZ)\r
+ else\r
+ {\r
+ /**********************************/\r
+ /* Disable the 40MHz quarz (DQ31) */\r
+ /**********************************/\r
+\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister4 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister4 & APCI1710_DISABLE_40MHZ_FILTER;\r
+\r
+ } // if (b_PCIInputClock == APCI1710_40MHZ)\r
+\r
+ /************************/\r
+ /* Set the filter value */\r
+ /************************/\r
+\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister3 = (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister3 & 0x1F) | ((b_Filter & 0x7) << 5);\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister4 = (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister4 & 0xFE) | ((b_Filter & 0x8) >> 3);\r
+\r
+ /***************************/\r
+ /* Write the configuration */\r
+ /***************************/\r
+\r
+ \r
+ outl(devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ dw_ModeRegister1_2_3_4,devpriv->s_BoardInfos.\r
+ ui_Address + 20 + (64 * b_ModulNbr));\r
+ } // if (i_ReturnValue == 0)\r
+ } // if (b_Filter < 16)\r
+ else\r
+ {\r
+ /**************************************/\r
+ /* The selected filter value is wrong */\r
+ /**************************************/\r
+\r DPRINTK("The selected filter value is wrong\n");
+ i_ReturnValue = -5;\r
+ } // if (b_Filter < 16)\r
+ } // if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ) || (b_PCIInputClock == APCI1710_40MHZ))\r
+ else\r
+ {\r
+ /*****************************************/\r
+ /* The selected PCI input clock is wrong */\r
+ /*****************************************/\r
+\r DPRINTK("The selected PCI input clock is wrong\n");
+ i_ReturnValue = 4;\r
+ } // if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ) || (b_PCIInputClock == APCI1710_40MHZ))\r
+ }\r
+ else\r
+ {\r
+ /**************************************/\r
+ /* The module is not a counter module */\r
+ /**************************************/\r
+\r DPRINTK("The module is not a counter module\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /**************************************/\r
+ /* The module is not a counter module */\r
+ /**************************************/\r
+\r DPRINTK("The module is not a counter module\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_LatchCounter (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_LatchReg) |\r
++----------------------------------------------------------------------------+\r
+| Task : Latch the courant value from selected module |\r
+| (b_ModulNbr) in to the selected latch register |\r
+| (b_LatchReg). |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Module number to configure |\r
+| (0 to 3) |\r
+| BYTE_ b_LatchReg : Selected latch register |\r
+| 0 : for the first latch register |\r
+| 1 : for the second latch register |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: No counter module found |\r
+| -3: Counter not initialised see function |\r
+| "i_APCI1710_InitCounter" |\r
+| -4: The selected latch register parameter is wrong |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_LatchCounter (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ BYTE b_LatchReg)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ \r
+\r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+ /*************************************/\r
+ /* Test the latch register parameter */\r
+ /*************************************/\r
+\r
+ if (b_LatchReg < 2)\r
+ {\r
+ /*********************/\r
+ /* Tatch the counter */\r
+ /*********************/\r
+\r
+ outl(1 << (b_LatchReg * 4),devpriv->s_BoardInfos.\r
+ ui_Address + (64 * b_ModulNbr));\r
+ }\r
+ else\r
+ {\r
+ /**************************************************/\r
+ /* The selected latch register parameter is wrong */\r
+ /**************************************************/\r
+\r DPRINTK("The selected latch register parameter is wrong\n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_SetIndexAndReferenceSource |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_SourceSelection) |\r
++----------------------------------------------------------------------------+\r
+| Task : Determine the hardware source for the index and the |\r
+| reference logic. Per default the index logic is |\r
+| connected to the difference input C and the reference |\r
+| logic is connected to the 24V input E |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Module number to configure |\r
+| (0 to 3) |\r
+| BYTE_ b_SourceSelection : APCI1710_SOURCE_0 : |\r
+| The index logic is connected |\r
+| to the difference input C and|\r
+| the reference logic is |\r
+| connected to the 24V input E.|\r
+| This is the default |\r
+| configuration. |\r
+| APCI1710_SOURCE_1 : |\r
+| The reference logic is |\r
+| connected to the difference |\r
+| input C and the index logic |\r
+| is connected to the 24V |\r
+| input E |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: The selected module number is wrong |\r
+| -3: The module is not a counter module. |\r
+| -4: The source selection is wrong |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_SetIndexAndReferenceSource (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ BYTE b_SourceSelection)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ \r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if incremental counter */\r
+ /*******************************/\r
+\r
+ if ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_INCREMENTAL_COUNTER)\r
+ {\r
+ /******************************/\r
+ /* Test if firmware >= Rev1.5 */\r
+ /******************************/\r
+\r
+ if ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF) >= 0x3135)\r
+ {\r
+ /*****************************/\r
+ /* Test the source selection */\r
+ /*****************************/\r
+\r
+ if (b_SourceSelection == APCI1710_SOURCE_0 ||\r
+ b_SourceSelection == APCI1710_SOURCE_1)\r
+ {\r
+ /******************************************/\r
+ /* Test if invert the index and reference */\r
+ /******************************************/\r
+\r
+ if (b_SourceSelection == APCI1710_SOURCE_1)\r
+ {\r
+ /********************************************/\r
+ /* Invert index and reference source (DQ25) */\r
+ /********************************************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister4 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister4 | APCI1710_INVERT_INDEX_RFERENCE;\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Set the default configuration (DQ25) */\r
+ /****************************************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister4 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister4 & APCI1710_DEFAULT_INDEX_RFERENCE;\r
+ }\r
+ } // if (b_SourceSelection == APCI1710_SOURCE_0 ||b_SourceSelection == APCI1710_SOURCE_1)\r
+ else\r
+ {\r
+ /*********************************/\r
+ /* The source selection is wrong */\r
+ /*********************************/\r
+\r DPRINTK("The source selection is wrong\n");
+ i_ReturnValue = -4;\r
+ } // if (b_SourceSelection == APCI1710_SOURCE_0 ||b_SourceSelection == APCI1710_SOURCE_1)\r
+ }\r
+ else\r
+ {\r
+ /**************************************/\r
+ /* The module is not a counter module */\r
+ /**************************************/\r
+\r DPRINTK("The module is not a counter module\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /**************************************/\r
+ /* The module is not a counter module */\r
+ /**************************************/\r
+\r DPRINTK("The module is not a counter module\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***************************************/\r
+ /* The selected module number is wrong */\r
+ /***************************************/\r
+\r DPRINTK("The selected module number is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_SetDigitalChlOn |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr) |\r
++----------------------------------------------------------------------------+\r
+| Task : Sets the digital output H Setting an output means |\r
+| setting an ouput high. |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Number of the module to be |\r
+| configured (0 to 3) |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: The selected module number is wrong |\r
+| -3: Counter not initialised see function |\r
+| "i_APCI1710_InitCounter" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_SetDigitalChlOn (comedi_device *dev,\r
+ BYTE b_ModulNbr)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister3 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister3 | 0x10;\r
+\r
+ /*********************/\r
+ /* Set the output On */\r
+ /*********************/\r
+\r
+ outl(devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ dw_ModeRegister1_2_3_4,devpriv->s_BoardInfos.\r
+ ui_Address + 20 + (64 * b_ModulNbr));\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_SetDigitalChlOff |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr) |\r
++----------------------------------------------------------------------------+\r
+| Task : Resets the digital output H. Resetting an output means |\r
+| setting an ouput low. |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Number of the module to be |\r
+| configured (0 to 3) |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: The selected module number is wrong |\r
+| -3: Counter not initialised see function |\r
+| "i_APCI1710_InitCounter" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_SetDigitalChlOff (comedi_device *dev,\r
+ BYTE b_ModulNbr)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister3 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister3 & 0xEF;\r
+\r
+ /**********************/\r
+ /* Set the output Off */\r
+ /**********************/\r
+\r
+ outl(devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ dw_ModeRegister1_2_3_4,devpriv->s_BoardInfos.\r
+ ui_Address + 20 + (64 * b_ModulNbr));\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+/*########################################################################### */\r
+\r
+ // INSN WRITE\r
+/*########################################################################### */\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name :INT i_APCI1710_InsnWriteINCCPT(comedi_device *dev,comedi_subdevice *s,\r
+comedi_insn *insn,lsampl_t *data) |\r
++----------------------------------------------------------------------------+\r
+| Task : Enable Disable functions for INC_CPT |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : \r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : \r
++----------------------------------------------------------------------------+\r
+*/\r
+INT i_APCI1710_InsnWriteINCCPT(comedi_device *dev,comedi_subdevice *s,\r
+comedi_insn *insn,lsampl_t *data)\r
+{\r
+ UINT ui_WriteType;\r
+ INT i_ReturnValue=0;\r
+ \r
+ ui_WriteType=CR_CHAN(insn->chanspec);\r
+ devpriv->tsk_Current=current; // Save the current process task structure
+\r
+ switch(ui_WriteType)\r
+ {\r
+ case APCI1710_INCCPT_ENABLELATCHINTERRUPT:\r
+ i_ReturnValue = i_APCI1710_EnableLatchInterrupt (dev,\r
+ (BYTE) CR_AREF(insn->chanspec));\r
+ break;\r
+\r
+ case APCI1710_INCCPT_DISABLELATCHINTERRUPT:\r
+ i_ReturnValue = i_APCI1710_DisableLatchInterrupt (dev,\r
+ (BYTE) CR_AREF(insn->chanspec));\r
+ break;\r
+\r
+ case APCI1710_INCCPT_WRITE16BITCOUNTERVALUE:\r
+ i_ReturnValue = i_APCI1710_Write16BitCounterValue (dev,\r
+ (BYTE) CR_AREF(insn->chanspec),\r
+ (BYTE) data[0],\r
+ (UINT) data[1]);\r
+ break;\r
+\r
+ case APCI1710_INCCPT_WRITE32BITCOUNTERVALUE:\r
+ i_ReturnValue = i_APCI1710_Write32BitCounterValue (dev,\r
+ (BYTE) CR_AREF(insn->chanspec),\r
+ (ULONG) data[0]);\r
+\r
+ break;\r
+\r
+ case APCI1710_INCCPT_ENABLEINDEX:\r
+ i_APCI1710_EnableIndex (dev,\r
+ (BYTE) CR_AREF(insn->chanspec));\r
+ break;\r
+\r
+ case APCI1710_INCCPT_DISABLEINDEX: \r
+ i_ReturnValue = i_APCI1710_DisableIndex (dev,\r
+ (BYTE) CR_AREF(insn->chanspec));\r
+ break;\r
+\r
+ case APCI1710_INCCPT_ENABLECOMPARELOGIC: \r
+ i_ReturnValue = i_APCI1710_EnableCompareLogic (dev,\r
+ (BYTE) CR_AREF(insn->chanspec));\r
+ break;\r
+\r
+ case APCI1710_INCCPT_DISABLECOMPARELOGIC: \r
+ i_ReturnValue = i_APCI1710_DisableCompareLogic (dev,\r
+ (BYTE) CR_AREF(insn->chanspec));\r
+ break;\r
+\r
+ case APCI1710_INCCPT_ENABLEFREQUENCYMEASUREMENT: \r
+ i_ReturnValue = i_APCI1710_EnableFrequencyMeasurement (dev,\r
+ (BYTE) CR_AREF(insn->chanspec),\r
+ (BYTE) data[0]);\r
+ break;\r
+\r
+ case APCI1710_INCCPT_DISABLEFREQUENCYMEASUREMENT: \r
+ i_ReturnValue = i_APCI1710_DisableFrequencyMeasurement (dev,\r
+ (BYTE) CR_AREF(insn->chanspec));\r
+ break;\r
+\r
+ default:\r
+ printk("Write Config Parameter Wrong\n");\r
+ }\r
+\r
+ if(i_ReturnValue>=0) i_ReturnValue =insn->n;\r
+ return (i_ReturnValue);\r
+}\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_EnableLatchInterrupt |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr) |\r
++----------------------------------------------------------------------------+\r
+| Task : Enable the latch interrupt from selected module |\r
+| (b_ModulNbr). Each software or hardware latch occur a |\r
+| interrupt. |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Module number to configure |\r
+| (0 to 3) |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: No counter module found |\r
+| -3: Counter not initialised see function |\r
+| "i_APCI1710_InitCounter" |\r
+| -4: Interrupt routine not installed see function |\r
+| "i_APCI1710_SetBoardIntRoutine" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_EnableLatchInterrupt (comedi_device *dev,\r
+ BYTE b_ModulNbr)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+\r
+ /********************/\r
+ /* Enable interrupt */\r
+ /********************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister2 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister2 | APCI1710_ENABLE_LATCH_INT;\r
+\r
+ /***************************/\r
+ /* Write the configuration */\r
+ /***************************/\r
+\r
+ outl(devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ dw_ModeRegister1_2_3_4,devpriv->s_BoardInfos.\r
+ ui_Address + 20 + (64 * b_ModulNbr));\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_DisableLatchInterrupt |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr) |\r
++----------------------------------------------------------------------------+\r
+| Task : Disable the latch interrupt from selected module |\r
+| (b_ModulNbr). |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Module number to configure |\r
+| (0 to 3) |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: No counter module found |\r
+| -3: Counter not initialised see function |\r
+| "i_APCI1710_InitCounter" |\r
+| -4: Interrupt routine not installed see function |\r
+| "i_APCI1710_SetBoardIntRoutine" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_DisableLatchInterrupt (comedi_device *dev,\r
+ BYTE b_ModulNbr)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+\r
+ /***************************/\r
+ /* Write the configuration */\r
+ /***************************/\r
+\r
+ outl(devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ dw_ModeRegister1_2_3_4 & ((APCI1710_DISABLE_LATCH_INT << 8) | 0xFF),devpriv->s_BoardInfos.\r
+ ui_Address + 20 + (64 * b_ModulNbr));\r
+\r
+ mdelay(1000);\r
+\r
+ /*********************/\r
+ /* Disable interrupt */\r
+ /*********************/\r
+\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister2 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister2 & APCI1710_DISABLE_LATCH_INT;\r
+\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_Write16BitCounterValue |\r
+| (BYTE_ b_BoardHandle |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_SelectedCounter, |\r
+| UINT_ ui_WriteValue) |\r
++----------------------------------------------------------------------------+\r
+| Task : Write a 16-Bit value (ui_WriteValue) in to the selected|\r
+| 16-Bit counter (b_SelectedCounter) from selected module|\r
+| (b_ModulNbr). |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Module number to configure |\r
+| (0 to 3) |\r
+| BYTE_ b_SelectedCounter : Selected 16-Bit counter |\r
+| (0 or 1) |\r
+| UINT_ ui_WriteValue : 16-Bit write value |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: No counter module found |\r
+| -3: Counter not initialised see function |\r
+| "i_APCI1710_InitCounter" |\r
+| -4: The selected 16-Bit counter parameter is wrong |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_Write16BitCounterValue (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ BYTE b_SelectedCounter,\r
+ UINT ui_WriteValue)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ \r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+ /******************************/\r
+ /* Test the counter selection */\r
+ /******************************/\r
+\r
+ if (b_SelectedCounter < 2)\r
+ {\r
+ /*******************/\r
+ /* Write the value */\r
+ /*******************/\r
+\r
+ outl((ULONG) ((ULONG) (ui_WriteValue) << (16 * b_SelectedCounter)),devpriv->s_BoardInfos.\r
+ ui_Address + 8 + (b_SelectedCounter * 4) + (64 * b_ModulNbr));\r
+ }\r
+ else\r
+ {\r
+ /**************************************************/\r
+ /* The selected 16-Bit counter parameter is wrong */\r
+ /**************************************************/\r
+\r DPRINTK("The selected 16-Bit counter parameter is wrong\n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_Write32BitCounterValue |\r
+| (BYTE_ b_BoardHandle |\r
+| BYTE_ b_ModulNbr, |\r
+| ULONG_ ul_WriteValue) |\r
++----------------------------------------------------------------------------+\r
+| Task : Write a 32-Bit value (ui_WriteValue) in to the selected|\r
+| module (b_ModulNbr). |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Module number to configure |\r
+| (0 to 3) |\r
+| ULONG_ ul_WriteValue : 32-Bit write value |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: No counter module found |\r
+| -3: Counter not initialised see function |\r
+| "i_APCI1710_InitCounter" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_Write32BitCounterValue (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ ULONG ul_WriteValue)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ \r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+ /*******************/\r
+ /* Write the value */\r
+ /*******************/\r
+\r
+ outl(ul_WriteValue,devpriv->s_BoardInfos.\r
+ ui_Address + 4 + (64 * b_ModulNbr));\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_EnableIndex (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr) |\r
++----------------------------------------------------------------------------+\r
+| Task : Enable the INDEX actions |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Module number to configure |\r
+| (0 to 3) |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: No counter module found |\r
+| -3: Counter not initialised see function |\r
+| "i_APCI1710_InitCounter" |\r
+| -4: Index not initialised see function |\r
+| "i_APCI1710_InitIndex" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_EnableIndex (comedi_device *dev,\r
+ BYTE b_ModulNbr)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ ULONG ul_InterruptLatchReg;\r
+ \r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+ /*****************************/\r
+ /* Test if index initialised */\r
+ /*****************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_IndexInit)\r
+ {\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister2 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister2 | APCI1710_ENABLE_INDEX;\r
+\r
+ ul_InterruptLatchReg=inl(devpriv->s_BoardInfos.\r
+ ui_Address + 24 + (64 * b_ModulNbr));\r
+\r
+\r
+ outl(devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ dw_ModeRegister1_2_3_4,devpriv->s_BoardInfos.\r
+ ui_Address + 20 + (64 * b_ModulNbr));\r
+ }\r
+ else\r
+ {\r
+ /*************************************************************/\r
+ /* Index not initialised see function "i_APCI1710_InitIndex" */\r
+ /*************************************************************/\r
+\r DPRINTK("Index not initialised \n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_DisableIndex (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr) |\r
++----------------------------------------------------------------------------+\r
+| Task : Disable the INDEX actions |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Module number to configure |\r
+| (0 to 3) |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: No counter module found |\r
+| -3: Counter not initialised see function |\r
+| "i_APCI1710_InitCounter" |\r
+| -4: Index not initialised see function |\r
+| "i_APCI1710_InitIndex" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_DisableIndex (comedi_device *dev,\r
+ BYTE b_ModulNbr)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ \r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+ /*****************************/\r
+ /* Test if index initialised */\r
+ /*****************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_IndexInit)\r
+ {\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister2 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister2 & APCI1710_DISABLE_INDEX;\r
+\r
+ outl(devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ dw_ModeRegister1_2_3_4,devpriv->s_BoardInfos.\r
+ ui_Address + 20 + (64 * b_ModulNbr));\r
+ }\r
+ else\r
+ {\r
+ /*************************************************************/\r
+ /* Index not initialised see function "i_APCI1710_InitIndex" */\r
+ /*************************************************************/\r
+\r DPRINTK("Index not initialised \n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_EnableCompareLogic |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr) |\r
++----------------------------------------------------------------------------+\r
+| Task : Enable the 32-Bit compare logic. At that moment that |\r
+| the incremental counter arrive to the compare value a |\r
+| interrupt is generated. |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Module number to configure |\r
+| (0 to 3) |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : -\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: No counter module found |\r
+| -3: Counter not initialised see function |\r
+| "i_APCI1710_InitCounter" |\r
+| -4: Compare logic not initialised. |\r
+| See function "i_APCI1710_InitCompareLogic" |\r
+| -5: Interrupt function not initialised. |\r
+| See function "i_APCI1710_SetBoardIntRoutineX" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_EnableCompareLogic (comedi_device *dev,\r
+ BYTE b_ModulNbr)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ \r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+ /*************************************/\r
+ /* Test if compare logic initialised */\r
+ /*************************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CompareLogicInit == 1)\r
+ {\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister3 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister3 | APCI1710_ENABLE_COMPARE_INT;\r
+\r
+ /***************************/\r
+ /* Write the configuration */\r
+ /***************************/\r
+\r
+ outl(devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ dw_ModeRegister1_2_3_4,devpriv->s_BoardInfos.\r
+ ui_Address + 20 + (64 * b_ModulNbr));\r
+ }\r
+ else\r
+ {\r
+ /*********************************/\r
+ /* Compare logic not initialised */\r
+ /*********************************/\r
+\r DPRINTK("Compare logic not initialised\n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_DisableCompareLogic |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr) |\r
++----------------------------------------------------------------------------+\r
+| Task : Disable the 32-Bit compare logic.\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Module number to configure |\r
+| (0 to 3) |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : -\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: No counter module found |\r
+| -3: Counter not initialised see function |\r
+| "i_APCI1710_InitCounter" |\r
+| -4: Compare logic not initialised. |\r
+| See function "i_APCI1710_InitCompareLogic" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_DisableCompareLogic (comedi_device *dev,\r
+ BYTE b_ModulNbr)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+ /*************************************/\r
+ /* Test if compare logic initialised */\r
+ /*************************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CompareLogicInit == 1)\r
+ {\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister3 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister3 & APCI1710_DISABLE_COMPARE_INT;\r
+\r
+ /***************************/\r
+ /* Write the configuration */\r
+ /***************************/\r
+\r
+ outl(devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ dw_ModeRegister1_2_3_4,devpriv->s_BoardInfos.\r
+ ui_Address + 20 + (64 * b_ModulNbr));\r
+ }\r
+ else\r
+ {\r
+ /*********************************/\r
+ /* Compare logic not initialised */\r
+ /*********************************/\r
+\r DPRINTK("Compare logic not initialised\n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+ /*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_EnableFrequencyMeasurement |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_InterruptEnable) |\r
++----------------------------------------------------------------------------+\r
+| Task : Enables the frequency measurement function |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Number of the module to be |\r
+| configured (0 to 3) |\r
+| BYTE_ b_InterruptEnable: Enable or disable the |\r
+| interrupt. |\r
+| APCI1710_ENABLE: |\r
+| Enable the interrupt |\r
+| APCI1710_DISABLE: |\r
+| Disable the interrupt |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: The selected module number is wrong |\r
+| -3: Counter not initialised see function |\r
+| "i_APCI1710_InitCounter" |\r
+| -4: Frequency measurement logic not initialised. |\r
+| See function "i_APCI1710_InitFrequencyMeasurement" |\r
+| -5: Interrupt parameter is wrong |\r
+| -6: Interrupt function not initialised. |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_EnableFrequencyMeasurement (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ BYTE b_InterruptEnable)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ \r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+ /********************************************/\r
+ /* Test if frequency mesurement initialised */\r
+ /********************************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_FrequencyMeasurementInit == 1)\r
+ {\r
+ /***************************/\r
+ /* Test the interrupt mode */\r
+ /***************************/\r
+\r
+ if ((b_InterruptEnable == APCI1710_DISABLE) ||\r
+ (b_InterruptEnable == APCI1710_ENABLE))\r
+ {\r
+\r
+ /************************************/\r
+ /* Enable the frequency measurement */\r
+ /************************************/\r
+\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister3 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister3 | APCI1710_ENABLE_FREQUENCY;\r
+\r
+ /*********************************************/\r
+ /* Disable or enable the frequency interrupt */\r
+ /*********************************************/\r
+\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister3 = (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister3 & APCI1710_DISABLE_FREQUENCY_INT) | (b_InterruptEnable << 3);\r
+\r
+ /***************************/\r
+ /* Write the configuration */\r
+ /***************************/\r
+\r
+ outl(devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ dw_ModeRegister1_2_3_4,devpriv->s_BoardInfos.\r
+ ui_Address + 20 + (64 * b_ModulNbr));\r
+\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_FrequencyMeasurementEnable = 1;\r
+ }\r
+ else\r
+ {\r
+ /********************************/\r
+ /* Interrupt parameter is wrong */\r
+ /********************************/\r
+\r DPRINTK("Interrupt parameter is wrong\n");
+ i_ReturnValue = -5;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***********************************************/\r
+ /* Frequency measurement logic not initialised */\r
+ /***********************************************/\r
+\r DPRINTK("Frequency measurement logic not initialised\n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+ /*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_DisableFrequencyMeasurement |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr) |\r
++----------------------------------------------------------------------------+\r
+| Task : Disables the frequency measurement function |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Number of the module to be |\r
+| configured (0 to 3) |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: The selected module number is wrong |\r
+| -3: Counter not initialised see function |\r
+| "i_APCI1710_InitCounter" |\r
+| -4: Frequency measurement logic not initialised. |\r
+| See function "i_APCI1710_InitFrequencyMeasurement" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_DisableFrequencyMeasurement (comedi_device *dev,\r
+ BYTE b_ModulNbr)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+ /********************************************/\r
+ /* Test if frequency mesurement initialised */\r
+ /********************************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_FrequencyMeasurementInit == 1)\r
+ {\r
+ /*************************************/\r
+ /* Disable the frequency measurement */\r
+ /*************************************/\r
+\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister3 = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister3 & APCI1710_DISABLE_FREQUENCY\r
+ // Begin CG 29/06/01 CG 1100/0231 -> 0701/0232 Frequence measure IRQ must be cleared\r
+ & APCI1710_DISABLE_FREQUENCY_INT;\r
+ // End CG 29/06/01 CG 1100/0231 -> 0701/0232 Frequence measure IRQ must be cleared\r
+\r
+ /***************************/\r
+ /* Write the configuration */\r
+ /***************************/\r
+\r
+ outl(devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ dw_ModeRegister1_2_3_4,devpriv->s_BoardInfos.\r
+ ui_Address + 20 + (64 * b_ModulNbr));\r
+\r
+ /*************************************/\r
+ /* Disable the frequency measurement */\r
+ /*************************************/\r
+\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_FrequencyMeasurementEnable = 0;\r
+ }\r
+ else\r
+ {\r
+ /***********************************************/\r
+ /* Frequency measurement logic not initialised */\r
+ /***********************************************/\r
+\r DPRINTK("Frequency measurement logic not initialised\n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+/*########################################################################### */\r
+\r
+ // INSN READ\r
+\r
+/*########################################################################### */\r
+\r
+ \r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name :INT i_APCI1710_InsnWriteINCCPT(comedi_device *dev,comedi_subdevice *s,\r
+comedi_insn *insn,lsampl_t *data) |\r
++----------------------------------------------------------------------------+\r
+| Task : Read and Get functions for INC_CPT |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : \r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : \r
++----------------------------------------------------------------------------+\r
+*/\r
+INT i_APCI1710_InsnReadINCCPT(comedi_device *dev,comedi_subdevice *s,\r
+comedi_insn *insn,lsampl_t *data)\r
+{\r
+ UINT ui_ReadType;\r
+ INT i_ReturnValue=0;
+ \r
+ ui_ReadType=CR_CHAN(insn->chanspec);\r
+\r devpriv->tsk_Current=current; // Save the current process task structure
+ switch(ui_ReadType)\r
+ {\r
+ case APCI1710_INCCPT_READLATCHREGISTERSTATUS:\r
+ i_ReturnValue=i_APCI1710_ReadLatchRegisterStatus (dev,\r
+ (BYTE) CR_AREF(insn->chanspec),\r
+ (BYTE) CR_RANGE(insn->chanspec),\r
+ (PBYTE) &data[0]);\r
+ break;\r
+\r
+ case APCI1710_INCCPT_READLATCHREGISTERVALUE:\r
+ i_ReturnValue=i_APCI1710_ReadLatchRegisterValue (dev,\r
+ (BYTE) CR_AREF(insn->chanspec),\r
+ (BYTE) CR_RANGE(insn->chanspec),\r
+ (PULONG) &data[0]);\r
+ printk("Latch Register Value %d\n",data[0]);
+ break;\r
+\r
+ case APCI1710_INCCPT_READ16BITCOUNTERVALUE:\r
+ i_ReturnValue=i_APCI1710_Read16BitCounterValue (dev,\r
+ (BYTE) CR_AREF(insn->chanspec),\r
+ (BYTE) CR_RANGE(insn->chanspec),\r
+ (PUINT) &data[0]);\r
+ break;\r
+ \r
+ case APCI1710_INCCPT_READ32BITCOUNTERVALUE:\r
+ i_ReturnValue=i_APCI1710_Read32BitCounterValue (dev,\r
+ (BYTE) CR_AREF(insn->chanspec),\r
+ (PULONG) &data[0]);\r
+ break;\r
+ \r
+ case APCI1710_INCCPT_GETINDEXSTATUS:\r
+ i_ReturnValue=i_APCI1710_GetIndexStatus (dev,\r
+ (BYTE) CR_AREF(insn->chanspec),\r
+ (PBYTE) &data[0]);\r
+ break;\r
+ \r
+ case APCI1710_INCCPT_GETREFERENCESTATUS:\r
+ i_ReturnValue=i_APCI1710_GetReferenceStatus (dev,\r
+ (BYTE) CR_AREF(insn->chanspec),\r
+ (PBYTE) &data[0]);\r
+ break;\r
+ \r
+ case APCI1710_INCCPT_GETUASSTATUS:\r
+ i_ReturnValue=i_APCI1710_GetUASStatus (dev,\r
+ (BYTE) CR_AREF(insn->chanspec),\r
+ (PBYTE) &data[0]);\r
+ break;\r
+ \r
+ case APCI1710_INCCPT_GETCBSTATUS:\r
+ i_ReturnValue=i_APCI1710_GetCBStatus (dev,\r
+ (BYTE) CR_AREF(insn->chanspec),\r
+ (PBYTE) &data[0]);\r
+ break;\r
+ \r
+ case APCI1710_INCCPT_GET16BITCBSTATUS:\r
+ i_ReturnValue=i_APCI1710_Get16BitCBStatus (dev,\r
+ (BYTE) CR_AREF(insn->chanspec),\r
+ (PBYTE) &data[0],\r
+ (PBYTE) &data[1]);\r
+ break;\r
+ \r
+ case APCI1710_INCCPT_GETUDSTATUS:\r
+ i_ReturnValue=i_APCI1710_GetUDStatus (dev,\r
+ (BYTE) CR_AREF(insn->chanspec),\r
+ (PBYTE) &data[0]);
+
+ break;\r
+ \r
+ case APCI1710_INCCPT_GETINTERRUPTUDLATCHEDSTATUS:\r
+ i_ReturnValue=i_APCI1710_GetInterruptUDLatchedStatus (dev,\r
+ (BYTE) CR_AREF(insn->chanspec),\r
+ (PBYTE) &data[0]);\r
+ break;\r
+ \r
+ case APCI1710_INCCPT_READFREQUENCYMEASUREMENT:\r
+ i_ReturnValue=i_APCI1710_ReadFrequencyMeasurement (dev,\r
+ (BYTE) CR_AREF(insn->chanspec),\r
+ (PBYTE) &data[0],\r
+ (PBYTE) &data[1],\r
+ (PULONG) &data[2]);\r
+ break;\r
+
+ case APCI1710_INCCPT_READINTERRUPT:
+ data[0]=devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Read].b_OldModuleMask;
+ data[1]=devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Read].ul_OldInterruptMask;
+ data[2]=devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Read].ul_OldCounterLatchValue;
+
+
+ /**************************/
+ /* Increment the read FIFO */
+ /***************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Read = (devpriv->s_InterruptParameters.
+ ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
+
+
+ break;
+ \r
+ default:\r
+ printk("ReadType Parameter wrong\n");\r
+ }\r
+\r
+ if(i_ReturnValue>=0) i_ReturnValue =insn->n;\r
+ return (i_ReturnValue); \r
+\r
+}\r
+\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_ReadLatchRegisterStatus |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_LatchReg, |\r
+| PBYTE_ pb_LatchStatus) |\r
++----------------------------------------------------------------------------+\r
+| Task : Read the latch register status from selected module |\r
+| (b_ModulNbr) and selected latch register (b_LatchReg). |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Module number to configure |\r
+| (0 to 3) |\r
+| BYTE_ b_LatchReg : Selected latch register |\r
+| 0 : for the first latch register |\r
+| 1 : for the second latch register |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : PBYTE_ pb_LatchStatus : Latch register status. |\r
+| 0 : No latch occur |\r
+| 1 : A software latch occur |\r
+| 2 : A hardware latch occur |\r
+| 3 : A software and hardware |\r
+| latch occur |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: No counter module found |\r
+| -3: Counter not initialised see function |\r
+| "i_APCI1710_InitCounter" |\r
+| -4: The selected latch register parameter is wrong |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_ReadLatchRegisterStatus (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ BYTE b_LatchReg,\r
+ PBYTE pb_LatchStatus)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ DWORD dw_LatchReg;\r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+ /*************************************/\r
+ /* Test the latch register parameter */\r
+ /*************************************/\r
+\r
+ if (b_LatchReg < 2)\r
+ {\r
+ dw_LatchReg=inl(devpriv->s_BoardInfos.\r
+ ui_Address + (64 * b_ModulNbr));\r
+\r
+ *pb_LatchStatus = (BYTE) ((dw_LatchReg >> (b_LatchReg * 4)) & 0x3);\r
+ }\r
+ else\r
+ {\r
+ /**************************************************/\r
+ /* The selected latch register parameter is wrong */\r
+ /**************************************************/\r
+\r DPRINTK("The selected latch register parameter is wrong\n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_ReadLatchRegisterValue |\r
+| (BYTE_ b_BoardHandle,|\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_LatchReg, |\r
+| PULONG_ pul_LatchValue) |\r
++----------------------------------------------------------------------------+\r
+| Task : Read the latch register value from selected module |\r
+| (b_ModulNbr) and selected latch register (b_LatchReg). |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Module number to configure |\r
+| (0 to 3) |\r
+| BYTE_ b_LatchReg : Selected latch register |\r
+| 0 : for the first latch register |\r
+| 1 : for the second latch register |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : PULONG_ pul_LatchValue : Latch register value |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: No counter module found |\r
+| -3: Counter not initialised see function |\r
+| "i_APCI1710_InitCounter" |\r
+| -4: The selected latch register parameter is wrong |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_ReadLatchRegisterValue (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ BYTE b_LatchReg,\r
+ PULONG pul_LatchValue)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+ /*************************************/\r
+ /* Test the latch register parameter */\r
+ /*************************************/\r
+\r
+ if (b_LatchReg < 2)\r
+ {\r
+ *pul_LatchValue=inl(devpriv->s_BoardInfos.\r
+ ui_Address + ((b_LatchReg + 1) * 4) + (64 * b_ModulNbr));
+
+ }\r
+ else\r
+ {\r
+ /**************************************************/\r
+ /* The selected latch register parameter is wrong */\r
+ /**************************************************/\r
+\r DPRINTK("The selected latch register parameter is wrong\n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_Read16BitCounterValue |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_SelectedCounter, |\r
+| PUINT_ pui_CounterValue) |\r
++----------------------------------------------------------------------------+\r
+| Task : Latch the selected 16-Bit counter (b_SelectedCounter) |\r
+| from selected module (b_ModulNbr) in to the first |\r
+| latch register and return the latched value. |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Module number to configure |\r
+| (0 to 3) |\r
+| BYTE_ b_SelectedCounter : Selected 16-Bit counter |\r
+| (0 or 1) |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : PUINT_ pui_CounterValue : 16-Bit counter value |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: No counter module found |\r
+| -3: Counter not initialised see function |\r
+| "i_APCI1710_InitCounter" |\r
+| -4: The selected 16-Bit counter parameter is wrong |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_Read16BitCounterValue (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ BYTE b_SelectedCounter,\r
+ PUINT pui_CounterValue)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ DWORD dw_LathchValue = 0;\r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+ /******************************/\r
+ /* Test the counter selection */\r
+ /******************************/\r
+\r
+ if (b_SelectedCounter < 2)\r
+ {\r
+ /*********************/\r
+ /* Latch the counter */\r
+ /*********************/\r
+\r
+ outl(1,devpriv->s_BoardInfos.\r
+ ui_Address + (64 * b_ModulNbr));\r
+\r
+ /************************/\r
+ /* Read the latch value */\r
+ /************************/\r
+\r
+ dw_LathchValue=inl(devpriv->s_BoardInfos.\r
+ ui_Address + 4 + (64 * b_ModulNbr));\r
+\r
+ *pui_CounterValue = (UINT) ((dw_LathchValue >> (16 * b_SelectedCounter)) & 0xFFFFU);\r
+ }\r
+ else\r
+ {\r
+ /**************************************************/\r
+ /* The selected 16-Bit counter parameter is wrong */\r
+ /**************************************************/\r
+\r DPRINTK("The selected 16-Bit counter parameter is wrong\n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_Read32BitCounterValue |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| PULONG_ pul_CounterValue) |\r
++----------------------------------------------------------------------------+\r
+| Task : Latch the 32-Bit counter from selected module |\r
+| (b_ModulNbr) in to the first latch register and return |\r
+| the latched value. |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Module number to configure |\r
+| (0 to 3) |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : PULONG_ pul_CounterValue : 32-Bit counter value |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: No counter module found |\r
+| -3: Counter not initialised see function |\r
+| "i_APCI1710_InitCounter" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_Read32BitCounterValue (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ PULONG pul_CounterValue)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ \r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+ /*********************/\r
+ /* Tatch the counter */\r
+ /*********************/\r
+\r
+ outl(1,devpriv->s_BoardInfos.\r
+ ui_Address + (64 * b_ModulNbr));\r
+\r
+ /************************/\r
+ /* Read the latch value */\r
+ /************************/\r
+\r
+ *pul_CounterValue=inl(devpriv->s_BoardInfos.\r
+ ui_Address + 4 + (64 * b_ModulNbr));\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_GetIndexStatus (BYTE_ b_BoardHandle,|\r
+| BYTE_ b_ModulNbr, |\r
+| PBYTE_ pb_IndexStatus)|\r
++----------------------------------------------------------------------------+\r
+| Task : Return the index status |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Module number to configure |\r
+| (0 to 3) |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : PBYTE_ pb_IndexStatus : 0 : No INDEX occur |\r
+| 1 : A INDEX occur |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: No counter module found |\r
+| -3: Counter not initialised see function |\r
+| "i_APCI1710_InitCounter" |\r
+| -4: Index not initialised see function |\r
+| "i_APCI1710_InitIndex" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_GetIndexStatus (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ PBYTE pb_IndexStatus)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ DWORD dw_StatusReg = 0;\r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+ /*****************************/\r
+ /* Test if index initialised */\r
+ /*****************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_IndexInit)\r
+ {\r
+ dw_StatusReg= inl(devpriv->s_BoardInfos.\r
+ ui_Address + 12 + (64 * b_ModulNbr));\r
+\r
+ *pb_IndexStatus = (BYTE) (dw_StatusReg & 1);\r
+ }\r
+ else\r
+ {\r
+ /*************************************************************/\r
+ /* Index not initialised see function "i_APCI1710_InitIndex" */\r
+ /*************************************************************/\r
+\r DPRINTK("Index not initialised\n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_GetReferenceStatus |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| PBYTE_ pb_ReferenceStatus) |\r
++----------------------------------------------------------------------------+\r
+| Task : Return the reference status |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Module number to configure |\r
+| (0 to 3) |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : PBYTE_ pb_ReferenceStatus : 0 : No REFERENCE occur |\r
+| 1 : A REFERENCE occur |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: No counter module found |\r
+| -3: Counter not initialised see function |\r
+| "i_APCI1710_InitCounter" |\r
+| -4: Reference not initialised see function |\r
+| "i_APCI1710_InitReference" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_GetReferenceStatus (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ PBYTE pb_ReferenceStatus)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ DWORD dw_StatusReg = 0;\r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+ /*********************************/\r
+ /* Test if reference initialised */\r
+ /*********************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_ReferenceInit)\r
+ {\r
+ dw_StatusReg=inl(devpriv->s_BoardInfos.\r
+ ui_Address + 24 + (64 * b_ModulNbr));\r
+\r
+ *pb_ReferenceStatus = (BYTE) (~dw_StatusReg & 1);\r
+ }\r
+ else\r
+ {\r
+ /*********************************************************************/\r
+ /* Reference not initialised see function "i_APCI1710_InitReference" */\r
+ /*********************************************************************/\r
+\r DPRINTK("Reference not initialised\n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_GetUASStatus |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| PBYTE_ pb_UASStatus) |\r
++----------------------------------------------------------------------------+\r
+| Task : Return the error signal (UAS) status |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Module number to configure |\r
+| (0 to 3) |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : PBYTE_ pb_UASStatus : 0 : UAS is low "0" |\r
+| 1 : UAS is high "1" |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: No counter module found |\r
+| -3: Counter not initialised see function |\r
+| "i_APCI1710_InitCounter" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_GetUASStatus (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ PBYTE pb_UASStatus)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ DWORD dw_StatusReg = 0;\r
+ \r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+ dw_StatusReg=inl(devpriv->s_BoardInfos.\r
+ ui_Address + 24 + (64 * b_ModulNbr));\r
+\r
+ *pb_UASStatus = (BYTE) ((dw_StatusReg >> 1) & 1);\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_GetCBStatus |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| PBYTE_ pb_CBStatus) |\r
++----------------------------------------------------------------------------+\r
+| Task : Return the counter overflow status |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Module number to configure |\r
+| (0 to 3) |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : PBYTE_ pb_CBStatus : 0 : Counter no overflow |\r
+| 1 : Counter overflow |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: No counter module found |\r
+| -3: Counter not initialised see function |\r
+| "i_APCI1710_InitCounter" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_GetCBStatus (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ PBYTE pb_CBStatus)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ DWORD dw_StatusReg = 0;\r
+ \r
+\r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+ dw_StatusReg=inl(devpriv->s_BoardInfos.\r
+ ui_Address + 16 + (64 * b_ModulNbr));\r
+\r
+ *pb_CBStatus = (BYTE) (dw_StatusReg & 1);\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_Get16BitCBStatus |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| PBYTE_ pb_CBStatusCounter0, |\r
+| PBYTE_ pb_CBStatusCounter1) |\r
++----------------------------------------------------------------------------+\r
+| Task : Returns the counter overflow (counter initialised to |\r
+| 2*16-bit) status from selected incremental counter |\r
+| module |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Module number to configure |\r
+| (0 to 3) |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : PBYTE_ pb_CBStatusCounter0 : 0 : No overflow occur for |\r
+| the first 16-bit |\r
+| counter |\r
+| 1 : Overflow occur for the|\r
+| first 16-bit counter |\r
+| PBYTE_ pb_CBStatusCounter1 : 0 : No overflow occur for |\r
+| the second 16-bit |\r
+| counter |\r
+| 1 : Overflow occur for the|\r
+| second 16-bit counter |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: No counter module found |\r
+| -3: Counter not initialised see function |\r
+| "i_APCI1710_InitCounter" |\r
+| -4: Counter not initialised to 2*16-bit mode. |\r
+| See function "i_APCI1710_InitCounter" |\r
+| -5: Firmware revision error |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_Get16BitCBStatus (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ PBYTE pb_CBStatusCounter0,\r
+ PBYTE pb_CBStatusCounter1)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ DWORD dw_StatusReg = 0;\r
+ \r
+\r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+ /*************************/\r
+ /* Test if 2*16-Bit mode */\r
+ /*************************/\r
+\r
+ if ((devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister1 & 0x10) == 0x10)\r
+ {\r
+ /*****************************/\r
+ /* Test the Firmware version */\r
+ /*****************************/\r
+\r
+ if ((devpriv->\r
+ s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF) >= 0x3136)\r
+ {\r
+ dw_StatusReg=inl(devpriv->s_BoardInfos.\r
+ ui_Address + 16 + (64 * b_ModulNbr));\r
+\r
+ *pb_CBStatusCounter1 = (BYTE) ((dw_StatusReg >> 0) & 1);\r
+ *pb_CBStatusCounter0 = (BYTE) ((dw_StatusReg >> 1) & 1);\r
+ } // if ((ps_APCI1710Variable->s_Board [b_BoardHandle].s_BoardInfos.dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF) >= 0x3136)\r
+ else\r
+ {\r
+ /****************************/\r
+ /* Firmware revision error */\r
+ /****************************/\r
+\r
+ i_ReturnValue = -5;\r
+ } // if ((ps_APCI1710Variable->s_Board [b_BoardHandle].s_BoardInfos.dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF) >= 0x3136)\r
+ } // if ((ps_APCI1710Variable->s_Board [b_BoardHandle].s_ModuleInfo [b_ModulNbr].s_SiemensCounterInfo.s_ModeRegister.s_ByteModeRegister.b_ModeRegister1 & 0x10) == 0x10)\r
+ else\r
+ {\r
+ /********************************************/\r
+ /* Counter not initialised to 2*16-bit mode */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /********************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -4;\r
+ } // if ((ps_APCI1710Variable->s_Board [b_BoardHandle].s_ModuleInfo [b_ModulNbr].s_SiemensCounterInfo.s_ModeRegister.s_ByteModeRegister.b_ModeRegister1 & 0x10) == 0x10)\r
+ } // if (ps_APCI1710Variable->s_Board [b_BoardHandle].s_ModuleInfo [b_ModulNbr].s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1)\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ } // if (ps_APCI1710Variable->s_Board [b_BoardHandle].s_ModuleInfo [b_ModulNbr].s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1)\r
+ } // if (b_ModulNbr < 4)\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ } // if (b_ModulNbr < 4)\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_GetUDStatus |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| PBYTE_ pb_UDStatus) |\r
++----------------------------------------------------------------------------+\r
+| Task : Return the counter progress status |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Module number to configure |\r
+| (0 to 3) |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : PBYTE_ pb_UDStatus : 0 : Counter progress in the |\r
+| selected mode down |\r
+| 1 : Counter progress in the |\r
+| selected mode up |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: No counter module found |\r
+| -3: Counter not initialised see function |\r
+| "i_APCI1710_InitCounter" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_GetUDStatus (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ PBYTE pb_UDStatus)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ DWORD dw_StatusReg = 0;\r
+ \r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+ dw_StatusReg=inl(devpriv->s_BoardInfos.\r
+ ui_Address + 24 + (64 * b_ModulNbr));\r
+\r
+ *pb_UDStatus = (BYTE) ((dw_StatusReg >> 2) & 1);\r
+
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_GetInterruptUDLatchedStatus |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| PBYTE_ pb_UDStatus) |\r
++----------------------------------------------------------------------------+\r
+| Task : Return the counter progress latched status after a |\r
+| index interrupt occur. |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Module number to configure |\r
+| (0 to 3) |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : PBYTE_ pb_UDStatus : 0 : Counter progress in the |\r
+| selected mode down |\r
+| 1 : Counter progress in the |\r
+| selected mode up |\r
+| 2 : No index interrupt occur |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: No counter module found |\r
+| -3: Counter not initialised see function |\r
+| "i_APCI1710_InitCounter" |\r
+| -4: Interrupt function not initialised. |\r
+| See function "i_APCI1710_SetBoardIntRoutineX" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_GetInterruptUDLatchedStatus (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ PBYTE pb_UDStatus)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ DWORD dw_StatusReg = 0;\r
+ \r
+\r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+ /*********************************/\r
+ /* Test if index interrupt occur */\r
+ /*********************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_IndexInterruptOccur == 1)\r
+ {\r
+ devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_IndexInterruptOccur = 0;\r
+\r
+ dw_StatusReg=inl(devpriv->s_BoardInfos.\r
+ ui_Address + 12 + (64 * b_ModulNbr));\r
+\r
+ *pb_UDStatus = (BYTE) ((dw_StatusReg >> 1) & 1);\r
+ }\r
+ else\r
+ {\r
+ /****************************/\r
+ /* No index interrupt occur */\r
+ /****************************/\r
+\r
+ *pb_UDStatus = 2;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+ /*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_ReadFrequencyMeasurement |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| PBYTE_ pb_Status, |\r
+| PULONG_ pul_ReadValue) |\r
++----------------------------------------------------------------------------+\r
+| Task : Returns the status (pb_Status) and the number of |\r
+| increments in the set time. |\r
+| See function " i_APCI1710_InitFrequencyMeasurement " |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Number of the module to be |\r
+| configured (0 to 3) |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : PBYTE_ pb_Status : Returns the frequency |\r
+| measurement status |\r
+| 0 : Counting cycle not |\r
+| started. |\r
+| 1 : Counting cycle started. |\r
+| 2 : Counting cycle stopped. |\r
+| The measurement cycle is |\r
+| completed. |\r
+| PBYTE_ pb_UDStatus : 0 : Counter progress in the |\r
+| selected mode down |\r
+| 1 : Counter progress in the |\r
+| selected mode up |\r
+| PULONG_ pul_ReadValue : Return the number of |\r
+| increments in the defined |\r
+| time base. |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: The selected module number is wrong |\r
+| -3: Counter not initialised see function |\r
+| "i_APCI1710_InitCounter" |\r
+| -4: Frequency measurement logic not initialised. |\r
+| See function "i_APCI1710_InitFrequencyMeasurement" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_ReadFrequencyMeasurement (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ PBYTE pb_Status,\r
+ PBYTE pb_UDStatus,\r
+ PULONG pul_ReadValue)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ UINT ui_16BitValue;\r
+ DWORD dw_StatusReg;\r
+ \r
+\r
+\r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_CounterInit == 1)\r
+ {\r
+ /********************************************/\r
+ /* Test if frequency mesurement initialised */\r
+ /********************************************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_FrequencyMeasurementInit == 1)\r
+ {\r
+ /******************/\r
+ /* Test if enable */\r
+ /******************/\r
+\r
+ if (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_InitFlag.\r
+ b_FrequencyMeasurementEnable == 1)\r
+ {\r
+ /*******************/\r
+ /* Read the status */\r
+ /*******************/\r
+\r
+ dw_StatusReg=inl(devpriv->s_BoardInfos.\r
+ ui_Address + 32 + (64 * b_ModulNbr));\r
+\r
+ /**************************/\r
+ /* Test if frequency stop */\r
+ /**************************/\r
+\r
+ if (dw_StatusReg & 1)\r
+ {\r
+ *pb_Status = 2;\r
+ *pb_UDStatus = (BYTE) ((dw_StatusReg >> 1) & 3);\r
+\r
+ /******************/\r
+ /* Read the value */\r
+ /******************/\r
+\r
+ *pul_ReadValue=inl(devpriv->s_BoardInfos.\r
+ ui_Address + 28 + (64 * b_ModulNbr));\r
+\r
+ if (*pb_UDStatus == 0)\r
+ {\r
+ /*************************/\r
+ /* Test the counter mode */\r
+ /*************************/\r
+\r
+ if ((devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_SiemensCounterInfo.\r
+ s_ModeRegister.\r
+ s_ByteModeRegister.\r
+ b_ModeRegister1 & APCI1710_16BIT_COUNTER) == APCI1710_16BIT_COUNTER)\r
+ {\r
+ /****************************************/\r
+ /* Test if 16-bit counter 1 pulse occur */\r
+ /****************************************/\r
+\r
+ if ((*pul_ReadValue & 0xFFFFU) != 0)\r
+ {\r
+ ui_16BitValue = (UINT) *pul_ReadValue & 0xFFFFU;\r
+ *pul_ReadValue = (*pul_ReadValue & 0xFFFF0000UL) | (0xFFFFU - ui_16BitValue);\r
+ }\r
+\r
+ /****************************************/\r
+ /* Test if 16-bit counter 2 pulse occur */\r
+ /****************************************/\r
+\r
+ if ((*pul_ReadValue & 0xFFFF0000UL) != 0)\r
+ {\r
+ ui_16BitValue = (UINT) ((*pul_ReadValue >> 16) & 0xFFFFU);\r
+ *pul_ReadValue = (*pul_ReadValue & 0xFFFFUL) | ((0xFFFFU - ui_16BitValue) << 16);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if (*pul_ReadValue != 0)\r
+ {\r
+ *pul_ReadValue = 0xFFFFFFFFUL - *pul_ReadValue;\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if (*pb_UDStatus == 1)\r
+ {\r
+ /****************************************/\r
+ /* Test if 16-bit counter 2 pulse occur */\r
+ /****************************************/\r
+\r
+ if ((*pul_ReadValue & 0xFFFF0000UL) != 0)\r
+ {\r
+ ui_16BitValue = (UINT) ((*pul_ReadValue >> 16) & 0xFFFFU);\r
+ *pul_ReadValue = (*pul_ReadValue & 0xFFFFUL) | ((0xFFFFU - ui_16BitValue) << 16);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if (*pb_UDStatus == 2)\r
+ {\r
+ /****************************************/\r
+ /* Test if 16-bit counter 1 pulse occur */\r
+ /****************************************/\r
+\r
+ if ((*pul_ReadValue & 0xFFFFU) != 0)\r
+ {\r
+ ui_16BitValue = (UINT) *pul_ReadValue & 0xFFFFU;\r
+ *pul_ReadValue = (*pul_ReadValue & 0xFFFF0000UL) | (0xFFFFU - ui_16BitValue);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ *pb_Status = 1;\r
+ *pb_UDStatus = 0;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ *pb_Status = 0;\r
+ *pb_UDStatus = 0;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***********************************************/\r
+ /* Frequency measurement logic not initialised */\r
+ /***********************************************/\r
+\r DPRINTK("Frequency measurement logic not initialised\n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /****************************************/\r
+ /* Counter not initialised see function */\r
+ /* "i_APCI1710_InitCounter" */\r
+ /****************************************/\r
+\r DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*************************************************/\r
+ /* The selected module number parameter is wrong */\r
+ /*************************************************/\r
+\r DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
--- /dev/null
+\r
+\r
+
+#define APCI1710_16BIT_COUNTER 0x10\r
+#define APCI1710_32BIT_COUNTER 0x0\r
+#define APCI1710_QUADRUPLE_MODE 0x0\r
+#define APCI1710_DOUBLE_MODE 0x3\r
+#define APCI1710_SIMPLE_MODE 0xF\r
+#define APCI1710_DIRECT_MODE 0x80\r
+#define APCI1710_HYSTERESIS_ON 0x60\r
+#define APCI1710_HYSTERESIS_OFF 0x0\r
+#define APCI1710_INCREMENT 0x60\r
+#define APCI1710_DECREMENT 0x0\r
+#define APCI1710_LATCH_COUNTER 0x1\r
+#define APCI1710_CLEAR_COUNTER 0x0\r
+#define APCI1710_LOW 0x0\r
+#define APCI1710_HIGH 0x1\r
+\r
+/*********************/\r
+/* Version 0600-0229 */\r
+/*********************/\r
+\r
+#define APCI1710_HIGH_EDGE_CLEAR_COUNTER 0x0\r
+#define APCI1710_HIGH_EDGE_LATCH_COUNTER 0x1\r
+#define APCI1710_LOW_EDGE_CLEAR_COUNTER 0x2\r
+#define APCI1710_LOW_EDGE_LATCH_COUNTER 0x3\r
+#define APCI1710_HIGH_EDGE_LATCH_AND_CLEAR_COUNTER 0x4\r
+#define APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER 0x5\r
+#define APCI1710_SOURCE_0 0x0\r
+#define APCI1710_SOURCE_1 0x1\r
+\r
+\r
+\r
+#define APCI1710_30MHZ 30\r
+#define APCI1710_33MHZ 33\r
+#define APCI1710_40MHZ 40\r
+\r
+\r
+#define APCI1710_ENABLE_LATCH_INT 0x80\r
+#define APCI1710_DISABLE_LATCH_INT (~APCI1710_ENABLE_LATCH_INT)\r
+\r
+#define APCI1710_INDEX_LATCH_COUNTER 0x10\r
+#define APCI1710_INDEX_AUTO_MODE 0x8\r
+#define APCI1710_ENABLE_INDEX 0x4\r
+#define APCI1710_DISABLE_INDEX (~APCI1710_ENABLE_INDEX)\r
+#define APCI1710_ENABLE_LATCH_AND_CLEAR 0x8\r
+#define APCI1710_DISABLE_LATCH_AND_CLEAR (~APCI1710_ENABLE_LATCH_AND_CLEAR)\r
+#define APCI1710_SET_LOW_INDEX_LEVEL 0x4\r
+#define APCI1710_SET_HIGH_INDEX_LEVEL (~APCI1710_SET_LOW_INDEX_LEVEL)\r
+#define APCI1710_INVERT_INDEX_RFERENCE 0x2\r
+#define APCI1710_DEFAULT_INDEX_RFERENCE (~APCI1710_INVERT_INDEX_RFERENCE)\r
+\r
+#define APCI1710_ENABLE_INDEX_INT 0x1\r
+#define APCI1710_DISABLE_INDEX_INT (~APCI1710_ENABLE_INDEX_INT)\r
+\r
+#define APCI1710_ENABLE_FREQUENCY 0x4\r
+#define APCI1710_DISABLE_FREQUENCY (~APCI1710_ENABLE_FREQUENCY)\r
+\r
+#define APCI1710_ENABLE_FREQUENCY_INT 0x8\r
+#define APCI1710_DISABLE_FREQUENCY_INT (~APCI1710_ENABLE_FREQUENCY_INT)\r
+\r
+#define APCI1710_ENABLE_40MHZ_FREQUENCY 0x40\r
+#define APCI1710_DISABLE_40MHZ_FREQUENCY (~APCI1710_ENABLE_40MHZ_FREQUENCY)\r
+\r
+#define APCI1710_ENABLE_40MHZ_FILTER 0x80\r
+#define APCI1710_DISABLE_40MHZ_FILTER (~APCI1710_ENABLE_40MHZ_FILTER)\r
+\r
+#define APCI1710_ENABLE_COMPARE_INT 0x2\r
+#define APCI1710_DISABLE_COMPARE_INT (~APCI1710_ENABLE_COMPARE_INT)\r
+\r
+#define APCI1710_ENABLE_INDEX_ACTION 0x20\r
+#define APCI1710_DISABLE_INDEX_ACTION (~APCI1710_ENABLE_INDEX_ACTION)\r
+#define APCI1710_REFERENCE_HIGH 0x40\r
+#define APCI1710_REFERENCE_LOW (~APCI1710_REFERENCE_HIGH)\r
+\r
+
+ #define APCI1710_TOR_GATE_LOW 0x40\r
+ #define APCI1710_TOR_GATE_HIGH (~APCI1710_TOR_GATE_LOW)\r
+
+\r
+// INSN CONFIG \r
+#define APCI1710_INCCPT_INITCOUNTER 100\r
+#define APCI1710_INCCPT_COUNTERAUTOTEST 101\r
+#define APCI1710_INCCPT_INITINDEX 102\r
+#define APCI1710_INCCPT_INITREFERENCE 103\r
+#define APCI1710_INCCPT_INITEXTERNALSTROBE 104\r
+#define APCI1710_INCCPT_INITCOMPARELOGIC 105\r
+#define APCI1710_INCCPT_INITFREQUENCYMEASUREMENT 106\r
+\r
+// INSN READ\r
+#define APCI1710_INCCPT_READLATCHREGISTERSTATUS 200 \r
+#define APCI1710_INCCPT_READLATCHREGISTERVALUE 201\r
+#define APCI1710_INCCPT_READ16BITCOUNTERVALUE 202 \r
+#define APCI1710_INCCPT_READ32BITCOUNTERVALUE 203\r
+#define APCI1710_INCCPT_GETINDEXSTATUS 204\r
+#define APCI1710_INCCPT_GETREFERENCESTATUS 205\r
+#define APCI1710_INCCPT_GETUASSTATUS 206\r
+#define APCI1710_INCCPT_GETCBSTATUS 207\r
+#define APCI1710_INCCPT_GET16BITCBSTATUS 208\r
+#define APCI1710_INCCPT_GETUDSTATUS 209\r
+#define APCI1710_INCCPT_GETINTERRUPTUDLATCHEDSTATUS 210\r
+#define APCI1710_INCCPT_READFREQUENCYMEASUREMENT 211\r
+#define APCI1710_INCCPT_READINTERRUPT 212
+\r
+//INSN BITS\r
+#define APCI1710_INCCPT_CLEARCOUNTERVALUE 300\r
+#define APCI1710_INCCPT_CLEARALLCOUNTERVALUE 301\r
+#define APCI1710_INCCPT_SETINPUTFILTER 302\r
+#define APCI1710_INCCPT_LATCHCOUNTER 303\r
+#define APCI1710_INCCPT_SETINDEXANDREFERENCESOURCE 304\r
+#define APCI1710_INCCPT_SETDIGITALCHLON 305\r
+#define APCI1710_INCCPT_SETDIGITALCHLOFF 306\r
+\r
+// INSN WRITE\r
+#define APCI1710_INCCPT_ENABLELATCHINTERRUPT 400\r
+#define APCI1710_INCCPT_DISABLELATCHINTERRUPT 401\r
+#define APCI1710_INCCPT_WRITE16BITCOUNTERVALUE 402\r
+#define APCI1710_INCCPT_WRITE32BITCOUNTERVALUE 403\r
+#define APCI1710_INCCPT_ENABLEINDEX 404 \r
+#define APCI1710_INCCPT_DISABLEINDEX 405\r
+#define APCI1710_INCCPT_ENABLECOMPARELOGIC 406 \r
+#define APCI1710_INCCPT_DISABLECOMPARELOGIC 407\r
+#define APCI1710_INCCPT_ENABLEFREQUENCYMEASUREMENT 408\r
+#define APCI1710_INCCPT_DISABLEFREQUENCYMEASUREMENT 409\r
+\r
+\r
+/************ Main Functions *************/ \r
+INT i_APCI1710_InsnConfigINCCPT(comedi_device *dev,comedi_subdevice *s,\r
+comedi_insn *insn,lsampl_t *data);\r
+\r
+INT i_APCI1710_InsnBitsINCCPT(comedi_device *dev,comedi_subdevice *s,\r
+comedi_insn *insn,lsampl_t *data);\r
+\r
+INT i_APCI1710_InsnWriteINCCPT(comedi_device *dev,comedi_subdevice *s,\r
+comedi_insn *insn,lsampl_t *data);\r
+\r
+INT i_APCI1710_InsnReadINCCPT(comedi_device *dev,comedi_subdevice *s,\r
+comedi_insn *insn,lsampl_t *data);\r
+\r
+/*********** Supplementary Functions********/\r
+\r
+\r
+// INSN CONFIG\r
+\r
+INT i_APCI1710_InitCounter (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ BYTE b_CounterRange,\r
+ BYTE b_FirstCounterModus,\r
+ BYTE b_FirstCounterOption,\r
+ BYTE b_SecondCounterModus,\r
+ BYTE b_SecondCounterOption);\r
+\r
+INT i_APCI1710_CounterAutoTest (comedi_device *dev,PBYTE pb_TestStatus);\r
+\r
+INT i_APCI1710_InitIndex (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ BYTE b_ReferenceAction,\r
+ BYTE b_IndexOperation,\r
+ BYTE b_AutoMode,\r
+ BYTE b_InterruptEnable);\r
+\r
+INT i_APCI1710_InitReference (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ BYTE b_ReferenceLevel);\r
+\r
+INT i_APCI1710_InitExternalStrobe (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ BYTE b_ExternalStrobe,\r
+ BYTE b_ExternalStrobeLevel);\r
+\r
+INT i_APCI1710_InitCompareLogic (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ UINT ui_CompareValue);\r
+\r
+INT i_APCI1710_InitFrequencyMeasurement (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ BYTE b_PCIInputClock,\r
+ BYTE b_TimingUnity,\r
+ ULONG ul_TimingInterval,\r
+ PULONG pul_RealTimingInterval);\r
+\r
+\r
+//INSN BITS\r
+\r
+INT i_APCI1710_ClearCounterValue (comedi_device *dev,\r
+ BYTE b_ModulNbr);\r
+\r
+INT i_APCI1710_ClearAllCounterValue (comedi_device *dev);\r
+\r
+INT i_APCI1710_SetInputFilter (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ BYTE b_PCIInputClock,\r
+ BYTE b_Filter);\r
+\r
+INT i_APCI1710_LatchCounter (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ BYTE b_LatchReg);\r
+\r
+INT i_APCI1710_SetIndexAndReferenceSource (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ BYTE b_SourceSelection);\r
+\r
+INT i_APCI1710_SetDigitalChlOn (comedi_device *dev,\r
+ BYTE b_ModulNbr);\r
+\r
+INT i_APCI1710_SetDigitalChlOff (comedi_device *dev,\r
+ BYTE b_ModulNbr);\r
+\r
+\r
+// INSN WRITE\r
+INT i_APCI1710_EnableLatchInterrupt (comedi_device *dev,\r
+ BYTE b_ModulNbr);\r
+\r
+\r
+INT i_APCI1710_DisableLatchInterrupt (comedi_device *dev,\r
+ BYTE b_ModulNbr);\r
+\r
+INT i_APCI1710_Write16BitCounterValue (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ BYTE b_SelectedCounter,\r
+ UINT ui_WriteValue);\r
+\r
+INT i_APCI1710_Write32BitCounterValue (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ ULONG ul_WriteValue);\r
+\r
+INT i_APCI1710_EnableIndex (comedi_device *dev,\r
+ BYTE b_ModulNbr);\r
+\r
+INT i_APCI1710_DisableIndex (comedi_device *dev,\r
+ BYTE b_ModulNbr);\r
+\r
+INT i_APCI1710_EnableCompareLogic (comedi_device *dev,\r
+ BYTE b_ModulNbr);\r
+\r
+INT i_APCI1710_DisableCompareLogic (comedi_device *dev,\r
+ BYTE b_ModulNbr);\r
+\r
+INT i_APCI1710_EnableFrequencyMeasurement (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ BYTE b_InterruptEnable);\r
+\r
+INT i_APCI1710_DisableFrequencyMeasurement (comedi_device *dev,\r
+ BYTE b_ModulNbr);\r
+\r
+\r
+// INSN READ\r
+\r
+INT i_APCI1710_ReadLatchRegisterStatus (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ BYTE b_LatchReg,\r
+ PBYTE pb_LatchStatus);\r
+\r
+INT i_APCI1710_ReadLatchRegisterValue (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ BYTE b_LatchReg,\r
+ PULONG pul_LatchValue);\r
+\r
+INT i_APCI1710_Read16BitCounterValue (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ BYTE b_SelectedCounter,\r
+ PUINT pui_CounterValue);\r
+\r
+INT i_APCI1710_Read32BitCounterValue (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ PULONG pul_CounterValue);\r
+\r
+INT i_APCI1710_GetIndexStatus (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ PBYTE pb_IndexStatus);\r
+\r
+INT i_APCI1710_GetReferenceStatus (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ PBYTE pb_ReferenceStatus);\r
+\r
+INT i_APCI1710_GetUASStatus (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ PBYTE pb_UASStatus);\r
+\r
+INT i_APCI1710_GetCBStatus (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ PBYTE pb_CBStatus);\r
+\r
+INT i_APCI1710_Get16BitCBStatus (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ PBYTE pb_CBStatusCounter0,\r
+ PBYTE pb_CBStatusCounter1);\r
+\r
+INT i_APCI1710_GetUDStatus (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ PBYTE pb_UDStatus);\r
+\r
+INT i_APCI1710_GetInterruptUDLatchedStatus (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ PBYTE pb_UDStatus);\r
+\r
+INT i_APCI1710_ReadFrequencyMeasurement (comedi_device *dev,\r
+ BYTE b_ModulNbr,\r
+ PBYTE pb_Status,\r
+ PBYTE pb_UDStatus,\r
+ PULONG pul_ReadValue);\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
--- /dev/null
+/*\r
+ +-----------------------------------------------------------------------+\r
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |\r
+ +-----------------------------------------------------------------------+\r
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |\r
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |\r
+ +-----------------------------------------------------------------------+\r
+ | Project : API APCI1710 | Compiler : BORLANDC/MICROSOFT C |\r
+ | Module name : INP_CPT.C | Version : 3.1 / 6.0 |\r
+ +-------------------------------+---------------------------------------+\r
+ | Author : S.WEBER | Date : 27.08.98 |\r
+ +-----------------------------------------------------------------------+\r
+ | Description : APCI-1710 pulse encoder module |\r
+ | |\r
+ | |\r
+ +-----------------------------------------------------------------------+\r
+ | UPDATES |\r
+ +-----------------------------------------------------------------------+\r
+ | Date | Author | Description of updates |\r
+ +----------+-----------+------------------------------------------------+\r
+ | | | |\r
+ |----------|-----------|------------------------------------------------|\r
+ | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |\r
+ | | | available |\r
+ +-----------------------------------------------------------------------+\r
+*/\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Included files |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+#include "APCI1710_Inp_cpt.h"\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_InitPulseEncoder |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_PulseEncoderNbr, |\r
+| BYTE_ b_InputLevelSelection, |\r
+| BYTE_ b_TriggerOutputAction, |\r
+| ULONG_ ul_StartValue) |\r
++----------------------------------------------------------------------------+\r
+| Task : Configure the pulse encoder operating mode selected via|\r
+| b_ModulNbr and b_PulseEncoderNbr. The pulse encoder |\r
+| after each pulse decrement the counter value from 1. |\r
+| |\r
+| You must calling this function be for you call any |\r
+| other function witch access of pulse encoders. |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|\r
+| BYTE_ b_ModulNbr : Module number to |\r
+| configure (0 to 3) |\r
+| BYTE_ b_PulseEncoderNbr : Pulse encoder selection |\r
+| (0 to 3) |\r
+| BYTE_ b_InputLevelSelection : Input level selection |\r
+| (0 or 1) |\r
+| 0 : Set pulse encoder|\r
+| count the the low|\r
+| level pulse. |\r
+| 1 : Set pulse encoder|\r
+| count the the |\r
+| high level pulse.|\r
+| BYTE_ b_TriggerOutputAction : Digital TRIGGER output |\r
+| action |\r
+| 0 : No action |\r
+| 1 : Set the trigger |\r
+| output to "1" |\r
+| (high) after the |\r
+| passage from 1 to|\r
+| 0 from pulse |\r
+| encoder. |\r
+| 2 : Set the trigger |\r
+| output to "0" |\r
+| (low) after the |\r
+| passage from 1 to|\r
+| 0 from pulse |\r
+| encoder |\r
+| ULONG_ ul_StartValue : Pulse encoder start value|\r
+| (1 to 4294967295) \r
+ b_ModulNbr =(BYTE) CR_AREF(insn->chanspec);\r
+ b_PulseEncoderNbr =(BYTE) data[0];\r
+ b_InputLevelSelection =(BYTE) data[1];\r
+ b_TriggerOutputAction =(BYTE) data[2];\r
+ ul_StartValue =(ULONG) data[3];\r
+ |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: The module is not a pulse encoder module |\r
+| -3: Pulse encoder selection is wrong |\r
+| -4: Input level selection is wrong |\r
+| -5: Digital TRIGGER output action selection is wrong |\r
+| -6: Pulse encoder start value is wrong |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_InsnConfigInitPulseEncoder(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ DWORD dw_IntRegister;\r
+ \r
+ BYTE b_ModulNbr;\r
+ BYTE b_PulseEncoderNbr;\r
+ BYTE b_InputLevelSelection;\r
+ BYTE b_TriggerOutputAction;\r
+ ULONG ul_StartValue;\r
+ \r
+ b_ModulNbr =(BYTE) CR_AREF(insn->chanspec);\r
+ b_PulseEncoderNbr =(BYTE) data[0];\r
+ b_InputLevelSelection =(BYTE) data[1];\r
+ b_TriggerOutputAction =(BYTE) data[2];\r
+ ul_StartValue =(ULONG) data[3];\r
+\r i_ReturnValue =insn->n;
+ \r
+\r
+ /***********************************/\r
+ /* Test the selected module number */\r
+ /***********************************/\r
+\r
+ if (b_ModulNbr >= 0 && b_ModulNbr <= 3)\r
+ {\r
+ /*************************/\r
+ /* Test if pulse encoder */\r
+ /*************************/\r
+\r
+ if ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & APCI1710_PULSE_ENCODER) == APCI1710_PULSE_ENCODER)\r
+ {\r
+ /******************************************/\r
+ /* Test the selected pulse encoder number */\r
+ /******************************************/\r
+\r
+ if (b_PulseEncoderNbr >= 0 && b_PulseEncoderNbr <= 3)\r
+ {\r
+ /************************/\r
+ /* Test the input level */\r
+ /************************/\r
+\r
+ if ((b_InputLevelSelection == 0) || (b_InputLevelSelection == 1))\r
+ {\r
+ /*******************************************/\r
+ /* Test the ouput TRIGGER action selection */\r
+ /*******************************************/\r
+\r
+ if ((b_TriggerOutputAction >= 0 && b_TriggerOutputAction <= 2) || (b_PulseEncoderNbr > 0))\r
+ {\r
+ if (ul_StartValue > 1)\r
+ {\r
+ \r
+ dw_IntRegister= inl(devpriv->s_BoardInfos.ui_Address + 20 + (64 * b_ModulNbr));\r
+\r
+ /***********************/\r
+ /* Set the start value */\r
+ /***********************/\r
+\r
+\r
+ outl(ul_StartValue,devpriv->s_BoardInfos.ui_Address + (b_PulseEncoderNbr * 4) + (64 * b_ModulNbr));\r
+\r
+ /***********************/\r
+ /* Set the input level */\r
+ /***********************/\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_PulseEncoderModuleInfo.\r
+ dw_SetRegister = (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_PulseEncoderModuleInfo.\r
+ dw_SetRegister & (0xFFFFFFFFUL - (1UL << (8 + b_PulseEncoderNbr)))) |\r
+ ((1UL & (~b_InputLevelSelection)) << (8 + b_PulseEncoderNbr));\r
+\r
+ /*******************************/\r
+ /* Test if output trigger used */\r
+ /*******************************/\r
+\r
+ if ((b_TriggerOutputAction > 0) && (b_PulseEncoderNbr > 1))\r
+ {\r
+ /****************************/\r
+ /* Enable the output action */\r
+ /****************************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_PulseEncoderModuleInfo.\r
+ dw_SetRegister = devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_PulseEncoderModuleInfo.\r
+ dw_SetRegister |\r
+ (1UL << (4 + b_PulseEncoderNbr));\r
+\r
+ /*********************************/\r
+ /* Set the output TRIGGER action */\r
+ /*********************************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_PulseEncoderModuleInfo.\r
+ dw_SetRegister = (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_PulseEncoderModuleInfo.\r
+ dw_SetRegister & (0xFFFFFFFFUL - (1UL << (12 + b_PulseEncoderNbr)))) |\r
+ ((1UL & (b_TriggerOutputAction - 1)) << (12 + b_PulseEncoderNbr));\r
+ }\r
+ else\r
+ {\r
+ /*****************************/\r
+ /* Disable the output action */\r
+ /*****************************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_PulseEncoderModuleInfo.\r
+ dw_SetRegister = devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_PulseEncoderModuleInfo.\r
+ dw_SetRegister & (0xFFFFFFFFUL - (1UL << (4 + b_PulseEncoderNbr)));\r
+ }\r
+\r
+ /*************************/\r
+ /* Set the configuration */\r
+ /*************************/\r
+\r
+ \r
+ outl(devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_PulseEncoderModuleInfo.dw_SetRegister,devpriv->s_BoardInfos.\r
+ ui_Address + 20 + (64 * b_ModulNbr));\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_PulseEncoderModuleInfo.\r
+ s_PulseEncoderInfo [b_PulseEncoderNbr].\r
+ b_PulseEncoderInit = 1;\r
+ }\r
+ else\r
+ {\r
+ /**************************************/\r
+ /* Pulse encoder start value is wrong */\r
+ /**************************************/\r
+\r DPRINTK("Pulse encoder start value is wrong\n");
+ i_ReturnValue = -6;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /****************************************************/\r
+ /* Digital TRIGGER output action selection is wrong */\r
+ /****************************************************/\r
+\r DPRINTK("Digital TRIGGER output action selection is wrong\n");
+ i_ReturnValue = -5;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /**********************************/\r
+ /* Input level selection is wrong */\r
+ /**********************************/\r
+\r DPRINTK("Input level selection is wrong\n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /************************************/\r
+ /* Pulse encoder selection is wrong */\r
+ /************************************/\r
+\r DPRINTK("Pulse encoder selection is wrong\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /********************************************/\r
+ /* The module is not a pulse encoder module */\r
+ /********************************************/\r
+\r DPRINTK("The module is not a pulse encoder module\n");
+ i_ReturnValue = -2;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /********************************************/\r
+ /* The module is not a pulse encoder module */\r
+ /********************************************/\r
+\r DPRINTK("The module is not a pulse encoder module\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_EnablePulseEncoder |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_PulseEncoderNbr, |\r
+| BYTE_ b_CycleSelection, |\r
+| BYTE_ b_InterruptHandling) |\r
++----------------------------------------------------------------------------+\r
+| Task : Enableor disable the selected pulse encoder (b_PulseEncoderNbr) |\r
+| from selected module (b_ModulNbr). Each input pulse |\r
+| decrement the pulse encoder counter value from 1. |\r
+| If you enabled the interrupt (b_InterruptHandling), a |\r
+| interrupt is generated when the pulse encoder has run |\r
+| down. |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|\r
+| BYTE_ b_ModulNbr : Module number to |\r
+| configure (0 to 3) |\r
+| BYTE_ b_PulseEncoderNbr : Pulse encoder selection |\r
+| (0 to 3) |\r
+| BYTE_ b_CycleSelection : APCI1710_CONTINUOUS: |\r
+| Each time the |\r
+| counting value is set|\r
+| on "0", the pulse |\r
+| encoder load the |\r
+| start value after |\r
+| the next pulse. |\r
+| APCI1710_SINGLE: |\r
+| If the counter is set|\r
+| on "0", the pulse |\r
+| encoder is stopped. |\r
+| BYTE_ b_InterruptHandling : Interrupts can be |\r
+| generated, when the pulse|\r
+| encoder has run down. |\r
+| With this parameter the |\r
+| user decides if |\r
+| interrupts are used or |\r
+| not. |\r
+| APCI1710_ENABLE: |\r
+| Interrupts are enabled |\r
+| APCI1710_DISABLE: |\r
+| Interrupts are disabled\r
+\r
+ b_ModulNbr =(BYTE) CR_AREF(insn->chanspec);\r
+ b_Action =(BYTE) data[0];\r
+ b_PulseEncoderNbr =(BYTE) data[1];\r
+ b_CycleSelection =(BYTE) data[2];\r
+ b_InterruptHandling =(BYTE) data[3];|\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: Module selection is wrong |\r
+| -3: Pulse encoder selection is wrong |\r
+| -4: Pulse encoder not initialised. |\r
+| See function "i_APCI1710_InitPulseEncoder" |\r
+| -5: Cycle selection mode is wrong |\r
+| -6: Interrupt handling mode is wrong |\r
+| -7: Interrupt routine not installed. |\r
+| See function "i_APCI1710_SetBoardIntRoutineX" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+
+ INT i_APCI1710_InsnWriteEnableDisablePulseEncoder(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ BYTE b_ModulNbr;\r
+ BYTE b_PulseEncoderNbr ;\r
+ BYTE b_CycleSelection ;\r
+ BYTE b_InterruptHandling;\r
+ BYTE b_Action;\r
+\r
+ i_ReturnValue =insn->n;\r
+ b_ModulNbr =(BYTE) CR_AREF(insn->chanspec);\r
+ b_Action =(BYTE) data[0];\r
+ b_PulseEncoderNbr =(BYTE) data[1];\r
+ b_CycleSelection =(BYTE) data[2];\r
+ b_InterruptHandling =(BYTE) data[3];\r
+\r
+\r
+ /***********************************/\r
+ /* Test the selected module number */\r
+ /***********************************/\r
+\r
+ if (b_ModulNbr >= 0 && b_ModulNbr <= 3)\r
+ {\r
+ /******************************************/\r
+ /* Test the selected pulse encoder number */\r
+ /******************************************/\r
+\r
+ if (b_PulseEncoderNbr >= 0 && b_PulseEncoderNbr <= 3)\r
+ {\r
+ /*************************************/\r
+ /* Test if pulse encoder initialised */\r
+ /*************************************/\r
+\r
+ if (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_PulseEncoderModuleInfo.\r
+ s_PulseEncoderInfo [b_PulseEncoderNbr].\r
+ b_PulseEncoderInit == 1)\r
+ {\r
+ switch(b_Action)\r
+ {\r
+\r
+ case APCI1710_ENABLE:\r
+ /****************************/\r
+ /* Test the cycle selection */\r
+ /****************************/\r
+\r
+ if (b_CycleSelection == APCI1710_CONTINUOUS || b_CycleSelection == APCI1710_SINGLE)\r
+ {\r
+ /*******************************/\r
+ /* Test the interrupt handling */\r
+ /*******************************/\r
+\r
+ if (b_InterruptHandling == APCI1710_ENABLE || b_InterruptHandling == APCI1710_DISABLE)\r
+ {\r
+ /******************************/\r
+ /* Test if interrupt not used */\r
+ /******************************/\r
+\r
+ if (b_InterruptHandling == APCI1710_DISABLE)\r
+ {\r
+ /*************************/\r
+ /* Disable the interrupt */\r
+ /*************************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_PulseEncoderModuleInfo.\r
+ dw_SetRegister = devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_PulseEncoderModuleInfo.\r
+ dw_SetRegister & (0xFFFFFFFFUL - (1UL << b_PulseEncoderNbr));\r
+ }\r
+ else\r
+ {\r
+ \r
+ /************************/\r
+ /* Enable the interrupt */\r
+ /************************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_PulseEncoderModuleInfo.\r
+ dw_SetRegister = devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_PulseEncoderModuleInfo.\r
+ dw_SetRegister | (1UL << b_PulseEncoderNbr);\r
+ devpriv->tsk_Current=current; // Save the current process task structure
+\r
+
+ }\r
+\r
+ if (i_ReturnValue>=0)\r
+ {\r
+ /***********************************/\r
+ /* Enable or disable the interrupt */\r
+ /***********************************/\r
+\r
+
+ outl(devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_PulseEncoderModuleInfo.\r
+ dw_SetRegister,devpriv->s_BoardInfos.\r
+ ui_Address + 20 + (64 * b_ModulNbr));\r
+\r
+ /****************************/\r
+ /* Enable the pulse encoder */\r
+ /****************************/\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_PulseEncoderModuleInfo.\r
+ dw_ControlRegister = devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_PulseEncoderModuleInfo.\r
+ dw_ControlRegister | (1UL << b_PulseEncoderNbr);\r
+\r
+ /**********************/\r
+ /* Set the cycle mode */\r
+ /**********************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_PulseEncoderModuleInfo.\r
+ dw_ControlRegister = (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_PulseEncoderModuleInfo.\r
+ dw_ControlRegister & (0xFFFFFFFFUL - (1 << (b_PulseEncoderNbr + 4)))) |\r
+ ((b_CycleSelection & 1UL) << (4 + b_PulseEncoderNbr));\r
+\r
+ /****************************/\r
+ /* Enable the pulse encoder */\r
+ /****************************/\r
+\r
+
+ outl(devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_PulseEncoderModuleInfo.\r
+ dw_ControlRegister,devpriv->s_BoardInfos.\r
+ ui_Address + 16 + (64 * b_ModulNbr));\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /************************************/\r
+ /* Interrupt handling mode is wrong */\r
+ /************************************/\r
+\r DPRINTK("Interrupt handling mode is wrong\n");
+ i_ReturnValue = -6;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*********************************/\r
+ /* Cycle selection mode is wrong */\r
+ /*********************************/\r
+\r DPRINTK("Cycle selection mode is wrong\n");
+ i_ReturnValue = -5;\r
+ }\r
+ break;\r
+\r
+ case APCI1710_DISABLE:\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_PulseEncoderModuleInfo.\r
+ dw_ControlRegister = devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_PulseEncoderModuleInfo.\r
+ dw_ControlRegister & (0xFFFFFFFFUL - (1UL << b_PulseEncoderNbr));\r
+\r
+ /*****************************/\r
+ /* Disable the pulse encoder */\r
+ /*****************************/\r
+\r
+ \r
+ outl(devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_PulseEncoderModuleInfo.\r
+ dw_ControlRegister,devpriv->s_BoardInfos.\r
+ ui_Address + 16 + (64 * b_ModulNbr));\r
+\r
+ break;\r
+ }// switch End\r
+\r
+ }\r
+ else\r
+ {\r
+ /*********************************/\r
+ /* Pulse encoder not initialised */\r
+ /*********************************/\r
+\r DPRINTK("Pulse encoder not initialised\n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /************************************/\r
+ /* Pulse encoder selection is wrong */\r
+ /************************************/\r
+\r DPRINTK("Pulse encoder selection is wrong\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*****************************/\r
+ /* Module selection is wrong */\r
+ /*****************************/\r
+\r DPRINTK("Module selection is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_ReadPulseEncoderStatus |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_PulseEncoderNbr, |\r
+| PBYTE_ pb_Status) |\r
++----------------------------------------------------------------------------+\r
+| Task APCI1710_PULSEENCODER_READ : Reads the pulse encoder status \r
+ and valuefrom selected pulse |\r
+| encoder (b_PulseEncoderNbr) from selected module |\r
+| (b_ModulNbr). |\r
++----------------------------------------------------------------------------+\r
+ BYTE b_Type; data[0]\r
+ APCI1710_PULSEENCODER_WRITE \r
+ Writes a 32-bit value (ul_WriteValue) into the selected|\r
+| pulse encoder (b_PulseEncoderNbr) from selected module |\r
+| (b_ModulNbr). This operation set the new start pulse |\r
+| encoder value.\r
+ APCI1710_PULSEENCODER_READ\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|\r
+| CRAREF() BYTE_ b_ModulNbr : Module number to |\r
+| configure (0 to 3) |\r
+| data[1] BYTE_ b_PulseEncoderNbr : Pulse encoder selection |\r
+| (0 to 3) \r
+ APCI1710_PULSEENCODER_WRITE \r
+ data[2] ULONG_ ul_WriteValue : 32-bit value to be |\r
+| written |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : PBYTE_ pb_Status : Pulse encoder status. |\r
+| 0 : No overflow occur|\r
+| 1 : Overflow occur \r
+ PULONG_ pul_ReadValue : Pulse encoder value | |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: Module selection is wrong |\r
+| -3: Pulse encoder selection is wrong |\r
+| -4: Pulse encoder not initialised. |\r
+| See function "i_APCI1710_InitPulseEncoder" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+\r
+/*_INT_ i_APCI1710_ReadPulseEncoderStatus (BYTE_ b_BoardHandle,\r
+ BYTE_ b_ModulNbr,\r
+ BYTE_ b_PulseEncoderNbr,\r
+\r
+ PBYTE_ pb_Status)\r
+ */\r
+INT i_APCI1710_InsnBitsReadWritePulseEncoder(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ DWORD dw_StatusRegister;\r
+ BYTE b_ModulNbr;\r
+ BYTE b_PulseEncoderNbr;\r
+ PBYTE pb_Status;\r
+ BYTE b_Type;\r
+ PULONG pul_ReadValue;\r
+ ULONG ul_WriteValue ; \r
+ \r
+ i_ReturnValue=insn->n;
+ b_ModulNbr =(BYTE) CR_AREF(insn->chanspec);
+ b_Type =(BYTE) data[0] ;\r
+ b_PulseEncoderNbr=(BYTE) data[1];
+ pb_Status =(PBYTE) &data[0];\r
+ pul_ReadValue =(PULONG) &data[1];\r
+ \r
+ /***********************************/\r
+ /* Test the selected module number */\r
+ /***********************************/\r
+\r
+ if (b_ModulNbr >= 0 && b_ModulNbr <= 3)\r
+ {\r
+ /******************************************/\r
+ /* Test the selected pulse encoder number */\r
+ /******************************************/\r
+\r
+ if (b_PulseEncoderNbr >= 0 && b_PulseEncoderNbr <= 3)\r
+ {\r
+ /*************************************/\r
+ /* Test if pulse encoder initialised */\r
+ /*************************************/\r
+\r
+ if (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_PulseEncoderModuleInfo.\r
+ s_PulseEncoderInfo [b_PulseEncoderNbr].\r
+ b_PulseEncoderInit == 1)\r
+ {\r
+\r
+ switch(b_Type)\r
+ {\r
+ case APCI1710_PULSEENCODER_READ:\r
+ /****************************/\r
+ /* Read the status register */\r
+ /****************************/\r
+\r
+
+ dw_StatusRegister=inl(devpriv->s_BoardInfos.\r
+ ui_Address + 16 + (64 * b_ModulNbr));\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_PulseEncoderModuleInfo.\r
+ dw_StatusRegister = devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_PulseEncoderModuleInfo.\r
+ dw_StatusRegister | dw_StatusRegister;\r
+\r
+ *pb_Status = (BYTE) (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_PulseEncoderModuleInfo.\r
+ dw_StatusRegister >> (1 + b_PulseEncoderNbr)) & 1;\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_PulseEncoderModuleInfo.\r
+ dw_StatusRegister = devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_PulseEncoderModuleInfo.\r
+ dw_StatusRegister & (0xFFFFFFFFUL - (1 << (1 + b_PulseEncoderNbr)));\r
+\r
+ /******************/\r
+ /* Read the value */\r
+ /******************/\r
+
+\r
+ *pul_ReadValue=inl(devpriv->s_BoardInfos.\r
+ ui_Address + (4 * b_PulseEncoderNbr) + (64 * b_ModulNbr));\r
+ break;\r
+\r
+ case APCI1710_PULSEENCODER_WRITE:\r
+ ul_WriteValue = (ULONG) data[2];\r
+ /*******************/\r
+ /* Write the value */\r
+ /*******************/\r
+\r
+
+ outl(ul_WriteValue,devpriv->s_BoardInfos.\r
+ ui_Address + (4 * b_PulseEncoderNbr) + (64 * b_ModulNbr));\r
+\r
+ }//end of switch\r
+ }\r
+ else\r
+ {\r
+ /*********************************/\r
+ /* Pulse encoder not initialised */\r
+ /*********************************/\r
+\r DPRINTK("Pulse encoder not initialised\n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /************************************/\r
+ /* Pulse encoder selection is wrong */\r
+ /************************************/\r
+\r DPRINTK("Pulse encoder selection is wrong\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*****************************/\r
+ /* Module selection is wrong */\r
+ /*****************************/\r
+\r DPRINTK("Module selection is wrong\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+
+INT i_APCI1710_InsnReadInterruptPulseEncoder(comedi_device *dev,comedi_subdevice *s,
+ comedi_insn *insn,lsampl_t *data)
+{
+
+ data[0] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Read].b_OldModuleMask;
+ data[1] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Read].ul_OldInterruptMask;
+ data[2] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Read].ul_OldCounterLatchValue;
+
+
+ /***************************/
+ /* Increment the read FIFO */
+ /***************************/
+
+ devpriv->s_InterruptParameters.
+ ui_Read = (devpriv->
+ s_InterruptParameters.ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
+
+ return insn->n;
+
+
+}
+
+\r
--- /dev/null
+\r\r
+\r
+\r
+ #define APCI1710_SINGLE 0\r
+ #define APCI1710_CONTINUOUS 1\r
+
+\r
+#define APCI1710_PULSEENCODER_READ 0 \r
+#define APCI1710_PULSEENCODER_WRITE 1\r
+\r
+\r
+INT i_APCI1710_InsnConfigInitPulseEncoder(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data);\r
+\r
+\r
+\r
+\r
+INT i_APCI1710_InsnWriteEnableDisablePulseEncoder(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data);\r
+/*\r
++----------------------------------------------------------------------------+\r
+| READ PULSE ENCODER FUNCTIONS |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_InsnReadInterruptPulseEncoder(comedi_device *dev,comedi_subdevice *s,
+ comedi_insn *insn,lsampl_t *data);
+
+/*\r
++----------------------------------------------------------------------------+\r
+| WRITE PULSE ENCODER FUNCTIONS |\r
++----------------------------------------------------------------------------+\r
+*/\r
+
+ INT i_APCI1710_InsnBitsReadWritePulseEncoder(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data);
+
+
--- /dev/null
+
+
+
+
+/*\r
+ +-----------------------------------------------------------------------+\r
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |\r
+ +-----------------------------------------------------------------------+\r
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |\r
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |\r
+ +-----------------------------------------------------------------------+\r
+ | Project : API APCI1710 | Compiler : BORLANDC/MICROSOFT C |\r
+ | Module name : PWM.C | Version : 3.1 / 6.0 |\r
+ +-------------------------------+---------------------------------------+\r
+ | Author : S.WEBER | Date : 22.01.99 |\r
+ +-----------------------------------------------------------------------+\r
+ | Description : APCI-1710 Wulse wide modulation module |\r
+ | |\r
+ | |\r
+ +-----------------------------------------------------------------------+\r
+ | UPDATES |\r
+ +-----------------------------------------------------------------------+\r
+ | Date | Author | Description of updates |\r
+ +-----------------------------------------------------------------------+\r
+ | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |\r
+ | | | available |\r
+ +-----------------------------------------------------------------------+\r
+*/\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Included files |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+\r
+#include "APCI1710_Pwm.h"\r
+\r
+
+
+/*
++----------------------------------------------------------------------------+
+| Function Name :INT i_APCI1710_InsnConfigPWM(comedi_device *dev,
+comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Pwm Init and Get Pwm Initialisation |
++----------------------------------------------------------------------------+
+| Input Parameters :
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnConfigPWM(comedi_device *dev,comedi_subdevice *s,
+comedi_insn *insn,lsampl_t *data)
+{
+ BYTE b_ConfigType;
+ INT i_ReturnValue=0;
+ b_ConfigType=CR_CHAN(insn->chanspec);
+
+ switch(b_ConfigType)
+ {
+ case APCI1710_PWM_INIT :
+ i_ReturnValue=i_APCI1710_InitPWM (dev,
+ (BYTE)CR_AREF(insn->chanspec), // b_ModulNbr
+ (BYTE) data[0], //b_PWM
+ (BYTE) data[1], // b_ClockSelection
+ (BYTE) data[2], // b_TimingUnit
+ (ULONG)data[3], //ul_LowTiming
+ (ULONG)data[4], //ul_HighTiming
+ (PULONG)&data[0], //pul_RealLowTiming
+ (PULONG)&data[1] //pul_RealHighTiming
+ );
+ break;
+
+ case APCI1710_PWM_GETINITDATA :
+ i_ReturnValue=i_APCI1710_GetPWMInitialisation (dev,
+ (BYTE)CR_AREF(insn->chanspec), // b_ModulNbr
+ (BYTE) data[0], //b_PWM
+ (PBYTE)&data[0], //pb_TimingUnit
+ (PULONG)&data[1], //pul_LowTiming
+ (PULONG)&data[2], //pul_HighTiming
+ (PBYTE) &data[3], // pb_StartLevel
+ (PBYTE) &data[4], // pb_StopMode
+ (PBYTE) &data[5], // pb_StopLevel
+ (PBYTE) &data[6], // pb_ExternGate
+ (PBYTE) &data[7], // pb_InterruptEnable
+ (PBYTE) &data[8] // pb_Enable
+ );
+ break;
+
+ default:
+ printk(" Config Parameter Wrong\n");
+ }
+
+ if(i_ReturnValue>=0) i_ReturnValue =insn->n;
+ return (i_ReturnValue);
+}
+
+
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_InitPWM |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_PWM, |
+| BYTE_ b_ClockSelection, |
+| BYTE_ b_TimingUnit, |
+| ULONG_ ul_LowTiming, |
+| ULONG_ ul_HighTiming, |
+| PULONG_ pul_RealLowTiming, |
+| PULONG_ pul_RealHighTiming) |
++----------------------------------------------------------------------------+
+| Task : Configure the selected PWM (b_PWM) from selected module|
+| (b_ModulNbr). The ul_LowTiming, ul_HighTiming and |
+| ul_TimingUnit determine the low/high timing base for |
+| the period. pul_RealLowTiming, pul_RealHighTiming |
+| return the real timing value. |
+| You must calling this function be for you call any |
+| other function witch access of the PWM. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure|
+| (0 to 3) |
+| BYTE_ b_PWM : Selected PWM (0 or 1). |
+| BYTE_ b_ClockSelection : Selection from PCI bus |
+| clock |
+| - APCI1710_30MHZ : |
+| The PC have a 30 MHz |
+| PCI bus clock |
+| - APCI1710_33MHZ : |
+| The PC have a 33 MHz |
+| PCI bus clock |
+| - APCI1710_40MHZ |
+| The APCI-1710 have a |
+| integrated 40Mhz |
+| quartz. |
+| BYTE_ b_TimingUnit : Base timing Unit (0 to 4) |
+| 0 : ns |
+| 1 : æs |
+| 2 : ms |
+| 3 : s |
+| 4 : mn |
+| ULONG_ ul_LowTiming : Low base timing value. |
+| ULONG_ ul_HighTiming : High base timing value. |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pul_RealLowTiming : Real low base timing |
+| value. |
+| PULONG_ pul_RealHighTiming : Real high base timing |
+| value. |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a PWM module |
+| -4: PWM selection is wrong |
+| -5: The selected input clock is wrong |
+| -6: Timing Unit selection is wrong |
+| -7: Low base timing selection is wrong |
+| -8: High base timing selection is wrong |
+| -9: You can not used the 40MHz clock selection with |
+| this board |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InitPWM (comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_PWM,
+ BYTE b_ClockSelection,
+ BYTE b_TimingUnit,
+ ULONG ul_LowTiming,
+ ULONG ul_HighTiming,
+ PULONG pul_RealLowTiming,
+ PULONG pul_RealHighTiming)
+ {
+ INT i_ReturnValue = 0;
+ ULONG ul_LowTimerValue;
+ ULONG ul_HighTimerValue;
+ DWORD dw_Command;
+ double d_RealLowTiming;
+ double d_RealHighTiming;
+
+
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4)
+ {
+ /***************/
+ /* Test if PWM */
+ /***************/
+
+ if ((devpriv->
+ s_BoardInfos.
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_PWM)
+ {
+ /**************************/
+ /* Test the PWM selection */
+ /**************************/
+
+ if (b_PWM >= 0 && b_PWM <= 1)
+ {
+ /******************/
+ /* Test the clock */
+ /******************/
+
+ if ((b_ClockSelection == APCI1710_30MHZ) ||
+ (b_ClockSelection == APCI1710_33MHZ) ||
+ (b_ClockSelection == APCI1710_40MHZ))
+ {
+ /************************/
+ /* Test the timing unit */
+ /************************/
+
+ if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
+ {
+ /*********************************/
+ /* Test the low timing selection */
+ /*********************************/
+
+ if (((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 0) && (ul_LowTiming >= 266) && (ul_LowTiming <= 0xFFFFFFFFUL)) ||
+ ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 1) && (ul_LowTiming >= 1) && (ul_LowTiming <= 571230650UL)) ||
+ ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 2) && (ul_LowTiming >= 1) && (ul_LowTiming <= 571230UL)) ||
+ ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 3) && (ul_LowTiming >= 1) && (ul_LowTiming <= 571UL)) ||
+ ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 4) && (ul_LowTiming >= 1) && (ul_LowTiming <= 9UL)) ||
+ ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 0) && (ul_LowTiming >= 242) && (ul_LowTiming <= 0xFFFFFFFFUL)) ||
+ ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 1) && (ul_LowTiming >= 1) && (ul_LowTiming <= 519691043UL)) ||
+ ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 2) && (ul_LowTiming >= 1) && (ul_LowTiming <= 519691UL)) ||
+ ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 3) && (ul_LowTiming >= 1) && (ul_LowTiming <= 520UL)) ||
+ ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 4) && (ul_LowTiming >= 1) && (ul_LowTiming <= 8UL)) ||
+ ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 0) && (ul_LowTiming >= 200) && (ul_LowTiming <= 0xFFFFFFFFUL)) ||
+ ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 1) && (ul_LowTiming >= 1) && (ul_LowTiming <= 429496729UL)) ||
+ ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 2) && (ul_LowTiming >= 1) && (ul_LowTiming <= 429496UL)) ||
+ ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 3) && (ul_LowTiming >= 1) && (ul_LowTiming <= 429UL)) ||
+ ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 4) && (ul_LowTiming >= 1) && (ul_LowTiming <= 7UL)))
+ {
+ /**********************************/
+ /* Test the High timing selection */
+ /**********************************/
+
+ if (((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 266) && (ul_HighTiming <= 0xFFFFFFFFUL)) ||
+ ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571230650UL)) ||
+ ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571230UL)) ||
+ ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571UL)) ||
+ ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 9UL)) ||
+ ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 242) && (ul_HighTiming <= 0xFFFFFFFFUL)) ||
+ ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 519691043UL)) ||
+ ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 519691UL)) ||
+ ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 520UL)) ||
+ ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 8UL)) ||
+ ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 200) && (ul_HighTiming <= 0xFFFFFFFFUL)) ||
+ ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429496729UL)) ||
+ ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429496UL)) ||
+ ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429UL)) ||
+ ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 7UL)))
+ {
+ /**************************/
+ /* Test the board version */
+ /**************************/
+
+ if ((b_ClockSelection == APCI1710_40MHZ) && (devpriv->
+ s_BoardInfos.
+ b_BoardVersion > 0) ||
+ (b_ClockSelection != APCI1710_40MHZ))
+ {
+
+ /************************************/
+ /* Calculate the low division fator */
+ /************************************/
+
+ switch (b_TimingUnit)
+ {
+ /******/
+ /* ns */
+ /******/
+
+ case 0:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_LowTimerValue = (ULONG) (ul_LowTiming * (0.00025 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double) ((double) ul_LowTiming * (0.00025 * (double) b_ClockSelection)) >= ((double) ((double) ul_LowTimerValue + 0.5)))
+ {
+ ul_LowTimerValue = ul_LowTimerValue + 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealLowTiming = (ULONG) (ul_LowTimerValue / (0.00025 * (double) b_ClockSelection));
+ d_RealLowTiming = (double) ul_LowTimerValue / (0.00025 * (double) b_ClockSelection);
+
+ if ((double) ((double) ul_LowTimerValue / (0.00025 * (double) b_ClockSelection)) >= (double) ((double) *pul_RealLowTiming + 0.5))
+ {
+ *pul_RealLowTiming = *pul_RealLowTiming + 1;
+ }
+
+ ul_LowTiming = ul_LowTiming - 1;
+ ul_LowTimerValue = ul_LowTimerValue - 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ)
+ {
+ ul_LowTimerValue = (ULONG) ((double) (ul_LowTimerValue) * 1.007752288);
+ }
+
+
+ break;
+
+ /******/
+ /* æs */
+ /******/
+
+ case 1:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_LowTimerValue = (ULONG) (ul_LowTiming * (0.25 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double) ((double) ul_LowTiming * (0.25 * (double) b_ClockSelection)) >= ((double) ((double) ul_LowTimerValue + 0.5)))
+ {
+ ul_LowTimerValue = ul_LowTimerValue + 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealLowTiming = (ULONG) (ul_LowTimerValue / (0.25 * (double) b_ClockSelection));
+ d_RealLowTiming = (double) ul_LowTimerValue / ((double) 0.25 * (double) b_ClockSelection);
+
+ if ((double) ((double) ul_LowTimerValue / (0.25 * (double) b_ClockSelection)) >= (double) ((double) *pul_RealLowTiming + 0.5))
+ {
+ *pul_RealLowTiming = *pul_RealLowTiming + 1;
+ }
+
+ ul_LowTiming = ul_LowTiming - 1;
+ ul_LowTimerValue = ul_LowTimerValue - 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ)
+ {
+ ul_LowTimerValue = (ULONG) ((double) (ul_LowTimerValue) * 1.007752288);
+ }
+
+
+ break;
+
+ /******/
+ /* ms */
+ /******/
+
+ case 2:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_LowTimerValue = ul_LowTiming * (250.0 * b_ClockSelection);
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double) ((double) ul_LowTiming * (250.0 * (double) b_ClockSelection)) >= ((double) ((double) ul_LowTimerValue + 0.5)))
+ {
+ ul_LowTimerValue = ul_LowTimerValue + 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealLowTiming = (ULONG) (ul_LowTimerValue / (250.0 * (double) b_ClockSelection));
+ d_RealLowTiming = (double) ul_LowTimerValue / (250.0 * (double) b_ClockSelection);
+
+ if ((double) ((double) ul_LowTimerValue / (250.0 * (double) b_ClockSelection)) >= (double) ((double) *pul_RealLowTiming + 0.5))
+ {
+ *pul_RealLowTiming = *pul_RealLowTiming + 1;
+ }
+
+ ul_LowTiming = ul_LowTiming - 1;
+ ul_LowTimerValue = ul_LowTimerValue - 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ)
+ {
+ ul_LowTimerValue = (ULONG) ((double) (ul_LowTimerValue) * 1.007752288);
+ }
+
+ break;
+
+ /*****/
+ /* s */
+ /*****/
+
+ case 3:
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_LowTimerValue = (ULONG) (ul_LowTiming * (250000.0 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double) ((double) ul_LowTiming * (250000.0 * (double) b_ClockSelection)) >= ((double) ((double) ul_LowTimerValue + 0.5)))
+ {
+ ul_LowTimerValue = ul_LowTimerValue + 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealLowTiming = (ULONG) (ul_LowTimerValue / (250000.0 * (double) b_ClockSelection));
+ d_RealLowTiming = (double) ul_LowTimerValue / (250000.0 * (double) b_ClockSelection);
+
+ if ((double) ((double) ul_LowTimerValue / (250000.0 * (double) b_ClockSelection)) >= (double) ((double) *pul_RealLowTiming + 0.5))
+ {
+ *pul_RealLowTiming = *pul_RealLowTiming + 1;
+ }
+
+ ul_LowTiming = ul_LowTiming - 1;
+ ul_LowTimerValue = ul_LowTimerValue - 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ)
+ {
+ ul_LowTimerValue = (ULONG) ((double) (ul_LowTimerValue) * 1.007752288);
+ }
+
+
+ break;
+
+ /******/
+ /* mn */
+ /******/
+
+ case 4:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_LowTimerValue = (ULONG) ((ul_LowTiming * 60) * (250000.0 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double) ((double) (ul_LowTiming * 60.0) * (250000.0 * (double) b_ClockSelection)) >= ((double) ((double) ul_LowTimerValue + 0.5)))
+ {
+ ul_LowTimerValue = ul_LowTimerValue + 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealLowTiming = (ULONG) (ul_LowTimerValue / (250000.0 * (double) b_ClockSelection)) / 60;
+ d_RealLowTiming = ((double) ul_LowTimerValue / (250000.0 * (double) b_ClockSelection)) / 60.0;
+
+ if ((double) (((double) ul_LowTimerValue / (250000.0 * (double) b_ClockSelection)) / 60.0) >= (double) ((double) *pul_RealLowTiming + 0.5))
+ {
+ *pul_RealLowTiming = *pul_RealLowTiming + 1;
+ }
+
+ ul_LowTiming = ul_LowTiming - 1;
+ ul_LowTimerValue = ul_LowTimerValue - 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ)
+ {
+ ul_LowTimerValue = (ULONG) ((double) (ul_LowTimerValue) * 1.007752288);
+ }
+
+ break;
+ }
+
+ /*************************************/
+ /* Calculate the high division fator */
+ /*************************************/
+
+ switch (b_TimingUnit)
+ {
+ /******/
+ /* ns */
+ /******/
+
+ case 0:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_HighTimerValue = (ULONG) (ul_HighTiming * (0.00025 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double) ((double) ul_HighTiming * (0.00025 * (double) b_ClockSelection)) >= ((double) ((double) ul_HighTimerValue + 0.5)))
+ {
+ ul_HighTimerValue = ul_HighTimerValue + 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealHighTiming = (ULONG) (ul_HighTimerValue / (0.00025 * (double) b_ClockSelection));
+ d_RealHighTiming = (double) ul_HighTimerValue / (0.00025 * (double) b_ClockSelection);
+
+ if ((double) ((double) ul_HighTimerValue / (0.00025 * (double) b_ClockSelection)) >= (double) ((double) *pul_RealHighTiming + 0.5))
+ {
+ *pul_RealHighTiming = *pul_RealHighTiming + 1;
+ }
+
+ ul_HighTiming = ul_HighTiming - 1;
+ ul_HighTimerValue = ul_HighTimerValue - 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ)
+ {
+ ul_HighTimerValue = (ULONG) ((double) (ul_HighTimerValue) * 1.007752288);
+ }
+
+
+ break;
+
+ /******/
+ /* æs */
+ /******/
+
+ case 1:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_HighTimerValue = (ULONG) (ul_HighTiming * (0.25 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double) ((double) ul_HighTiming * (0.25 * (double) b_ClockSelection)) >= ((double) ((double) ul_HighTimerValue + 0.5)))
+ {
+ ul_HighTimerValue = ul_HighTimerValue + 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealHighTiming = (ULONG) (ul_HighTimerValue / (0.25 * (double) b_ClockSelection));
+ d_RealHighTiming = (double) ul_HighTimerValue / ((double) 0.25 * (double) b_ClockSelection);
+
+ if ((double) ((double) ul_HighTimerValue / (0.25 * (double) b_ClockSelection)) >= (double) ((double) *pul_RealHighTiming + 0.5))
+ {
+ *pul_RealHighTiming = *pul_RealHighTiming + 1;
+ }
+
+ ul_HighTiming = ul_HighTiming - 1;
+ ul_HighTimerValue = ul_HighTimerValue - 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ)
+ {
+ ul_HighTimerValue = (ULONG) ((double) (ul_HighTimerValue) * 1.007752288);
+ }
+
+
+ break;
+
+ /******/
+ /* ms */
+ /******/
+
+ case 2:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_HighTimerValue = ul_HighTiming * (250.0 * b_ClockSelection);
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double) ((double) ul_HighTiming * (250.0 * (double) b_ClockSelection)) >= ((double) ((double) ul_HighTimerValue + 0.5)))
+ {
+ ul_HighTimerValue = ul_HighTimerValue + 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealHighTiming = (ULONG) (ul_HighTimerValue / (250.0 * (double) b_ClockSelection));
+ d_RealHighTiming = (double) ul_HighTimerValue / (250.0 * (double) b_ClockSelection);
+
+ if ((double) ((double) ul_HighTimerValue / (250.0 * (double) b_ClockSelection)) >= (double) ((double) *pul_RealHighTiming + 0.5))
+ {
+ *pul_RealHighTiming = *pul_RealHighTiming + 1;
+ }
+
+ ul_HighTiming = ul_HighTiming - 1;
+ ul_HighTimerValue = ul_HighTimerValue - 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ)
+ {
+ ul_HighTimerValue = (ULONG) ((double) (ul_HighTimerValue) * 1.007752288);
+ }
+
+
+ break;
+
+ /*****/
+ /* s */
+ /*****/
+
+ case 3:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_HighTimerValue = (ULONG) (ul_HighTiming * (250000.0 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double) ((double) ul_HighTiming * (250000.0 * (double) b_ClockSelection)) >= ((double) ((double) ul_HighTimerValue + 0.5)))
+ {
+ ul_HighTimerValue = ul_HighTimerValue + 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealHighTiming = (ULONG) (ul_HighTimerValue / (250000.0 * (double) b_ClockSelection));
+ d_RealHighTiming = (double) ul_HighTimerValue / (250000.0 * (double) b_ClockSelection);
+
+ if ((double) ((double) ul_HighTimerValue / (250000.0 * (double) b_ClockSelection)) >= (double) ((double) *pul_RealHighTiming + 0.5))
+ {
+ *pul_RealHighTiming = *pul_RealHighTiming + 1;
+ }
+
+ ul_HighTiming = ul_HighTiming - 1;
+ ul_HighTimerValue = ul_HighTimerValue - 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ)
+ {
+ ul_HighTimerValue = (ULONG) ((double) (ul_HighTimerValue) * 1.007752288);
+ }
+
+
+ break;
+
+ /******/
+ /* mn */
+ /******/
+
+ case 4:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_HighTimerValue = (ULONG) ((ul_HighTiming * 60) * (250000.0 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double) ((double) (ul_HighTiming * 60.0) * (250000.0 * (double) b_ClockSelection)) >= ((double) ((double) ul_HighTimerValue + 0.5)))
+ {
+ ul_HighTimerValue = ul_HighTimerValue + 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealHighTiming = (ULONG) (ul_HighTimerValue / (250000.0 * (double) b_ClockSelection)) / 60;
+ d_RealHighTiming = ((double) ul_HighTimerValue / (250000.0 * (double) b_ClockSelection)) / 60.0;
+
+ if ((double) (((double) ul_HighTimerValue / (250000.0 * (double) b_ClockSelection)) / 60.0) >= (double) ((double) *pul_RealHighTiming + 0.5))
+ {
+ *pul_RealHighTiming = *pul_RealHighTiming + 1;
+ }
+
+ ul_HighTiming = ul_HighTiming - 1;
+ ul_HighTimerValue = ul_HighTimerValue - 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ)
+ {
+ ul_HighTimerValue = (ULONG) ((double) (ul_HighTimerValue) * 1.007752288);
+ }
+
+ break;
+ }
+
+ /****************************/
+ /* Save the clock selection */
+ /****************************/
+
+ devpriv->
+ s_ModuleInfo [b_ModulNbr].
+ s_PWMModuleInfo.
+ b_ClockSelection = b_ClockSelection;
+
+ /************************/
+ /* Save the timing unit */
+ /************************/
+
+ devpriv->
+ s_ModuleInfo [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo [b_PWM].
+ b_TimingUnit = b_TimingUnit;
+
+ /****************************/
+ /* Save the low base timing */
+ /****************************/
+
+ devpriv->
+ s_ModuleInfo [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo [b_PWM].
+ d_LowTiming = d_RealLowTiming;
+
+ devpriv->
+ s_ModuleInfo [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo [b_PWM].
+ ul_RealLowTiming = *pul_RealLowTiming;
+
+ /****************************/
+ /* Save the high base timing */
+ /****************************/
+
+ devpriv->
+ s_ModuleInfo [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo [b_PWM].
+ d_HighTiming = d_RealHighTiming;
+
+ devpriv->
+ s_ModuleInfo [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo [b_PWM].
+ ul_RealHighTiming = *pul_RealHighTiming;
+
+ /************************/
+ /* Write the low timing */
+ /************************/
+
+ outl(ul_LowTimerValue,devpriv->s_BoardInfos.
+ ui_Address + 0 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+ /*************************/
+ /* Write the high timing */
+ /*************************/
+
+ outl(ul_HighTimerValue,devpriv->s_BoardInfos.
+ ui_Address + 4 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+ /***************************/
+ /* Set the clock selection */
+ /***************************/
+
+ dw_Command=inl(devpriv->s_BoardInfos.
+ ui_Address + 8 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+ dw_Command = dw_Command & 0x7F;
+
+ if (b_ClockSelection == APCI1710_40MHZ)
+ {
+ dw_Command = dw_Command | 0x80;
+ }
+
+ /***************************/
+ /* Set the clock selection */
+ /***************************/
+
+ outl(dw_Command,devpriv->s_BoardInfos.
+ ui_Address + 8 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+ /*************/
+ /* PWM init. */
+ /*************/
+ devpriv->
+ s_ModuleInfo [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo [b_PWM].
+ b_PWMInit = 1;
+ }
+ else
+ {
+ /***************************************************/
+ /* You can not used the 40MHz clock selection with */
+ /* this board */
+ /***************************************************/
+ DPRINTK("You can not used the 40MHz clock selection with this board\n");
+ i_ReturnValue = -9;
+ }
+ }
+ else
+ {
+ /***************************************/
+ /* High base timing selection is wrong */
+ /***************************************/
+ DPRINTK("High base timing selection is wrong\n");
+ i_ReturnValue = -8;
+ }
+ }
+ else
+ {
+ /**************************************/
+ /* Low base timing selection is wrong */
+ /**************************************/
+ DPRINTK("Low base timing selection is wrong\n");
+ i_ReturnValue = -7;
+ }
+ } // if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
+ else
+ {
+ /**********************************/
+ /* Timing unit selection is wrong */
+ /**********************************/
+ DPRINTK("Timing unit selection is wrong\n");
+ i_ReturnValue = -6;
+ } // if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
+ } // if ((b_ClockSelection == APCI1710_30MHZ) || (b_ClockSelection == APCI1710_33MHZ) || (b_ClockSelection == APCI1710_40MHZ))
+ else
+ {
+ /*******************************/
+ /* The selected clock is wrong */
+ /*******************************/
+ DPRINTK("The selected clock is wrong\n");
+ i_ReturnValue = -5;
+ } // if ((b_ClockSelection == APCI1710_30MHZ) || (b_ClockSelection == APCI1710_33MHZ) || (b_ClockSelection == APCI1710_40MHZ))
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ else
+ {
+ /******************************/
+ /* Tor PWM selection is wrong */
+ /******************************/
+ DPRINTK("Tor PWM selection is wrong\n");
+ i_ReturnValue = -4;
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ }
+ else
+ {
+ /**********************************/
+ /* The module is not a PWM module */
+ /**********************************/
+ DPRINTK("The module is not a PWM module\n");
+ i_ReturnValue = -3;
+ }
+ }
+ else
+ {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+ }
+
+
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_GetPWMInitialisation |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_PWM, |
+| PBYTE_ pb_TimingUnit, |
+| PULONG_ pul_LowTiming, |
+| PULONG_ pul_HighTiming, |
+| PBYTE_ pb_StartLevel, |
+| PBYTE_ pb_StopMode, |
+| PBYTE_ pb_StopLevel, |
+| PBYTE_ pb_ExternGate, |
+| PBYTE_ pb_InterruptEnable, |
+| PBYTE_ pb_Enable) |
++----------------------------------------------------------------------------+
+| Task : Return the PWM (b_PWM) initialisation from selected |
+| module (b_ModulNbr). You must calling the |
+| "i_APCI1710_InitPWM" function be for you call this |
+| function. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3) |
+| BYTE_ b_PWM : Selected PWM (0 or 1) |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_TimingUnit : Base timing Unit (0 to 4) |
+| 0 : ns |
+| 1 : æs |
+| 2 : ms |
+| 3 : s |
+| 4 : mn |
+| PULONG_ pul_LowTiming : Low base timing value. |
+| PULONG_ pul_HighTiming : High base timing value. |
+| PBYTE_ pb_StartLevel : Start period level |
+| selection |
+| 0 : The period start |
+| with a low level |
+| 1 : The period start |
+| with a high level|
+| PBYTE_ pb_StopMode : Stop mode selection |
+| 0 : The PWM is stopped |
+| directly after the |
+| "i_APCI1710_DisablePWM"|
+| function and break the|
+| last period |
+| 1 : After the |
+| "i_APCI1710_DisablePWM"|
+| function the PWM is |
+| stopped at the end |
+| from last period cycle|
+| PBYTE_ pb_StopLevel : Stop PWM level selection |
+| 0 : The output signal |
+| keep the level after|
+| the |
+| "i_APCI1710_DisablePWM"|
+| function |
+| 1 : The output signal is|
+| set to low after the|
+| "i_APCI1710_DisablePWM"|
+| function |
+| 2 : The output signal is|
+| set to high after |
+| the |
+| "i_APCI1710_DisablePWM"|
+| function |
+| PBYTE_ pb_ExternGate : Extern gate action |
+| selection |
+| 0 : Extern gate signal |
+| not used. |
+| 1 : Extern gate signal |
+| used. |
+| PBYTE_ pb_InterruptEnable : Enable or disable the PWM |
+| interrupt. |
+| - APCI1710_ENABLE : |
+| Enable the PWM interrupt|
+| A interrupt occur after |
+| each period |
+| - APCI1710_DISABLE : |
+| Disable the PWM |
+| interrupt |
+| PBYTE_ pb_Enable : Indicate if the PWM is |
+| enabled or no |
+| 0 : PWM not enabled |
+| 1 : PWM enabled |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a PWM module |
+| -4: PWM selection is wrong |
+| -5: PWM not initialised see function |
+| "i_APCI1710_InitPWM" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetPWMInitialisation (comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_PWM,
+ PBYTE pb_TimingUnit,
+ PULONG pul_LowTiming,
+ PULONG pul_HighTiming,
+ PBYTE pb_StartLevel,
+ PBYTE pb_StopMode,
+ PBYTE pb_StopLevel,
+ PBYTE pb_ExternGate,
+ PBYTE pb_InterruptEnable,
+ PBYTE pb_Enable)
+ {
+ INT i_ReturnValue = 0;
+ DWORD dw_Status;
+ DWORD dw_Command;
+
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4)
+ {
+ /***************/
+ /* Test if PWM */
+ /***************/
+
+ if ((devpriv->
+ s_BoardInfos.
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_PWM)
+ {
+ /**************************/
+ /* Test the PWM selection */
+ /**************************/
+
+ if (b_PWM >= 0 && b_PWM <= 1)
+ {
+ /***************************/
+ /* Test if PWM initialised */
+ /***************************/
+
+ dw_Status=inl(devpriv->s_BoardInfos.
+ ui_Address + 12 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+ if (dw_Status & 0x10)
+ {
+ /***********************/
+ /* Read the low timing */
+ /***********************/
+
+ *pul_LowTiming = inl(devpriv->s_BoardInfos.
+ ui_Address + 0 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+ /************************/
+ /* Read the high timing */
+ /************************/
+
+ *pul_HighTiming= inl(devpriv->s_BoardInfos.
+ ui_Address + 4 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+ /********************/
+ /* Read the command */
+ /********************/
+
+ dw_Command = inl(devpriv->s_BoardInfos.
+ ui_Address + 8 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+ *pb_StartLevel = (BYTE) ((dw_Command >> 5) & 1);
+ *pb_StopMode = (BYTE) ((dw_Command >> 0) & 1);
+ *pb_StopLevel = (BYTE) ((dw_Command >> 1) & 1);
+ *pb_ExternGate = (BYTE) ((dw_Command >> 4) & 1);
+ *pb_InterruptEnable = (BYTE) ((dw_Command >> 3) & 1);
+
+ if (*pb_StopLevel)
+ {
+ *pb_StopLevel = *pb_StopLevel + (BYTE) ((dw_Command >> 2) & 1);
+ }
+
+ /********************/
+ /* Read the command */
+ /********************/
+
+ dw_Command=inl(devpriv->s_BoardInfos.
+ ui_Address + 8 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+ *pb_Enable = (BYTE) ((dw_Command >> 0) & 1);
+
+ *pb_TimingUnit = devpriv->
+ s_ModuleInfo [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo [b_PWM].
+ b_TimingUnit;
+ } // if (dw_Status & 0x10)
+ else
+ {
+ /***********************/
+ /* PWM not initialised */
+ /***********************/
+ DPRINTK("PWM not initialised\n");
+ i_ReturnValue = -5;
+ } // if (dw_Status & 0x10)
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ else
+ {
+ /******************************/
+ /* Tor PWM selection is wrong */
+ /******************************/
+ DPRINTK("Tor PWM selection is wrong\n");
+ i_ReturnValue = -4;
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ }
+ else
+ {
+ /**********************************/
+ /* The module is not a PWM module */
+ /**********************************/
+ DPRINTK("The module is not a PWM module\n");
+ i_ReturnValue = -3;
+ }
+ }
+ else
+ {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+ }
+\r
+\r
+\r
+
+
+/*
++----------------------------------------------------------------------------+
+| Function Name :INT i_APCI1710_InsnWritePWM(comedi_device *dev,
+comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Pwm Enable Disable and Set New Timing |
++----------------------------------------------------------------------------+
+| Input Parameters :
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnWritePWM(comedi_device *dev,comedi_subdevice *s,
+comedi_insn *insn,lsampl_t *data)
+{
+ BYTE b_WriteType;
+ INT i_ReturnValue=0;
+ b_WriteType=CR_CHAN(insn->chanspec);
+
+ switch(b_WriteType)
+ {
+ case APCI1710_PWM_ENABLE :
+ i_ReturnValue=i_APCI1710_EnablePWM (dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (BYTE) data[0],
+ (BYTE) data[1],
+ (BYTE) data[2],
+ (BYTE) data[3],
+ (BYTE) data[4],
+ (BYTE) data[5]);
+ break;
+
+ case APCI1710_PWM_DISABLE :
+ i_ReturnValue=i_APCI1710_DisablePWM (dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (BYTE) data[0]);
+ break;
+
+ case APCI1710_PWM_NEWTIMING:
+ i_ReturnValue=i_APCI1710_SetNewPWMTiming (dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (BYTE) data[0],
+ (BYTE) data[1],
+ (ULONG) data[2],
+ (ULONG) data[3]);
+ break;
+
+
+ default:
+ printk("Write Config Parameter Wrong\n");
+ }
+
+ if(i_ReturnValue>=0) i_ReturnValue =insn->n;
+ return (i_ReturnValue);
+}
+
+
+
+
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_EnablePWM |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_PWM, |
+| BYTE_ b_StartLevel, |
+| BYTE_ b_StopMode, |
+| BYTE_ b_StopLevel, |
+| BYTE_ b_ExternGate, |
+| BYTE_ b_InterruptEnable) |
++----------------------------------------------------------------------------+
+| Task : Enable the selected PWM (b_PWM) from selected module |
+| (b_ModulNbr). You must calling the "i_APCI1710_InitPWM"|
+| function be for you call this function. |
+| If you enable the PWM interrupt, the PWM generate a |
+| interrupt after each period. |
+| See function "i_APCI1710_SetBoardIntRoutineX" and the |
+| Interrupt mask description chapter. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number |
+| (0 to 3) |
+| BYTE_ b_PWM : Selected PWM (0 or 1) |
+| BYTE_ b_StartLevel : Start period level selection |
+| 0 : The period start with a |
+| low level |
+| 1 : The period start with a |
+| high level |
+| BYTE_ b_StopMode : Stop mode selection |
+| 0 : The PWM is stopped |
+| directly after the |
+| "i_APCI1710_DisablePWM" |
+| function and break the |
+| last period |
+| 1 : After the |
+| "i_APCI1710_DisablePWM" |
+| function the PWM is |
+| stopped at the end from|
+| last period cycle. |
+| BYTE_ b_StopLevel : Stop PWM level selection |
+| 0 : The output signal keep |
+| the level after the |
+| "i_APCI1710_DisablePWM" |
+| function |
+| 1 : The output signal is set|
+| to low after the |
+| "i_APCI1710_DisablePWM" |
+| function |
+| 2 : The output signal is set|
+| to high after the |
+| "i_APCI1710_DisablePWM" |
+| function |
+| BYTE_ b_ExternGate : Extern gate action selection |
+| 0 : Extern gate signal not |
+| used. |
+| 1 : Extern gate signal used.|
+| BYTE_ b_InterruptEnable : Enable or disable the PWM |
+| interrupt. |
+| - APCI1710_ENABLE : |
+| Enable the PWM interrupt |
+| A interrupt occur after |
+| each period |
+| - APCI1710_DISABLE : |
+| Disable the PWM interrupt |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a PWM module |
+| -4: PWM selection is wrong |
+| -5: PWM not initialised see function |
+| "i_APCI1710_InitPWM" |
+| -6: PWM start level selection is wrong |
+| -7: PWM stop mode selection is wrong |
+| -8: PWM stop level selection is wrong |
+| -9: Extern gate signal selection is wrong |
+| -10: Interrupt parameter is wrong |
+| -11: Interrupt function not initialised. |
+| See function "i_APCI1710_SetBoardIntRoutineX" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_EnablePWM (comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_PWM,
+ BYTE b_StartLevel,
+ BYTE b_StopMode,
+ BYTE b_StopLevel,
+ BYTE b_ExternGate,
+ BYTE b_InterruptEnable)
+ {
+ INT i_ReturnValue = 0;
+ DWORD dw_Status;
+ DWORD dw_Command;
+
+ devpriv->tsk_Current=current; // Save the current process task structure
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4)
+ {
+ /***************/
+ /* Test if PWM */
+ /***************/
+
+ if ((devpriv->
+ s_BoardInfos.
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_PWM)
+ {
+ /**************************/
+ /* Test the PWM selection */
+ /**************************/
+
+ if (b_PWM >= 0 && b_PWM <= 1)
+ {
+ /***************************/
+ /* Test if PWM initialised */
+ /***************************/
+
+ dw_Status= inl(devpriv->s_BoardInfos.
+ ui_Address + 12 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+ if (dw_Status & 0x10)
+ {
+ /**********************************/
+ /* Test the start level selection */
+ /**********************************/
+
+ if (b_StartLevel >= 0 && b_StartLevel <= 1)
+ {
+ /**********************/
+ /* Test the stop mode */
+ /**********************/
+
+ if (b_StopMode >= 0 && b_StopMode <= 1)
+ {
+ /***********************/
+ /* Test the stop level */
+ /***********************/
+
+ if (b_StopLevel >= 0 && b_StopLevel <= 2)
+ {
+ /*****************************/
+ /* Test the extern gate mode */
+ /*****************************/
+
+ if (b_ExternGate >= 0 && b_ExternGate <= 1)
+ {
+ /*****************************/
+ /* Test the interrupt action */
+ /*****************************/
+
+ if (b_InterruptEnable == APCI1710_ENABLE || b_InterruptEnable == APCI1710_DISABLE)
+ {
+ /******************************************/
+ /* Test if interrupt function initialised */
+ /******************************************/
+
+ /********************/
+ /* Read the command */
+ /********************/
+
+ dw_Command=inl(devpriv->s_BoardInfos.
+ ui_Address + 8 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+ dw_Command = dw_Command & 0x80;
+
+ /********************/
+ /* Make the command */
+ /********************/
+
+ dw_Command = dw_Command | b_StopMode | (b_InterruptEnable << 3) | (b_ExternGate << 4) | (b_StartLevel << 5);
+
+ if (b_StopLevel & 3)
+ {
+ dw_Command = dw_Command | 2;
+
+ if (b_StopLevel & 2)
+ {
+ dw_Command = dw_Command | 4;
+ }
+ }
+
+
+ devpriv->
+ s_ModuleInfo [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo [b_PWM].
+ b_InterruptEnable = b_InterruptEnable;
+
+ /*******************/
+ /* Set the command */
+ /*******************/
+
+ outl(dw_Command,devpriv->s_BoardInfos.
+ ui_Address + 8 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+ /******************/
+ /* Enable the PWM */
+ /******************/
+ outl(1,devpriv->s_BoardInfos.
+ ui_Address + 12 + (20 * b_PWM) + (64 * b_ModulNbr));
+ } // if (b_InterruptEnable == APCI1710_ENABLE || b_InterruptEnable == APCI1710_DISABLE)
+ else
+ {
+ /********************************/
+ /* Interrupt parameter is wrong */
+ /********************************/
+ DPRINTK("Interrupt parameter is wrong\n");
+ i_ReturnValue = -10;
+ } // if (b_InterruptEnable == APCI1710_ENABLE || b_InterruptEnable == APCI1710_DISABLE)
+ } // if (b_ExternGate >= 0 && b_ExternGate <= 1)
+ else
+ {
+ /*****************************************/
+ /* Extern gate signal selection is wrong */
+ /*****************************************/
+ DPRINTK("Extern gate signal selection is wrong\n");
+ i_ReturnValue = -9;
+ } // if (b_ExternGate >= 0 && b_ExternGate <= 1)
+ } // if (b_StopLevel >= 0 && b_StopLevel <= 2)
+ else
+ {
+ /*************************************/
+ /* PWM stop level selection is wrong */
+ /*************************************/
+ DPRINTK("PWM stop level selection is wrong\n");
+ i_ReturnValue = -8;
+ } // if (b_StopLevel >= 0 && b_StopLevel <= 2)
+ } // if (b_StopMode >= 0 && b_StopMode <= 1)
+ else
+ {
+ /************************************/
+ /* PWM stop mode selection is wrong */
+ /************************************/
+ DPRINTK("PWM stop mode selection is wrong\n");
+ i_ReturnValue = -7;
+ } // if (b_StopMode >= 0 && b_StopMode <= 1)
+ } // if (b_StartLevel >= 0 && b_StartLevel <= 1)
+ else
+ {
+ /**************************************/
+ /* PWM start level selection is wrong */
+ /**************************************/
+ DPRINTK("PWM start level selection is wrong\n");
+ i_ReturnValue = -6;
+ } // if (b_StartLevel >= 0 && b_StartLevel <= 1)
+ } // if (dw_Status & 0x10)
+ else
+ {
+ /***********************/
+ /* PWM not initialised */
+ /***********************/
+ DPRINTK("PWM not initialised\n");
+ i_ReturnValue = -5;
+ } // if (dw_Status & 0x10)
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ else
+ {
+ /******************************/
+ /* Tor PWM selection is wrong */
+ /******************************/
+ DPRINTK("Tor PWM selection is wrong\n");
+ i_ReturnValue = -4;
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ }
+ else
+ {
+ /**********************************/
+ /* The module is not a PWM module */
+ /**********************************/
+ DPRINTK("The module is not a PWM module\n");
+ i_ReturnValue = -3;
+ }
+ }
+ else
+ {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+ }
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_DisablePWM (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_PWM) |
++----------------------------------------------------------------------------+
+| Task : Disable the selected PWM (b_PWM) from selected module |
+| (b_ModulNbr). The output signal level depend of the |
+| initialisation by the "i_APCI1710_EnablePWM". |
+| See the b_StartLevel, b_StopMode and b_StopLevel |
+| parameters from this function. |
++----------------------------------------------------------------------------+
+| Input Parameters :BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3) |
+| BYTE_ b_PWM : Selected PWM (0 or 1) |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a PWM module |
+| -4: PWM selection is wrong |
+| -5: PWM not initialised see function |
+| "i_APCI1710_InitPWM" |
+| -6: PWM not enabled see function |
+| "i_APCI1710_EnablePWM" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_DisablePWM (comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_PWM)
+ {
+ INT i_ReturnValue = 0;
+ DWORD dw_Status;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4)
+ {
+ /***************/
+ /* Test if PWM */
+ /***************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_PWM)
+ {
+ /**************************/
+ /* Test the PWM selection */
+ /**************************/
+
+ if (b_PWM >= 0 && b_PWM <= 1)
+ {
+ /***************************/
+ /* Test if PWM initialised */
+ /***************************/
+
+ dw_Status=inl(devpriv->s_BoardInfos.
+ ui_Address + 12 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+ if (dw_Status & 0x10)
+ {
+ /***********************/
+ /* Test if PWM enabled */
+ /***********************/
+
+ if (dw_Status & 0x1)
+ {
+ /*******************/
+ /* Disable the PWM */
+ /*******************/
+ outl(0,devpriv->s_BoardInfos.
+ ui_Address + 12 + (20 * b_PWM) + (64 * b_ModulNbr));
+ } // if (dw_Status & 0x1)
+ else
+ {
+ /*******************/
+ /* PWM not enabled */
+ /*******************/
+ DPRINTK("PWM not enabled\n");
+ i_ReturnValue = -6;
+ } // if (dw_Status & 0x1)
+ } // if (dw_Status & 0x10)
+ else
+ {
+ /***********************/
+ /* PWM not initialised */
+ /***********************/
+ DPRINTK(" PWM not initialised\n");
+ i_ReturnValue = -5;
+ } // if (dw_Status & 0x10)
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ else
+ {
+ /******************************/
+ /* Tor PWM selection is wrong */
+ /******************************/
+ DPRINTK("Tor PWM selection is wrong\n");
+ i_ReturnValue = -4;
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ }
+ else
+ {
+ /**********************************/
+ /* The module is not a PWM module */
+ /**********************************/
+ DPRINTK("The module is not a PWM module\n");
+ i_ReturnValue = -3;
+ }
+ }
+ else
+ {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+ }
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_SetNewPWMTiming |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_PWM, |
+| BYTE_ b_ClockSelection, |
+| BYTE_ b_TimingUnit, |
+| ULONG_ ul_LowTiming, |
+| ULONG_ ul_HighTiming) |
++----------------------------------------------------------------------------+
+| Task : Set a new timing. The ul_LowTiming, ul_HighTiming and |
+| ul_TimingUnit determine the low/high timing base for |
+| the period. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure|
+| (0 to 3) |
+| BYTE_ b_PWM : Selected PWM (0 or 1). |
+| BYTE_ b_TimingUnit : Base timing Unit (0 to 4) |
+| 0 : ns |
+| 1 : æs |
+| 2 : ms |
+| 3 : s |
+| 4 : mn |
+| ULONG_ ul_LowTiming : Low base timing value. |
+| ULONG_ ul_HighTiming : High base timing value. |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a PWM module |
+| -4: PWM selection is wrong |
+| -5: PWM not initialised |
+| -6: Timing Unit selection is wrong |
+| -7: Low base timing selection is wrong |
+| -8: High base timing selection is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_SetNewPWMTiming (comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_PWM,
+ BYTE b_TimingUnit,
+ ULONG ul_LowTiming,
+ ULONG ul_HighTiming)
+ {
+ BYTE b_ClockSelection;
+ INT i_ReturnValue = 0;
+ ULONG ul_LowTimerValue;
+ ULONG ul_HighTimerValue;
+ ULONG ul_RealLowTiming;
+ ULONG ul_RealHighTiming;
+ DWORD dw_Status;
+ DWORD dw_Command;
+ double d_RealLowTiming;
+ double d_RealHighTiming;
+
+
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4)
+ {
+ /***************/
+ /* Test if PWM */
+ /***************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_PWM)
+ {
+ /**************************/
+ /* Test the PWM selection */
+ /**************************/
+
+ if (b_PWM >= 0 && b_PWM <= 1)
+ {
+ /***************************/
+ /* Test if PWM initialised */
+ /***************************/
+
+ dw_Status=inl(devpriv->s_BoardInfos.
+ ui_Address + 12 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+ if (dw_Status & 0x10)
+ {
+ b_ClockSelection = devpriv->
+ s_ModuleInfo [b_ModulNbr].
+ s_PWMModuleInfo.
+ b_ClockSelection;
+
+ /************************/
+ /* Test the timing unit */
+ /************************/
+
+ if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
+ {
+ /*********************************/
+ /* Test the low timing selection */
+ /*********************************/
+
+ if (((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 0) && (ul_LowTiming >= 266) && (ul_LowTiming <= 0xFFFFFFFFUL)) ||
+ ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 1) && (ul_LowTiming >= 1) && (ul_LowTiming <= 571230650UL)) ||
+ ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 2) && (ul_LowTiming >= 1) && (ul_LowTiming <= 571230UL)) ||
+ ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 3) && (ul_LowTiming >= 1) && (ul_LowTiming <= 571UL)) ||
+ ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 4) && (ul_LowTiming >= 1) && (ul_LowTiming <= 9UL)) ||
+ ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 0) && (ul_LowTiming >= 242) && (ul_LowTiming <= 0xFFFFFFFFUL)) ||
+ ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 1) && (ul_LowTiming >= 1) && (ul_LowTiming <= 519691043UL)) ||
+ ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 2) && (ul_LowTiming >= 1) && (ul_LowTiming <= 519691UL)) ||
+ ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 3) && (ul_LowTiming >= 1) && (ul_LowTiming <= 520UL)) ||
+ ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 4) && (ul_LowTiming >= 1) && (ul_LowTiming <= 8UL)) ||
+ ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 0) && (ul_LowTiming >= 200) && (ul_LowTiming <= 0xFFFFFFFFUL)) ||
+ ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 1) && (ul_LowTiming >= 1) && (ul_LowTiming <= 429496729UL)) ||
+ ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 2) && (ul_LowTiming >= 1) && (ul_LowTiming <= 429496UL)) ||
+ ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 3) && (ul_LowTiming >= 1) && (ul_LowTiming <= 429UL)) ||
+ ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 4) && (ul_LowTiming >= 1) && (ul_LowTiming <= 7UL)))
+ {
+ /**********************************/
+ /* Test the High timing selection */
+ /**********************************/
+
+ if (((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 266) && (ul_HighTiming <= 0xFFFFFFFFUL)) ||
+ ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571230650UL)) ||
+ ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571230UL)) ||
+ ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571UL)) ||
+ ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 9UL)) ||
+ ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 242) && (ul_HighTiming <= 0xFFFFFFFFUL)) ||
+ ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 519691043UL)) ||
+ ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 519691UL)) ||
+ ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 520UL)) ||
+ ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 8UL)) ||
+ ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 200) && (ul_HighTiming <= 0xFFFFFFFFUL)) ||
+ ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429496729UL)) ||
+ ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429496UL)) ||
+ ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429UL)) ||
+ ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 7UL)))
+ {
+ /************************************/
+ /* Calculate the low division fator */
+ /************************************/
+
+ switch (b_TimingUnit)
+ {
+ /******/
+ /* ns */
+ /******/
+
+ case 0:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_LowTimerValue = (ULONG) (ul_LowTiming * (0.00025 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double) ((double) ul_LowTiming * (0.00025 * (double) b_ClockSelection)) >= ((double) ((double) ul_LowTimerValue + 0.5)))
+ {
+ ul_LowTimerValue = ul_LowTimerValue + 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealLowTiming = (ULONG) (ul_LowTimerValue / (0.00025 * (double) b_ClockSelection));
+ d_RealLowTiming = (double) ul_LowTimerValue / (0.00025 * (double) b_ClockSelection);
+
+ if ((double) ((double) ul_LowTimerValue / (0.00025 * (double) b_ClockSelection)) >= (double) ((double) ul_RealLowTiming + 0.5))
+ {
+ ul_RealLowTiming = ul_RealLowTiming + 1;
+ }
+
+ ul_LowTiming = ul_LowTiming - 1;
+ ul_LowTimerValue = ul_LowTimerValue - 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ)
+ {
+ ul_LowTimerValue = (ULONG) ((double) (ul_LowTimerValue) * 1.007752288);
+ }
+
+
+ break;
+
+ /******/
+ /* æs */
+ /******/
+
+ case 1:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_LowTimerValue = (ULONG) (ul_LowTiming * (0.25 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double) ((double) ul_LowTiming * (0.25 * (double) b_ClockSelection)) >= ((double) ((double) ul_LowTimerValue + 0.5)))
+ {
+ ul_LowTimerValue = ul_LowTimerValue + 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealLowTiming = (ULONG) (ul_LowTimerValue / (0.25 * (double) b_ClockSelection));
+ d_RealLowTiming = (double) ul_LowTimerValue / ((double) 0.25 * (double) b_ClockSelection);
+
+ if ((double) ((double) ul_LowTimerValue / (0.25 * (double) b_ClockSelection)) >= (double) ((double) ul_RealLowTiming + 0.5))
+ {
+ ul_RealLowTiming = ul_RealLowTiming + 1;
+ }
+
+ ul_LowTiming = ul_LowTiming - 1;
+ ul_LowTimerValue = ul_LowTimerValue - 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ)
+ {
+ ul_LowTimerValue = (ULONG) ((double) (ul_LowTimerValue) * 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* ms */
+ /******/
+
+ case 2:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_LowTimerValue = ul_LowTiming * (250.0 * b_ClockSelection);
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double) ((double) ul_LowTiming * (250.0 * (double) b_ClockSelection)) >= ((double) ((double) ul_LowTimerValue + 0.5)))
+ {
+ ul_LowTimerValue = ul_LowTimerValue + 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealLowTiming = (ULONG) (ul_LowTimerValue / (250.0 * (double) b_ClockSelection));
+ d_RealLowTiming = (double) ul_LowTimerValue / (250.0 * (double) b_ClockSelection);
+
+ if ((double) ((double) ul_LowTimerValue / (250.0 * (double) b_ClockSelection)) >= (double) ((double) ul_RealLowTiming + 0.5))
+ {
+ ul_RealLowTiming = ul_RealLowTiming + 1;
+ }
+
+ ul_LowTiming = ul_LowTiming - 1;
+ ul_LowTimerValue = ul_LowTimerValue - 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ)
+ {
+ ul_LowTimerValue = (ULONG) ((double) (ul_LowTimerValue) * 1.007752288);
+ }
+
+ break;
+
+ /*****/
+ /* s */
+ /*****/
+
+ case 3:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_LowTimerValue = (ULONG) (ul_LowTiming * (250000.0 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double) ((double) ul_LowTiming * (250000.0 * (double) b_ClockSelection)) >= ((double) ((double) ul_LowTimerValue + 0.5)))
+ {
+ ul_LowTimerValue = ul_LowTimerValue + 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealLowTiming = (ULONG) (ul_LowTimerValue / (250000.0 * (double) b_ClockSelection));
+ d_RealLowTiming = (double) ul_LowTimerValue / (250000.0 * (double) b_ClockSelection);
+
+ if ((double) ((double) ul_LowTimerValue / (250000.0 * (double) b_ClockSelection)) >= (double) ((double) ul_RealLowTiming + 0.5))
+ {
+ ul_RealLowTiming = ul_RealLowTiming + 1;
+ }
+
+ ul_LowTiming = ul_LowTiming - 1;
+ ul_LowTimerValue = ul_LowTimerValue - 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ)
+ {
+ ul_LowTimerValue = (ULONG) ((double) (ul_LowTimerValue) * 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* mn */
+ /******/
+
+ case 4:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_LowTimerValue = (ULONG) ((ul_LowTiming * 60) * (250000.0 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double) ((double) (ul_LowTiming * 60.0) * (250000.0 * (double) b_ClockSelection)) >= ((double) ((double) ul_LowTimerValue + 0.5)))
+ {
+ ul_LowTimerValue = ul_LowTimerValue + 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealLowTiming = (ULONG) (ul_LowTimerValue / (250000.0 * (double) b_ClockSelection)) / 60;
+ d_RealLowTiming = ((double) ul_LowTimerValue / (250000.0 * (double) b_ClockSelection)) / 60.0;
+
+ if ((double) (((double) ul_LowTimerValue / (250000.0 * (double) b_ClockSelection)) / 60.0) >= (double) ((double) ul_RealLowTiming + 0.5))
+ {
+ ul_RealLowTiming = ul_RealLowTiming + 1;
+ }
+
+ ul_LowTiming = ul_LowTiming - 1;
+ ul_LowTimerValue = ul_LowTimerValue - 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ)
+ {
+ ul_LowTimerValue = (ULONG) ((double) (ul_LowTimerValue) * 1.007752288);
+ }
+
+ break;
+ }
+
+ /*************************************/
+ /* Calculate the high division fator */
+ /*************************************/
+
+ switch (b_TimingUnit)
+ {
+ /******/
+ /* ns */
+ /******/
+
+ case 0:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_HighTimerValue = (ULONG) (ul_HighTiming * (0.00025 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double) ((double) ul_HighTiming * (0.00025 * (double) b_ClockSelection)) >= ((double) ((double) ul_HighTimerValue + 0.5)))
+ {
+ ul_HighTimerValue = ul_HighTimerValue + 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealHighTiming = (ULONG) (ul_HighTimerValue / (0.00025 * (double) b_ClockSelection));
+ d_RealHighTiming = (double) ul_HighTimerValue / (0.00025 * (double) b_ClockSelection);
+
+ if ((double) ((double) ul_HighTimerValue / (0.00025 * (double) b_ClockSelection)) >= (double) ((double) ul_RealHighTiming + 0.5))
+ {
+ ul_RealHighTiming = ul_RealHighTiming + 1;
+ }
+
+ ul_HighTiming = ul_HighTiming - 1;
+ ul_HighTimerValue = ul_HighTimerValue - 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ)
+ {
+ ul_HighTimerValue = (ULONG) ((double) (ul_HighTimerValue) * 1.007752288);
+ }
+
+
+ break;
+
+ /******/
+ /* æs */
+ /******/
+
+ case 1:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_HighTimerValue = (ULONG) (ul_HighTiming * (0.25 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double) ((double) ul_HighTiming * (0.25 * (double) b_ClockSelection)) >= ((double) ((double) ul_HighTimerValue + 0.5)))
+ {
+ ul_HighTimerValue = ul_HighTimerValue + 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealHighTiming = (ULONG) (ul_HighTimerValue / (0.25 * (double) b_ClockSelection));
+ d_RealHighTiming = (double) ul_HighTimerValue / ((double) 0.25 * (double) b_ClockSelection);
+
+ if ((double) ((double) ul_HighTimerValue / (0.25 * (double) b_ClockSelection)) >= (double) ((double) ul_RealHighTiming + 0.5))
+ {
+ ul_RealHighTiming = ul_RealHighTiming + 1;
+ }
+
+ ul_HighTiming = ul_HighTiming - 1;
+ ul_HighTimerValue = ul_HighTimerValue - 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ)
+ {
+ ul_HighTimerValue = (ULONG) ((double) (ul_HighTimerValue) * 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* ms */
+ /******/
+
+ case 2:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_HighTimerValue = ul_HighTiming * (250.0 * b_ClockSelection);
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double) ((double) ul_HighTiming * (250.0 * (double) b_ClockSelection)) >= ((double) ((double) ul_HighTimerValue + 0.5)))
+ {
+ ul_HighTimerValue = ul_HighTimerValue + 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealHighTiming = (ULONG) (ul_HighTimerValue / (250.0 * (double) b_ClockSelection));
+ d_RealHighTiming = (double) ul_HighTimerValue / (250.0 * (double) b_ClockSelection);
+
+ if ((double) ((double) ul_HighTimerValue / (250.0 * (double) b_ClockSelection)) >= (double) ((double) ul_RealHighTiming + 0.5))
+ {
+ ul_RealHighTiming = ul_RealHighTiming + 1;
+ }
+
+ ul_HighTiming = ul_HighTiming - 1;
+ ul_HighTimerValue = ul_HighTimerValue - 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ)
+ {
+ ul_HighTimerValue = (ULONG) ((double) (ul_HighTimerValue) * 1.007752288);
+ }
+
+ break;
+
+ /*****/
+ /* s */
+ /*****/
+
+ case 3:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_HighTimerValue = (ULONG) (ul_HighTiming * (250000.0 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double) ((double) ul_HighTiming * (250000.0 * (double) b_ClockSelection)) >= ((double) ((double) ul_HighTimerValue + 0.5)))
+ {
+ ul_HighTimerValue = ul_HighTimerValue + 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealHighTiming = (ULONG) (ul_HighTimerValue / (250000.0 * (double) b_ClockSelection));
+ d_RealHighTiming = (double) ul_HighTimerValue / (250000.0 * (double) b_ClockSelection);
+
+ if ((double) ((double) ul_HighTimerValue / (250000.0 * (double) b_ClockSelection)) >= (double) ((double) ul_RealHighTiming + 0.5))
+ {
+ ul_RealHighTiming = ul_RealHighTiming + 1;
+ }
+
+ ul_HighTiming = ul_HighTiming - 1;
+ ul_HighTimerValue = ul_HighTimerValue - 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ)
+ {
+ ul_HighTimerValue = (ULONG) ((double) (ul_HighTimerValue) * 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* mn */
+ /******/
+
+ case 4:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_HighTimerValue = (ULONG) ((ul_HighTiming * 60) * (250000.0 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double) ((double) (ul_HighTiming * 60.0) * (250000.0 * (double) b_ClockSelection)) >= ((double) ((double) ul_HighTimerValue + 0.5)))
+ {
+ ul_HighTimerValue = ul_HighTimerValue + 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealHighTiming = (ULONG) (ul_HighTimerValue / (250000.0 * (double) b_ClockSelection)) / 60;
+ d_RealHighTiming = ((double) ul_HighTimerValue / (250000.0 * (double) b_ClockSelection)) / 60.0;
+
+ if ((double) (((double) ul_HighTimerValue / (250000.0 * (double) b_ClockSelection)) / 60.0) >= (double) ((double) ul_RealHighTiming + 0.5))
+ {
+ ul_RealHighTiming = ul_RealHighTiming + 1;
+ }
+
+ ul_HighTiming = ul_HighTiming - 1;
+ ul_HighTimerValue = ul_HighTimerValue - 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ)
+ {
+ ul_HighTimerValue = (ULONG) ((double) (ul_HighTimerValue) * 1.007752288);
+ }
+
+ break;
+ }
+ /************************/
+ /* Save the timing unit */
+ /************************/
+
+ devpriv->
+ s_ModuleInfo [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo [b_PWM].
+ b_TimingUnit = b_TimingUnit;
+
+ /****************************/
+ /* Save the low base timing */
+ /****************************/
+
+ devpriv->
+ s_ModuleInfo [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo [b_PWM].
+ d_LowTiming = d_RealLowTiming;
+
+ devpriv->
+ s_ModuleInfo [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo [b_PWM].
+ ul_RealLowTiming = ul_RealLowTiming;
+
+ /****************************/
+ /* Save the high base timing */
+ /****************************/
+
+ devpriv->
+ s_ModuleInfo [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo [b_PWM].
+ d_HighTiming = d_RealHighTiming;
+
+ devpriv->
+ s_ModuleInfo [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo [b_PWM].
+ ul_RealHighTiming = ul_RealHighTiming;
+
+ /************************/
+ /* Write the low timing */
+ /************************/
+
+ outl(ul_LowTimerValue,devpriv->s_BoardInfos.
+ ui_Address + 0 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+ /*************************/
+ /* Write the high timing */
+ /*************************/
+
+ outl(ul_HighTimerValue,devpriv->s_BoardInfos.
+ ui_Address + 4 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+ /***************************/
+ /* Set the clock selection */
+ /***************************/
+
+ dw_Command=inl(devpriv->s_BoardInfos.
+ ui_Address + 8 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+ dw_Command = dw_Command & 0x7F;
+
+ if (b_ClockSelection == APCI1710_40MHZ)
+ {
+ dw_Command = dw_Command | 0x80;
+ }
+
+ /***************************/
+ /* Set the clock selection */
+ /***************************/
+
+ outl(dw_Command,devpriv->s_BoardInfos.
+ ui_Address + 8 + (20 * b_PWM) + (64 * b_ModulNbr));
+ }
+ else
+ {
+ /***************************************/
+ /* High base timing selection is wrong */
+ /***************************************/
+ DPRINTK("High base timing selection is wrong\n");
+ i_ReturnValue = -8;
+ }
+ }
+ else
+ {
+ /**************************************/
+ /* Low base timing selection is wrong */
+ /**************************************/
+ DPRINTK("Low base timing selection is wrong\n");
+ i_ReturnValue = -7;
+ }
+ } // if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
+ else
+ {
+ /**********************************/
+ /* Timing unit selection is wrong */
+ /**********************************/
+ DPRINTK("Timing unit selection is wrong\n");
+ i_ReturnValue = -6;
+ } // if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
+ } // if (dw_Status & 0x10)
+ else
+ {
+ /***********************/
+ /* PWM not initialised */
+ /***********************/
+ DPRINTK("PWM not initialised\n");
+ i_ReturnValue = -5;
+ } // if (dw_Status & 0x10)
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ else
+ {
+ /******************************/
+ /* Tor PWM selection is wrong */
+ /******************************/
+ DPRINTK("Tor PWM selection is wrong\n");
+ i_ReturnValue = -4;
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ }
+ else
+ {
+ /**********************************/
+ /* The module is not a PWM module */
+ /**********************************/
+ DPRINTK("The module is not a PWM module\n");
+ i_ReturnValue = -3;
+ }
+ }
+ else
+ {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+ }
+
+
+\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_GetPWMStatus |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_PWM, |\r
+| PBYTE_ pb_PWMOutputStatus, |\r
+| PBYTE_ pb_ExternGateStatus) |\r
++----------------------------------------------------------------------------+\r
+| Task : Return the status from selected PWM (b_PWM) from |\r
+| selected module (b_ModulNbr). |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_PWM : Selected PWM (0 or 1) |\r
+| BYTE_ b_ModulNbr : Selected module number (0 to 3)\r
+ b_ModulNbr =(BYTE) CR_AREF(insn->chanspec);\r
+ b_PWM =(BYTE) data[0];\r
+ \r
+ |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : PBYTE_ pb_PWMOutputStatus : Return the PWM output |\r
+| level status. |\r
+| 0 : The PWM output level|\r
+| is low. |\r
+| 1 : The PWM output level|\r
+| is high. |\r
+| PBYTE_ pb_ExternGateStatus : Return the extern gate |\r
+| level status. |\r
+| 0 : The extern gate is |\r
+| low. |\r
+| 1 : The extern gate is |\r
+| high. \r
+ pb_PWMOutputStatus =(PBYTE) data[0];\r
+ pb_ExternGateStatus =(PBYTE) data[1]; |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: Module selection wrong |\r
+| -3: The module is not a PWM module |\r
+| -4: PWM selection is wrong |\r
+| -5: PWM not initialised see function |\r
+| "i_APCI1710_InitPWM" |\r
+| -6: PWM not enabled see function "i_APCI1710_EnablePWM"|\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_InsnReadGetPWMStatus(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ DWORD dw_Status;\r
+\r
+ BYTE b_ModulNbr;\r
+ BYTE b_PWM;\r
+ PBYTE pb_PWMOutputStatus;\r
+ PBYTE pb_ExternGateStatus;\r
+ \r
+ i_ReturnValue = insn->n;\r
+ b_ModulNbr =(BYTE) CR_AREF(insn->chanspec);\r
+ b_PWM =(BYTE) CR_CHAN(insn->chanspec);\r
+ pb_PWMOutputStatus =(PBYTE) &data[0];\r
+ pb_ExternGateStatus =(PBYTE) &data[1];\r
+\r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /***************/\r
+ /* Test if PWM */\r
+ /***************/\r
+\r
+ if ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_PWM)\r
+ {\r
+ /**************************/\r
+ /* Test the PWM selection */\r
+ /**************************/\r
+\r
+ if (b_PWM >= 0 && b_PWM <= 1)\r
+ {\r
+ /***************************/\r
+ /* Test if PWM initialised */\r
+ /***************************/\r
+\r
+ dw_Status=inl(devpriv->s_BoardInfos.\r
+ ui_Address + 12 + (20 * b_PWM) + (64 * b_ModulNbr));\r
+\r
+ if (dw_Status & 0x10)\r
+ {\r
+ /***********************/\r
+ /* Test if PWM enabled */\r
+ /***********************/\r
+\r
+ if (dw_Status & 0x1)\r
+ {\r
+ *pb_PWMOutputStatus = (BYTE) ((dw_Status >> 7) & 1);\r
+ *pb_ExternGateStatus = (BYTE) ((dw_Status >> 6) & 1);\r
+ } // if (dw_Status & 0x1)\r
+ else\r
+ {\r
+ /*******************/\r
+ /* PWM not enabled */\r
+ /*******************/\r
+\r DPRINTK("PWM not enabled \n");
+ i_ReturnValue = -6;\r
+ } // if (dw_Status & 0x1)\r
+ } // if (dw_Status & 0x10)\r
+ else\r
+ {\r
+ /***********************/\r
+ /* PWM not initialised */\r
+ /***********************/\r
+\r DPRINTK("PWM not initialised\n");
+ i_ReturnValue = -5;\r
+ } // if (dw_Status & 0x10)\r
+ } // if (b_PWM >= 0 && b_PWM <= 1)\r
+ else\r
+ {\r
+ /******************************/\r
+ /* Tor PWM selection is wrong */\r
+ /******************************/\r
+\r DPRINTK("Tor PWM selection is wrong\n");
+ i_ReturnValue = -4;\r
+ } // if (b_PWM >= 0 && b_PWM <= 1)\r
+ }\r
+ else\r
+ {\r
+ /**********************************/\r
+ /* The module is not a PWM module */\r
+ /**********************************/\r
+\r DPRINTK("The module is not a PWM module\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***********************/\r
+ /* Module number error */\r
+ /***********************/\r
+\r DPRINTK("Module number error\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+
+INT i_APCI1710_InsnBitsReadPWMInterrupt(comedi_device *dev,comedi_subdevice *s,
+ comedi_insn *insn,lsampl_t *data)
+{
+ data[0]=devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Read].b_OldModuleMask;
+ data[1]=devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Read].ul_OldInterruptMask;
+ data[2]=devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Read].ul_OldCounterLatchValue;
+
+
+ /**************************/
+ /* Increment the read FIFO */
+ /***************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Read = (devpriv->
+ s_InterruptParameters.
+ ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
+
+ return insn->n;
+
+}
--- /dev/null
+\r
+\r
+
+\r
+
+ #define APCI1710_30MHZ 30\r
+ #define APCI1710_33MHZ 33\r
+ #define APCI1710_40MHZ 40\r
+
+\r
+#define APCI1710_PWM_INIT 0\r
+#define APCI1710_PWM_GETINITDATA 1\r
+\r
+#define APCI1710_PWM_DISABLE 0\r
+#define APCI1710_PWM_ENABLE 1\r
+#define APCI1710_PWM_NEWTIMING 2 \r
+
+
+\r
+
+INT i_APCI1710_InsnConfigPWM(comedi_device *dev,comedi_subdevice *s,
+comedi_insn *insn,lsampl_t *data);
+
+INT i_APCI1710_InitPWM (comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_PWM,
+ BYTE b_ClockSelection,
+ BYTE b_TimingUnit,
+ ULONG ul_LowTiming,
+ ULONG ul_HighTiming,
+ PULONG pul_RealLowTiming,
+ PULONG pul_RealHighTiming);
+
+INT i_APCI1710_GetPWMInitialisation (comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_PWM,
+ PBYTE pb_TimingUnit,
+ PULONG pul_LowTiming,
+ PULONG pul_HighTiming,
+ PBYTE pb_StartLevel,
+ PBYTE pb_StopMode,
+ PBYTE pb_StopLevel,
+ PBYTE pb_ExternGate,
+ PBYTE pb_InterruptEnable,
+ PBYTE pb_Enable);
+
+
+
+
+INT i_APCI1710_InsnWritePWM(comedi_device *dev,comedi_subdevice *s,
+comedi_insn *insn,lsampl_t *data);
+
+INT i_APCI1710_EnablePWM (comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_PWM,
+ BYTE b_StartLevel,
+ BYTE b_StopMode,
+ BYTE b_StopLevel,
+ BYTE b_ExternGate,
+ BYTE b_InterruptEnable);
+
+INT i_APCI1710_SetNewPWMTiming (comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_PWM,
+ BYTE b_TimingUnit,
+ ULONG ul_LowTiming,
+ ULONG ul_HighTiming);
+
+INT i_APCI1710_DisablePWM (comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_PWM);
+\r
+INT i_APCI1710_InsnReadGetPWMStatus(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data);\r
+
+INT i_APCI1710_InsnBitsReadPWMInterrupt(comedi_device *dev,comedi_subdevice *s,
+ comedi_insn *insn,lsampl_t *data);
+\r
--- /dev/null
+/*\r
+ +-----------------------------------------------------------------------+\r
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |\r
+ +-----------------------------------------------------------------------+\r
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |\r
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |\r
+ +-----------------------------------------------------------------------+\r
+ | Project : API APCI1710 | Compiler : BORLANDC/MICROSOFT C |\r
+ | Module name : SSI.C | Version : 3.1 / 6.0 |\r
+ +-------------------------------+---------------------------------------+\r
+ | Author : S.WEBER | Date : 14.01.98 |\r
+ +-----------------------------------------------------------------------+\r
+ | Description : APCI-1710 SSI counter module |\r
+ | |\r
+ | |\r
+ +-----------------------------------------------------------------------+\r
+ | UPDATES |\r
+ +-----------------------------------------------------------------------+\r
+ | Date | Author | Description of updates |\r
+ +----------+-----------+------------------------------------------------+\r
+ | 13/05/98 | S. Weber | SSI digital input / output implementation |\r
+ |----------|-----------|------------------------------------------------|\r
+ | 22/03/00 | C.Guinot | 0100/0226 -> 0200/0227 |\r
+ | | | Änderung in InitSSI Funktion |\r
+ | | | b_SSIProfile >= 2 anstatt b_SSIProfile > 2 |\r
+ | | | |\r
+ +-----------------------------------------------------------------------+\r
+ | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |\r
+ | | | available |\r
+ +-----------------------------------------------------------------------+\r
+*/\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Included files |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+\r
+#include "APCI1710_Ssi.h"\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_InitSSI |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_SSIProfile, |\r
+| BYTE_ b_PositionTurnLength, |\r
+| BYTE_ b_TurnCptLength, |\r
+| BYTE_ b_PCIInputClock, |\r
+| ULONG_ ul_SSIOutputClock, |\r
+| BYTE_ b_SSICountingMode) |\r
++----------------------------------------------------------------------------+\r
+| Task : Configure the SSI operating mode from selected module |\r
+| (b_ModulNbr). You must calling this function be for you|\r
+| call any other function witch access of SSI. |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|\r
+| BYTE_ b_ModulNbr : Module number to |\r
+| configure (0 to 3) |\r
+| BYTE_ b_SSIProfile : Selection from SSI |\r
+| profile length (2 to 32).|\r
+| BYTE_ b_PositionTurnLength : Selection from SSI |\r
+| position data length |\r
+| (1 to 31). |\r
+| BYTE_ b_TurnCptLength : Selection from SSI turn |\r
+| counter data length |\r
+| (1 to 31). |\r
+| BYTE b_PCIInputClock : Selection from PCI bus |\r
+| clock |\r
+| - APCI1710_30MHZ : |\r
+| The PC have a PCI bus |\r
+| clock from 30 MHz |\r
+| - APCI1710_33MHZ : |\r
+| The PC have a PCI bus |\r
+| clock from 33 MHz |\r
+| ULONG_ ul_SSIOutputClock : Selection from SSI output|\r
+| clock. |\r
+| From 229 to 5 000 000 Hz|\r
+| for 30 MHz selection. |\r
+| From 252 to 5 000 000 Hz|\r
+| for 33 MHz selection. |\r
+| BYTE b_SSICountingMode : SSI counting mode |\r
+| selection |\r
+| - APCI1710_BINARY_MODE : |\r
+| Binary counting mode. |\r
+| - APCI1710_GRAY_MODE : |\r
+| Gray counting mode.\r
+\r
+ b_ModulNbr = CR_AREF(insn->chanspec);\r
+ b_SSIProfile = (BYTE) data[0]; \r
+ b_PositionTurnLength= (BYTE) data[1]; \r
+ b_TurnCptLength = (BYTE) data[2];\r
+ b_PCIInputClock = (BYTE) data[3];\r
+ ul_SSIOutputClock = (ULONG) data[4];\r
+ b_SSICountingMode = (BYTE) data[5]; |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: The module parameter is wrong |\r
+| -3: The module is not a SSI module |\r
+| -4: The selected SSI profile length is wrong |\r
+| -5: The selected SSI position data length is wrong |\r
+| -6: The selected SSI turn counter data length is wrong |\r
+| -7: The selected PCI input clock is wrong |\r
+| -8: The selected SSI output clock is wrong |\r
+| -9: The selected SSI counting mode parameter is wrong |\r
++----------------------------------------------------------------------------+\r
+*/\r
+
+\r
+INT i_APCI1710_InsnConfigInitSSI(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ UINT ui_TimerValue;\r
+ BYTE b_ModulNbr,b_SSIProfile,b_PositionTurnLength,b_TurnCptLength,b_PCIInputClock,b_SSICountingMode;\r
+ ULONG ul_SSIOutputClock;\r
+ \r
+ b_ModulNbr = CR_AREF(insn->chanspec);\r
+ b_SSIProfile = (BYTE) data[0]; \r
+ b_PositionTurnLength= (BYTE) data[1]; \r
+ b_TurnCptLength = (BYTE) data[2];\r
+ b_PCIInputClock = (BYTE) data[3];\r
+ ul_SSIOutputClock = (ULONG) data[4];\r
+ b_SSICountingMode = (BYTE) data[5];\r
+\r
+ i_ReturnValue = insn->n;\r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /***********************/\r
+ /* Test if SSI counter */\r
+ /***********************/\r
+\r
+ if ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_SSI_COUNTER)\r
+ {\r
+ /*******************************/\r
+ /* Test the SSI profile length */\r
+ /*******************************/\r
+\r
+ // CG 22/03/00 b_SSIProfile >= 2 anstatt b_SSIProfile > 2\r
+ if (b_SSIProfile >= 2 && b_SSIProfile < 33)\r
+ {\r
+ /*************************************/\r
+ /* Test the SSI position data length */\r
+ /*************************************/\r
+\r
+ if (b_PositionTurnLength > 0 && b_PositionTurnLength < 32)\r
+ {\r
+ /*****************************************/\r
+ /* Test the SSI turn counter data length */\r
+ /*****************************************/\r
+\r
+ if (b_TurnCptLength > 0 && b_TurnCptLength < 32)\r
+ {\r
+ /***************************/\r
+ /* Test the profile length */\r
+ /***************************/\r
+\r
+ if ((b_TurnCptLength + b_PositionTurnLength) <= b_SSIProfile)\r
+ {\r
+ /****************************/\r
+ /* Test the PCI input clock */\r
+ /****************************/\r
+\r
+ if (b_PCIInputClock == APCI1710_30MHZ || b_PCIInputClock == APCI1710_33MHZ)\r
+ {\r
+ /*************************/\r
+ /* Test the output clock */\r
+ /*************************/\r
+\r
+ if ((b_PCIInputClock == APCI1710_30MHZ &&\r
+ (ul_SSIOutputClock > 228 && ul_SSIOutputClock <= 5000000UL)) ||\r
+ (b_PCIInputClock == APCI1710_33MHZ &&\r
+ (ul_SSIOutputClock > 251 && ul_SSIOutputClock <= 5000000UL)))\r
+ {\r
+ if (b_SSICountingMode == APCI1710_BINARY_MODE ||\r
+ b_SSICountingMode == APCI1710_GRAY_MODE)\r
+ {\r
+ /**********************/\r
+ /* Save configuration */\r
+ /**********************/\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SSICounterInfo.\r
+ b_SSIProfile = b_SSIProfile;\r
+\r
+ \r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SSICounterInfo.\r
+ b_PositionTurnLength = b_PositionTurnLength;\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SSICounterInfo.\r
+ b_TurnCptLength = b_TurnCptLength;\r
+\r
+ /*********************************/\r
+ /* Initialise the profile length */\r
+ /*********************************/\r
+\r
+ if (b_SSICountingMode == APCI1710_BINARY_MODE)\r
+ {\r
+
+ outl(b_SSIProfile + 1,devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr));\r
+ }\r
+ else\r
+ {\r
+
+ outl(b_SSIProfile,devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr));\r
+ }\r
+\r
+ /******************************/\r
+ /* Calculate the output clock */\r
+ /******************************/\r
+\r
+ ui_TimerValue = (UINT) (((ULONG) (b_PCIInputClock) * 500000UL) / ul_SSIOutputClock);\r
+\r
+ /************************/\r
+ /* Initialise the timer */\r
+ /************************/\r
+\r
+ \r
+ outl(ui_TimerValue,devpriv->s_BoardInfos.ui_Address + (64 * b_ModulNbr));\r
+\r
+\r
+ /********************************/\r
+ /* Initialise the counting mode */\r
+ /********************************/\r
+ \r
+ outl(7 * b_SSICountingMode,devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr));\r
+ \r
+ devpriv->s_ModuleInfo [b_ModulNbr].s_SSICounterInfo.b_SSIInit = 1;\r
+ }\r
+ else\r
+ {\r
+ /*****************************************************/\r
+ /* The selected SSI counting mode parameter is wrong */\r
+ /*****************************************************/\r
+\r DPRINTK("The selected SSI counting mode parameter is wrong\n");
+ i_ReturnValue = -9;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /******************************************/\r
+ /* The selected SSI output clock is wrong */\r
+ /******************************************/\r
+\r DPRINTK("The selected SSI output clock is wrong\n");
+ i_ReturnValue = -8;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*****************************************/\r
+ /* The selected PCI input clock is wrong */\r
+ /*****************************************/\r
+\r DPRINTK("The selected PCI input clock is wrong\n");
+ i_ReturnValue = -7;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /********************************************/\r
+ /* The selected SSI profile length is wrong */\r
+ /********************************************/\r
+\r DPRINTK("The selected SSI profile length is wrong\n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /******************************************************/\r
+ /* The selected SSI turn counter data length is wrong */\r
+ /******************************************************/\r
+\r DPRINTK("The selected SSI turn counter data length is wrong\n");
+ i_ReturnValue = -6;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /**************************************************/\r
+ /* The selected SSI position data length is wrong */\r
+ /**************************************************/\r
+\r DPRINTK("The selected SSI position data length is wrong\n");
+ i_ReturnValue = -5;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /********************************************/\r
+ /* The selected SSI profile length is wrong */\r
+ /********************************************/\r
+\r DPRINTK("The selected SSI profile length is wrong\n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /**********************************/\r
+ /* The module is not a SSI module */\r
+ /**********************************/\r
+\r DPRINTK("The module is not a SSI module\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***********************/\r
+ /* Module number error */\r
+ /***********************/\r
+\r DPRINTK("Module number error\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_Read1SSIValue |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_SelectedSSI, |\r
+| PULONG_ pul_Position, |\r
+| PULONG_ pul_TurnCpt) \r
+ INT i_APCI1710_ReadSSIValue(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data) |\r
++----------------------------------------------------------------------------+\r
+| Task :\r
+\r
+ \r
+ Read the selected SSI counter (b_SelectedSSI) from |\r
+| selected module (b_ModulNbr).\r
+ or Read all SSI counter (b_SelectedSSI) from |\r
+| selected module (b_ModulNbr). |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|\r
+| BYTE_ b_ModulNbr : Module number to |\r
+| configure (0 to 3) |\r
+| BYTE_ b_SelectedSSI : Selection from SSI |\r
+| counter (0 to 2) \r
+\r
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);\r
+ b_SelectedSSI = (BYTE) CR_CHAN(insn->chanspec); (in case of single ssi)\r
+ b_ReadType = (BYTE) CR_RANGE(insn->chanspec);\r
+|\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : PULONG_ pul_Position : SSI position in the turn |\r
+| PULONG_ pul_TurnCpt : Number of turns \r
+\r
+pul_Position = (PULONG) &data[0];\r
+ pul_TurnCpt = (PULONG) &data[1]; |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: The module parameter is wrong |\r
+| -3: The module is not a SSI module |\r
+| -4: SSI not initialised see function |\r
+| "i_APCI1710_InitSSI" |\r
+| -5: The selected SSI is wrong |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+ INT i_APCI1710_InsnReadSSIValue(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ BYTE b_Cpt;\r
+ BYTE b_Length;\r
+ BYTE b_Schift;\r
+ BYTE b_SSICpt;\r
+ DWORD dw_And;\r
+ DWORD dw_And1;\r
+ DWORD dw_And2;\r
+ DWORD dw_StatusReg;\r
+ DWORD dw_CounterValue;\r
+ BYTE b_ModulNbr;\r
+ BYTE b_SelectedSSI;\r
+ BYTE b_ReadType;\r
+ PULONG pul_Position;\r
+ PULONG pul_TurnCpt;\r
+ PULONG pul_Position1;
+ PULONG pul_TurnCpt1;
+
+\r
+ i_ReturnValue = insn->n; \r
+ pul_Position1 = (PULONG) &data[0];\r// For Read1
+ pul_TurnCpt1 = (PULONG) &data[1];\r// For Read all
+ pul_Position = (PULONG) &data[0];//0-2
+ pul_TurnCpt = (PULONG) &data[3];//3-5
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);\r
+ b_SelectedSSI = (BYTE) CR_CHAN(insn->chanspec);\r
+ b_ReadType = (BYTE) CR_RANGE(insn->chanspec);\r
+\r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /***********************/\r
+ /* Test if SSI counter */\r
+ /***********************/\r
+\r
+ if ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_SSI_COUNTER)\r
+ {\r
+ /***************************/\r
+ /* Test if SSI initialised */\r
+ /***************************/\r
+\r
+ if (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SSICounterInfo.\r
+ b_SSIInit == 1)\r
+ {\r
+ \r
+ switch(b_ReadType)\r
+ {\r
+\r
+ case APCI1710_SSI_READ1VALUE :\r
+ /****************************************/\r
+ /* Test the selected SSI counter number */\r
+ /****************************************/\r
+\r
+ if (b_SelectedSSI < 3)\r
+ {\r
+ /************************/\r
+ /* Start the conversion */\r
+ /************************/\r
+\r\r
+ outl(0,devpriv->s_BoardInfos.ui_Address + 8 + (64 * b_ModulNbr));\r
+ \r
+\r
+ do\r
+ {\r
+ /*******************/\r
+ /* Read the status */\r
+ /*******************/\r
+ \r
+ dw_StatusReg = inl(devpriv->s_BoardInfos.ui_Address + (64 * b_ModulNbr));\r
+ }\r
+ while ((dw_StatusReg & 0x1) != 0);\r
+\r
+ /******************************/\r
+ /* Read the SSI counter value */\r
+ /******************************/\r
+
+ dw_CounterValue = inl(devpriv->s_BoardInfos.ui_Address + 4 + (b_SelectedSSI * 4) + (64 * b_ModulNbr));\r
+\r
+ b_Length = devpriv->s_ModuleInfo [b_ModulNbr].s_SSICounterInfo.b_SSIProfile / 2;\r
+\r
+ if ((b_Length * 2) != devpriv->s_ModuleInfo [b_ModulNbr].s_SSICounterInfo.b_SSIProfile)\r
+ {\r
+ b_Length ++;\r
+ }\r
+\r
+ b_Schift = b_Length - devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SSICounterInfo.\r
+ b_PositionTurnLength;\r
+\r
+\r
+ *pul_Position1 = dw_CounterValue >> b_Schift;\r
+\r
+ dw_And = 1;\r
+\r
+ for (b_Cpt = 0; b_Cpt < devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SSICounterInfo.\r
+ b_PositionTurnLength; b_Cpt ++)\r
+ {\r
+ dw_And = dw_And * 2;\r
+ }\r
+\r
+ *pul_Position1 = *pul_Position1 & ((dw_And) - 1);\r
+\r
+ *pul_TurnCpt1 = dw_CounterValue >> b_Length;\r
+\r
+ dw_And = 1;\r
+\r
+ for (b_Cpt = 0; b_Cpt < devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SSICounterInfo.\r
+ b_TurnCptLength; b_Cpt ++)\r
+ {\r
+ dw_And = dw_And * 2;\r
+ }\r
+\r
+ *pul_TurnCpt1 = *pul_TurnCpt1 & ((dw_And) - 1);\r
+ }\r
+ else\r
+ {\r
+ /*****************************/\r
+ /* The selected SSI is wrong */\r
+ /*****************************/\r
+\r DPRINTK("The selected SSI is wrong\n");
+ i_ReturnValue = -5;\r
+ }\r
+ break;\r
+\r
+ case APCI1710_SSI_READALLVALUE :\r
+ dw_And1 = 1;\r
+\r
+ for (b_Cpt = 0; b_Cpt < devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SSICounterInfo.\r
+ b_PositionTurnLength; b_Cpt ++)\r
+ {\r
+ dw_And1 = dw_And1 * 2;\r
+ }\r
+\r
+ dw_And2 = 1;\r
+\r
+ for (b_Cpt = 0; b_Cpt < devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SSICounterInfo.\r
+ b_TurnCptLength; b_Cpt ++)\r
+ {\r
+ dw_And2 = dw_And2 * 2;\r
+ }\r
+\r
+ /************************/\r
+ /* Start the conversion */\r
+ /************************/\r
+
+ outl(0,devpriv->s_BoardInfos.ui_Address + 8 + (64 * b_ModulNbr));\r
+\r
+ do\r
+ {\r
+ /*******************/\r
+ /* Read the status */\r
+ /*******************/\r
+ \r
+ dw_StatusReg = inl(devpriv->s_BoardInfos.ui_Address + (64 * b_ModulNbr));\r
+ }\r
+ while ((dw_StatusReg & 0x1) != 0);\r
+\r
+ for (b_SSICpt = 0; b_SSICpt < 3; b_SSICpt ++)\r
+ {\r
+ /******************************/\r
+ /* Read the SSI counter value */\r
+ /******************************/\r
+\r
+ \r
+ dw_CounterValue = inl(devpriv->s_BoardInfos.ui_Address + 4 + (b_SSICpt * 4) + (64 * b_ModulNbr));\r
+\r
+ b_Length = devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SSICounterInfo.\r
+ b_SSIProfile / 2;\r
+\r
+ if ((b_Length * 2) != devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SSICounterInfo.\r
+ b_SSIProfile)\r
+ {\r
+ b_Length ++;\r
+ }\r
+\r
+ b_Schift = b_Length - devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_SSICounterInfo.\r
+ b_PositionTurnLength;\r
+\r
+\r
+ pul_Position [b_SSICpt] = dw_CounterValue >> b_Schift;\r
+ pul_Position [b_SSICpt] = pul_Position [b_SSICpt] & ((dw_And1) - 1);\r
+\r
+ pul_TurnCpt [b_SSICpt] = dw_CounterValue >> b_Length;\r
+ pul_TurnCpt [b_SSICpt] = pul_TurnCpt [b_SSICpt] & ((dw_And2) - 1);\r
+ }\r
+ break;\r
+\r
+ default :\r
+ printk("Read Type Inputs Wrong\n");\r
+\r
+ } // switch ending\r
+\r
+ }\r
+ else\r
+ {\r
+ /***********************/\r
+ /* SSI not initialised */\r
+ /***********************/\r
+\r DPRINTK("SSI not initialised\n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /**********************************/\r
+ /* The module is not a SSI module */\r
+ /**********************************/\r
+\r DPRINTK("The module is not a SSI module\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***********************/\r
+ /* Module number error */\r
+ /***********************/\r
+\r DPRINTK("Module number error\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+\r
+\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_ReadSSI1DigitalInput |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_InputChannel, |\r
+| PBYTE_ pb_ChannelStatus) |\r
++----------------------------------------------------------------------------+\r
+| Task :\r
+ (0) Set the digital output from selected SSI moule |\r
+| (b_ModuleNbr) ON\r
+ (1) Set the digital output from selected SSI moule |\r
+| (b_ModuleNbr) OFF \r
+ (2)Read the status from selected SSI digital input |\r
+| (b_InputChannel) \r
+ (3)Read the status from all SSI digital inputs from |\r
+| selected SSI module (b_ModulNbr) |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|\r
+| BYTE_ b_ModulNbr CR_AREF : Module number to |\r
+| configure (0 to 3) |\r
+| BYTE_ b_InputChannel CR_CHAN : Selection from digital |\r
+| data[0] which IOTYPE input ( 0 to 2) |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : PBYTE_ pb_ChannelStatus : Digital input channel |\r
+| data[0] status |\r
+| 0 : Channle is not active|\r
+| 1 : Channle is active |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: The module parameter is wrong |\r
+| -3: The module is not a SSI module |\r
+| -4: The selected SSI digital input is wrong |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+\r
+\r
+INT i_APCI1710_InsnBitsSSIDigitalIO(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,\r
+lsampl_t *data)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ DWORD dw_StatusReg;\r
+ BYTE b_ModulNbr;\r
+ BYTE b_InputChannel;\r
+ PBYTE pb_ChannelStatus;
+ PBYTE pb_InputStatus;\r
+ BYTE b_IOType;\r
+ i_ReturnValue = insn->n;\r
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);\r
+ b_IOType = (BYTE) data[0];\r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /***********************/\r
+ /* Test if SSI counter */\r
+ /***********************/\r
+\r
+ if ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_SSI_COUNTER)\r
+ {\r
+ switch(b_IOType)\r
+ {\r
+ case APCI1710_SSI_SET_CHANNELON :\r
+ /*****************************/\r
+ /* Set the digital output ON */\r
+ /*****************************/\r
+\r
+
+ outl(1,devpriv->s_BoardInfos.ui_Address + 16 + (64 * b_ModulNbr));\r
+ break ;\r
+\r
+ case APCI1710_SSI_SET_CHANNELOFF :\r
+ /******************************/\r
+ /* Set the digital output OFF */\r
+ /******************************/\r
+\r
+
+ outl(0,devpriv->s_BoardInfos.ui_Address + 16 + (64 * b_ModulNbr));\r
+ break ;\r
+ \r
+ \r
+\r
+ case APCI1710_SSI_READ_1CHANNEL:\r
+ /******************************************/\r
+ /* Test the digital imnput channel number */\r
+ /******************************************/\r
+\r
+ b_InputChannel = (BYTE) CR_CHAN(insn->chanspec);\r
+ pb_ChannelStatus = (PBYTE) &data[0];\r
+\r
+ if ((b_InputChannel >= 0) && (b_InputChannel <= 2))\r
+ {\r
+ /**************************/\r
+ /* Read all digital input */\r
+ /**************************/\r
+ \r
+ \r
+ dw_StatusReg = inl(devpriv->s_BoardInfos.ui_Address + (64 * b_ModulNbr));\r
+ *pb_ChannelStatus = (BYTE) (((~dw_StatusReg) >> (4 + b_InputChannel)) & 1);\r
+ }\r
+ else\r
+ {\r
+ /********************************/\r
+ /* Selected digital input error */\r
+ /********************************/\r
+\r DPRINTK("Selected digital input error\n");
+ i_ReturnValue = -4;\r
+ }\r
+ break;\r
+\r
+ case APCI1710_SSI_READ_ALLCHANNEL:\r
+ /**************************/\r
+ /* Read all digital input */\r
+ /**************************/\r
+ pb_InputStatus = (PBYTE) &data[0];\r
+\r
+ \r
+ dw_StatusReg = inl(devpriv->s_BoardInfos.ui_Address + (64 * b_ModulNbr));\r
+ *pb_InputStatus = (BYTE) (((~dw_StatusReg) >> 4) & 7);\r
+ break;\r
+\r
+ default :\r
+ printk("IO type wrong\n");\r
+
+ } //switch end\r
+ }\r
+ else\r
+ {\r
+ /**********************************/\r
+ /* The module is not a SSI module */\r
+ /**********************************/\r
+\r DPRINTK("The module is not a SSI module\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***********************/\r
+ /* Module number error */\r
+ /***********************/\r
+\r DPRINTK("Module number error\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
--- /dev/null
+\r
+
+\r
+\r
+#define APCI1710_30MHZ 30\r
+#define APCI1710_33MHZ 33\r
+#define APCI1710_40MHZ 40\r
+
+\r
+#define APCI1710_BINARY_MODE 0x1\r
+#define APCI1710_GRAY_MODE 0x0\r
+\r
+#define APCI1710_SSI_READ1VALUE 1\r
+#define APCI1710_SSI_READALLVALUE 2\r
+\r
+\r
+#define APCI1710_SSI_SET_CHANNELON 0\r
+#define APCI1710_SSI_SET_CHANNELOFF 1\r
+#define APCI1710_SSI_READ_1CHANNEL 2\r
+#define APCI1710_SSI_READ_ALLCHANNEL 3\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| SSI INISIALISATION FUNCTION |\r
++----------------------------------------------------------------------------+\r
+*/\r
+INT i_APCI1710_InsnConfigInitSSI(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data);\r
+\r
+
+INT i_APCI1710_InsnReadSSIValue(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data);\r
+\r
+
+\r
+INT i_APCI1710_InsnBitsSSIDigitalIO(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,\r
+lsampl_t *data);\r
+\r
+
+\r
--- /dev/null
+/*\r
+ +-----------------------------------------------------------------------+\r
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |\r
+ +-----------------------------------------------------------------------+\r
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |\r
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |\r
+ +-----------------------------------------------------------------------+\r
+ | Project : API APCI1710 | Compiler : BORLANDC/MICROSOFT C |\r
+ | Module name : TOR.C | Version : 3.1 / 6.0 |\r
+ +-------------------------------+---------------------------------------+\r
+ | Author : S.WEBER | Date : 14.12.98 |\r
+ +-----------------------------------------------------------------------+\r
+ | Description : APCI-1710 tor counter module |\r
+ | |\r
+ | |\r
+ +-----------------------------------------------------------------------+\r
+ | UPDATES |\r
+ +-----------------------------------------------------------------------+\r
+ | Date | Author | Description of updates |\r
+ +----------+-----------+------------------------------------------------+\r
+ | 27/01/99 | S. Weber | 40 MHz implementation |\r
+ +-----------------------------------------------------------------------+\r
+ | 28/04/00 | S. Weber | Simple,double and quadruple mode implementation|\r
+ | | | Extern clock implementation |\r
+ +-----------------------------------------------------------------------+\r
+ | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |\r
+ | | | available |\r
+ +-----------------------------------------------------------------------+\r
+*/\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Included files |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+\r
+#include "APCI1710_Tor.h"\r
+\r
+\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_InitTorCounter |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_TorCounter, |\r
+| BYTE_ b_PCIInputClock, |\r
+| BYTE_ b_TimingUnit, |\r
+| ULONG_ ul_TimingInterval, |\r
+| PULONG_ pul_RealTimingInterval) |\r
++----------------------------------------------------------------------------+\r
+| Task : Configure the selected tor counter (b_TorCounter) |\r
+| from selected module (b_ModulNbr). |\r
+| The ul_TimingInterval and ul_TimingUnit determine the |\r
+| timing base for the measurement. |\r
+| The pul_RealTimingInterval return the real timing |\r
+| value. You must calling this function be for you call |\r
+| any other function witch access of the tor counter. |\r
+| |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : |\r
+| \r
+ CR_AREF BYTE_ b_ModulNbr : Module number to configure |\r
+| (0 to 3) |\r
+| data[0] BYTE_ b_TorCounter : Tor counter selection |\r
+| (0 or 1). |\r
+| data[1] BYTE_ b_PCIInputClock : Selection from PCI bus clock|\r
+| - APCI1710_30MHZ : |\r
+| The PC have a PCI bus |\r
+| clock from 30 MHz |\r
+| - APCI1710_33MHZ : |\r
+| The PC have a PCI bus |\r
+| clock from 33 MHz |\r
+| - APCI1710_40MHZ |\r
+| The APCI-1710 have a |\r
+| integrated 40Mhz |\r
+| quartz. |\r
+| - APCI1710_GATE_INPUT |\r
+| Used the gate input for |\r
+| the base clock. If you |\r
+| have selected this option,|\r
+| than it is not possibl to |\r
+| used the gate input for |\r
+| enabled the acquisition |\r
+| data[2] BYTE_ b_TimingUnit : Base timing unit (0 to 4) |\r
+| 0 : ns |\r
+| 1 : µs |\r
+| 2 : ms |\r
+| 3 : s |\r
+| 4 : mn |\r
+| data[3] ULONG_ ul_TimingInterval : Base timing value. |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : PULONG_ pul_RealTimingInterval : Real base timing |\r
+| data[0] value. |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: Module selection wrong |\r
+| -3: The module is not a tor counter module |\r
+| -4: Tor counter selection is wrong |\r
+| -5: The selected PCI input clock is wrong |\r
+| -6: Timing unit selection is wrong |\r
+| -7: Base timing selection is wrong |\r
+| -8: You can not used the 40MHz clock selection wich |\r
+| this board |\r
+| -9: You can not used the 40MHz clock selection wich |\r
+| this TOR version |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+
+\r
+INT i_APCI1710_InsnConfigInitTorCounter(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ ULONG ul_TimerValue;\r
+ DWORD dw_Command;\r
+ double d_RealTimingInterval;\r
+ BYTE b_ModulNbr;\r
+ BYTE b_TorCounter;\r
+ BYTE b_PCIInputClock;\r
+ BYTE b_TimingUnit;\r
+ ULONG ul_TimingInterval;\r
+ ULONG ul_RealTimingInterval;\r
+\r
+ i_ReturnValue = insn->n;\r
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);\r
+\r
+ b_TorCounter = (BYTE) data[0];\r
+ b_PCIInputClock = (BYTE) data[1];\r
+ b_TimingUnit = (BYTE) data[2];\r
+ ul_TimingInterval = (ULONG) data[3];\r
+ printk("INPUT clock %d\n",b_PCIInputClock);
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /***********************/\r
+ /* Test if tor counter */\r
+ /***********************/\r
+\r
+ if ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_TOR_COUNTER)\r
+ {\r
+ /**********************************/\r
+ /* Test the tor counter selection */\r
+ /**********************************/\r
+\r
+ if (b_TorCounter >= 0 && b_TorCounter <= 1)\r
+ {\r
+ /**************************/\r
+ /* Test the PCI bus clock */\r
+ /**************************/\r
+\r
+ if ((b_PCIInputClock == APCI1710_30MHZ) ||\r
+ (b_PCIInputClock == APCI1710_33MHZ) ||\r
+ (b_PCIInputClock == APCI1710_40MHZ) ||\r
+ (b_PCIInputClock == APCI1710_GATE_INPUT))\r
+ {\r
+ /************************/\r
+ /* Test the timing unit */\r
+ /************************/\r
+\r
+ if (((b_TimingUnit >= 0) && (b_TimingUnit <= 4)) || (b_PCIInputClock == APCI1710_GATE_INPUT))\r
+ {\r
+ /**********************************/\r
+ /* Test the base timing selection */\r
+ /**********************************/\r
+\r
+ if(((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 133) && (ul_TimingInterval <= 0xFFFFFFFFUL)) ||\r
+ ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 571230650UL)) ||\r
+ ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 571230UL)) ||\r
+ ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 571UL)) ||\r
+ ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 9UL)) ||\r
+ ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 121) && (ul_TimingInterval <= 0xFFFFFFFFUL)) ||\r
+ ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 519691043UL)) ||\r
+ ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 519691UL)) ||\r
+ ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 520UL)) ||\r
+ ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 8UL)) ||\r
+ ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 100) && (ul_TimingInterval <= 0xFFFFFFFFUL)) ||\r
+ ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 429496729UL)) ||\r
+ ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 429496UL)) ||\r
+ ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 429UL)) ||\r
+ ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 7UL)) ||\r
+ ((b_PCIInputClock == APCI1710_GATE_INPUT) && (ul_TimingInterval >= 2)))\r
+ {\r
+ /**************************/\r
+ /* Test the board version */\r
+ /**************************/\r
+\r
+ if ((b_PCIInputClock == APCI1710_40MHZ) && (devpriv->s_BoardInfos.\r
+ b_BoardVersion > 0) ||\r
+ (b_PCIInputClock != APCI1710_40MHZ))\r
+ {\r
+ /************************/\r
+ /* Test the TOR version */\r
+ /************************/\r
+\r
+ if ((b_PCIInputClock == APCI1710_40MHZ) && ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF) >= 0x3131) ||\r
+ (b_PCIInputClock == APCI1710_GATE_INPUT) && ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF) >= 0x3132) ||\r
+ (b_PCIInputClock == APCI1710_30MHZ) ||\r
+ (b_PCIInputClock == APCI1710_33MHZ))\r
+ {\r
+ /*********************************/\r
+ /* Test if not extern clock used */\r
+ /*********************************/\r
+\r
+ if (b_PCIInputClock != APCI1710_GATE_INPUT)\r
+ {\r
+ /****************************************/\r
+ /* Calculate the timer 0 division fator */\r
+ /****************************************/\r
+\r
+ switch (b_TimingUnit)\r
+ {\r
+ /******/\r
+ /* ns */\r
+ /******/\r
+\r
+ case 0:\r
+ \r
+ /******************/\r
+ /* Timer 0 factor */\r
+ /******************/\r
+\r
+ ul_TimerValue = (ULONG) (ul_TimingInterval * (0.00025 * b_PCIInputClock));\r
+\r
+ /*******************/\r
+ /* Round the value */\r
+ /*******************/\r
+\r
+ if ((double) ((double) ul_TimingInterval * (0.00025 * (double) b_PCIInputClock)) >= ((double) ((double) ul_TimerValue + 0.5)))\r
+ {\r
+ ul_TimerValue = ul_TimerValue + 1;\r
+ }\r
+\r
+ /*****************************/\r
+ /* Calculate the real timing */\r
+ /*****************************/\r
+\r
+ ul_RealTimingInterval = (ULONG) (ul_TimerValue / (0.00025 * (double) b_PCIInputClock));\r
+ d_RealTimingInterval = (double) ul_TimerValue / (0.00025 * (double) b_PCIInputClock);\r
+\r
+ if ((double) ((double) ul_TimerValue / (0.00025 * (double) b_PCIInputClock)) >= (double) ((double) ul_RealTimingInterval + 0.5))\r
+ {\r
+ ul_RealTimingInterval = ul_RealTimingInterval + 1;\r
+ }\r
+\r
+ ul_TimingInterval = ul_TimingInterval - 1;\r
+ ul_TimerValue = ul_TimerValue - 2;\r
+\r
+ if (b_PCIInputClock != APCI1710_40MHZ)\r
+ {\r
+ ul_TimerValue = (ULONG) ((double) (ul_TimerValue) * 1.007752288);\r
+ }\r
+ \r
+\r
+ break;\r
+\r
+ /******/\r
+ /* æs */\r
+ /******/\r
+\r
+ case 1:\r
+ \r
+ /******************/\r
+ /* Timer 0 factor */\r
+ /******************/\r
+\r
+ ul_TimerValue = (ULONG) (ul_TimingInterval * (0.25 * b_PCIInputClock));\r
+\r
+ /*******************/\r
+ /* Round the value */\r
+ /*******************/\r
+\r
+ if ((double) ((double) ul_TimingInterval * (0.25 * (double) b_PCIInputClock)) >= ((double) ((double) ul_TimerValue + 0.5)))\r
+ {\r
+ ul_TimerValue = ul_TimerValue + 1;\r
+ }\r
+\r
+ /*****************************/\r
+ /* Calculate the real timing */\r
+ /*****************************/\r
+\r
+ ul_RealTimingInterval = (ULONG) (ul_TimerValue / (0.25 * (double) b_PCIInputClock));\r
+ d_RealTimingInterval = (double) ul_TimerValue / ((double) 0.25 * (double) b_PCIInputClock);\r
+\r
+ if ((double) ((double) ul_TimerValue / (0.25 * (double) b_PCIInputClock)) >= (double) ((double) ul_RealTimingInterval + 0.5))\r
+ {\r
+ ul_RealTimingInterval = ul_RealTimingInterval + 1;\r
+ }\r
+\r
+ ul_TimingInterval = ul_TimingInterval - 1;\r
+ ul_TimerValue = ul_TimerValue - 2;\r
+\r
+ if (b_PCIInputClock != APCI1710_40MHZ)\r
+ {\r
+ ul_TimerValue = (ULONG) ((double) (ul_TimerValue) * 1.007752288);\r
+ }\r
+ \r
+\r
+ break;\r
+\r
+ /******/\r
+ /* ms */\r
+ /******/\r
+\r
+ case 2:\r
+ \r
+ /******************/\r
+ /* Timer 0 factor */\r
+ /******************/\r
+\r
+ ul_TimerValue = ul_TimingInterval * (250.0 * b_PCIInputClock);\r
+\r
+ /*******************/\r
+ /* Round the value */\r
+ /*******************/\r
+\r
+ if ((double) ((double) ul_TimingInterval * (250.0 * (double) b_PCIInputClock)) >= ((double) ((double) ul_TimerValue + 0.5)))\r
+ {\r
+ ul_TimerValue = ul_TimerValue + 1;\r
+ }\r
+\r
+ /*****************************/\r
+ /* Calculate the real timing */\r
+ /*****************************/\r
+\r
+ ul_RealTimingInterval = (ULONG) (ul_TimerValue / (250.0 * (double) b_PCIInputClock));\r
+ d_RealTimingInterval = (double) ul_TimerValue / (250.0 * (double) b_PCIInputClock);\r
+\r
+ if ((double) ((double) ul_TimerValue / (250.0 * (double) b_PCIInputClock)) >= (double) ((double) ul_RealTimingInterval + 0.5))\r
+ {\r
+ ul_RealTimingInterval = ul_RealTimingInterval + 1;\r
+ }\r
+\r
+ ul_TimingInterval = ul_TimingInterval - 1;\r
+ ul_TimerValue = ul_TimerValue - 2;\r
+\r
+ if (b_PCIInputClock != APCI1710_40MHZ)\r
+ {\r
+ ul_TimerValue = (ULONG) ((double) (ul_TimerValue) * 1.007752288);\r
+ }\r
+ \r
+\r
+ break;\r
+\r
+ /*****/\r
+ /* s */\r
+ /*****/\r
+\r
+ case 3:\r
+ \r
+ /******************/\r
+ /* Timer 0 factor */\r
+ /******************/\r
+\r
+ ul_TimerValue = (ULONG) (ul_TimingInterval * (250000.0 * b_PCIInputClock));\r
+\r
+ /*******************/\r
+ /* Round the value */\r
+ /*******************/\r
+\r
+ if ((double) ((double) ul_TimingInterval * (250000.0 * (double) b_PCIInputClock)) >= ((double) ((double) ul_TimerValue + 0.5)))\r
+ {\r
+ ul_TimerValue = ul_TimerValue + 1;\r
+ }\r
+\r
+ /*****************************/\r
+ /* Calculate the real timing */\r
+ /*****************************/\r
+\r
+ ul_RealTimingInterval = (ULONG) (ul_TimerValue / (250000.0 * (double) b_PCIInputClock));\r
+ d_RealTimingInterval = (double) ul_TimerValue / (250000.0 * (double) b_PCIInputClock);\r
+\r
+ if ((double) ((double) ul_TimerValue / (250000.0 * (double) b_PCIInputClock)) >= (double) ((double) ul_RealTimingInterval + 0.5))\r
+ {\r
+ ul_RealTimingInterval = ul_RealTimingInterval + 1;\r
+ }\r
+\r
+ ul_TimingInterval = ul_TimingInterval - 1;\r
+ ul_TimerValue = ul_TimerValue - 2;\r
+\r
+ if (b_PCIInputClock != APCI1710_40MHZ)\r
+ {\r
+ ul_TimerValue = (ULONG) ((double) (ul_TimerValue) * 1.007752288);\r
+ }\r
+ \r
+\r
+ break;\r
+\r
+ /******/\r
+ /* mn */\r
+ /******/\r
+\r
+ case 4:\r
+ \r
+ /******************/\r
+ /* Timer 0 factor */\r
+ /******************/\r
+\r
+ ul_TimerValue = (ULONG) ((ul_TimingInterval * 60) * (250000.0 * b_PCIInputClock));\r
+\r
+ /*******************/\r
+ /* Round the value */\r
+ /*******************/\r
+\r
+ if ((double) ((double) (ul_TimingInterval * 60.0) * (250000.0 * (double) b_PCIInputClock)) >= ((double) ((double) ul_TimerValue + 0.5)))\r
+ {\r
+ ul_TimerValue = ul_TimerValue + 1;\r
+ }\r
+\r
+ /*****************************/\r
+ /* Calculate the real timing */\r
+ /*****************************/\r
+\r
+ ul_RealTimingInterval = (ULONG) (ul_TimerValue / (250000.0 * (double) b_PCIInputClock)) / 60;\r
+ d_RealTimingInterval = ((double) ul_TimerValue / (250000.0 * (double) b_PCIInputClock)) / 60.0;\r
+\r
+ if ((double) (((double) ul_TimerValue / (250000.0 * (double) b_PCIInputClock)) / 60.0) >= (double) ((double) ul_RealTimingInterval + 0.5))\r
+ {\r
+ ul_RealTimingInterval = ul_RealTimingInterval + 1;\r
+ }\r
+\r
+ ul_TimingInterval = ul_TimingInterval - 1;\r
+ ul_TimerValue = ul_TimerValue - 2;\r
+\r
+ if (b_PCIInputClock != APCI1710_40MHZ)\r
+ {\r
+ ul_TimerValue = (ULONG) ((double) (ul_TimerValue) * 1.007752288);\r
+ }\r
+ \r
+ break;\r
+ }\r
+ } // if (b_PCIInputClock != APCI1710_GATE_INPUT)\r
+ else\r
+ {\r
+ /*************************************************************/\r
+ /* 2 Clock used for the overflow and the reload from counter */\r
+ /*************************************************************/\r
+\r
+ ul_TimerValue = ul_TimingInterval - 2;\r
+ } // if (b_PCIInputClock != APCI1710_GATE_INPUT)\r
+\r
+ /****************************/\r
+ /* Save the PCI input clock */\r
+ /****************************/\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_TorCounterModuleInfo.\r
+ b_PCIInputClock = b_PCIInputClock;\r
+\r
+ /************************/\r
+ /* Save the timing unit */\r
+ /************************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_TorCounterModuleInfo.\r
+ s_TorCounterInfo [b_TorCounter].\r
+ b_TimingUnit = b_TimingUnit;\r
+\r
+ /************************/\r
+ /* Save the base timing */\r
+ /************************/\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_TorCounterModuleInfo.\r
+ s_TorCounterInfo [b_TorCounter].\r
+ d_TimingInterval = d_RealTimingInterval;\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_TorCounterModuleInfo.\r
+ s_TorCounterInfo [b_TorCounter].\r
+ ul_RealTimingInterval = ul_RealTimingInterval;\r
+\r
+ /*******************/\r
+ /* Get the command */\r
+ /*******************/\r
+\r
+
+ dw_Command = inl(devpriv->s_BoardInfos.ui_Address + 4 + (16 * b_TorCounter) + (64 * b_ModulNbr));\r
+\r
+ dw_Command = (dw_Command >> 4) & 0xF;\r
+\r
+ /******************/\r
+ /* Test if 40 MHz */\r
+ /******************/\r
+\r
+ if (b_PCIInputClock == APCI1710_40MHZ)\r
+ {\r
+ /****************************/\r
+ /* Set the 40 MHz selection */\r
+ /****************************/\r
+\r
+ dw_Command = dw_Command | 0x10;\r
+ }\r
+\r
+ /*****************************/\r
+ /* Test if extern clock used */\r
+ /*****************************/\r
+\r
+ if (b_PCIInputClock == APCI1710_GATE_INPUT)\r
+ {\r
+ /****************************/\r
+ /* Set the 40 MHz selection */\r
+ /****************************/\r
+\r
+ dw_Command = dw_Command | 0x20;\r
+ }\r
+\r
+ /*************************/\r
+ /* Write the new command */\r
+ /*************************/\r
+\r
+ \r
+ outl(dw_Command,devpriv->s_BoardInfos.ui_Address + 4 + (16 * b_TorCounter) + (64 * b_ModulNbr));\r
+ \r
+ /*******************/\r
+ /* Disable the tor */\r
+ /*******************/\r
+ \r
+ outl(0,devpriv->s_BoardInfos.\r
+ ui_Address + 8 + (16 * b_TorCounter) + (64 * b_ModulNbr));\r
+ /*************************/\r
+ /* Set the timer 1 value */\r
+ /*************************/\r
+\r
+ \r
+ outl(ul_TimerValue,devpriv->s_BoardInfos.ui_Address + 0 + (16 * b_TorCounter) + (64 * b_ModulNbr));\r
+\r
+ /*********************/\r
+ /* Tor counter init. */\r
+ /*********************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_TorCounterModuleInfo.\r
+ s_TorCounterInfo [b_TorCounter].\r
+ b_TorCounterInit = 1;\r
+ }\r
+ else\r
+ {\r
+ /***********************************************/\r
+ /* TOR version error for 40MHz clock selection */\r
+ /***********************************************/\r
+\r DPRINTK("TOR version error for 40MHz clock selection\n");
+ i_ReturnValue = -9;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /**************************************************************/\r
+ /* You can not used the 40MHz clock selection wich this board */\r
+ /**************************************************************/\r
+\r DPRINTK("You can not used the 40MHz clock selection wich this board\n");
+ i_ReturnValue = -8;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /**********************************/\r
+ /* Base timing selection is wrong */\r
+ /**********************************/\r
+\r DPRINTK("Base timing selection is wrong\n");
+ i_ReturnValue = -7;\r
+ }\r
+ } // if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))\r
+ else\r
+ {\r
+ /**********************************/\r
+ /* Timing unit selection is wrong */\r
+ /**********************************/\r
+\r DPRINTK("Timing unit selection is wrong\n");
+ i_ReturnValue = -6;\r
+ } // if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))\r
+ } // if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ))\r
+ else\r
+ {\r
+ /*****************************************/\r
+ /* The selected PCI input clock is wrong */\r
+ /*****************************************/\r
+\r DPRINTK("The selected PCI input clock is wrong\n");
+ i_ReturnValue = -5;\r
+ } // if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ))\r
+ } // if (b_TorCounterMode >= 0 && b_TorCounterMode <= 7)\r
+ else\r
+ {\r
+ /**********************************/\r
+ /* Tor Counter selection is wrong */\r
+ /**********************************/\r
+\r DPRINTK("Tor Counter selection is wrong\n");
+ i_ReturnValue = -4;\r
+ } // if (b_TorCounterMode >= 0 && b_TorCounterMode <= 7)\r
+ }\r
+ else\r
+ {\r
+ /******************************************/\r
+ /* The module is not a tor counter module */\r
+ /******************************************/\r
+\r DPRINTK("The module is not a tor counter module\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***********************/\r
+ /* Module number error */\r
+ /***********************/\r
+\r DPRINTK("Module number error\n");
+ i_ReturnValue = -2;\r
+ }\r
+ data[0] = (UINT) ul_RealTimingInterval;\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_EnableTorCounter |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_TorCounter, |\r
+| BYTE_ b_InputMode, |\r
+| BYTE_ b_ExternGate, |\r
+| BYTE_ b_CycleMode, |\r
+| BYTE_ b_InterruptEnable) |\r
++----------------------------------------------------------------------------+\r
+| Task : Enable the tor counter (b_TorCounter) from selected |\r
+| module (b_ModulNbr). You must calling the |\r
+| "i_APCI1710_InitTorCounter" function be for you call |\r
+| this function. |\r
+| If you enable the tor counter interrupt, the |\r
+| tor counter generate a interrupt after the timing cycle|\r
+| See function "i_APCI1710_SetBoardIntRoutineX" and the |\r
+| Interrupt mask description chapter from this manual. |\r
+| The b_CycleMode parameter determine if you will |\r
+| measured a single or more cycle. |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Selected module number (0 to 3) |\r
+| BYTE_ b_TorCounter : Tor counter selection (0 or 1). |\r
+| BYTE_ b_InputMode : Input signal level selection |\r
+| 0 : Tor count each low level |\r
+| 1 : Tor count each high level|\r
+| BYTE_ b_ExternGate : Extern gate action selection |\r
+| 0 : Extern gate signal not |\r
+| used |\r
+| 1 : Extern gate signal used. |\r
+| If you selected the |\r
+| single mode, each high |\r
+| level signal start the |\r
+| counter. |\r
+| If you selected the |\r
+| continuous mode, the |\r
+| first high level signal |\r
+| start the tor counter |\r
+| |\r
+| APCI1710_TOR_QUADRUPLE _MODE : |\r
+| In the quadruple mode, the edge|\r
+| analysis circuit generates a |\r
+| counting pulse from each edge |\r
+| of 2 signals which are phase |\r
+| shifted in relation to each |\r
+| other. |\r
+| The gate input is used for the |\r
+| signal B |\r
+| |\r
+| APCI1710_TOR_DOUBLE_MODE: |\r
+| Functions in the same way as |\r
+| the quadruple mode, except that|\r
+| only two of the four edges are |\r
+| analysed per period. |\r
+| The gate input is used for the |\r
+| signal B |\r
+| |\r
+| APCI1710_TOR_SIMPLE_MODE: |\r
+| Functions in the same way as |\r
+| the quadruple mode, except that|\r
+| only one of the four edges is |\r
+| analysed per period. |\r
+| The gate input is used for the |\r
+| signal B |\r
+| |\r
+| BYTE_ b_CycleMode : Selected the tor counter |\r
+| acquisition mode |\r
+| BYTE_ b_InterruptEnable : Enable or disable the |\r
+| tor counter interrupt. |\r
+| APCI1710_ENABLE: |\r
+| Enable the tor counter |\r
+| interrupt |\r
+| APCI1710_DISABLE: |\r
+| Disable the tor counter |\r
+| interrupt |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: Module selection wrong |\r
+| -3: The module is not a tor counter module |\r
+| -4: Tor counter selection is wrong |\r
+| -5: Tor counter not initialised see function |\r
+| "i_APCI1710_InitTorCounter" |\r
+| -6: Tor input signal selection is wrong |\r
+| -7: Extern gate signal mode is wrong |\r
+| -8: Tor counter acquisition mode cycle is wrong |\r
+| -9: Interrupt parameter is wrong |\r
+| -10:Interrupt function not initialised. |\r
+| See function "i_APCI1710_SetBoardIntRoutineX" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_DisableTorCounter |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_TorCounter) |\r
++----------------------------------------------------------------------------+\r
+| Task : Disable the tor counter (b_TorCounter) from selected |\r
+| module (b_ModulNbr). If you disable the tor counter |\r
+| after a start cycle occur and you restart the tor |\r
+| counter witch the " i_APCI1710_EnableTorCounter" |\r
+| function, the status register is cleared |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Selected module number (0 to 3) |\r
+| BYTE_ b_TorCounter : Tor counter selection (0 or 1). |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: Module selection wrong |\r
+| -3: The module is not a tor counter module |\r
+| -4: Tor counter selection is wrong |\r
+| -5: Tor counter not initialised see function |\r
+| "i_APCI1710_InitTorCounter" |\r
+| -6: Tor counter not enabled see function |\r
+| "i_APCI1710_EnableTorCounter" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+\r
+
+INT i_APCI1710_InsnWriteEnableDisableTorCounter (comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ DWORD dw_Status;\r
+ DWORD dw_DummyRead;\r
+ DWORD dw_ConfigReg;\r
+ BYTE b_ModulNbr,b_Action;\r
+ BYTE b_TorCounter;\r
+ BYTE b_InputMode;\r
+ BYTE b_ExternGate;\r
+ BYTE b_CycleMode;\r
+ BYTE b_InterruptEnable;\r
+\r
+ b_ModulNbr =(BYTE) CR_AREF(insn->chanspec);\r
+ b_Action =(BYTE) data[0]; // enable or disable\r
+ b_TorCounter =(BYTE) data[1];\r
+ b_InputMode =(BYTE) data[2] ;\r
+ b_ExternGate =(BYTE) data[3] ;\r
+ b_CycleMode =(BYTE) data[4] ;\r
+ b_InterruptEnable =(BYTE) data[5] ;\r
+ i_ReturnValue = insn->n; ;\r
+ devpriv->tsk_Current=current; // Save the current process task structure\r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /***********************/\r
+ /* Test if tor counter */\r
+ /***********************/\r
+\r
+ if ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_TOR_COUNTER)\r
+ {\r
+ /**********************************/\r
+ /* Test the tor counter selection */\r
+ /**********************************/\r
+\r
+ if (b_TorCounter >= 0 && b_TorCounter <= 1)\r
+ {\r
+ switch(b_Action)// Enable or Disable\r
+ {\r
+ case APCI1710_ENABLE :\r
+ /***********************************/\r
+ /* Test if tor counter initialised */\r
+ /***********************************/\r
+\r
+
+\r
+ dw_Status =inl(devpriv->s_BoardInfos.ui_Address + 8 + (16 * b_TorCounter) + (64 * b_ModulNbr));\r
+\r
+ if (dw_Status & 0x10)\r
+ {\r
+ /******************************/\r
+ /* Test the input signal mode */\r
+ /******************************/\r
+\r
+ if (b_InputMode == 0 ||\r
+ b_InputMode == 1 ||\r
+ b_InputMode == APCI1710_TOR_SIMPLE_MODE ||\r
+ b_InputMode == APCI1710_TOR_DOUBLE_MODE ||\r
+ b_InputMode == APCI1710_TOR_QUADRUPLE_MODE)\r
+ {\r
+ /************************************/\r
+ /* Test the extern gate signal mode */\r
+ /************************************/\r
+\r
+ if (b_ExternGate == 0 || b_ExternGate == 1 || b_InputMode > 1)\r
+ {\r
+ /*********************************/\r
+ /* Test the cycle mode parameter */\r
+ /*********************************/\r
+\r
+ if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS))\r
+ {\r
+ /***************************/\r
+ /* Test the interrupt flag */\r
+ /***************************/\r
+\r
+ if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE))\r
+ {\r
+\r
+
+
+ /***************************/\r
+ /* Save the interrupt mode */\r
+ /***************************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_TorCounterModuleInfo.\r
+ s_TorCounterInfo [b_TorCounter].\r
+ b_InterruptEnable = b_InterruptEnable;\r
+\r
+ /*******************/\r
+ /* Get the command */\r
+ /*******************/\r
+\r
+
+ dw_ConfigReg = inl(devpriv->s_BoardInfos.ui_Address + 4 + (16 * b_TorCounter) + (64 * b_ModulNbr));\r
+\r
+ dw_ConfigReg = (dw_ConfigReg >> 4) & 0x30;\r
+\r
+ /********************************/\r
+ /* Test if not direct mode used */\r
+ /********************************/\r
+\r
+ if (b_InputMode > 1)\r
+ {\r
+ /*******************************/\r
+ /* Extern gate can not be used */\r
+ /*******************************/\r
+\r
+ b_ExternGate = 0;\r
+\r
+ /*******************************************/\r
+ /* Enable the extern gate for the Signal B */\r
+ /*******************************************/\r
+\r
+ dw_ConfigReg = dw_ConfigReg | 0x40;\r
+\r
+ /***********************/\r
+ /* Test if simple mode */\r
+ /***********************/\r
+\r
+ if (b_InputMode == APCI1710_TOR_SIMPLE_MODE)\r
+ {\r
+ /**************************/\r
+ /* Enable the sinple mode */\r
+ /**************************/\r
+\r
+ dw_ConfigReg = dw_ConfigReg | 0x780;\r
+\r
+ } // if (b_InputMode == APCI1710_TOR_SIMPLE_MODE)\r
+\r
+ /***********************/\r
+ /* Test if double mode */\r
+ /***********************/\r
+\r
+ if (b_InputMode == APCI1710_TOR_DOUBLE_MODE)\r
+ {\r
+ /**************************/\r
+ /* Enable the double mode */\r
+ /**************************/\r
+\r
+ dw_ConfigReg = dw_ConfigReg | 0x180;\r
+\r
+ } // if (b_InputMode == APCI1710_TOR_DOUBLE_MODE)\r
+\r
+ b_InputMode = 0;\r
+ } // if (b_InputMode > 1)\r
+\r
+ /*******************/\r
+ /* Set the command */\r
+ /*******************/\r
+\r
+ dw_ConfigReg = dw_ConfigReg | b_CycleMode | (b_InterruptEnable * 2) | (b_InputMode * 4) | (b_ExternGate * 8);\r
+\r
+ /*****************************/\r
+ /* Clear the status register */\r
+ /*****************************/\r
+\r
+ \r
+ dw_DummyRead = inl(devpriv->s_BoardInfos.\r
+ ui_Address + 0 + (16 * b_TorCounter) + (64 * b_ModulNbr));\r
+\r
+ /***************************************/\r
+ /* Clear the interrupt status register */\r
+ /***************************************/\r
+\r
+ \r
+ dw_DummyRead=inl(devpriv->s_BoardInfos.\r
+ ui_Address + 12 + (16 * b_TorCounter) + (64 * b_ModulNbr)); \r
+\r
+ /********************/\r
+ /* Set the commando */\r
+ /********************/\r
+\r
+
+ outl(dw_ConfigReg,devpriv->s_BoardInfos.\r
+ ui_Address + 4 + (16 * b_TorCounter) + (64 * b_ModulNbr));\r
+\r
+ /****************/\r
+ /* Set the gate */\r
+ /****************/\r
+
+\r
+ outl(1,devpriv->s_BoardInfos.\r
+ ui_Address + 8 + (16 * b_TorCounter) + (64 * b_ModulNbr));\r
+
+ } // if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE))\r
+ else\r
+ {\r
+ /********************************/\r
+ /* Interrupt parameter is wrong */\r
+ /********************************/\r
+\r DPRINTK("Interrupt parameter is wrong\n");
+ i_ReturnValue = -9;\r
+ } // if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE))\r
+ } // if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS))\r
+ else\r
+ {\r
+ /***********************************************/\r
+ /* Tor counter acquisition mode cycle is wrong */\r
+ /***********************************************/\r
+\r DPRINTK("Tor counter acquisition mode cycle is wrong\n");
+ i_ReturnValue = -8;\r
+ } // if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS))\r
+ } // if (b_ExternGate >= 0 && b_ExternGate <= 1)\r
+ else\r
+ {\r
+ /***********************************/\r
+ /* Extern gate input mode is wrong */\r
+ /***********************************/\r
+\r DPRINTK("Extern gate input mode is wrong\n");
+ i_ReturnValue = -7;\r
+ } // if (b_ExternGate >= 0 && b_ExternGate <= 1)\r
+ } // if (b_InputMode >= 0 && b_InputMode <= 1)\r
+ else\r
+ {\r
+ /***************************************/\r
+ /* Tor input signal selection is wrong */\r
+ /***************************************/\r
+\r DPRINTK("Tor input signal selection is wrong\n");
+ i_ReturnValue = -6;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*******************************/\r
+ /* Tor counter not initialised */\r
+ /*******************************/\r
+\r DPRINTK("Tor counter not initialised\n");
+ i_ReturnValue = -5;\r
+ }\r
+ break;\r
+\r
+ case APCI1710_DISABLE :\r
+ /***********************************/\r
+ /* Test if tor counter initialised */\r
+ /***********************************/\r
+
+ dw_Status = inl(devpriv->s_BoardInfos.\r
+ ui_Address + 8 + (16 * b_TorCounter) + (64 * b_ModulNbr));\r
+\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (dw_Status & 0x10)\r
+ {\r
+ /***************************/\r
+ /* Test if counter enabled */\r
+ /***************************/\r
+\r
+ if (dw_Status & 0x1)\r
+ {\r
+ /****************************/\r
+ /* Clear the interrupt mode */\r
+ /****************************/\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_TorCounterModuleInfo.\r
+ s_TorCounterInfo [b_TorCounter].\r
+ b_InterruptEnable = APCI1710_DISABLE;\r
+\r
+\r
+ /******************/\r
+ /* Clear the gate */\r
+ /******************/\r
+ \r
+ outl(0,devpriv->s_BoardInfos.ui_Address + 8 + (16 * b_TorCounter) + (64 * b_ModulNbr));\r
+ } // if (dw_Status & 0x1)\r
+ else\r
+ {\r
+ /***************************/\r
+ /* Tor counter not enabled */\r
+ /***************************/\r
+\r DPRINTK("Tor counter not enabled \n");
+ i_ReturnValue = -6;\r
+ } // if (dw_Status & 0x1)\r
+ } // if (dw_Status & 0x10)\r
+ else\r
+ {\r
+ /*******************************/\r
+ /* Tor counter not initialised */\r
+ /*******************************/\r
+\r DPRINTK("Tor counter not initialised\n");
+ i_ReturnValue = -5;\r
+ } // // if (dw_Status & 0x10)\r
+ \r
+\r
+\r
+ } // switch\r
+ } // if (b_TorCounter >= 0 && b_TorCounter <= 1)\r
+ else\r
+ {\r
+ /**********************************/\r
+ /* Tor counter selection is wrong */\r
+ /**********************************/\r
+\r DPRINTK("Tor counter selection is wrong\n");
+ i_ReturnValue = -4;\r
+ } // if (b_TorCounter >= 0 && b_TorCounter <= 1)\r
+ }\r
+ else\r
+ {\r
+ /******************************************/\r
+ /* The module is not a tor counter module */\r
+ /******************************************/\r
+\r DPRINTK("The module is not a tor counter module \n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***********************/\r
+ /* Module number error */\r
+ /***********************/\r
+\r DPRINTK("Module number error \n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_GetTorCounterInitialisation |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_TorCounter, |\r
+| PBYTE_ pb_TimingUnit, |\r
+| PULONG_ pul_TimingInterval, |\r
+| PBYTE_ pb_InputMode, |\r
+| PBYTE_ pb_ExternGate, |\r
+| PBYTE_ pb_CycleMode, |\r
+| PBYTE_ pb_Enable, |\r
+| PBYTE_ pb_InterruptEnable)|\r
++----------------------------------------------------------------------------+\r
+| Task : Enable the tor counter (b_TorCounter) from selected |\r
+| module (b_ModulNbr). You must calling the |\r
+| "i_APCI1710_InitTorCounter" function be for you call |\r
+| this function. |\r
+| If you enable the tor counter interrupt, the |\r
+| tor counter generate a interrupt after the timing cycle|\r
+| See function "i_APCI1710_SetBoardIntRoutineX" and the |\r
+| Interrupt mask description chapter from this manual. |\r
+| The b_CycleMode parameter determine if you will |\r
+| measured a single or more cycle. |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Selected module number (0 to 3) |\r
+| BYTE_ b_TorCounter : Tor counter selection (0 or 1)\r
+\r
+ b_ModulNbr = CR_AREF(insn->chanspec);\r
+ b_TorCounter = CR_CHAN(insn->chanspec);\r
+. |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : PBYTE_ pb_TimingUnit : Base timing unit (0 to 4) |\r
+| 0 : ns |\r
+| 1 : µs |\r
+| 2 : ms |\r
+| 3 : s |\r
+| 4 : mn |\r
+| PULONG_ pul_TimingInterval : Base timing value. |\r
+| PBYTE_ pb_InputMode : Input signal level |\r
+| selection |\r
+| 0 : Tor count each low level |\r
+| 1 : Tor count each high level|\r
+| PBYTE_ pb_ExternGate : Extern gate action |\r
+| selection |\r
+| 0 : Extern gate signal not |\r
+| used |\r
+| 1 : Extern gate signal used|\r
+| PBYTE_ pb_CycleMode : Tor counter acquisition |\r
+| mode |\r
+| PBYTE_ pb_Enable : Indicate if the tor counter|\r
+| is enabled or no |\r
+| 0 : Tor counter disabled |\r
+| 1 : Tor counter enabled |\r
+| PBYTE_ pb_InterruptEnable : Enable or disable the |\r
+| tor counter interrupt. |\r
+| APCI1710_ENABLE: |\r
+| Enable the tor counter |\r
+| interrupt |\r
+| APCI1710_DISABLE: |\r
+| Disable the tor counter |\r
+| interrupt \r
+ pb_TimingUnit = (PBYTE) &data[0];\r
+ pul_TimingInterval = (PULONG) &data[1];\r
+ pb_InputMode = (PBYTE) &data[2];\r
+ pb_ExternGate = (PBYTE) &data[3];\r
+ pb_CycleMode = (PBYTE) &data[4];\r
+ pb_Enable = (PBYTE) &data[5];\r
+ pb_InterruptEnable = (PBYTE) &data[6];\r
+ |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: Module selection wrong |\r
+| -3: The module is not a tor counter module |\r
+| -4: Tor counter selection is wrong |\r
+| -5: Tor counter not initialised see function |\r
+| "i_APCI1710_InitTorCounter" |\r
++----------------------------------------------------------------------------+\r
+*/\r
+
+\r
+INT i_APCI1710_InsnReadGetTorCounterInitialisation(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ DWORD dw_Status;\r
+ BYTE b_ModulNbr;\r
+ BYTE b_TorCounter;\r
+ PBYTE pb_TimingUnit;\r
+ PULONG pul_TimingInterval;\r
+ PBYTE pb_InputMode;\r
+ PBYTE pb_ExternGate;\r
+ PBYTE pb_CycleMode;\r
+ PBYTE pb_Enable;\r
+ PBYTE pb_InterruptEnable ;\r
+ \r
+ i_ReturnValue = insn->n;\r
+ b_ModulNbr = CR_AREF(insn->chanspec);\r
+ b_TorCounter = CR_CHAN(insn->chanspec);\r
+\r
+ pb_TimingUnit = (PBYTE) &data[0];\r
+ pul_TimingInterval = (PULONG) &data[1];\r
+ pb_InputMode = (PBYTE) &data[2];\r
+ pb_ExternGate = (PBYTE) &data[3];\r
+ pb_CycleMode = (PBYTE) &data[4];\r
+ pb_Enable = (PBYTE) &data[5];\r
+ pb_InterruptEnable = (PBYTE) &data[6];\r
+\r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /***********************/\r
+ /* Test if tor counter */\r
+ /***********************/\r
+\r
+ if ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_TOR_COUNTER)\r
+ {\r
+ /**********************************/\r
+ /* Test the tor counter selection */\r
+ /**********************************/\r
+\r
+ if (b_TorCounter >= 0 && b_TorCounter <= 1)\r
+ {\r
+ \r
+ \r
+ /***********************************/\r
+ /* Test if tor counter initialised */\r
+ /***********************************/\r
+\r
+
+ dw_Status = inl(devpriv->s_BoardInfos.\r
+ ui_Address + 8 + (16 * b_TorCounter) + (64 * b_ModulNbr));\r
+\r
+\r
+ if (dw_Status & 0x10)\r
+ {\r
+ *pb_Enable = dw_Status & 1;\r
+\r
+ /********************/\r
+ /* Get the commando */\r
+ /********************/\r
+\r
+
+ dw_Status=inl(devpriv->s_BoardInfos.\r
+ ui_Address + 4 + (16 * b_TorCounter) + (64 * b_ModulNbr));\r
+\r
+ *pb_CycleMode = (BYTE) ((dw_Status >> 4) & 1);\r
+ *pb_InterruptEnable = (BYTE) ((dw_Status >> 5) & 1);\r
+\r
+ /******************************************************/\r
+ /* Test if extern gate used for clock or for signal B */\r
+ /******************************************************/\r
+\r
+ if (dw_Status & 0x600)\r
+ {\r
+ /*****************************************/\r
+ /* Test if extern gate used for signal B */\r
+ /*****************************************/\r
+\r
+ if (dw_Status & 0x400)\r
+ {\r
+ /***********************/\r
+ /* Test if simple mode */\r
+ /***********************/\r
+\r
+ if ((dw_Status & 0x7800) == 0x7800)\r
+ {\r
+ *pb_InputMode = APCI1710_TOR_SIMPLE_MODE;\r
+ }\r
+\r
+ /***********************/\r
+ /* Test if double mode */\r
+ /***********************/\r
+\r
+ if ((dw_Status & 0x7800) == 0x1800)\r
+ {\r
+ *pb_InputMode = APCI1710_TOR_DOUBLE_MODE;\r
+ }\r
+\r
+ /**************************/\r
+ /* Test if quadruple mode */\r
+ /**************************/\r
+\r
+ if ((dw_Status & 0x7800) == 0x0000)\r
+ {\r
+ *pb_InputMode = APCI1710_TOR_QUADRUPLE_MODE;\r
+ }\r
+ } // if (dw_Status & 0x400)\r
+ else\r
+ {\r
+ *pb_InputMode = 1;\r
+ } // // if (dw_Status & 0x400)\r
+\r
+ /************************/\r
+ /* Extern gate not used */\r
+ /************************/\r
+\r
+ *pb_ExternGate = 0;\r
+ } // if (dw_Status & 0x600)\r
+ else\r
+ {\r
+ *pb_InputMode = (BYTE) ((dw_Status >> 6) & 1);\r
+ *pb_ExternGate = (BYTE) ((dw_Status >> 7) & 1);\r
+ } // if (dw_Status & 0x600)\r
+\r
+ *pb_TimingUnit = devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_TorCounterModuleInfo.\r
+ s_TorCounterInfo [b_TorCounter].\r
+ b_TimingUnit;\r
+\r
+ *pul_TimingInterval = devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_TorCounterModuleInfo.\r
+ s_TorCounterInfo [b_TorCounter].\r
+ ul_RealTimingInterval;\r
+ }\r
+ else\r
+ {\r
+ /*******************************/\r
+ /* Tor counter not initialised */\r
+ /*******************************/\r
+\r DPRINTK("Tor counter not initialised\n");
+ i_ReturnValue = -5;\r
+ }\r
+ \r
+ } // if (b_TorCounter >= 0 && b_TorCounter <= 1)\r
+ else\r
+ {\r
+ /**********************************/\r
+ /* Tor counter selection is wrong */\r
+ /**********************************/\r
+\r DPRINTK("Tor counter selection is wrong \n");
+ i_ReturnValue = -4;\r
+ } // if (b_TorCounter >= 0 && b_TorCounter <= 1)\r
+ }\r
+ else\r
+ {\r
+ /******************************************/\r
+ /* The module is not a tor counter module */\r
+ /******************************************/\r
+\r DPRINTK("The module is not a tor counter module\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***********************/\r
+ /* Module number error */\r
+ /***********************/\r
+\r DPRINTK("Module number error\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_ReadTorCounterValue |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_TorCounter, |\r
+| UINT_ ui_TimeOut, |\r
+| PBYTE_ pb_TorCounterStatus, |\r
+| PULONG_ pul_TorCounterValue) |\r
++----------------------------------------------------------------------------+\r
+| Task case APCI1710_TOR_GETPROGRESSSTATUS: Return the tor counter \r
+(b_TorCounter) status (pb_TorCounterStatus) from selected tor counter |\r
+| module (b_ModulNbr). \r
+ \r
+ case APCI1710_TOR_GETCOUNTERVALUE :\r
+ Return the tor counter (b_TorCounter) status |\r
+| (pb_TorCounterStatus) and the timing value |\r
+| (pul_TorCounterValue) after a conting cycle stop |\r
+| from selected tor counter module (b_ModulNbr). |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Selected module number (0 to 3) |\r
+| BYTE_ b_TorCounter : Tor counter selection (0 or 1).\r
+ b_ModulNbr = CR_AREF(insn->chanspec);\r
+ b_ReadType = (BYTE) data[0]; \r
+ b_TorCounter = (BYTE) data[1];\r
+ ui_TimeOut = (UINT) data[2]; |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : PBYTE_ pb_TorCounterStatus : Return the tor counter |\r
+| status. |\r
+| 0 : Conting cycle not started|\r
+| Software gate not set. |\r
+| 1 : Conting cycle started. |\r
+| Software gate set. |\r
+| 2 : Conting cycle stopped. |\r
+| The conting cycle is |\r
+| terminate. |\r
+| 3 : A overflow occur. You |\r
+| must change the base |\r
+| timing witch the |\r
+| function |\r
+| "i_APCI1710_InitTorCounter"|\r
+| 4 : Timeeout occur |\r
+| PULONG pul_TorCounterValue : Tor counter value. \r
+ pb_TorCounterStatus=(PBYTE) &data[0];\r
+ pul_TorCounterValue=(PULONG) &data[1]; |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: Module selection wrong |\r
+| -3: The module is not a tor counter module |\r
+| -4: Tor counter selection is wrong |\r
+| -5: Tor counter not initialised see function |\r
+| "i_APCI1710_InitTorCounter" |\r
+| -6: Tor counter not enabled see function |\r
+| "i_APCI1710_EnableTorCounter" |\r
+| -7: Timeout parameter is wrong (0 to 65535) |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+\r
+INT i_APCI1710_InsnBitsGetTorCounterProgressStatusAndValue(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ DWORD dw_Status;\r
+ DWORD dw_TimeOut = 0;\r
+\r
+ BYTE b_ModulNbr;\r
+ BYTE b_TorCounter;\r
+ BYTE b_ReadType;
+ UINT ui_TimeOut;\r
+ PBYTE pb_TorCounterStatus;\r
+ PULONG pul_TorCounterValue;\r
+\r
+ i_ReturnValue = insn->n;\r
+ b_ModulNbr = CR_AREF(insn->chanspec);\r
+ b_ReadType = (BYTE) data[0]; \r
+ b_TorCounter = (BYTE) data[1];\r
+ ui_TimeOut = (UINT) data[2];\r
+ pb_TorCounterStatus=(PBYTE) &data[0];\r
+ pul_TorCounterValue=(PULONG) &data[1];\r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+
+
+ if(b_ReadType==APCI1710_TOR_READINTERRUPT)
+ {
+
+ data[0]=devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Read].b_OldModuleMask;
+ data[1]=devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Read].ul_OldInterruptMask;
+ data[2]=devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Read].ul_OldCounterLatchValue;
+
+
+ /**************************/
+ /* Increment the read FIFO */
+ /***************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Read = (devpriv->
+ s_InterruptParameters.
+ ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
+
+ return insn->n;
+ }
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /***********************/\r
+ /* Test if tor counter */\r
+ /***********************/\r
+\r
+ if ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_TOR_COUNTER)\r
+ {\r
+ /**********************************/\r
+ /* Test the tor counter selection */\r
+ /**********************************/\r
+\r
+ if (b_TorCounter >= 0 && b_TorCounter <= 1)\r
+ {\r
+ /***********************************/\r
+ /* Test if tor counter initialised */\r
+ /***********************************/\r
+\r
+ \r
+
+ dw_Status=inl(devpriv->s_BoardInfos.\r
+ ui_Address + 8 + (16 * b_TorCounter) + (64 * b_ModulNbr));\r
+\r
+ /*******************************/\r
+ /* Test if counter initialised */\r
+ /*******************************/\r
+\r
+ if (dw_Status & 0x10)\r
+ {\r
+ /***************************/\r
+ /* Test if counter enabled */\r
+ /***************************/\r
+\r
+ if (dw_Status & 0x1)\r
+ {\r
+ \r
+ switch(b_ReadType)\r
+ {\r
+
+ case APCI1710_TOR_GETPROGRESSSTATUS:\r
+ /*******************/\r
+ /* Read the status */\r
+ /*******************/\r
+ \r
+ dw_Status=inl(devpriv->s_BoardInfos.\r
+ ui_Address + 4 + (16 * b_TorCounter) + (64 * b_ModulNbr));\r
+\r
+ dw_Status = dw_Status & 0xF;\r
+\r
+ /*****************/\r
+ /* Test if start */\r
+ /*****************/\r
+\r
+ if (dw_Status & 1)\r
+ {\r
+ if (dw_Status & 2)\r
+ {\r
+ if (dw_Status & 4)\r
+ {\r
+ /************************/\r
+ /* Tor counter owerflow */\r
+ /************************/\r
+\r
+ *pb_TorCounterStatus = 3;\r
+ }\r
+ else\r
+ {\r
+ /***********************/\r
+ /* Tor counter started */\r
+ /***********************/\r
+\r
+ *pb_TorCounterStatus = 2;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***********************/\r
+ /* Tor counter started */\r
+ /***********************/\r
+\r
+ *pb_TorCounterStatus = 1;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***************************/\r
+ /* Tor counter not started */\r
+ /***************************/\r
+\r
+ *pb_TorCounterStatus = 0;\r
+ }\r
+ break;\r
+\r
+ case APCI1710_TOR_GETCOUNTERVALUE :\r
+ \r
+ /*****************************/\r
+ /* Test the timout parameter */\r
+ /*****************************/\r
+\r
+ if ((ui_TimeOut >= 0) && (ui_TimeOut <= 65535UL))\r
+ {\r
+ for (;;)\r
+ {\r
+ /*******************/\r
+ /* Read the status */\r
+ /*******************/\r
+
+ dw_Status=inl(devpriv->s_BoardInfos.\r
+ ui_Address + 4 + (16 * b_TorCounter) + (64 * b_ModulNbr));\r
+ /********************/\r
+ /* Test if overflow */\r
+ /********************/\r
+\r
+ if ((dw_Status & 4) == 4)\r
+ {\r
+ /******************/\r
+ /* Overflow occur */\r
+ /******************/\r
+\r
+ *pb_TorCounterStatus = 3;\r
+\r
+ /******************/\r
+ /* Read the value */\r
+ /******************/\r
+\r
+ \r
+ *pul_TorCounterValue=inl(devpriv->s_BoardInfos.\r
+ ui_Address + 0 + (16 * b_TorCounter) + (64 * b_ModulNbr));\r
+ break;\r
+ } // if ((dw_Status & 4) == 4)\r
+ else\r
+ {\r
+ /*******************************/\r
+ /* Test if measurement stopped */\r
+ /*******************************/\r
+\r
+ if ((dw_Status & 2) == 2)\r
+ {\r
+ /***********************/\r
+ /* A stop signal occur */\r
+ /***********************/\r
+\r
+ *pb_TorCounterStatus = 2;\r
+\r
+ /******************/\r
+ /* Read the value */\r
+ /******************/\r
+\r\r
+ *pul_TorCounterValue=inl(devpriv->s_BoardInfos.\r
+ ui_Address + 0 + (16 * b_TorCounter) + (64 * b_ModulNbr));\r
+\r
+ break;\r
+ } // if ((dw_Status & 2) == 2)\r
+ else\r
+ {\r
+ /*******************************/\r
+ /* Test if measurement started */\r
+ /*******************************/\r
+\r
+ if ((dw_Status & 1) == 1)\r
+ {\r
+ /************************/\r
+ /* A start signal occur */\r
+ /************************/\r
+\r
+ *pb_TorCounterStatus = 1;\r
+ } // if ((dw_Status & 1) == 1)\r
+ else\r
+ {\r
+ /***************************/\r
+ /* Measurement not started */\r
+ /***************************/\r
+\r
+ *pb_TorCounterStatus = 0;\r
+ } // if ((dw_Status & 1) == 1)\r
+ } // if ((dw_Status & 2) == 2)\r
+ } // if ((dw_Status & 8) == 8)\r
+\r
+ if (dw_TimeOut == ui_TimeOut)\r
+ {\r
+ /*****************/\r
+ /* Timeout occur */\r
+ /*****************/\r
+\r
+ break;\r
+ }\r
+ else\r
+ {\r
+ /*************************/\r
+ /* Increment the timeout */\r
+ /*************************/\r
+\r
+ dw_TimeOut = dw_TimeOut + 1;\r
+ \r
+ mdelay(1000);\r
+ }\r
+ } // for (;;)\r
+\r
+ /*************************/\r
+ /* Test if timeout occur */\r
+ /*************************/\r
+\r
+ if ((*pb_TorCounterStatus != 3) && (dw_TimeOut == ui_TimeOut) && (ui_TimeOut != 0))\r
+ {\r
+ /*****************/\r
+ /* Timeout occur */\r
+ /*****************/\r
+\r
+ *pb_TorCounterStatus = 4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /******************************/\r
+ /* Timeout parameter is wrong */\r
+ /******************************/\r
+\r DPRINTK("Timeout parameter is wrong\n");
+ i_ReturnValue = -7;\r
+ }\r
+ break;\r
+
+
+ default:\r
+ printk("Inputs wrong\n");\r
+ } // switch end\r
+ } // if (dw_Status & 0x1)\r
+ else\r
+ {\r
+ /***************************/\r
+ /* Tor counter not enabled */\r
+ /***************************/\r
+\r DPRINTK("Tor counter not enabled\n");
+ i_ReturnValue = -6;\r
+ } // if (dw_Status & 0x1)\r
+ }\r
+ else\r
+ {\r
+ /*******************************/\r
+ /* Tor counter not initialised */\r
+ /*******************************/\r
+\r DPRINTK("Tor counter not initialised\n");
+ i_ReturnValue = -5;\r
+ }\r
+ } // if (b_TorCounter >= 0 && b_TorCounter <= 1)\r
+ else\r
+ {\r
+ /**********************************/\r
+ /* Tor counter selection is wrong */\r
+ /**********************************/\r
+\r DPRINTK("Tor counter selection is wrong\n");
+ i_ReturnValue = -4;\r
+ } // if (b_TorCounter >= 0 && b_TorCounter <= 1)\r
+ }\r
+ else\r
+ {\r
+ /******************************************/\r
+ /* The module is not a tor counter module */\r
+ /******************************************/\r
+\r DPRINTK("The module is not a tor counter module\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***********************/\r
+ /* Module number error */\r
+ /***********************/\r
+\r DPRINTK("Module number error\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
--- /dev/null
+\r
+\r
+\r\r
+ #define APCI1710_30MHZ 30\r
+ #define APCI1710_33MHZ 33\r
+ #define APCI1710_40MHZ 40\r
+
+\r
+
+ #define APCI1710_GATE_INPUT 10\r
+
+\r
+#define APCI1710_TOR_SIMPLE_MODE 2\r
+#define APCI1710_TOR_DOUBLE_MODE 3\r
+#define APCI1710_TOR_QUADRUPLE_MODE 4\r
+\r
+
+#define APCI1710_SINGLE 0\r
+#define APCI1710_CONTINUOUS 1\r
+
+\r
+#define APCI1710_TOR_GETPROGRESSSTATUS 0\r
+#define APCI1710_TOR_GETCOUNTERVALUE 1
+#define APCI1710_TOR_READINTERRUPT 2\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| TOR_COUNTER INISIALISATION FUNCTION |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+INT i_APCI1710_InsnConfigInitTorCounter(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data);\r
+\r
+
+\r
+\r
+\r
+\r
+INT i_APCI1710_InsnWriteEnableDisableTorCounter (comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data);\r
+
+\r
+INT i_APCI1710_InsnReadGetTorCounterInitialisation(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data);\r
+/*\r
++----------------------------------------------------------------------------+\r
+| TOR_COUNTER READ FUNCTION |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+
+\r
+INT i_APCI1710_InsnBitsGetTorCounterProgressStatusAndValue(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data);\r
--- /dev/null
+
+
+
+/*\r
+ +-----------------------------------------------------------------------+\r
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |\r
+ +-----------------------------------------------------------------------+\r
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |\r
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |\r
+ +-----------------------------------------------------------------------+\r
+ | Project : API APCI1710 | Compiler : BORLANDC/MICROSOFT C |\r
+ | Module name : TTL.C | Version : 3.1 / 6.0 |\r
+ +-------------------------------+---------------------------------------+\r
+ | Author : S.WEBER | Date : 04.06.98 |\r
+ +-----------------------------------------------------------------------+\r
+ | Description : APCI-1710 TTL I/O module |\r
+ | |\r
+ | |\r
+ +-----------------------------------------------------------------------+\r
+ | UPDATES |\r
+ +-----------------------------------------------------------------------+\r
+ | Date | Author | Description of updates |\r
+ +----------+-----------+------------------------------------------------+\r
+ | 13/05/98 | S. Weber | TTL digital input / output implementation |\r
+ |----------|-----------|------------------------------------------------|\r
+ | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |\r
+ | | | available |\r
+ +-----------------------------------------------------------------------+\r
+ | | | |\r
+ | | | |\r
+ +-----------------------------------------------------------------------+\r
+*/\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Included files |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+#include "APCI1710_Ttl.h"\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_InitTTLIODirection |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_PortAMode, |\r
+| BYTE_ b_PortBMode, |\r
+| BYTE_ b_PortCMode, |\r
+| BYTE_ b_PortDMode) |\r
++----------------------------------------------------------------------------+\r
+| Task APCI1710_TTL_INIT (using defaults) : Configure the TTL I/O operating mode from selected |\r
+| module (b_ModulNbr). You must calling this function be|\r
+| for you call any other function witch access of TTL. |\r
+ APCI1710_TTL_INITDIRECTION(user inputs for direction) \r
+\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|\r
+| BYTE_ b_ModulNbr : Module number to |\r
+| configure (0 to 3) \r
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);\r
+ b_InitType = (BYTE) data[0];\r
+ b_PortAMode = (BYTE) data[1];\r
+ b_PortBMode = (BYTE) data[2];\r
+ b_PortCMode = (BYTE) data[3];\r
+ b_PortDMode = (BYTE) data[4];|\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: The module parameter is wrong |\r
+| -3: The module is not a TTL module |\r
+| -4: Function not available for this version |\r
+| -5: Port A mode selection is wrong |\r
+| -6: Port B mode selection is wrong |\r
+| -7: Port C mode selection is wrong |\r
+| -8: Port D mode selection is wrong |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+\r
+INT i_APCI1710_InsnConfigInitTTLIO(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data) \r
+ {\r
+ INT i_ReturnValue = 0;\r
+ BYTE b_ModulNbr;\r
+ BYTE b_InitType;\r
+ BYTE b_PortAMode;\r
+ BYTE b_PortBMode;\r
+ BYTE b_PortCMode;\r
+ BYTE b_PortDMode;\r
+\r
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);\r
+ b_InitType = (BYTE) data[0];\r
+ i_ReturnValue = insn->n;\r
+\r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+ \r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /**************************/\r
+ /* Test if TTL I/O module */\r
+ /**************************/\r
+\r
+ if ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_TTL_IO)\r
+ {\r
+ switch(b_InitType)\r
+ {\r
+ case APCI1710_TTL_INIT :\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_TTLIOInfo.b_TTLInit = 1;\r
+\r
+ /***************************/\r
+ /* Set TTL port A to input */\r
+ /***************************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_TTLIOInfo.\r
+ b_PortConfiguration [0] = 0;\r
+\r
+ /***************************/\r
+ /* Set TTL port B to input */\r
+ /***************************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_TTLIOInfo.\r
+ b_PortConfiguration [1] = 0;\r
+\r
+ /***************************/\r
+ /* Set TTL port C to input */\r
+ /***************************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_TTLIOInfo.\r
+ b_PortConfiguration [2] = 0;\r
+\r
+ /****************************/\r
+ /* Set TTL port D to output */\r
+ /****************************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_TTLIOInfo.\r
+ b_PortConfiguration [3] = 1;\r
+\r
+ /*************************/\r
+ /* Set the configuration */\r
+ /*************************/\r
+
+ outl(0x8,devpriv->s_BoardInfos.ui_Address + 20 + (64 * b_ModulNbr));\r
+ break;\r
+\r
+\r
+ case APCI1710_TTL_INITDIRECTION :\r
+\r
+ b_PortAMode = (BYTE) data[1];\r
+ b_PortBMode = (BYTE) data[2];\r
+ b_PortCMode = (BYTE) data[3];\r
+ b_PortDMode = (BYTE) data[4];\r
+\r
+ /********************/\r
+ /* Test the version */\r
+ /********************/\r
+\r
+ if ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF) >= 0x3230)\r
+ {\r
+ /************************/\r
+ /* Test the port A mode */\r
+ /************************/\r
+\r
+ if ((b_PortAMode == 0) || (b_PortAMode == 1))\r
+ {\r
+ /************************/\r
+ /* Test the port B mode */\r
+ /************************/\r
+\r
+ if ((b_PortBMode == 0) || (b_PortBMode == 1))\r
+ {\r
+ /************************/\r
+ /* Test the port C mode */\r
+ /************************/\r
+\r
+ if ((b_PortCMode == 0) || (b_PortCMode == 1))\r
+ {\r
+ /************************/\r
+ /* Test the port D mode */\r
+ /************************/\r
+\r
+ if ((b_PortDMode == 0) || (b_PortDMode == 1))\r
+ {\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_TTLIOInfo.\r
+ b_TTLInit = 1;\r
+\r
+ /***********************/\r
+ /* Set TTL port A mode */\r
+ /***********************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_TTLIOInfo.\r
+ b_PortConfiguration [0] = b_PortAMode;\r
+\r
+ /***********************/\r
+ /* Set TTL port B mode */\r
+ /***********************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_TTLIOInfo.\r
+ b_PortConfiguration [1] = b_PortBMode;\r
+\r
+ /***********************/\r
+ /* Set TTL port C mode */\r
+ /***********************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_TTLIOInfo.\r
+ b_PortConfiguration [2] = b_PortCMode;\r
+\r
+ /***********************/\r
+ /* Set TTL port D mode */\r
+ /***********************/\r
+\r
+ devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_TTLIOInfo.\r
+ b_PortConfiguration [3] = b_PortDMode;\r
+\r
+ /*************************/\r
+ /* Set the configuration */\r
+ /*************************/\r
+\r
+
+ outl((b_PortAMode << 0) |\r
+ (b_PortBMode << 1) |\r
+ (b_PortCMode << 2) |\r
+ (b_PortDMode << 3),devpriv->s_BoardInfos.\r
+ ui_Address + 20 + (64 * b_ModulNbr));\r
+ }\r
+ else\r
+ {\r
+ /**********************************/\r
+ /* Port D mode selection is wrong */\r
+ /**********************************/\r
+\r DPRINTK("Port D mode selection is wrong\n");
+ i_ReturnValue = -8;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /**********************************/\r
+ /* Port C mode selection is wrong */\r
+ /**********************************/\r
+\r DPRINTK("Port C mode selection is wrong\n");
+ i_ReturnValue = -7;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /**********************************/\r
+ /* Port B mode selection is wrong */\r
+ /**********************************/\r
+\r DPRINTK("Port B mode selection is wrong\n");
+ i_ReturnValue = -6;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /**********************************/\r
+ /* Port A mode selection is wrong */\r
+ /**********************************/\r
+\r DPRINTK("Port A mode selection is wrong\n");
+ i_ReturnValue = -5;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*******************************************/\r
+ /* Function not available for this version */\r
+ /*******************************************/\r
+\r DPRINTK("Function not available for this version\n");
+ i_ReturnValue = -4;\r
+ }\r
+ break;\r
+\r DPRINTK("\n");
+ default:\r
+ printk("Bad Config Type\n");\r
+ }// switch end\r
+ }\r
+ else\r
+ {\r
+ /**********************************/\r
+ /* The module is not a TTL module */\r
+ /**********************************/\r
+\r DPRINTK("The module is not a TTL module\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***********************/\r
+ /* Module number error */\r
+ /***********************/\r
+\r DPRINTK("Module number error\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| INPUT FUNCTIONS |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_ReadTTLIOChannelValue |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_SelectedPort, |\r
+| BYTE_ b_InputChannel, |\r
+| PBYTE_ pb_ChannelStatus) |\r
++----------------------------------------------------------------------------+\r
+| Task : Read the status from selected TTL digital input |\r
+| (b_InputChannel) \r
++----------------------------------------------------------------------------+\r
+| Task : Read the status from digital input port |\r
+| (b_SelectedPort) from selected TTL module (b_ModulNbr) |\r
++----------------------------------------------------------------------------+ \r
+
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|\r
+| BYTE_ b_ModulNbr : Module number to |\r
+| configure (0 to 7) |\r
+| BYTE_ b_SelectedPort, : Selection from TTL I/O |\r
+| port (0 to 2) |\r
+| 0 : Port A selection |\r
+| 1 : Port B selection |\r
+| 2 : Port C selection |\r
+| 3 : Port D selection |\r
+| BYTE_ b_InputChannel : Selection from digital |\r
+| input ( 0 to 2) \r
+APCI1710_TTL_READCHANNEL \r
+ b_ModulNbr = CR_AREF(insn->chanspec);\r
+ b_SelectedPort= CR_RANGE(insn->chanspec);\r
+ b_InputChannel= CR_CHAN(insn->chanspec);\r
+ b_ReadType = (BYTE) data[0];\r
+\r
+ APCI1710_TTL_READPORT|\r
+ b_ModulNbr = CR_AREF(insn->chanspec);\r
+ b_SelectedPort= CR_RANGE(insn->chanspec);\r
+ b_ReadType = (BYTE) data[0];\r
+\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : data[0]\r
+\r
+ PBYTE_ pb_ChannelStatus : Digital input channel |\r
+| status |\r
+| 0 : Channle is not active|\r
+| 1 : Channle is active |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: The module parameter is wrong |\r
+| -3: The module is not a TTL module |\r
+| -4: The selected TTL input port is wrong |\r
+| -5: The selected TTL digital input is wrong |\r
+| -6: TTL I/O not initialised |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+\r
+INT i_APCI1710_InsnBitsReadTTLIO(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data)\r
+ {\r
+ INT i_ReturnValue = 0;\r
+ DWORD dw_StatusReg;\r
+ BYTE b_ModulNbr;\r
+ BYTE b_SelectedPort;\r
+ BYTE b_InputChannel;\r
+ BYTE b_ReadType;\r
+ PBYTE pb_ChannelStatus;\r
+ PBYTE pb_PortValue;\r
+
+ \r
+ i_ReturnValue = insn->n;\r
+ b_ReadType = (BYTE) data[0];\r
+ b_ModulNbr = CR_AREF(insn->chanspec);\r
+ b_SelectedPort= CR_RANGE(insn->chanspec);\r
+ b_InputChannel= CR_CHAN(insn->chanspec);\r
+\r
+ \r
+ \r
+ \r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /**************************/\r
+ /* Test if TTL I/O module */\r
+ /**************************/\r
+\r
+ if ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_TTL_IO)\r
+ {\r
+ switch(b_ReadType)\r
+ {\r
+\r
+ case APCI1710_TTL_READCHANNEL:\r
+ pb_ChannelStatus = (PBYTE) &data[0];\r
+ /********************************/\r
+ /* Test the TTL I/O port number */\r
+ /********************************/\r
+\r
+ if ((((b_SelectedPort >= 0) && (b_SelectedPort <= 2)) && ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF) == 0x3130)) ||\r
+ (((b_SelectedPort >= 0) && (b_SelectedPort <= 3)) && ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF) >= 0x3230)))\r
+ {\r
+ /******************************************/\r
+ /* Test the digital imnput channel number */\r
+ /******************************************/\r
+\r
+ if ((((b_InputChannel >= 0) && (b_InputChannel <= 7)) && (b_SelectedPort < 3)) ||\r
+ (((b_InputChannel >= 0) && (b_InputChannel <= 1)) && (b_SelectedPort == 3)))\r
+ {\r
+ /******************************************/\r
+ /* Test if the TTL I/O module initialised */\r
+ /******************************************/\r
+\r
+ if (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_TTLIOInfo.\r
+ b_TTLInit == 1)\r
+ {\r
+ /***********************************/\r
+ /* Test if TTL port used for input */\r
+ /***********************************/\r
+\r
+ if (((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF) == 0x3130) ||\r
+ (((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF) >= 0x3230) &&\r
+ (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_TTLIOInfo.\r
+ b_PortConfiguration [b_SelectedPort] == 0)))\r
+ {\r
+ /**************************/\r
+ /* Read all digital input */\r
+ /**************************/\r
+
+ dw_StatusReg = inl(devpriv->s_BoardInfos.ui_Address + (64 * b_ModulNbr));\r
+\r
+ *pb_ChannelStatus = (BYTE) ((dw_StatusReg >> (8 * b_SelectedPort)) >>
+ b_InputChannel) & 1;\r
+ }\r
+ else\r
+ {\r
+ /*******************************/\r
+ /* Selected TTL I/O port error */\r
+ /*******************************/\r
+\r DPRINTK("Selected TTL I/O port error\n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***************************/\r
+ /* TTL I/O not initialised */\r
+ /***************************/\r
+\r DPRINTK("TTL I/O not initialised\n");
+ i_ReturnValue = -6;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /********************************/\r
+ /* Selected digital input error */\r
+ /********************************/\r
+\r DPRINTK("Selected digital input error\n");
+ i_ReturnValue = -5;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*******************************/\r
+ /* Selected TTL I/O port error */\r
+ /*******************************/\r
+\r DPRINTK("Selected TTL I/O port error\n");
+ i_ReturnValue = -4;\r
+ }\r
+ break;\r
+\r
+ case APCI1710_TTL_READPORT:\r
+ pb_PortValue = (PBYTE) &data[0];\r
+ /********************************/\r
+ /* Test the TTL I/O port number */\r
+ /********************************/\r
+\r
+ if ((((b_SelectedPort >= 0) && (b_SelectedPort <= 2)) && ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF) == 0x3130)) ||\r
+ (((b_SelectedPort >= 0) && (b_SelectedPort <= 3)) && ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF) >= 0x3230)))\r
+ {\r
+ /******************************************/\r
+ /* Test if the TTL I/O module initialised */\r
+ /******************************************/\r
+\r
+ if (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_TTLIOInfo.\r
+ b_TTLInit == 1)\r
+ {\r
+ /***********************************/\r
+ /* Test if TTL port used for input */\r
+ /***********************************/\r
+\r
+ if (((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF) == 0x3130) ||\r
+ (((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF) >= 0x3230) &&\r
+ (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_TTLIOInfo.\r
+ b_PortConfiguration [b_SelectedPort] == 0)))\r
+ {\r
+ /**************************/\r
+ /* Read all digital input */\r
+ /**************************/\r
+
+ dw_StatusReg=inl(devpriv->s_BoardInfos.ui_Address + (64 * b_ModulNbr));\r
+\r
+ *pb_PortValue = (BYTE) ((dw_StatusReg >> (8 * b_SelectedPort)) & 0xFF);\r
+ }\r
+ else\r
+ {\r
+ /*******************************/\r
+ /* Selected TTL I/O port error */\r
+ /*******************************/\r
+\r DPRINTK("Selected TTL I/O port error\n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***************************/\r
+ /* TTL I/O not initialised */\r
+ /***************************/\r
+\r DPRINTK("TTL I/O not initialised\n");
+ i_ReturnValue = -5;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /*******************************/\r
+ /* Selected TTL I/O port error */\r
+ /*******************************/\r
+\r DPRINTK("Selected TTL I/O port error\n");
+ i_ReturnValue = -4;\r
+ }\r
+ break;\r
+\r
+ default:\r
+ printk("Bad ReadType\n");\r
+ \r
+ }//End Switch\r
+ }\r
+ else\r
+ {\r
+ /**********************************/\r
+ /* The module is not a TTL module */\r
+ /**********************************/\r
+\r DPRINTK("The module is not a TTL module\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***********************/\r
+ /* Module number error */\r
+ /***********************/\r
+\r DPRINTK("Module number error\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI1710_InsnReadTTLIOAllPortValue(comedi_device
+*dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Read the status from all digital input ports |
+| (port A, port B and port C) from selected TTL |
+| module (b_ModulNbr) |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|
+| BYTE_ b_ModulNbr : Module number to |
+| configure (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pul_PortValue : Digital TTL inputs port |
+| status |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The module parameter is wrong |
+| -3: The module is not a TTL module |
+| -4: TTL I/O not initialised |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnReadTTLIOAllPortValue(comedi_device *dev,comedi_subdevice *s,
+comedi_insn *insn,lsampl_t *data)
+ {
+ INT i_ReturnValue = 0;
+ DWORD dw_StatusReg;
+ BYTE b_ModulNbr;
+ PULONG pul_PortValue;
+
+ b_ModulNbr=(BYTE) CR_AREF(insn->chanspec);
+ i_ReturnValue=insn->n;
+ pul_PortValue=(PULONG) &data[0];
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4)
+ {
+ /**************************/
+ /* Test if TTL I/O module */
+ /**************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_TTL_IO)
+ {
+ /******************************************/
+ /* Test if the TTL I/O module initialised */
+ /******************************************/
+
+ if (devpriv->
+ s_ModuleInfo [b_ModulNbr].
+ s_TTLIOInfo.
+ b_TTLInit == 1)
+ {
+ /**************************/
+ /* Read all digital input */
+ /**************************/
+
+
+ dw_StatusReg=inl(devpriv->s_BoardInfos.
+ ui_Address + (64 * b_ModulNbr));
+
+ /**********************/
+ /* Test if TTL Rev1.0 */
+ /**********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF) == 0x3130)
+ {
+ *pul_PortValue = dw_StatusReg & 0xFFFFFFUL;
+ }
+ else
+ {
+ /**************************************/
+ /* Test if port A not used for output */
+ /**************************************/
+
+ if (devpriv->s_ModuleInfo [b_ModulNbr].
+ s_TTLIOInfo.b_PortConfiguration [0] == 1)
+ {
+ *pul_PortValue = dw_StatusReg & 0x3FFFF00UL;
+ }
+
+ /**************************************/
+ /* Test if port B not used for output */
+ /**************************************/
+
+ if (devpriv->
+ s_ModuleInfo [b_ModulNbr].
+ s_TTLIOInfo.
+ b_PortConfiguration [1] == 1)
+ {
+ *pul_PortValue = dw_StatusReg & 0x3FF00FFUL;
+ }
+
+ /**************************************/
+ /* Test if port C not used for output */
+ /**************************************/
+
+ if (devpriv->
+ s_ModuleInfo [b_ModulNbr].
+ s_TTLIOInfo.
+ b_PortConfiguration [2] == 1)
+ {
+ *pul_PortValue = dw_StatusReg & 0x300FFFFUL;
+ }
+
+ /**************************************/
+ /* Test if port D not used for output */
+ /**************************************/
+
+ if (devpriv->
+ s_ModuleInfo [b_ModulNbr].
+ s_TTLIOInfo.
+ b_PortConfiguration [3] == 1)
+ {
+ *pul_PortValue = dw_StatusReg & 0xFFFFFFUL;
+ }
+ }
+ }
+ else
+ {
+ /***************************/
+ /* TTL I/O not initialised */
+ /***************************/
+ DPRINTK("TTL I/O not initialised\n");
+ i_ReturnValue = -5;
+ }
+ }
+ else
+ {
+ /**********************************/
+ /* The module is not a TTL module */
+ /**********************************/
+ DPRINTK("The module is not a TTL module\n");
+ i_ReturnValue = -3;
+ }
+ }
+ else
+ {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+ }
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| OUTPUT FUNCTIONS |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : _INT_ i_APCI1710_SetTTLIOChlOn |\r
+| (BYTE_ b_BoardHandle, |\r
+| BYTE_ b_ModulNbr, |\r
+| BYTE_ b_OutputChannel) \r
+INT i_APCI1710_InsnWriteSetTTLIOChlOnOff(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data) |\r
++----------------------------------------------------------------------------+\r
+| Task : Sets or resets the output witch has been passed with the |\r
+| parameter b_Channel. Setting an output means setting |\r
+| an ouput high. |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |\r
+| BYTE_ b_ModulNbr : Selected module number (0 to 3)|\r
+| BYTE_ b_OutputChannel : Selection from digital output |\r
+| channel (0 or 1) |\r
+| 0 : PD0 |\r
+| 1 : PD1 |\r
+| 2 to 9 : PA |\r
+| 10 to 17: PB |\r
+| 18 to 25: PC |\r
+\r
+ b_ModulNbr = CR_AREF(insn->chanspec);\r
+ b_OutputChannel= CR_CHAN(insn->chanspec);\r
+ ui_State = data[0]; // ON or OFF\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : 0: No error |\r
+| -1: The handle parameter of the board is wrong |\r
+| -2: The module parameter is wrong |\r
+| -3: The module is not a TTL I/O module |\r
+| -4: The selected digital output is wrong |\r
+| -5: TTL I/O not initialised see function |\r
+| " i_APCI1710_InitTTLIO"\r
++----------------------------------------------------------------------------+\r
+*/\r
+
+INT i_APCI1710_InsnWriteSetTTLIOChlOnOff(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data)\r
+ {\r
+ INT i_ReturnValue = 0; \r
+ DWORD dw_StatusReg = 0;\r
+ BYTE b_ModulNbr;\r
+ BYTE b_OutputChannel;\r
+ UINT ui_State;\r
+\r
+ i_ReturnValue = insn->n;\r
+ b_ModulNbr = CR_AREF(insn->chanspec);\r
+ b_OutputChannel= CR_CHAN(insn->chanspec);\r
+ ui_State = data[0]; // ON or OFF\r
+\r
+ /**************************/\r
+ /* Test the module number */\r
+ /**************************/\r
+\r
+ if (b_ModulNbr < 4)\r
+ {\r
+ /**************************/\r
+ /* Test if TTL I/O module */\r
+ /**************************/\r
+\r
+ if ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF0000UL) == APCI1710_TTL_IO)\r
+ {\r
+ /******************************************/\r
+ /* Test if the TTL I/O module initialised */\r
+ /******************************************/\r
+\r
+ if (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_TTLIOInfo.\r
+ b_TTLInit == 1)\r
+ {\r
+ /***********************************/\r
+ /* Test the TTL I/O channel number */\r
+ /***********************************/\r
+\r
+ if ((((b_OutputChannel >= 0) && (b_OutputChannel <= 1)) && ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF) == 0x3130)) ||\r
+ (((b_OutputChannel >= 0) && (b_OutputChannel <= 25)) && ((devpriv->s_BoardInfos.\r
+ dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF) >= 0x3230)))\r
+ {\r
+ /****************************************************/\r
+ /* Test if the selected channel is a output channel */\r
+ /****************************************************/\r
+\r
+ if (((b_OutputChannel >= 0) && (b_OutputChannel <= 1) && (devpriv->\r
+ s_ModuleInfo [b_ModulNbr].\r
+ s_TTLIOInfo.\r
+ b_PortConfiguration [3] == 1)) ||\r
+ ((b_OutputChannel >= 2) && (b_OutputChannel <= 9) && (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_TTLIOInfo.\r
+ b_PortConfiguration [0] == 1)) ||\r
+ ((b_OutputChannel >= 10) && (b_OutputChannel <= 17) && (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_TTLIOInfo.\r
+ b_PortConfiguration [1] == 1)) ||\r
+ ((b_OutputChannel >= 18) && (b_OutputChannel <= 25) && (devpriv->s_ModuleInfo [b_ModulNbr].\r
+ s_TTLIOInfo.\r
+ b_PortConfiguration [2] == 1)))\r
+ {\r
+ /************************/\r
+ /* Test if PD0 selected */\r
+ /************************/\r
+\r
+ if (b_OutputChannel == 0)\r
+ {\r
+
+ outl(ui_State,devpriv->s_BoardInfos.\r
+ ui_Address + (64 * b_ModulNbr));\r
+ }\r
+ else\r
+ {\r
+ /************************/\r
+ /* Test if PD1 selected */\r
+ /************************/\r
+\r
+ if (b_OutputChannel == 1)\r
+ {\r
+\r
+ outl(ui_State,devpriv->s_BoardInfos.\r
+ ui_Address + 4 + (64 * b_ModulNbr));\r
+ }\r
+ else\r
+ {\r
+ b_OutputChannel = b_OutputChannel - 2;\r
+\r
+ /********************/\r
+ /* Read all channel */\r
+ /********************/\r
+\r
+
+ dw_StatusReg =inl(devpriv->s_BoardInfos.\r
+ ui_Address + (64 * b_ModulNbr));\r
+ if(ui_State) // ON\r
+ {\r
+ dw_StatusReg = (dw_StatusReg >> ((b_OutputChannel / 8) * 8)) & 0xFF;\r
+ dw_StatusReg = dw_StatusReg | (1 << (b_OutputChannel % 8));\r
+ }else // Off\r
+ {\r
+ dw_StatusReg = (dw_StatusReg >> ((b_OutputChannel / 8) * 8)) & 0xFF;\r
+ dw_StatusReg = dw_StatusReg & (0xFF - (1 << (b_OutputChannel % 8)));\r
+\r
+ }\r
+\r
+ /****************************/\r
+ /* Set the new output value */\r
+ /****************************/\r
+\r
+ \r
+ outl(dw_StatusReg,devpriv->s_BoardInfos.\r
+ ui_Address + 8 + ((b_OutputChannel / 8) * 4) + (64 * b_ModulNbr));\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /************************************/\r
+ /* The selected TTL output is wrong */\r
+ /************************************/\r
+\r DPRINTK(" The selected TTL output is wrong\n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /************************************/\r
+ /* The selected TTL output is wrong */\r
+ /************************************/\r
+\r DPRINTK("The selected TTL output is wrong\n");
+ i_ReturnValue = -4;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***************************/\r
+ /* TTL I/O not initialised */\r
+ /***************************/\r
+\r DPRINTK("TTL I/O not initialised\n");
+ i_ReturnValue = -5;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /**************************************/\r
+ /* The module is not a TTL I/O module */\r
+ /**************************************/\r
+\r DPRINTK("The module is not a TTL I/O module\n");
+ i_ReturnValue = -3;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /***********************/\r
+ /* Module number error */\r
+ /***********************/\r
+\r DPRINTK("Module number error\n");
+ i_ReturnValue = -2;\r
+ }\r
+\r
+ return (i_ReturnValue);\r
+ }\r
+\r
+\r
--- /dev/null
+\r
+\r
+
+\r
+#define APCI1710_TTL_INIT 0\r
+#define APCI1710_TTL_INITDIRECTION 1\r
+\r
+\r
+#define APCI1710_TTL_READCHANNEL 0\r
+#define APCI1710_TTL_READPORT 1\r
+
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| TTL INISIALISATION FUNCTION |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+\r
+ INT i_APCI1710_InsnConfigInitTTLIO(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data);\r
+/*\r
++----------------------------------------------------------------------------+\r
+| TTL INPUT FUNCTION |\r
++----------------------------------------------------------------------------+\r
+*/\r
+
+ INT i_APCI1710_InsnBitsReadTTLIO(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data);\r
+ INT i_APCI1710_InsnReadTTLIOAllPortValue(comedi_device *dev,comedi_subdevice *s,
+ comedi_insn *insn,lsampl_t *data);
+/*\r
++----------------------------------------------------------------------------+\r
+| TTL OUTPUT FUNCTIONS |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+ INT i_APCI1710_InsnWriteSetTTLIOChlOnOff(comedi_device *dev,comedi_subdevice *s,\r
+ comedi_insn *insn,lsampl_t *data);\r
--- /dev/null
+
+AM_CFLAGS = $(COMEDI_CFLAGS) $(LINUX_CFLAGS)
+LINK = $(top_builddir)/modtool --link -o $@
+
+module_PROGRAMS = addi_common.ko
+
+addi_common_ko_SOURCES = addi_common.c
+
--- /dev/null
+
+//addi_amcc_s5933.h
+
+/*
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstrasse 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 : ADDI DATA | Compiler : GCC |
+ | Modulname : addi_amcc_s5933.h | Version : 2.96 Redhat Linux |
+ | | kernel-2.4.2 |
+ +-------------------------------+---------------------------------------+
+ | Author : | Date : |
+ +-----------------------------------------------------------------------+
+ | Description :|Header file for AMCC s 5933 |
+ +-----------------------------------------------------------------------+
+ | UPDATE'S |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+
+#ifndef _AMCC_S5933_H_
+#define _AMCC_S5933_H_
+
+#include <linux/pci.h>
+#include <linux/comedidev.h>
+
+#ifdef PCI_SUPPORT_VER1
+#error No support for 2.1.55 and older
+#endif
+
+#define FIFO_ADVANCE_ON_BYTE_2 0x20000000 // written on base0
+
+#define AMWEN_ENABLE 0x02 // added for step 6 dma written on base2
+#define A2P_FIFO_WRITE_ENABLE 0x01
+
+#define AGCSTS_TC_ENABLE 0x10000000 // for transfer count enable bit
+
+// ADDON RELATED ADDITIONS
+// Constant
+ #define APCI3120_ENABLE_TRANSFER_ADD_ON_LOW 0x00
+ #define APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH 0x1200
+ #define APCI3120_A2P_FIFO_MANAGEMENT 0x04000400L
+ #define APCI3120_AMWEN_ENABLE 0x02
+ #define APCI3120_A2P_FIFO_WRITE_ENABLE 0x01
+ #define APCI3120_FIFO_ADVANCE_ON_BYTE_2 0x20000000L
+ #define APCI3120_ENABLE_WRITE_TC_INT 0x00004000L
+ #define APCI3120_CLEAR_WRITE_TC_INT 0x00040000L
+ #define APCI3120_DISABLE_AMWEN_AND_A2P_FIFO_WRITE 0x0
+ #define APCI3120_DISABLE_BUS_MASTER_ADD_ON 0x0
+ #define APCI3120_DISABLE_BUS_MASTER_PCI 0x0
+
+ // ADD_ON ::: this needed since apci supports 16 bit interface to add on
+ #define APCI3120_ADD_ON_AGCSTS_LOW 0x3C
+ #define APCI3120_ADD_ON_AGCSTS_HIGH APCI3120_ADD_ON_AGCSTS_LOW + 2
+ #define APCI3120_ADD_ON_MWAR_LOW 0x24
+ #define APCI3120_ADD_ON_MWAR_HIGH APCI3120_ADD_ON_MWAR_LOW + 2
+ #define APCI3120_ADD_ON_MWTC_LOW 0x058
+ #define APCI3120_ADD_ON_MWTC_HIGH APCI3120_ADD_ON_MWTC_LOW + 2
+
+// AMCC
+ #define APCI3120_AMCC_OP_MCSR 0x3C
+ #define APCI3120_AMCC_OP_REG_INTCSR 0x38
+
+/****************************************************************************/
+/* AMCC Operation Register Offsets - PCI */
+/****************************************************************************/
+
+#define AMCC_OP_REG_OMB1 0x00
+#define AMCC_OP_REG_OMB2 0x04
+#define AMCC_OP_REG_OMB3 0x08
+#define AMCC_OP_REG_OMB4 0x0c
+#define AMCC_OP_REG_IMB1 0x10
+#define AMCC_OP_REG_IMB2 0x14
+#define AMCC_OP_REG_IMB3 0x18
+#define AMCC_OP_REG_IMB4 0x1c
+#define AMCC_OP_REG_FIFO 0x20
+#define AMCC_OP_REG_MWAR 0x24
+#define AMCC_OP_REG_MWTC 0x28
+#define AMCC_OP_REG_MRAR 0x2c
+#define AMCC_OP_REG_MRTC 0x30
+#define AMCC_OP_REG_MBEF 0x34
+#define AMCC_OP_REG_INTCSR 0x38
+#define AMCC_OP_REG_INTCSR_SRC (AMCC_OP_REG_INTCSR + 2) /* INT source */
+#define AMCC_OP_REG_INTCSR_FEC (AMCC_OP_REG_INTCSR + 3) /* FIFO ctrl */
+#define AMCC_OP_REG_MCSR 0x3c
+#define AMCC_OP_REG_MCSR_NVDATA (AMCC_OP_REG_MCSR + 2) /* Data in byte 2 */
+#define AMCC_OP_REG_MCSR_NVCMD (AMCC_OP_REG_MCSR + 3) /* Command in byte 3 */
+
+#define AMCC_FIFO_DEPTH_DWORD 8
+#define AMCC_FIFO_DEPTH_BYTES (8 * sizeof (u32))
+
+/****************************************************************************/
+/* AMCC Operation Registers Size - PCI */
+/****************************************************************************/
+
+#define AMCC_OP_REG_SIZE 64 /* in bytes */
+
+/****************************************************************************/
+/* AMCC Operation Register Offsets - Add-on */
+/****************************************************************************/
+
+#define AMCC_OP_REG_AIMB1 0x00
+#define AMCC_OP_REG_AIMB2 0x04
+#define AMCC_OP_REG_AIMB3 0x08
+#define AMCC_OP_REG_AIMB4 0x0c
+#define AMCC_OP_REG_AOMB1 0x10
+#define AMCC_OP_REG_AOMB2 0x14
+#define AMCC_OP_REG_AOMB3 0x18
+#define AMCC_OP_REG_AOMB4 0x1c
+#define AMCC_OP_REG_AFIFO 0x20
+#define AMCC_OP_REG_AMWAR 0x24
+#define AMCC_OP_REG_APTA 0x28
+#define AMCC_OP_REG_APTD 0x2c
+#define AMCC_OP_REG_AMRAR 0x30
+#define AMCC_OP_REG_AMBEF 0x34
+#define AMCC_OP_REG_AINT 0x38
+#define AMCC_OP_REG_AGCSTS 0x3c
+#define AMCC_OP_REG_AMWTC 0x58
+#define AMCC_OP_REG_AMRTC 0x5c
+
+/****************************************************************************/
+/* AMCC - Add-on General Control/Status Register */
+/****************************************************************************/
+
+#define AGCSTS_CONTROL_MASK 0xfffff000
+#define AGCSTS_NV_ACC_MASK 0xe0000000
+#define AGCSTS_RESET_MASK 0x0e000000
+#define AGCSTS_NV_DA_MASK 0x00ff0000
+#define AGCSTS_BIST_MASK 0x0000f000
+#define AGCSTS_STATUS_MASK 0x000000ff
+#define AGCSTS_TCZERO_MASK 0x000000c0
+#define AGCSTS_FIFO_ST_MASK 0x0000003f
+
+#define AGCSTS_RESET_MBFLAGS 0x08000000
+#define AGCSTS_RESET_P2A_FIFO 0x04000000
+#define AGCSTS_RESET_A2P_FIFO 0x02000000
+#define AGCSTS_RESET_FIFOS (AGCSTS_RESET_A2P_FIFO | AGCSTS_RESET_P2A_FIFO)
+
+#define AGCSTS_A2P_TCOUNT 0x00000080
+#define AGCSTS_P2A_TCOUNT 0x00000040
+
+#define AGCSTS_FS_P2A_EMPTY 0x00000020
+#define AGCSTS_FS_P2A_HALF 0x00000010
+#define AGCSTS_FS_P2A_FULL 0x00000008
+
+#define AGCSTS_FS_A2P_EMPTY 0x00000004
+#define AGCSTS_FS_A2P_HALF 0x00000002
+#define AGCSTS_FS_A2P_FULL 0x00000001
+
+/****************************************************************************/
+/* AMCC - Add-on Interrupt Control/Status Register */
+/****************************************************************************/
+
+#define AINT_INT_MASK 0x00ff0000
+#define AINT_SEL_MASK 0x0000ffff
+#define AINT_IS_ENSEL_MASK 0x00001f1f
+
+#define AINT_INT_ASSERTED 0x00800000
+#define AINT_BM_ERROR 0x00200000
+#define AINT_BIST_INT 0x00100000
+
+#define AINT_RT_COMPLETE 0x00080000
+#define AINT_WT_COMPLETE 0x00040000
+
+#define AINT_OUT_MB_INT 0x00020000
+#define AINT_IN_MB_INT 0x00010000
+
+#define AINT_READ_COMPL 0x00008000
+#define AINT_WRITE_COMPL 0x00004000
+
+#define AINT_OMB_ENABLE 0x00001000
+#define AINT_OMB_SELECT 0x00000c00
+#define AINT_OMB_BYTE 0x00000300
+
+#define AINT_IMB_ENABLE 0x00000010
+#define AINT_IMB_SELECT 0x0000000c
+#define AINT_IMB_BYTE 0x00000003
+
+/* Enable Bus Mastering */
+#define EN_A2P_TRANSFERS 0x00000400
+/* FIFO Flag Reset */
+#define RESET_A2P_FLAGS 0x04000000L
+/* FIFO Relative Priority */
+#define A2P_HI_PRIORITY 0x00000100L
+/* Identify Interrupt Sources */
+#define ANY_S593X_INT 0x00800000L
+#define READ_TC_INT 0x00080000L
+#define WRITE_TC_INT 0x00040000L
+#define IN_MB_INT 0x00020000L
+#define MASTER_ABORT_INT 0x00100000L
+#define TARGET_ABORT_INT 0x00200000L
+#define BUS_MASTER_INT 0x00200000L
+
+/****************************************************************************/
+
+struct pcilst_struct{
+ struct pcilst_struct *next;
+ int used;
+ struct pci_dev *pcidev;
+ unsigned short vendor;
+ unsigned short device;
+ unsigned int master;
+ unsigned char pci_bus;
+ unsigned char pci_slot;
+ unsigned char pci_func;
+ unsigned int io_addr[5];
+ unsigned int irq;
+};
+
+struct pcilst_struct *amcc_devices; // ptr to root list of all amcc devices
+
+
+int i_ADDIDATADeviceID[]={0x15B8,0x10E8};
+
+
+/****************************************************************************/
+
+void v_pci_card_list_init(unsigned short pci_vendor, char display);
+void v_pci_card_list_cleanup(unsigned short pci_vendor);
+struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id, unsigned short device_id);
+int i_find_free_pci_card_by_position(unsigned short vendor_id, unsigned short device_id, unsigned short pci_bus, unsigned short pci_slot, struct pcilst_struct **card);
+struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id, unsigned short device_id, unsigned short pci_bus, unsigned short pci_slot);
+
+int i_pci_card_alloc(struct pcilst_struct *amcc);
+int i_pci_card_free(struct pcilst_struct *amcc);
+void v_pci_card_list_display(void);
+int i_pci_card_data(struct pcilst_struct *amcc,
+ unsigned char *pci_bus, unsigned char *pci_slot, unsigned char *pci_func,
+ unsigned short *io_addr, unsigned short *irq, unsigned short *master);
+
+/****************************************************************************/
+
+/* build list of amcc cards in this system */
+void v_pci_card_list_init(unsigned short pci_vendor, char display)
+{
+ struct pci_dev *pcidev;
+ struct pcilst_struct *amcc,*last;
+ int i;
+ int i_Count=0;
+ amcc_devices=NULL;
+ last=NULL;
+
+#if LINUX_VERSION_CODE < 0x020300
+ for(pcidev=pci_devices;pcidev;pcidev=pcidev->next){
+#else
+ pci_for_each_dev(pcidev){
+#endif
+ for(i_Count=0;i_Count<2;i_Count++)
+ {
+ pci_vendor=i_ADDIDATADeviceID[i_Count];
+ if(pcidev->vendor==pci_vendor){
+ amcc=kmalloc(sizeof(*amcc),GFP_KERNEL);
+ memset(amcc,0,sizeof(*amcc));
+
+ amcc->pcidev=pcidev;
+ if (last) { last->next=amcc; }
+ else { amcc_devices=amcc; }
+ last=amcc;
+
+#if LINUX_VERSION_CODE < 0x020300
+ amcc->vendor=pcidev->vendor;
+ amcc->device=pcidev->device;
+ amcc->master=pcidev->master;
+ amcc->pci_bus=pcidev->bus->number;
+ amcc->pci_slot=PCI_SLOT(pcidev->devfn);
+ amcc->pci_func=PCI_FUNC(pcidev->devfn);
+ for (i=0;i<5;i++)
+ amcc->io_addr[i]=pcidev->base_address[i] & ~3UL;
+ amcc->irq=pcidev->irq;
+#else
+ amcc->vendor=pcidev->vendor;
+ amcc->device=pcidev->device;
+#if 0
+ amcc->master=pcidev->master; // how get this information under 2.4 kernels?
+#endif
+ amcc->pci_bus=pcidev->bus->number;
+ amcc->pci_slot=PCI_SLOT(pcidev->devfn);
+ amcc->pci_func=PCI_FUNC(pcidev->devfn);
+ for (i=0;i<5;i++)
+ amcc->io_addr[i]=pcidev->resource[i].start & ~3UL;
+ amcc->irq=pcidev->irq;
+#endif
+
+ }
+ }
+ }
+
+ if (display) v_pci_card_list_display();
+}
+
+/****************************************************************************/
+/* free up list of amcc cards in this system */
+void v_pci_card_list_cleanup(unsigned short pci_vendor)
+{
+ struct pcilst_struct *amcc,*next;
+
+ for(amcc=amcc_devices;amcc;amcc=next){
+ next=amcc->next;
+ kfree(amcc);
+ }
+
+ amcc_devices=NULL;
+}
+
+/****************************************************************************/
+/* find first unused card with this device_id */
+struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id, unsigned short device_id)
+{
+ struct pcilst_struct *amcc,*next;
+
+ for (amcc=amcc_devices;amcc;amcc=next) {
+ next=amcc->next;
+ if ((!amcc->used)&&(amcc->device==device_id)&&(amcc->vendor==vendor_id)) return amcc;
+
+ }
+
+ return NULL;
+}
+
+/****************************************************************************/
+/* find card on requested position */
+int i_find_free_pci_card_by_position(unsigned short vendor_id, unsigned short device_id, unsigned short pci_bus, unsigned short pci_slot, struct pcilst_struct **card)
+{
+ struct pcilst_struct *amcc,*next;
+
+ *card=NULL;
+ for (amcc=amcc_devices;amcc;amcc=next) {
+ next=amcc->next;
+ if ((amcc->vendor==vendor_id)&&(amcc->device==device_id)&&(amcc->pci_bus==pci_bus)&&(amcc->pci_slot==pci_slot)) {
+ if (!(amcc->used)) {
+ *card=amcc;
+ return 0; // ok, card is found
+ } else {
+ rt_printk(" - \nCard on requested position is used b:s %d:%d!\n",pci_bus,pci_slot);
+ return 2; // card exist but is used
+ }
+ }
+ }
+
+ return 1; // no card found
+}
+
+/****************************************************************************/
+/* mark card as used */
+int i_pci_card_alloc(struct pcilst_struct *amcc)
+{
+ if (!amcc) return -1;
+
+ if (amcc->used) return 1;
+ amcc->used=1;
+ return 0;
+}
+
+/****************************************************************************/
+/* mark card as free */
+int i_pci_card_free(struct pcilst_struct *amcc)
+{
+ if (!amcc) return -1;
+
+ if (!amcc->used) return 1;
+ amcc->used=0;
+ return 0;
+}
+
+/****************************************************************************/
+/* display list of found cards */
+void v_pci_card_list_display(void)
+{
+ struct pcilst_struct *amcc,*next;
+
+ printk("List of pci cards\n");
+ printk("bus:slot:func vendor device master io_amcc io_daq irq used\n");
+
+ for (amcc=amcc_devices;amcc;amcc=next) {
+ next=amcc->next;
+ printk("%2d %2d %2d 0x%4x 0x%4x %3s 0x%4x 0x%4x %2d %2d\n",
+ amcc->pci_bus,amcc->pci_slot,amcc->pci_func,amcc->vendor,amcc->device,amcc->master?"yes":"no",
+ amcc->io_addr[0],amcc->io_addr[2],amcc->irq,amcc->used);
+
+ }
+}
+
+/****************************************************************************/
+/* return all card information for driver */
+int i_pci_card_data(struct pcilst_struct *amcc,
+ unsigned char *pci_bus, unsigned char *pci_slot, unsigned char *pci_func,
+ unsigned short *io_addr, unsigned short *irq, unsigned short *master)
+{
+ int i;
+
+ if (!amcc) return -1;
+ *pci_bus=amcc->pci_bus;
+ *pci_slot=amcc->pci_slot;
+ *pci_func=amcc->pci_func;
+ for (i=0;i<5;i++)
+ io_addr[i]=amcc->io_addr[i];
+ *irq=amcc->irq;
+ *master=amcc->master;
+ return 0;
+}
+
+/****************************************************************************/
+/* select and alloc card */
+struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id, unsigned short device_id, unsigned short pci_bus, unsigned short pci_slot)
+{
+ struct pcilst_struct *card;
+
+ if ((pci_bus<1)&(pci_slot<1)) { // use autodetection
+ if ((card=ptr_find_free_pci_card_by_device(vendor_id,device_id))==NULL) {
+ rt_printk(" - Unused card not found in system!\n");
+ return NULL;
+ }
+ } else {
+ switch (i_find_free_pci_card_by_position(vendor_id,device_id,pci_bus,pci_slot,&card)) {
+ case 1:
+ rt_printk(" - Card not found on requested position b:s %d:%d!\n",pci_bus,pci_slot);
+ return NULL;
+ case 2:
+ rt_printk(" - Card on requested position is used b:s %d:%d!\n",pci_bus,pci_slot);
+ return NULL;
+ }
+ }
+
+
+ if (i_pci_card_alloc(card)!=0) {
+ rt_printk(" - Can't allocate card!\n");
+ return NULL;
+ }
+
+ return card;
+}
+#endif
--- /dev/null
+
+
+
+
+/***************************************************
+ Generic Driver For ADDI APCI CARDs
+
+
+
+ CONFIG OPTIONS
+ option[0] - PCI bus number - if bus number and slot number are 0,
+ then driver search for first unused card
+ option[1] - PCI slot number
+
+ option[2]= 0 DMA ENABLE
+ = 1 DMA DISABLE
+
+ ******************************************************************/
+
+/*======================================================================
+ Authors Email ID
+ Santosh Raktawan santosh.raktawan@tatainfotech.com
+ Sarath Chandran K R sarath.chandran@tatainfotech.com
+========================================================================*/
+
+
+
+
+/*
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstrasse 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 : ADDI DATA | Compiler : GCC |
+ | Modulname : addi_common.c | Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Author : | Date : |
+ +-----------------------------------------------------------------------+
+ | Description : ADDI COMMON Main Module |
+ +-----------------------------------------------------------------------+
+ | UPDATE'S |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+
+
+
+
+
+
+#include<linux/kernel.h>
+#include<linux/module.h>
+#include<linux/sched.h>
+#include<linux/mm.h>
+#include<linux/malloc.h>
+#include<linux/errno.h>
+#include<linux/ioport.h>
+#include<linux/delay.h>
+#include<linux/interrupt.h>
+#include<linux/timex.h>
+#include<linux/timer.h>
+#include<linux/pci.h>
+#include<linux/comedidev.h>
+#include<asm/io.h>
+
+#include "addi_common.h"
+#include "addi_amcc_s5933.h"
+//#include "addi_eeprom.c"
+
+#define devpriv ((addi_private *)dev->private)
+#define this_board ((boardtype *)dev->board_ptr)
+
+
+#include "addi_eeprom.c"
+#include "hwdrv_apci3120.c"
+#include "hwdrv_apci1032.c"
+#include "hwdrv_apci1516.c"
+#include "hwdrv_apci2016.c"
+#include "hwdrv_apci2032.c"
+#include "hwdrv_apci2200.c"
+#include "hwdrv_apci1564.c"
+#include "hwdrv_apci1500.c"
+#include "hwdrv_apci3501.c"
+#include "hwdrv_apci035.c"
+#include "hwdrv_apci3200.c"
+#include "hwdrv_APCI1710.c"
+
+static boardtype boardtypes[] =
+{
+ {"apci3120", APCI3120_BOARD_VENDOR_ID, 0x818D,
+ AMCC_OP_REG_SIZE, APCI3120_ADDRESS_RANGE,8,0,
+ ADDIDATA_NO_EEPROM,NULL,
+ 16, 8, 16, 8, 0xffff, 0x3fff,
+ &range_apci3120_ai, &range_apci3120_ao,
+ 4,4,0x0f,1,1,10000,100000,
+ v_APCI3120_Interrupt,
+ i_APCI3120_Reset,
+ i_APCI3120_InsnConfigAnalogInput,
+ i_APCI3120_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ i_APCI3120_CommandTestAnalogInput,
+ i_APCI3120_CommandAnalogInput,
+ i_APCI3120_StopCyclicAcquisition,
+ NULL,
+ i_APCI3120_InsnWriteAnalogOutput,
+ NULL,
+ NULL,
+ i_APCI3120_InsnReadDigitalInput,
+ NULL,
+ i_APCI3120_InsnBitsDigitalInput,
+ i_APCI3120_InsnConfigDigitalOutput,
+ i_APCI3120_InsnWriteDigitalOutput,
+ i_APCI3120_InsnBitsDigitalOutput,
+ NULL,
+ i_APCI3120_InsnConfigTimer,
+ i_APCI3120_InsnWriteTimer,
+ i_APCI3120_InsnReadTimer,
+ NULL
+ },
+
+ {"apci1032",APCI1032_BOARD_VENDOR_ID,0x1003,
+ 4,APCI1032_ADDRESS_RANGE,0,0,
+ ADDIDATA_EEPROM,ADDIDATA_93C76,
+ 0,0,0,0,0,0,0,0,
+ 32,0,0,0,0,0,0,
+ v_APCI1032_Interrupt,
+ i_APCI1032_Reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI1032_ConfigDigitalInput,
+ i_APCI1032_Read1DigitalInput,
+ NULL,
+ i_APCI1032_ReadMoreDigitalInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ {"apci1516",APCI1516_BOARD_VENDOR_ID,0x1001,
+ 128,APCI1516_ADDRESS_RANGE,32,0,
+ ADDIDATA_EEPROM,ADDIDATA_S5920,
+ 0,0,0,0,0,0,NULL,NULL,8,
+ 8,0,0,1,0,0,
+ NULL,
+ i_APCI1516_Reset,
+ NULL,NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI1516_Read1DigitalInput,
+ NULL,
+ i_APCI1516_ReadMoreDigitalInput,
+ i_APCI1516_ConfigDigitalOutput,
+ i_APCI1516_WriteDigitalOutput,
+ i_APCI1516_ReadDigitalOutput,
+ NULL,
+ i_APCI1516_ConfigWatchdog,
+ i_APCI1516_StartStopWriteWatchdog,
+ i_APCI1516_ReadWatchdog,
+ NULL
+ },
+
+ {"apci2016",APCI2016_BOARD_VENDOR_ID,0x1002,
+ 128,APCI2016_ADDRESS_RANGE,32,0,
+ ADDIDATA_EEPROM,ADDIDATA_S5920,
+ 0,0,0,0,0,0,
+ NULL,NULL,
+ 0,16,0,0,1,0,0,
+ NULL,
+ i_APCI2016_Reset,
+ NULL,NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI2016_ConfigDigitalOutput,
+ i_APCI2016_WriteDigitalOutput,
+ i_APCI2016_BitsDigitalOutput,
+ NULL,
+ i_APCI2016_ConfigWatchdog,
+ i_APCI2016_StartStopWriteWatchdog,
+ i_APCI2016_ReadWatchdog,
+ NULL
+ },
+
+ {"apci2032", APCI2032_BOARD_VENDOR_ID, 0x1004,
+ 4,APCI2032_ADDRESS_RANGE,0,0,
+ ADDIDATA_EEPROM,ADDIDATA_93C76,
+ 0, 0, 0, 0, 0, 0,
+ NULL, NULL,
+ 0,32,0xffffffff,0,1,0,0,
+ v_APCI2032_Interrupt,
+ i_APCI2032_Reset,
+ NULL,NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI2032_ConfigDigitalOutput,
+ i_APCI2032_WriteDigitalOutput,
+ i_APCI2032_ReadDigitalOutput,
+ i_APCI2032_ReadInterruptStatus,
+ i_APCI2032_ConfigWatchdog,
+ i_APCI2032_StartStopWriteWatchdog,
+ i_APCI2032_ReadWatchdog,
+ NULL
+ },
+ {"apci2200",APCI2200_BOARD_VENDOR_ID,0x1005,
+ 4,APCI2200_ADDRESS_RANGE,0,0,
+ ADDIDATA_EEPROM,ADDIDATA_93C76,
+ 0,0,0,0,0,0,NULL,NULL,8,
+ 16,0,0,1,0,0,
+ NULL,
+ i_APCI2200_Reset,
+ NULL,NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI2200_Read1DigitalInput,
+ NULL,
+ i_APCI2200_ReadMoreDigitalInput,
+ i_APCI2200_ConfigDigitalOutput,
+ i_APCI2200_WriteDigitalOutput,
+ i_APCI2200_ReadDigitalOutput,
+ NULL,
+ i_APCI2200_ConfigWatchdog,
+ i_APCI2200_StartStopWriteWatchdog,
+ i_APCI2200_ReadWatchdog,
+ NULL
+ },
+ {"apci1564",APCI1564_BOARD_VENDOR_ID,0x1006,
+ 128,APCI1564_ADDRESS_RANGE,0,0,
+ ADDIDATA_EEPROM,ADDIDATA_93C76,
+ 0,0,0,0,0,0,
+ NULL,NULL,
+ 32,32,0xffffffff,0,1,0,0,
+ v_APCI1564_Interrupt,
+ i_APCI1564_Reset,
+ NULL,NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI1564_ConfigDigitalInput,
+ i_APCI1564_Read1DigitalInput,
+ NULL,
+ i_APCI1564_ReadMoreDigitalInput,
+ i_APCI1564_ConfigDigitalOutput,
+ i_APCI1564_WriteDigitalOutput,
+ i_APCI1564_ReadDigitalOutput,
+ i_APCI1564_ReadInterruptStatus,
+ i_APCI1564_ConfigTimerCounterWatchdog,
+ i_APCI1564_StartStopWriteTimerCounterWatchdog,
+ i_APCI1564_ReadTimerCounterWatchdog,
+ NULL
+ },
+ {"apci1500", APCI1500_BOARD_VENDOR_ID, 0x80fc,
+ 128,APCI1500_ADDRESS_RANGE,4,0,
+ ADDIDATA_NO_EEPROM,NULL,
+ 0, 0, 0, 0, 0, 0,
+ NULL, NULL,
+ 16,16,0xffff,0,1,0,0,
+ v_APCI1500_Interrupt,
+ i_APCI1500_Reset,
+ NULL,NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI1500_ConfigDigitalInputEvent,
+ i_APCI1500_Initialisation,
+ i_APCI1500_StartStopInputEvent,
+ i_APCI1500_ReadMoreDigitalInput,
+ i_APCI1500_ConfigDigitalOutputErrorInterrupt,
+ i_APCI1500_WriteDigitalOutput,
+ i_APCI1500_ConfigureInterrupt,
+ NULL,
+ i_APCI1500_ConfigCounterTimerWatchdog,
+ i_APCI1500_StartStopTriggerTimerCounterWatchdog,
+ i_APCI1500_ReadInterruptMask,
+ i_APCI1500_ReadCounterTimerWatchdog
+ },
+
+
+ {"apci3001", APCI3120_BOARD_VENDOR_ID, 0x828D,
+ AMCC_OP_REG_SIZE, APCI3120_ADDRESS_RANGE,8,0,
+ ADDIDATA_NO_EEPROM,NULL,
+ 16, 8, 16, 0, 0xfff, 0,
+ &range_apci3120_ai, NULL,
+ 4,4,0x0f,1,1,10000,100000,
+ v_APCI3120_Interrupt,
+ i_APCI3120_Reset,
+ i_APCI3120_InsnConfigAnalogInput,
+ i_APCI3120_InsnReadAnalogInput,
+ NULL,NULL,
+ i_APCI3120_CommandTestAnalogInput,
+ i_APCI3120_CommandAnalogInput,
+ i_APCI3120_StopCyclicAcquisition,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3120_InsnReadDigitalInput,
+ NULL,
+ i_APCI3120_InsnBitsDigitalInput,
+ i_APCI3120_InsnConfigDigitalOutput,
+ i_APCI3120_InsnWriteDigitalOutput,
+ i_APCI3120_InsnBitsDigitalOutput,
+ NULL,
+ i_APCI3120_InsnConfigTimer,
+ i_APCI3120_InsnWriteTimer,
+ i_APCI3120_InsnReadTimer,
+ NULL
+ },
+ {"apci3501", APCI3501_BOARD_VENDOR_ID, 0x3001,
+ 64,APCI3501_ADDRESS_RANGE,0,0,
+ ADDIDATA_EEPROM,ADDIDATA_S5933,
+ 0, 0, 0, 8, 0,16383,
+ NULL,&range_apci3501_ao,
+ 2,2,0x3,0,1,0,0,
+ v_APCI3501_Interrupt,
+ i_APCI3501_Reset,
+ NULL,NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3501_ConfigAnalogOutput,
+ i_APCI3501_WriteAnalogOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3501_ReadDigitalInput,
+ i_APCI3501_ConfigDigitalOutput,
+ i_APCI3501_WriteDigitalOutput,
+ i_APCI3501_ReadDigitalOutput,
+ NULL,
+ i_APCI3501_ConfigTimerCounterWatchdog,
+ i_APCI3501_StartStopWriteTimerCounterWatchdog,
+ i_APCI3501_ReadTimerCounterWatchdog,
+ NULL
+ },
+ {"apci035", APCI035_BOARD_VENDOR_ID, 0x0300,
+ 127,APCI035_ADDRESS_RANGE ,0,0,1,ADDIDATA_S5920,
+ 16,8,16,0, 0xff, 0,
+ &range_apci035_ai, NULL,
+ 0,0,0,0,1,10000,100000,
+ v_APCI035_Interrupt,
+ i_APCI035_Reset,
+ i_APCI035_ConfigAnalogInput,
+ i_APCI035_ReadAnalogInput ,
+ NULL,NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI035_ConfigTimerWatchdog,
+ i_APCI035_StartStopWriteTimerWatchdog,
+ i_APCI035_ReadTimerWatchdog,
+ NULL
+ },
+ {"apci3200", APCI3200_BOARD_VENDOR_ID, 0x3000,
+ 128,256,4,4,ADDIDATA_EEPROM,ADDIDATA_S5920,
+ 16,8,16,0, 0x3ffff, 0,
+ &range_apci3200_ai, NULL,
+ 4,4,0,0,0,10000,100000,
+ v_APCI3200_Interrupt,
+ i_APCI3200_Reset,
+ i_APCI3200_ConfigAnalogInput,
+ i_APCI3200_ReadAnalogInput ,
+ i_APCI3200_InsnWriteReleaseAnalogInput,
+ i_APCI3200_InsnBits_AnalogInput_Test,
+ i_APCI3200_CommandTestAnalogInput,
+ i_APCI3200_CommandAnalogInput,
+ i_APCI3200_StopCyclicAcquisition,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3200_ReadDigitalInput,
+ i_APCI3200_ConfigDigitalOutput,
+ i_APCI3200_WriteDigitalOutput,
+ i_APCI3200_ReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+
+ {"apci1710",APCI1710_BOARD_VENDOR_ID,APCI1710_BOARD_DEVICE_ID,
+ 128,8,256,0,
+ ADDIDATA_NO_EEPROM,NULL,
+ 0, 0, 0, 0, 0, 0,
+ NULL, NULL,
+ 0,0,0,0,0,0,0,
+ v_APCI1710_Interrupt,
+ i_APCI1710_Reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ }
+
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(boardtype))
+
+comedi_driver driver_addi ={
+ driver_name: "addi_common",
+ module: THIS_MODULE,
+ attach: i_ADDI_Attach,
+ detach: i_ADDI_Detach,
+ num_names: n_boardtypes,
+ board_name: boardtypes,
+ offset: sizeof(boardtype),
+ };
+
+
+
+//This macro is defined in comedidev.h
+/* #define COMEDI_INITCLEANUP(x) \
+ int init_module(void){return comedi_driver_register(&(x));} \
+ void cleanup_module(void){comedi_driver_unregister(&(x));}
+*/
+
+COMEDI_INITCLEANUP(driver_addi);
+
+
+
+
+/*
++----------------------------------------------------------------------------+
+| Function name :static int i_ADDI_Attach(comedi_device *dev, |
+| comedi_devconfig *it) |
+| |
++----------------------------------------------------------------------------+
+| Task :Detects the card. |
+| Configure the driver for a particular board. |
+| This function does all the initializations and memory |
+| allocation of data structures for the driver. |
++----------------------------------------------------------------------------+
+| Input Parameters :comedi_device *dev |
+| comedi_devconfig *it |
+| |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
+| |
++----------------------------------------------------------------------------+
+*/
+
+
+static int i_ADDI_Attach(comedi_device *dev,comedi_devconfig *it)
+{
+ comedi_subdevice *s;
+ int ret,pages,i;
+ DWORD dw_Dummy;
+ unsigned short io_addr[5],master,irq;//v_58
+ unsigned int iobase_a,iobase_main,iobase_addon,iobase_reserved;
+ struct pcilst_struct *card=NULL;
+ unsigned char pci_bus,pci_slot,pci_func;
+
+ if (!pci_list_builded)
+ {
+ v_pci_card_list_init(this_board->i_VendorId,1); //1 for displaying the list..
+ pci_list_builded=1;
+ }
+ //rt_printk("comedi%d: addi_common: board=%s",dev->minor,this_board->pc_DriverName);
+
+ if ((card=ptr_select_and_alloc_pci_card(this_board->i_VendorId, this_board->i_DeviceId, it->options[0], it->options[1]))==NULL)
+ return -EIO;
+ if ((i_pci_card_data(card,&pci_bus,&pci_slot,&pci_func,&io_addr[0],&irq,&master))<0)
+ {
+ i_pci_card_free(card);
+ rt_printk(" - Can't get AMCC data!\n");
+ return -EIO;
+ }
+ iobase_a=io_addr[0];
+ iobase_main=io_addr[1];
+ iobase_addon=io_addr[2];
+ iobase_reserved=io_addr[3];
+ rt_printk(", b:s:f=%d:%d:%d, base0:0x%4x, base1: 0x%4x, base2: 0x%4x",pci_bus,pci_slot,pci_func,io_addr[0],io_addr[1],io_addr[2]);
+ if (check_region(iobase_main, this_board->i_IorangeBase1) < 0)
+ {
+ rt_printk("I/O port conflict\n");
+ return -EIO;
+ }
+ //if(this_board->i_Dma)
+ if(iobase_a)
+ {
+ if (check_region(iobase_a, this_board->i_IorangeBase0) < 0)
+ {
+ printk("AMCC check region failed\n");
+ rt_printk("I/O port conflict\n");
+ return -EIO;
+ }
+ }
+
+ // ##
+ if(io_addr[2])
+ {
+ if (check_region(io_addr[2], this_board->i_IorangeBase2) < 0)
+ {
+ printk("Base 2 check region failed\n");
+ rt_printk("I/O port conflict\n");
+ return -EIO;
+ }
+
+
+ }
+ //##
+ dev->iobase=iobase_main;// DAQ base address...
+ request_region(dev->iobase, this_board->i_IorangeBase1, "ADDI COMMON");
+
+ dev->board_name =this_board->pc_DriverName;
+ if((ret=alloc_private(dev,sizeof(addi_private)))<0)
+ return -ENOMEM;
+ devpriv->amcc=card;
+ devpriv->master=master; //testing
+ devpriv->iobase=dev->iobase;
+ devpriv->i_IobaseAmcc=iobase_a;//AMCC base address...
+ devpriv->i_IobaseAddon=iobase_addon;//ADD ON base address....
+ devpriv->i_IobaseReserved=iobase_reserved;
+
+ //if(this_board->i_Dma)
+ if(iobase_a)
+ {
+ request_region(devpriv->i_IobaseAmcc,this_board->i_IorangeBase0, "ADDI COMMON");
+ }
+
+ //##
+ if(io_addr[2])
+ {
+ request_region(io_addr[2],this_board->i_IorangeBase2, "ADDI COMMON");
+ }
+
+ //##
+
+ if (irq>0)
+ {
+ if (comedi_request_irq(irq, v_ADDI_Interrupt, SA_SHIRQ, "ADDI COMMON", dev))
+ {
+ rt_printk(", unable to allocate IRQ %d, DISABLING IT", irq);
+ irq=0; /* Can't use IRQ */
+ }
+ else
+ {
+ rt_printk(", irq=%d", irq);
+ }
+ }
+ else
+ {
+ rt_printk(", IRQ disabled");
+ }
+ rt_printk("\n%d %d %d\n",it->options[0],it->options[1],it->options[2]);
+ dev->irq = irq;
+
+ // Read eepeom and fill boardtype Structure
+
+ if(this_board->i_PCIEeprom)
+ {
+ if (!(strcmp(this_board->pc_EepromChip, "S5920")))
+ {
+ // Set 3 wait stait
+ if(!(strcmp(this_board->pc_DriverName,"apci035")))
+ {
+ outl(0x80808082,devpriv->i_IobaseAmcc+0x60);
+ }
+ else
+ {
+ 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);
+ }
+ i_EepromReadMainHeader(io_addr[0],this_board->pc_EepromChip,dev);
+ }
+ if (it->options[2]>0) \r
+ {
+ devpriv->us_UseDma=ADDI_DISABLE;
+ }
+ else
+ {
+ devpriv->us_UseDma=ADDI_ENABLE;
+ }
+
+ if(this_board->i_Dma)
+ {
+ if (devpriv->us_UseDma==ADDI_ENABLE)
+ {
+ // alloc DMA buffers
+ devpriv->b_DmaDoubleBuffer=0;
+ for (i=0; i<2; i++)
+ {
+ for (pages=4; pages>=0; pages--)
+ {
+
+ if((devpriv->ul_DmaBufferVirtual[i]=__get_free_pages(GFP_KERNEL,pages)))
+ break;
+
+ }
+
+
+ if (devpriv->ul_DmaBufferVirtual[i])
+ {
+
+ devpriv->ui_DmaBufferPages[i]=pages;
+ devpriv->ui_DmaBufferSize[i]=PAGE_SIZE*pages;
+ devpriv->ui_DmaBufferSamples[i]=devpriv->ui_DmaBufferSize[i]>>1;
+ devpriv->ul_DmaBufferHw[i]=virt_to_bus((void*)devpriv->ul_DmaBufferVirtual[i]);
+
+ }
+ }
+ if (!devpriv->ul_DmaBufferVirtual[0])
+ {
+ rt_printk(", Can't allocate DMA buffer, DMA disabled!");
+ master=0;
+ devpriv->us_UseDma=ADDI_DISABLE;
+ }
+
+ if (devpriv->ul_DmaBufferVirtual[1])
+ devpriv->b_DmaDoubleBuffer=1;
+
+
+ }
+
+
+ if ((devpriv->us_UseDma==ADDI_ENABLE))
+ {
+ rt_printk("\nDMA ENABLED\n");
+ }
+ else
+ {
+ rt_printk("\nDMA DISABLED\n");
+ }
+ }
+
+
+
+ if (!strcmp(this_board->pc_DriverName,"apci1710"))
+ {
+ dev->n_subdevices = 9;
+ if((ret=alloc_subdevices(dev))<0)
+ return ret;
+
+ // Allocate and Initialise Timer Subdevice Structures
+ s = dev->subdevices + 0;
+
+ s->type = COMEDI_SUBD_TIMER;
+ s->subdev_flags = SDF_WRITEABLE|SDF_RT|SDF_GROUND|SDF_COMMON;
+ s->n_chan = 3;
+ s->maxdata = 0;
+ s->len_chanlist = 3;
+ s->range_table = &range_digital;
+ s->insn_write=i_APCI1710_InsnWriteEnableDisableTimer;
+ s->insn_read=i_APCI1710_InsnReadAllTimerValue;
+ s->insn_config=i_APCI1710_InsnConfigInitTimer;
+ s->insn_bits=i_APCI1710_InsnBitsTimer;
+
+
+ // Allocate and Initialise DIO Subdevice Structures
+ s = dev->subdevices + 1;
+
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_WRITEABLE|SDF_READABLE|SDF_RT|SDF_GROUND|SDF_COMMON;
+ s->n_chan = 7;
+ s->maxdata = 1;
+ s->len_chanlist = 7;
+ s->range_table = &range_digital;
+ s->insn_config=i_APCI1710_InsnConfigDigitalIO;
+ s->insn_read= i_APCI1710_InsnReadDigitalIOChlValue;
+ s->insn_bits=i_APCI1710_InsnBitsDigitalIOPortOnOff;
+ s->insn_write=i_APCI1710_InsnWriteDigitalIOChlOnOff;
+
+
+ // Allocate and Initialise Chrono Subdevice Structures
+ s = dev->subdevices + 2;
+
+ s->type = COMEDI_SUBD_CHRONO;
+ s->subdev_flags = SDF_WRITEABLE|SDF_RT|SDF_GROUND|SDF_COMMON;
+ s->n_chan = 4;
+ s->maxdata = 0;
+ s->len_chanlist = 4;
+ s->range_table = &range_digital;
+ s->insn_write=i_APCI1710_InsnWriteEnableDisableChrono;
+ s->insn_read=i_APCI1710_InsnReadChrono;
+ s->insn_config=i_APCI1710_InsnConfigInitChrono;
+ s->insn_bits=i_APCI1710_InsnBitsChronoDigitalIO;
+
+
+ // Allocate and Initialise PWM Subdevice Structures
+ s = dev->subdevices + 3;
+ s->type = COMEDI_SUBD_PWM;
+ s->subdev_flags = SDF_WRITEABLE|SDF_READABLE|SDF_RT|SDF_GROUND|SDF_COMMON;
+ s->n_chan = 3;
+ s->maxdata = 1;
+ s->len_chanlist = 3;
+ s->range_table = &range_digital;
+ s->io_bits=0; //all bits input
+ s->insn_config = i_APCI1710_InsnConfigPWM;
+ s->insn_read = i_APCI1710_InsnReadGetPWMStatus;
+ s->insn_write = i_APCI1710_InsnWritePWM;
+ s->insn_bits = i_APCI1710_InsnBitsReadPWMInterrupt;
+
+ // Allocate and Initialise TTLIO Subdevice Structures
+ s = dev->subdevices + 4;
+ s->type = COMEDI_SUBD_TTLIO;
+ s->subdev_flags = SDF_WRITEABLE|SDF_READABLE|SDF_RT|SDF_GROUND|SDF_COMMON;
+ s->n_chan = 8;
+ s->maxdata = 1;
+ s->len_chanlist = 8;
+ s->range_table = &range_apci1710_ttl; // to pass arguments in range
+ s->insn_config = i_APCI1710_InsnConfigInitTTLIO;
+ s->insn_bits = i_APCI1710_InsnBitsReadTTLIO;
+ s->insn_write = i_APCI1710_InsnWriteSetTTLIOChlOnOff;
+ s->insn_read = i_APCI1710_InsnReadTTLIOAllPortValue;
+
+
+ // Allocate and Initialise TOR Subdevice Structures
+ s = dev->subdevices + 5;
+ s->type = COMEDI_SUBD_TOR;
+ s->subdev_flags = SDF_WRITEABLE|SDF_READABLE|SDF_RT|SDF_GROUND|SDF_COMMON;
+ s->n_chan = 8;
+ s->maxdata = 1;
+ s->len_chanlist = 8;
+ s->range_table = &range_digital;
+ s->io_bits=0; //all bits input
+ s->insn_config = i_APCI1710_InsnConfigInitTorCounter;
+ s->insn_read = i_APCI1710_InsnReadGetTorCounterInitialisation;
+ s->insn_write = i_APCI1710_InsnWriteEnableDisableTorCounter;
+ s->insn_bits = i_APCI1710_InsnBitsGetTorCounterProgressStatusAndValue;
+
+ // Allocate and Initialise SSI Subdevice Structures
+ s = dev->subdevices + 6;
+ s->type = COMEDI_SUBD_SSI;
+ s->subdev_flags = SDF_WRITEABLE|SDF_READABLE|SDF_RT|SDF_GROUND|SDF_COMMON;
+ s->n_chan =4;
+ s->maxdata = 1;
+ s->len_chanlist = 4;
+ s->range_table = &range_apci1710_ssi;
+ s->insn_config = i_APCI1710_InsnConfigInitSSI;
+ s->insn_read = i_APCI1710_InsnReadSSIValue;
+ s->insn_bits = i_APCI1710_InsnBitsSSIDigitalIO;
+
+ // Allocate and Initialise PULSEENCODER Subdevice Structures
+ s = dev->subdevices + 7;
+ s->type = COMEDI_SUBD_PULSEENCODER;
+ s->subdev_flags = SDF_WRITEABLE|SDF_READABLE|SDF_RT|SDF_GROUND|SDF_COMMON;
+ s->n_chan = 4;
+ s->maxdata = 1;
+ s->len_chanlist = 4;
+ s->range_table = &range_digital;
+ s->insn_config = i_APCI1710_InsnConfigInitPulseEncoder;
+ s->insn_write = i_APCI1710_InsnWriteEnableDisablePulseEncoder;
+ s->insn_bits = i_APCI1710_InsnBitsReadWritePulseEncoder;
+ s->insn_read = i_APCI1710_InsnReadInterruptPulseEncoder;
+
+ // Allocate and Initialise INCREMENTALCOUNTER Subdevice Structures
+ s = dev->subdevices + 8;
+ s->type = COMEDI_SUBD_INCREMENTALCOUNTER;
+ s->subdev_flags = SDF_WRITEABLE|SDF_READABLE|SDF_RT|SDF_GROUND|SDF_COMMON;
+ s->n_chan = 500;
+ s->maxdata = 1;
+ s->len_chanlist = 500;
+ s->range_table = &range_apci1710_inccpt;
+ s->insn_config = i_APCI1710_InsnConfigINCCPT;
+ s->insn_write = i_APCI1710_InsnWriteINCCPT;
+ s->insn_read = i_APCI1710_InsnReadINCCPT;
+ s->insn_bits = i_APCI1710_InsnBitsINCCPT;
+
+ // save base address
+ devpriv->s_BoardInfos.ui_Address=io_addr[2];
+ }
+ else
+ {
+ dev->n_subdevices = 6;
+ if((ret=alloc_subdevices(dev))<0)
+ return ret;
+
+ // Allocate and Initialise AI Subdevice Structures
+ s = dev->subdevices + 0;
+ if(this_board->i_NbrAiChannel)
+ {
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE|SDF_RT|SDF_COMMON|SDF_GROUND|SDF_DIFF;
+ s->n_chan = this_board->i_NbrAiChannel;
+ s->maxdata = this_board->i_AiMaxdata;
+ s->len_chanlist = this_board->i_AiChannelList;
+ s->range_table = this_board->pr_AiRangelist;
+
+
+
+ s->insn_config=this_board->i_hwdrv_InsnConfigAnalogInput;
+ s->insn_read=this_board->i_hwdrv_InsnReadAnalogInput;
+ s->insn_write=this_board->i_hwdrv_InsnWriteAnalogInput;
+ s->insn_bits=this_board->i_hwdrv_InsnBitsAnalogInput;
+ s->do_cmdtest=this_board->i_hwdrv_CommandTestAnalogInput;
+ s->do_cmd=this_board->i_hwdrv_CommandAnalogInput;
+ s->cancel=this_board->i_hwdrv_CancelAnalogInput;
+
+ }
+ else
+ {
+ s->type=COMEDI_SUBD_UNUSED;
+ }
+
+ // Allocate and Initialise AO Subdevice Structures
+ s = dev->subdevices + 1;
+ if(this_board->i_NbrAoChannel)
+ {
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITEABLE|SDF_GROUND|SDF_COMMON|SDF_RT;
+ s->n_chan = this_board->i_NbrAoChannel;
+ s->maxdata = this_board->i_AoMaxdata;
+ s->len_chanlist = this_board->i_NbrAoChannel;
+ s->range_table = this_board->pr_AoRangelist;
+ s->insn_config=this_board->i_hwdrv_InsnConfigAnalogOutput;
+ s->insn_write=this_board->i_hwdrv_InsnWriteAnalogOutput;
+ }
+ else
+ {
+ s->type=COMEDI_SUBD_UNUSED;
+ }
+ // Allocate and Initialise DI Subdevice Structures
+ s = dev->subdevices + 2;
+ if(this_board->i_NbrDiChannel)
+ {
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE|SDF_RT|SDF_GROUND|SDF_COMMON;
+ s->n_chan = this_board->i_NbrDiChannel;
+ s->maxdata = 1;
+ s->len_chanlist = this_board->i_NbrDiChannel;
+ s->range_table = &range_digital;
+ s->io_bits=0; /* all bits input */
+
+ s->insn_config=this_board->i_hwdrv_InsnConfigDigitalInput;
+ s->insn_read=this_board->i_hwdrv_InsnReadDigitalInput;
+ s->insn_write=this_board->i_hwdrv_InsnWriteDigitalInput;
+ s->insn_bits=this_board->i_hwdrv_InsnBitsDigitalInput;
+
+ }
+ else
+ {
+ s->type=COMEDI_SUBD_UNUSED;
+ }
+ // Allocate and Initialise DO Subdevice Structures
+ s = dev->subdevices + 3;
+ if(this_board->i_NbrDoChannel)
+ {
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITEABLE|SDF_RT|SDF_GROUND|SDF_COMMON;
+ s->n_chan= this_board->i_NbrDoChannel;
+ s->maxdata = this_board->i_DoMaxdata;
+ s->len_chanlist =this_board->i_NbrDoChannel ;
+ s->range_table = &range_digital;
+ s->io_bits=0xf; /* all bits output */
+
+ s->insn_config=this_board->i_hwdrv_InsnConfigDigitalOutput;//for digital output memory..
+ s->insn_write=this_board->i_hwdrv_InsnWriteDigitalOutput;
+ s->insn_bits=this_board->i_hwdrv_InsnBitsDigitalOutput;
+ s->insn_read=this_board->i_hwdrv_InsnReadDigitalOutput;
+ }
+ else
+ {
+ s->type=COMEDI_SUBD_UNUSED;
+ }
+
+ // Allocate and Initialise Timer Subdevice Structures
+ s = dev->subdevices + 4;
+ if(this_board->i_Timer)
+ {
+ s->type = COMEDI_SUBD_TIMER;
+ s->subdev_flags = SDF_WRITEABLE|SDF_RT|SDF_GROUND|SDF_COMMON;
+ s->n_chan = 1;
+ s->maxdata = 0;
+ s->len_chanlist = 1;
+ s->range_table = &range_digital;
+
+ s->insn_write=this_board->i_hwdrv_InsnWriteTimer;
+ s->insn_read=this_board->i_hwdrv_InsnReadTimer;
+ s->insn_config=this_board->i_hwdrv_InsnConfigTimer;
+ s->insn_bits=this_board->i_hwdrv_InsnBitsTimer;
+ }
+ else
+ {
+ s->type=COMEDI_SUBD_UNUSED;
+ }
+
+ /* EEPROM */
+ s=dev->subdevices+5;
+ if(this_board->i_PCIEeprom)
+ {
+ s->type=COMEDI_SUBD_MEMORY;
+ s->subdev_flags=SDF_READABLE|SDF_INTERNAL;
+ s->n_chan=256;
+ s->maxdata=0xffff;
+ s->insn_read=i_ADDIDATA_InsnReadEeprom;
+ }
+ else
+ {
+ s->type=COMEDI_SUBD_UNUSED;
+ }
+ }
+ i_ADDI_Reset(dev);
+ devpriv->b_ValidDriver=1;
+ return 0;
+}
+
+
+
+/*
++----------------------------------------------------------------------------+
+| Function name : static int i_ADDI_Detach(comedi_device *dev) |
+| |
+| |
++----------------------------------------------------------------------------+
+| Task : Deallocates resources of the addi_common driver |
+| Free the DMA buffers, unregister irq. |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev |
+| |
+| |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
+| |
++----------------------------------------------------------------------------+
+*/
+
+
+static int i_ADDI_Detach(comedi_device *dev)
+{
+
+ if (dev->private)
+ {
+ if (devpriv->b_ValidDriver) i_ADDI_Reset(dev);
+ if(devpriv->i_IobaseAmcc)
+ release_region(devpriv->i_IobaseAmcc,this_board->i_IorangeBase0);
+ if (devpriv->allocated)
+ i_pci_card_free(devpriv->amcc);
+ if (devpriv->ul_DmaBufferVirtual[0])
+ free_pages(devpriv->ul_DmaBufferVirtual[0],devpriv->ui_DmaBufferPages[0]);
+ if (devpriv->ul_DmaBufferVirtual[1])
+ free_pages(devpriv->ul_DmaBufferVirtual[1],devpriv->ui_DmaBufferPages[1]);
+ }
+
+ if(dev->irq)
+ {
+ free_irq(dev->irq,dev);
+ }
+
+ if(dev->iobase) release_region(dev->iobase,this_board->i_IorangeBase1);
+
+ if(devpriv->i_IobaseAddon) release_region(devpriv->i_IobaseAddon,this_board->i_IorangeBase2);
+
+ if (pci_list_builded)
+ {
+ //v_pci_card_list_cleanup(PCI_VENDOR_ID_AMCC);
+ v_pci_card_list_cleanup(this_board->i_VendorId);
+ pci_list_builded=0;
+ }
+
+ return 0;
+}
+
+
+/*
++----------------------------------------------------------------------------+
+| Function name : static int i_ADDI_Reset(comedi_device *dev) |
+| |
++----------------------------------------------------------------------------+
+| Task : Disables all interrupts, Resets digital output to low, |
+| Set all analog output to low |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev |
+| |
+| |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
+| |
++----------------------------------------------------------------------------+
+*/
+
+static int i_ADDI_Reset(comedi_device *dev)
+{
+
+ this_board->i_hwdrv_Reset(dev);
+ return 0;
+}
+
+
+
+// Interrupt function
+/*
++----------------------------------------------------------------------------+
+| Function name : |
+|static void v_ADDI_Interrupt(int irq, void *d, struct pt_regs *regs) |
+| |
++----------------------------------------------------------------------------+
+| Task : Registerd interrupt routine |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : int irq |
+| |
+| |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+static void v_ADDI_Interrupt(int irq, void *d, struct pt_regs *regs)
+{
+comedi_device *dev = d;
+this_board->v_hwdrv_Interrupt(irq,d,regs);
+return;
+}
+// EEPROM Read Function
+/*
++----------------------------------------------------------------------------+
+| Function name : |
+|INT i_ADDIDATA_InsnReadEeprom(comedi_device *dev,comedi_subdevice *s,
+ comedi_insn *insn,lsampl_t *data)
+| |
++----------------------------------------------------------------------------+
+| Task : Read 256 words from EEPROM |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters :(comedi_device *dev,comedi_subdevice *s,
+ comedi_insn *insn,lsampl_t *data) |
+| |
+| |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+
+static int i_ADDIDATA_InsnReadEeprom(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ WORD w_Data;
+ WORD w_Address;
+ w_Address = CR_CHAN(insn->chanspec);// address to be read as 0,1,2,3...255
+
+ w_Data=w_EepromReadWord(devpriv->i_IobaseAmcc,this_board->pc_EepromChip,0x100+(2*w_Address));
+ data[0]=w_Data;
+ //multiplied by 2 bcozinput will be like 0,1,2...255
+ return insn->n;
+
+}
+
+
+
+
+
--- /dev/null
+/***********ADDI_COMMON.H*********************/
+
+
+
+
+
+/*
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstrasse 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 : ADDI DATA | Compiler : GCC |
+ | Modulname : addi_common.h | Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Author : | Date : |
+ +-----------------------------------------------------------------------+
+ | Description : ADDI COMMON Header File |
+ +-----------------------------------------------------------------------+
+ | UPDATE'S |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+
+
+
+//including header files
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/malloc.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/timer.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+#include <linux/comedidev.h>
+#include "addi_amcc_s5933.h"
+#include <linux/kmod.h>
+#include <asm/uaccess.h>
+
+#define ERROR -1
+#define SUCCESS 1
+
+// variable type definition
+
+#define VOID void
+#define UINT unsigned int
+#define ULONG unsigned long
+#define USHORT unsigned short
+#define PUSHORT unsigned short *
+#define INT int
+#define BYTE unsigned char
+#define PBYTE unsigned char *
+#define PINT int *
+#define PUINT unsigned int *
+#define CHAR char
+#define PCHAR char *
+#define PRANGE comedi_lrange *
+#define LOBYTE(W) (BYTE )((W)&0xFF)
+#define HIBYTE(W) (BYTE )(((W)>>8)&0xFF)
+#define MAKEWORD(H,L) (USHORT )((L)|( (H)<<8) )
+#define LOWORD(W) (USHORT )((W)&0xFFFF)
+#define HIWORD(W) (USHORT )(((W)>>16)&0xFFFF)
+#define MAKEDWORD(H,L) (UINT )((L)|( (H)<<16) )
+
+#define DWORD unsigned long
+#define WORD unsigned short
+
+#define ADDI_ENABLE 1
+#define ADDI_DISABLE 0
+#define APCI1710_SAVE_INTERRUPT 1
+
+#define ADDIDATA_EEPROM 1
+#define ADDIDATA_NO_EEPROM 0
+#define ADDIDATA_93C76 "93C76"
+#define ADDIDATA_S5920 "S5920"
+#define ADDIDATA_S5933 "S5933"
+
+// Structures
+// structure for the boardtype
+typedef struct {
+
+ PCHAR pc_DriverName; // driver name
+ INT i_VendorId; //PCI vendor a device ID of card
+ INT i_DeviceId;
+ INT i_IorangeBase0;
+ INT i_IorangeBase1;
+ INT i_IorangeBase2; // base 2 range
+ INT i_IorangeBase3; // base 3 range
+ INT i_PCIEeprom; // eeprom present or not
+ PCHAR pc_EepromChip; // type of chip
+ INT i_NbrAiChannel; // num of A/D chans
+ INT i_NbrAiChannelDiff;// num of A/D chans in diff mode
+ INT i_AiChannelList;// len of chanlist
+ INT i_NbrAoChannel;// num of D/A chans
+ INT i_AiMaxdata;// resolution of A/D
+ INT i_AoMaxdata;// resolution of D/A
+ PRANGE pr_AiRangelist; // rangelist for A/D
+ PRANGE pr_AoRangelist;// rangelist for D/A
+
+ INT i_NbrDiChannel; // Number of DI channels
+ INT i_NbrDoChannel; // Number of DO channels
+ INT i_DoMaxdata; // data to set all chanels high
+
+ INT i_Dma; // dma present or not
+ INT i_Timer; // timer subdevice present or not
+ UINT ui_MinAcquisitiontimeNs; // Minimum Acquisition in Nano secs
+ UINT ui_MinDelaytimeNs; // Minimum Delay in Nano secs
+
+// interrupt and reset
+ void (*v_hwdrv_Interrupt)(int irq, void *d, struct pt_regs *regs);
+ int (*i_hwdrv_Reset)(comedi_device *dev);
+
+//Subdevice functions
+//ANALOG INPUT
+
+int (*i_hwdrv_InsnConfigAnalogInput)(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+int (*i_hwdrv_InsnReadAnalogInput)(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+int (*i_hwdrv_InsnWriteAnalogInput)(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+int (*i_hwdrv_InsnBitsAnalogInput)(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+int (*i_hwdrv_CommandTestAnalogInput)(comedi_device *dev,comedi_subdevice *s,comedi_cmd *cmd) ;
+int (*i_hwdrv_CommandAnalogInput)(comedi_device * dev,comedi_subdevice * s);
+int (*i_hwdrv_CancelAnalogInput)(comedi_device * dev, comedi_subdevice * s);
+
+
+//Analog Output
+int (*i_hwdrv_InsnConfigAnalogOutput)(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+int (*i_hwdrv_InsnWriteAnalogOutput)(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+int (*i_hwdrv_InsnBitsAnalogOutput)(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+
+
+//Digital Input
+int (*i_hwdrv_InsnConfigDigitalInput)(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+ int (*i_hwdrv_InsnReadDigitalInput)(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+int (*i_hwdrv_InsnWriteDigitalInput)(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+int (*i_hwdrv_InsnBitsDigitalInput)(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+
+//Digital Output
+int (*i_hwdrv_InsnConfigDigitalOutput)(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+int (*i_hwdrv_InsnWriteDigitalOutput)(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+int (*i_hwdrv_InsnBitsDigitalOutput)(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn,lsampl_t *data);
+int (*i_hwdrv_InsnReadDigitalOutput)(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn,lsampl_t *data);
+//TIMER
+ int (*i_hwdrv_InsnConfigTimer)(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+ int (*i_hwdrv_InsnWriteTimer)(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+ int (*i_hwdrv_InsnReadTimer)(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+ int (*i_hwdrv_InsnBitsTimer)(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+} boardtype;
+
+
+
+
+
+
+//MODULE INFO STRUCTURE
+
+
+
+ typedef union
+ {
+ /*****************************/
+ /* Incremental counter infos */
+ /*****************************/
+
+ struct
+ {
+ union
+ {
+ struct
+ {
+ BYTE b_ModeRegister1;
+ BYTE b_ModeRegister2;
+ BYTE b_ModeRegister3;
+ BYTE b_ModeRegister4;
+ }s_ByteModeRegister;
+ DWORD dw_ModeRegister1_2_3_4;
+ }s_ModeRegister;
+
+ struct
+ {
+ unsigned int b_IndexInit : 1;
+ unsigned int b_CounterInit : 1;
+ unsigned int b_ReferenceInit : 1;
+ unsigned int b_IndexInterruptOccur : 1;
+ unsigned int b_CompareLogicInit : 1;
+ unsigned int b_FrequencyMeasurementInit : 1;
+ unsigned int b_FrequencyMeasurementEnable : 1;
+ }s_InitFlag;
+
+ }s_SiemensCounterInfo;
+
+ /*************/
+ /* SSI infos */
+ /*************/
+
+ struct
+ {
+ BYTE b_SSIProfile;
+ BYTE b_PositionTurnLength;
+ BYTE b_TurnCptLength;
+ BYTE b_SSIInit;
+ }s_SSICounterInfo;
+
+
+ /*****************/
+ /* TTL I/O infos */
+ /*****************/
+
+ struct
+ {
+ BYTE b_TTLInit;
+ BYTE b_PortConfiguration [4];
+ }s_TTLIOInfo;
+
+ /*********************/
+ /* Digital I/O infos */
+ /*********************/
+
+ struct
+ {
+ BYTE b_DigitalInit;
+ BYTE b_ChannelAMode;
+ BYTE b_ChannelBMode;
+ BYTE b_OutputMemoryEnabled;
+ DWORD dw_OutputMemory;
+ }s_DigitalIOInfo;
+
+ /*********************/
+ /* 82X54 timer infos */
+ /*********************/
+
+ struct
+ {
+ struct
+ {
+ BYTE b_82X54Init;
+ BYTE b_InputClockSelection;
+ BYTE b_InputClockLevel;
+ BYTE b_OutputLevel;
+ BYTE b_HardwareGateLevel;
+ DWORD dw_ConfigurationWord;
+ }s_82X54TimerInfo [3];
+ BYTE b_InterruptMask;
+ }s_82X54ModuleInfo;
+
+ /*********************/
+ /* Chronometer infos */
+ /*********************/
+
+ struct
+ {
+ BYTE b_ChronoInit;
+ BYTE b_InterruptMask;
+ BYTE b_PCIInputClock;
+ BYTE b_TimingUnit;
+ BYTE b_CycleMode;
+ double d_TimingInterval;
+ DWORD dw_ConfigReg;
+ }s_ChronoModuleInfo;
+
+ /***********************/
+ /* Pulse encoder infos */
+ /***********************/
+
+ struct
+ {
+ struct
+ {
+ BYTE b_PulseEncoderInit;
+ }s_PulseEncoderInfo [4];
+ DWORD dw_SetRegister;
+ DWORD dw_ControlRegister;
+ DWORD dw_StatusRegister;
+ }s_PulseEncoderModuleInfo;
+
+ /********************/
+ /* Tor conter infos */
+ /********************/
+
+ struct
+ {
+ struct
+ {
+ BYTE b_TorCounterInit;
+ BYTE b_TimingUnit;
+ BYTE b_InterruptEnable;
+ double d_TimingInterval;
+ ULONG ul_RealTimingInterval;
+ }s_TorCounterInfo [2];
+ BYTE b_PCIInputClock;
+ }s_TorCounterModuleInfo;
+
+ /*************/
+ /* PWM infos */
+ /*************/
+
+ struct
+ {
+ struct
+ {
+ BYTE b_PWMInit;
+ BYTE b_TimingUnit;
+ BYTE b_InterruptEnable;
+ double d_LowTiming;
+ double d_HighTiming;
+ ULONG ul_RealLowTiming;
+ ULONG ul_RealHighTiming;
+ }s_PWMInfo [2];
+ BYTE b_ClockSelection;
+ }s_PWMModuleInfo;
+
+ /*************/
+ /* ETM infos */
+ /*************/
+
+ struct
+ {
+ struct
+ {
+ BYTE b_ETMEnable;
+ BYTE b_ETMInterrupt;
+ }s_ETMInfo [2];
+ BYTE b_ETMInit;
+ BYTE b_TimingUnit;
+ BYTE b_ClockSelection;
+ double d_TimingInterval;
+ ULONG ul_Timing;
+ }s_ETMModuleInfo;
+
+ /*************/
+ /* CDA infos */
+ /*************/
+
+ struct
+ {
+ BYTE b_CDAEnable;
+ BYTE b_CDAInterrupt;
+ BYTE b_CDAInit;
+ BYTE b_FctSelection;
+ BYTE b_CDAReadFIFOOverflow;
+ }s_CDAModuleInfo;
+
+ }str_ModuleInfo;
+// Private structure for the addi_apci3120 driver
+
+typedef struct{
+
+ INT iobase;
+ INT i_IobaseAmcc; // base+size for AMCC chip
+ INT i_IobaseAddon; //addon base address
+ INT i_IobaseReserved;
+ struct pcilst_struct *amcc; // ptr too AMCC data
+ UINT master; // master capable
+ BYTE allocated; // we have blocked card
+ BYTE b_ValidDriver;// driver is ok
+ BYTE b_AiContinuous; // we do unlimited AI
+ UINT ui_AiActualScan; //how many scans we finished
+ UINT ui_AiBufferPtr;// data buffer ptr in samples
+ UINT ui_AiNbrofChannels;// how many channels is measured
+ UINT ui_AiScanLength;// Length of actual scanlist
+ UINT ui_AiActualScanPosition; // position in actual scan
+ PUINT pui_AiChannelList; // actual chanlist
+ UINT ui_AiChannelList[32]; // actual chanlist
+ UINT ui_AiReadData[32];
+ UINT ui_AiTimer0; //Timer Constant for Timer0
+ UINT ui_AiTimer1; //Timer constant for Timer1
+ UINT ui_AiFlags;
+ UINT ui_AiDataLength;
+ sampl_t *AiData; // Pointer to sample data
+ UINT ui_AiNbrofScans;// number of scans to do
+ USHORT us_UseDma; // To use Dma or not
+ BYTE b_DmaDoubleBuffer;// we can use double buffering
+ UINT ui_DmaActualBuffer; // which buffer is used now
+ ULONG ul_DmaBufferVirtual[2];// pointers to begin of DMA buffer
+ ULONG ul_DmaBufferHw[2]; // hw address of DMA buff
+ UINT ui_DmaBufferSize[2];// size of dma buffer in bytes
+ UINT ui_DmaBufferUsesize[2];// which size e may now used for transfer
+ UINT ui_DmaBufferSamples[2];// size in samples
+ UINT ui_DmaBufferPages[2];// number of pages in buffer
+ BYTE b_DigitalOutputRegister; // Digital Output Register
+ BYTE b_OutputMemoryStatus;
+ BYTE b_AnalogInputChannelNbr; // Analog input channel Nbr
+ BYTE b_AnalogOutputChannelNbr;// Analog input Output Nbr
+ BYTE b_TimerSelectMode; // Contain data written at iobase + 0C
+ BYTE b_ModeSelectRegister; // Contain data written at iobase + 0E
+ USHORT us_OutputRegister; // Contain data written at iobase + 0
+ BYTE b_InterruptState;
+ BYTE b_TimerInit; // Specify if InitTimerWatchdog was load
+ BYTE b_TimerStarted; // Specify if timer 2 is running or not
+ BYTE b_Timer2Mode; // Specify the timer 2 mode
+ BYTE b_Timer2Interrupt;//Timer2 interrupt enable or disable
+ BYTE b_AiCyclicAcquisition;// indicate cyclic acquisition
+ BYTE b_InterruptMode; // eoc eos or dma
+ BYTE b_EocEosInterrupt; // Enable disable eoc eos interrupt
+ UINT ui_EocEosConversionTime;
+ BYTE b_ExttrigEnable; // To enable or disable external trigger
+ struct task_struct *tsk_Current; // Pointer to the current process
+
+
+
+ // Hardware board infos for 1710
+
+ struct
+ {
+ UINT ui_Address; // Board address
+ UINT ui_FlashAddress;
+ BYTE b_InterruptNbr; // Board interrupt number
+ BYTE b_SlotNumber; // PCI slot number
+ BYTE b_BoardVersion;
+ DWORD dw_MolduleConfiguration [4]; // Module configuration
+ }s_BoardInfos;
+
+
+ /*******************/
+ /* Interrupt infos */
+ /*******************/
+
+
+ struct
+ {
+ ULONG ul_InterruptOccur; /* 0 : No interrupt occur */
+ /* > 0 : Interrupt occur */
+ UINT ui_Read; /* Read FIFO */
+ UINT ui_Write; /* Write FIFO */
+ struct
+ {
+ BYTE b_OldModuleMask;
+ ULONG ul_OldInterruptMask; /* Interrupt mask */
+ ULONG ul_OldCounterLatchValue; /* Interrupt counter value */
+ }s_FIFOInterruptParameters [APCI1710_SAVE_INTERRUPT];
+ }s_InterruptParameters;
+
+ str_ModuleInfo s_ModuleInfo [4];
+
+ } addi_private;
+
+
+static unsigned short pci_list_builded=0; /* set to 1 when list of card is known */
+
+
+
+
+
+
+
+//Function declarations
+
+static int i_ADDI_Attach(comedi_device *dev,comedi_devconfig *it);
+static int i_ADDI_Detach(comedi_device *dev);
+static int i_ADDI_Reset(comedi_device *dev);
+
+static void v_ADDI_Interrupt(int irq, void *d, struct pt_regs *regs);
+static int i_ADDIDATA_InsnReadEeprom(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+
+
+
--- /dev/null
+
+
+/*
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstrasse 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 : ADDI DATA | Compiler : GCC |
+ | Modulname : addi_eeprom.c | Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Author : | Date : |
+ +-----------------------------------------------------------------------+
+ | Description : ADDI EEPROM Module |
+ +-----------------------------------------------------------------------+
+ | UPDATE'S |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+
+
+
+
+
+
+
+#define NVCMD_BEGIN_READ (0x7 << 5 ) // nvRam begin read command
+#define NVCMD_LOAD_LOW (0x4 << 5 ) // nvRam load low command
+#define NVCMD_LOAD_HIGH (0x5 << 5 ) // nvRam load high command
+#define EE76_CMD_LEN 13 // bits in instructions
+#define EE_READ 0x0180 // 01 1000 0000 read instruction
+
+#define WORD unsigned short
+#define DWORD unsigned int
+#define PWORD unsigned short *
+#define PDWORD unsigned int *
+
+
+
+
+#define EEPROM_DIGITALINPUT 0
+#define EEPROM_DIGITALOUTPUT 1
+#define EEPROM_ANALOGINPUT 2
+#define EEPROM_ANALOGOUTPUT 3
+#define EEPROM_TIMER 4
+#define EEPROM_WATCHDOG 5
+#define EEPROM_TIMER_WATCHDOG_COUNTER 10
+
+struct str_Functionality
+{
+ BYTE b_Type;
+ WORD w_Address;
+};
+
+
+typedef struct
+{
+ WORD w_HeaderSize;
+ BYTE b_Nfunctions;
+ struct str_Functionality s_Functions[7];
+}str_MainHeader;
+
+
+
+typedef struct
+{
+ WORD w_Nchannel;
+ BYTE b_Interruptible;
+ WORD w_NinterruptLogic;
+}str_DigitalInputHeader;
+
+typedef struct
+{
+ WORD w_Nchannel;
+}str_DigitalOutputHeader;
+
+// used for timer as well as watchdog
+
+typedef struct
+{
+ WORD w_HeaderSize;
+ BYTE b_Resolution;
+ BYTE b_Mode; // in case of Watchdog it is functionality
+ WORD w_MinTiming;
+ BYTE b_TimeBase;
+}str_TimerDetails;
+typedef struct
+{
+
+ WORD w_Ntimer;
+ str_TimerDetails s_TimerDetails[4]; // supports 4 timers
+}str_TimerMainHeader;
+
+
+typedef struct
+{
+ WORD w_Nchannel;
+ BYTE b_Resolution;
+ }str_AnalogOutputHeader ;
+
+typedef struct
+{
+ WORD w_Nchannel;
+ WORD w_MinConvertTiming;
+ WORD w_MinDelayTiming;
+ BYTE b_HasDma;
+ BYTE b_Resolution;
+} str_AnalogInputHeader;
+
+ /*****************************************/
+ /* Read Header Functions */
+ /*****************************************/
+
+INT i_EepromReadMainHeader(WORD w_PCIBoardEepromAddress,PCHAR pc_PCIChipInformation,comedi_device *dev);
+
+INT i_EepromReadDigitalInputHeader(WORD w_PCIBoardEepromAddress,PCHAR pc_PCIChipInformation,WORD w_Address,str_DigitalInputHeader *s_Header);
+
+INT i_EepromReadDigitalOutputHeader(WORD w_PCIBoardEepromAddress,PCHAR pc_PCIChipInformation,WORD w_Address,str_DigitalOutputHeader *s_Header);
+
+INT i_EepromReadTimerHeader(WORD w_PCIBoardEepromAddress,PCHAR pc_PCIChipInformation,WORD w_Address,str_TimerMainHeader *s_Header);
+
+INT i_EepromReadAnlogOutputHeader(WORD w_PCIBoardEepromAddress,PCHAR pc_PCIChipInformation,WORD w_Address,str_AnalogOutputHeader *s_Header);
+
+INT i_EepromReadAnlogInputHeader(WORD w_PCIBoardEepromAddress,PCHAR pc_PCIChipInformation,WORD w_Address,str_AnalogInputHeader *s_Header);
+
+ /******************************************/
+ /* Eeprom Specific Functions */
+ /******************************************/
+WORD w_EepromReadWord(WORD w_PCIBoardEepromAddress,PCHAR pc_PCIChipInformation,WORD w_EepromStartAddress);
+VOID v_EepromWaitBusy(WORD w_PCIBoardEepromAddress);
+VOID v_EepromClock76(DWORD dw_Address,DWORD dw_RegisterValue);
+VOID v_EepromWaitBusy(WORD w_PCIBoardEepromAddress);
+VOID v_EepromSendCommand76(DWORD dw_Address,DWORD dw_EepromCommand,BYTE b_DataLengthInBits);
+VOID v_EepromCs76Read(DWORD dw_Address,WORD w_offset,PWORD pw_Value);
+
+
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : WORD w_EepromReadWord |
+| (WORD w_PCIBoardEepromAddress, |
+| PCHAR pc_PCIChipInformation, |
+| WORD w_EepromStartAddress) |
++----------------------------------------------------------------------------+
+| Task : Read from eepromn a word |
++----------------------------------------------------------------------------+
+| Input Parameters : WORD w_PCIBoardEepromAddress : PCI eeprom address |
+| |
+| PCHAR pc_PCIChipInformation : PCI Chip Type. |
+| |
+| WORD w_EepromStartAddress : Selected eeprom address |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : Read word value from eeprom |
++----------------------------------------------------------------------------+
+*/
+
+WORD w_EepromReadWord(WORD w_PCIBoardEepromAddress,PCHAR pc_PCIChipInformation,WORD w_EepromStartAddress)\r
+{\r
+ BYTE b_Counter = 0;\r
+ BYTE b_ReadByte = 0;\r
+ BYTE b_ReadLowByte = 0;\r
+ BYTE b_ReadHighByte = 0;\r
+ BYTE b_SelectedAddressLow = 0;\r
+ BYTE b_SelectedAddressHigh = 0;\r
+ WORD w_ReadWord = 0;\r
+
+\r
+ /**************************/\r
+ /* Test the PCI chip type */\r
+ /**************************/\r
+\r
+
+ if ((!strcmp(pc_PCIChipInformation, "S5920")) || \r
+ (!strcmp(pc_PCIChipInformation, "S5933")))\r
+ {\r
+
+ for (b_Counter=0; b_Counter<2; b_Counter++)\r
+ {\r
+ b_SelectedAddressLow = (w_EepromStartAddress + b_Counter) % 256; //Read the low 8 bit part\r
+ b_SelectedAddressHigh = (w_EepromStartAddress + b_Counter) / 256; //Read the high 8 bit part\r
+\r
+ /************************************/\r
+ /* Select the load low address mode */\r
+ /************************************/\r
+\r outb(NVCMD_LOAD_LOW,w_PCIBoardEepromAddress + 0x3F);
+
+\r
+ /****************/\r
+ /* Wait on busy */\r
+ /****************/\r
+ v_EepromWaitBusy (w_PCIBoardEepromAddress);\r
+
+ /************************/\r
+ /* Load the low address */\r
+ /************************/\r
+\r outb(b_SelectedAddressLow,w_PCIBoardEepromAddress + 0x3E);
+
+\r
+ /****************/\r
+ /* Wait on busy */\r
+ /****************/\r
+ v_EepromWaitBusy (w_PCIBoardEepromAddress);\r
+\r
+ /*************************************/\r
+ /* Select the load high address mode */\r
+ /*************************************/\r
+\r outb(NVCMD_LOAD_HIGH,w_PCIBoardEepromAddress + 0x3F);
+
+\r
+ /****************/\r
+ /* Wait on busy */\r
+ /****************/\r
+ v_EepromWaitBusy (w_PCIBoardEepromAddress);\r
+\r
+ /*************************/\r
+ /* Load the high address */\r
+ /*************************/\r
+\r outb(b_SelectedAddressHigh,w_PCIBoardEepromAddress +0x3E);
+
+
+ /****************/\r
+ /* Wait on busy */\r
+ /****************/\r
+ v_EepromWaitBusy (w_PCIBoardEepromAddress);\r
+\r
+ /************************/\r
+ /* Select the READ mode */\r
+ /************************/\r
+\r outb(NVCMD_BEGIN_READ,w_PCIBoardEepromAddress + 0x3F);
+
+
+ /****************/\r
+ /* Wait on busy */\r
+ /****************/\r\r
+ v_EepromWaitBusy (w_PCIBoardEepromAddress);\r
+\r
+ /*****************************/\r
+ /* Read data into the EEPROM */\r
+ /*****************************/\r
+ b_ReadByte = inb(w_PCIBoardEepromAddress + 0x3E); \r
+
+\r
+ /****************/\r
+ /* Wait on busy */\r
+ /****************/\r
+\r
+ v_EepromWaitBusy (w_PCIBoardEepromAddress);\r
+\r
+ /*********************************/\r
+ /* Select the upper address part */\r
+ /*********************************/\r
+\r
+ if(b_Counter==0)\r
+ {\r
+ b_ReadLowByte=b_ReadByte;\r
+ } // if(b_Counter==0)\r
+ else\r
+ {\r
+ b_ReadHighByte=b_ReadByte;\r
+ } // if(b_Counter==0)\r
+ } // for (b_Counter=0; b_Counter<2; b_Counter++)\r
+\r
+ w_ReadWord=(b_ReadLowByte | (((WORD) b_ReadHighByte) * 256));\r
+ \r
+ } // end of if ((!strcmp(pc_PCIChipInformation, "S5920")) || (!strcmp(pc_PCIChipInformation, "S5933"))) \r
+ if (!strcmp(pc_PCIChipInformation, "93C76"))\r
+ {\r
+ /*************************************/\r
+ /* Read 16 bit from the EEPROM 93C76 */\r
+ /*************************************/\r
+\r
+ v_EepromCs76Read(w_PCIBoardEepromAddress, w_EepromStartAddress, &w_ReadWord);\r
+ }\r
+
+ return (w_ReadWord);\r
+ }\r
+\r
+\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : VOID v_EepromWaitBusy |\r
+| (WORD w_PCIBoardEepromAddress) |\r
++----------------------------------------------------------------------------+\r
+| Task : Wait the busy flag from PCI controller |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : WORD w_PCIBoardEepromAddress : PCI eeprom base address |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++----------------------------------------------------------------------------+\r
+| Return Value : - |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+VOID v_EepromWaitBusy(WORD w_PCIBoardEepromAddress)\r
+ {\r
+ BYTE b_EepromBusy = 0;\r
+\r
+ do\r
+ {\r
+ /*************/\r
+ /* IMPORTANT */\r
+ /*************/\r
+\r
+ /************************************************************************/\r
+ /* An error has been written in the AMCC 5933 book at the page B-13*/\r
+ /* Ex: if you read a byte and look for the busy statusEEPROM=0x80 and */
+ \r /* the operator register is AMCC_OP_REG_MCSR+3*/\r
+ /* WORD read EEPROM=0x8000 andAMCC_OP_REG_MCSR+2 */\r
+ /* DWORD read EEPROM=0x80000000 and AMCC_OP_REG_MCSR */\r
+ /************************************************************************/\r \r
+ b_EepromBusy = inb(w_PCIBoardEepromAddress + 0x3F);
+ b_EepromBusy = b_EepromBusy &0x80;\r
+ }\r while(b_EepromBusy == 0x80);\r \r
+
+ }\r
+\r
+\r
+
+/*\r
++---------------------------------------------------------------------------------+\r
+| Function Name : VOID v_EepromClock76(DWORD dw_Address, |\r
+| DWORD dw_RegisterValue) |\r
++---------------------------------------------------------------------------------+\r
+| Task : This function sends the clocking sequence to the EEPROM. |\r
++---------------------------------------------------------------------------------+\r
+| Input Parameters : DWORD dw_Address : PCI eeprom base address |\r
+| DWORD dw_RegisterValue : PCI eeprom register value to write.|\r
++---------------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++---------------------------------------------------------------------------------+\r
+| Return Value : - |\r
++---------------------------------------------------------------------------------+\r
+*/\r
+\r
+VOID v_EepromClock76(DWORD dw_Address,DWORD dw_RegisterValue)\r
+ {\r
+\r
+ /************************/\r
+ /* Set EEPROM clock Low */\r
+ /************************/\r
+ \routl(dw_RegisterValue & 0x6,dw_Address);
+
+ /***************/\r
+ /* Wait 0.1 ms */\r
+ /***************/\r\r
+ udelay(100);
+ \r
+ /*************************/\r
+ /* Set EEPROM clock High */\r
+ /*************************/\r
+\r outl(dw_RegisterValue | 0x1,dw_Address);
+\r
+ /***************/\r
+ /* Wait 0.1 ms */\r
+ /***************/\r
+\r udelay(100);
+
+ }\r
+\r
+/*\r
++---------------------------------------------------------------------------------+\r
+| Function Name : VOID v_EepromSendCommand76(DWORD dw_Address, |\r
+| DWORD dw_EepromCommand, |\r
+| BYTE b_DataLengthInBits) |\r
++---------------------------------------------------------------------------------+\r
+| Task : This function sends a Command to the EEPROM 93C76. |\r
++---------------------------------------------------------------------------------+\r
+| Input Parameters : DWORD dw_Address : PCI eeprom base address |\r
+| DWORD dw_EepromCommand : PCI eeprom command to write. |\r
+| BYTE b_DataLengthInBits : PCI eeprom command data length. |\r
++---------------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++---------------------------------------------------------------------------------+\r
+| Return Value : - |\r
++---------------------------------------------------------------------------------+\r
+*/\r
+\r
+VOID v_EepromSendCommand76(DWORD dw_Address,DWORD dw_EepromCommand,BYTE b_DataLengthInBits)\r
+ {\r
+ CHAR c_BitPos = 0;\r
+ DWORD dw_RegisterValue = 0;\r
+\r
+ \r
+ /*****************************/\r
+ /* Enable EEPROM Chip Select */\r
+ /*****************************/\r
+ dw_RegisterValue = 0x2;\r
+\r
+ /********************************************************************/\r
+ /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */\r
+ /********************************************************************/\r
+ outl(dw_RegisterValue,dw_Address);\r
+
+\r
+ /***************/\r
+ /* Wait 0.1 ms */\r
+ /***************/\r
+ \rudelay(100);
+
+ \r
+ /*******************************************/\r
+ /* Send EEPROM command - one bit at a time */\r
+ /*******************************************/\r \r
+ for (c_BitPos = (b_DataLengthInBits - 1); c_BitPos >= 0; c_BitPos--)\r
+ {\r
+
+ /**********************************/\r
+ /* Check if current bit is 0 or 1 */\r
+ /**********************************/\r\r
+ if (dw_EepromCommand & (1 << c_BitPos))\r
+ {\r
+ /***********/\r
+ /* Write 1 */\r
+ /***********/\r
+\r
+ dw_RegisterValue = dw_RegisterValue | 0x4;\r
+ }\r
+ else\r
+ {\r
+ /***********/\r
+ /* Write 0 */\r
+ /***********/\r
+\r
+ dw_RegisterValue = dw_RegisterValue & 0x3;\r
+ }\r
+\r
+ /*********************/\r
+ /* Write the command */\r
+ /*********************/\r
+\r outl(dw_RegisterValue,dw_Address);
+
+\r
+ /***************/\r
+ /* Wait 0.1 ms */\r
+ /***************/\r
+ \r udelay(100);
+
+ \r
+ /****************************/\r
+ /* Trigger the EEPROM clock */\r
+ /****************************/\r
+ v_EepromClock76(dw_Address, dw_RegisterValue);\r
+
+ }\r
+\r
+ }\r
+\r
+/*\r
++---------------------------------------------------------------------------------+\r
+| Function Name : VOID v_EepromCs76Read(DWORD dw_Address, |\r
+| WORD w_offset, |\r
+| PWORD pw_Value) |\r
++---------------------------------------------------------------------------------+\r
+| Task : This function read a value from the EEPROM 93C76. |\r
++---------------------------------------------------------------------------------+\r
+| Input Parameters : DWORD dw_Address : PCI eeprom base address |\r
+| WORD w_offset : Offset of the adress to read |\r
+| PWORD pw_Value : PCI eeprom 16 bit read value. |\r
++---------------------------------------------------------------------------------+\r
+| Output Parameters : - |\r
++---------------------------------------------------------------------------------+\r
+| Return Value : - |\r
++---------------------------------------------------------------------------------+\r
+*/\r
+\r
+VOID v_EepromCs76Read(DWORD dw_Address,WORD w_offset,\rPWORD pw_Value)\r
+ {\r
+ CHAR c_BitPos = 0;\r
+ DWORD dw_RegisterValue = 0;\r
+ DWORD dw_RegisterValueRead = 0;\r
+\r
+\r
+ /*************************************************/\r
+ /* Send EEPROM read command and offset to EEPROM */\r
+ /*************************************************/\r
+ v_EepromSendCommand76(dw_Address, (EE_READ << 4) | (w_offset / 2), EE76_CMD_LEN);\r
+\r
+ /*******************************/\r
+ /* Get the last register value */\r
+ /*******************************/\r
+ dw_RegisterValue = (((w_offset / 2) & 0x1) << 2) | 0x2;\r
+ \r
+ /*****************************/\r
+ /* Set the 16-bit value of 0 */\r
+ /*****************************/\r\r
+ *pw_Value = 0;\r
+\r
+ /************************/\r
+ /* Get the 16-bit value */\r
+ /************************/\r
+ for (c_BitPos = 0; c_BitPos < 16; c_BitPos++)\r
+ {\r
+
+ /****************************/\r
+ /* Trigger the EEPROM clock */\r
+ /****************************/\r\r
+ v_EepromClock76(dw_Address, dw_RegisterValue);\r
+\r
+ /**********************/\r
+ /* Get the result bit */\r
+ /**********************/\r
+\r dw_RegisterValueRead = inl(dw_Address);
+
+ /***************/\r
+ /* Wait 0.1 ms */\r
+ /***************/\r
+ \r udelay(100);
+ \r
+ /***************************************/\r
+ /* Get bit value and shift into result */\r
+ /***************************************/\r\r
+ if (dw_RegisterValueRead & 0x8)\r
+ {\r
+
+ /**********/\r
+ /* Read 1 */\r
+ /**********/\r\r
+ *pw_Value = (*pw_Value << 1) | 0x1;\r
+ }\r
+ else\r
+ {\r
+ /**********/\r
+ /* Read 0 */\r
+ /**********/\r
+ *pw_Value = (*pw_Value << 1);\r
+
+ }\r
+ }\r
+\r
+ /*************************/\r
+ /* Clear all EEPROM bits */\r
+ /*************************/\r\r
+ dw_RegisterValue = 0x0;\r
+\r
+ /********************************************************************/\r
+ /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */\r
+ /********************************************************************/\r
+\r outl(dw_RegisterValue,dw_Address);
+
+ /***************/\r
+ /* Wait 0.1 ms */\r
+ /***************/\r
+ udelay(100);
+
+ }\r
+\r
+
+
+ /******************************************/
+ /* EEPROM HEADER READ FUNCTIONS */
+ /******************************************/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_EepromReadMainHeader(WORD w_PCIBoardEepromAddress, |
+| PCHAR pc_PCIChipInformation,comedi_device *dev) |
++----------------------------------------------------------------------------+
+| Task : Read from eeprom Main Header |
++----------------------------------------------------------------------------+
+| Input Parameters : WORD w_PCIBoardEepromAddress : PCI eeprom address |
+| |
+| PCHAR pc_PCIChipInformation : PCI Chip Type. |
+| |
+| comedi_device *dev : comedi device structure |
+| pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
++----------------------------------------------------------------------------+
+*/
+
+
+INT i_EepromReadMainHeader(WORD w_PCIBoardEepromAddress,PCHAR pc_PCIChipInformation,comedi_device *dev)
+{
+ WORD w_Temp,i,w_Count=0;
+ UINT ui_Temp;
+ str_MainHeader s_MainHeader;
+ str_DigitalInputHeader s_DigitalInputHeader;
+ str_DigitalOutputHeader s_DigitalOutputHeader;
+ //str_TimerMainHeader s_TimerMainHeader,s_WatchdogMainHeader;
+ str_AnalogOutputHeader s_AnalogOutputHeader;
+ str_AnalogInputHeader s_AnalogInputHeader;
+
+ // Read size
+ s_MainHeader.w_HeaderSize = w_EepromReadWord(w_PCIBoardEepromAddress,pc_PCIChipInformation,0x100+8);
+
+ // Read nbr of functionality
+ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,pc_PCIChipInformation,0x100+10);
+ s_MainHeader.b_Nfunctions =(BYTE)w_Temp & 0x00FF;
+
+ // Read functionality details
+ for(i=0;i<s_MainHeader.b_Nfunctions;i++)
+ {
+ // Read Type
+ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,pc_PCIChipInformation,0x100+12+w_Count);
+ s_MainHeader.s_Functions[i].b_Type =(BYTE) w_Temp & 0x3F;
+ w_Count=w_Count+2;
+ //Read Address
+ s_MainHeader.s_Functions[i].w_Address= w_EepromReadWord(w_PCIBoardEepromAddress,pc_PCIChipInformation,0x100+12+w_Count);
+ w_Count=w_Count+2;
+ }
+
+ // Display main header info
+ for(i=0;i<s_MainHeader.b_Nfunctions;i++)
+ {
+
+ switch(s_MainHeader.s_Functions[i].b_Type)
+ {
+ case EEPROM_DIGITALINPUT:
+ i_EepromReadDigitalInputHeader(w_PCIBoardEepromAddress,pc_PCIChipInformation,
+ s_MainHeader.s_Functions[i].w_Address,&s_DigitalInputHeader);
+ this_board->i_NbrDiChannel=s_DigitalInputHeader.w_Nchannel;
+ break;
+
+ case EEPROM_DIGITALOUTPUT:
+ i_EepromReadDigitalOutputHeader(w_PCIBoardEepromAddress,pc_PCIChipInformation,
+ s_MainHeader.s_Functions[i].w_Address,&s_DigitalOutputHeader);
+ this_board->i_NbrDoChannel=s_DigitalOutputHeader.w_Nchannel;
+ ui_Temp=0xffffffff;
+ this_board->i_DoMaxdata= ui_Temp >>(32 - this_board->i_NbrDoChannel);
+ break;
+
+ case EEPROM_ANALOGINPUT:
+ i_EepromReadAnlogInputHeader(w_PCIBoardEepromAddress,pc_PCIChipInformation,
+ s_MainHeader.s_Functions[i].w_Address,&s_AnalogInputHeader);
+ this_board->i_NbrAiChannel=s_AnalogInputHeader.w_Nchannel;
+ this_board->i_Dma=s_AnalogInputHeader.b_HasDma;
+ this_board->ui_MinAcquisitiontimeNs=(UINT)s_AnalogInputHeader.w_MinConvertTiming * 1000;
+ this_board->ui_MinDelaytimeNs =(UINT)s_AnalogInputHeader.w_MinDelayTiming * 1000;
+ ui_Temp=0xffff;
+ this_board->i_AiMaxdata = ui_Temp >> (16 - s_AnalogInputHeader.b_Resolution);
+ break;
+
+ case EEPROM_ANALOGOUTPUT:
+ i_EepromReadAnlogOutputHeader(w_PCIBoardEepromAddress,pc_PCIChipInformation,
+ s_MainHeader.s_Functions[i].w_Address,&s_AnalogOutputHeader);
+ this_board->i_NbrAoChannel=s_AnalogOutputHeader.w_Nchannel;
+ ui_Temp=0xffff;
+ this_board->i_AoMaxdata= ui_Temp >>(16 - s_AnalogOutputHeader.b_Resolution);
+ break;
+
+ case EEPROM_TIMER:
+ this_board->i_Timer=1;//Timer subdevice present
+ break;
+
+ case EEPROM_WATCHDOG:
+ this_board->i_Timer=1; //Timer subdevice present
+ break;
+
+ case EEPROM_TIMER_WATCHDOG_COUNTER:
+ this_board->i_Timer=1; //Timer subdevice present
+ }
+ }
+
+ return 0;
+}
+
+
+
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_EepromReadDigitalInputHeader(WORD |
+| w_PCIBoardEepromAddress,PCHAR pc_PCIChipInformation, |
+| WORD w_Address,str_DigitalInputHeader *s_Header) |
+| |
++----------------------------------------------------------------------------+
+| Task : Read Digital Input Header |
++----------------------------------------------------------------------------+
+| Input Parameters : WORD w_PCIBoardEepromAddress : PCI eeprom address |
+| |
+| PCHAR pc_PCIChipInformation : PCI Chip Type. |
+| |
+| str_DigitalInputHeader *s_Header: Digita Input Header |
+| Pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
++----------------------------------------------------------------------------+
+*/
+INT i_EepromReadDigitalInputHeader(WORD w_PCIBoardEepromAddress,PCHAR pc_PCIChipInformation,WORD w_Address,str_DigitalInputHeader *s_Header)
+{
+ WORD w_Temp;
+
+ // read nbr of channels
+ s_Header->w_Nchannel=w_EepromReadWord(w_PCIBoardEepromAddress,pc_PCIChipInformation,0x100+w_Address+6);
+
+ // interruptible or not
+ w_Temp=w_EepromReadWord(w_PCIBoardEepromAddress,pc_PCIChipInformation,0x100+w_Address+8);
+ s_Header->b_Interruptible=(BYTE) (w_Temp>>7)& 0x01;
+
+// How many interruptible logic
+ s_Header->w_NinterruptLogic=w_EepromReadWord(w_PCIBoardEepromAddress,pc_PCIChipInformation,0x100+w_Address+10);
+
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_EepromReadDigitalOutputHeader(WORD |
+| w_PCIBoardEepromAddress,PCHAR pc_PCIChipInformation, |
+| WORD w_Address,str_DigitalOutputHeader *s_Header) |
+| |
++----------------------------------------------------------------------------+
+| Task : Read Digital Output Header |
++----------------------------------------------------------------------------+
+| Input Parameters : WORD w_PCIBoardEepromAddress : PCI eeprom address |
+| |
+| PCHAR pc_PCIChipInformation : PCI Chip Type. |
+| |
+| str_DigitalOutputHeader *s_Header: Digital Output Header|
+| Pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
++----------------------------------------------------------------------------+
+*/
+INT i_EepromReadDigitalOutputHeader(WORD w_PCIBoardEepromAddress,PCHAR pc_PCIChipInformation,WORD w_Address,str_DigitalOutputHeader *s_Header)
+{
+// Read Nbr channels
+ s_Header->w_Nchannel=w_EepromReadWord(w_PCIBoardEepromAddress,pc_PCIChipInformation,0x100+w_Address+6);
+return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_EepromReadTimerHeader(WORD w_PCIBoardEepromAddress, |
+| PCHAR pc_PCIChipInformation,WORD w_Address, |
+| str_TimerMainHeader *s_Header) |
++----------------------------------------------------------------------------+
+| Task : Read Timer or Watchdog Header |
++----------------------------------------------------------------------------+
+| Input Parameters : WORD w_PCIBoardEepromAddress : PCI eeprom address |
+| |
+| PCHAR pc_PCIChipInformation : PCI Chip Type. |
+| |
+| str_TimerMainHeader *s_Header: Timer Header |
+| Pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
++----------------------------------------------------------------------------+
+*/
+INT i_EepromReadTimerHeader(WORD w_PCIBoardEepromAddress,PCHAR pc_PCIChipInformation,WORD w_Address,str_TimerMainHeader *s_Header)
+{
+
+WORD i,w_Size=0,w_Temp;
+
+
+//Read No of Timer
+s_Header->w_Ntimer=w_EepromReadWord(w_PCIBoardEepromAddress,pc_PCIChipInformation,0x100+w_Address+6);
+//Read header size
+
+for(i=0;i<s_Header->w_Ntimer;i++)
+{
+ s_Header->s_TimerDetails[i].w_HeaderSize=w_EepromReadWord(w_PCIBoardEepromAddress,pc_PCIChipInformation,0x100+w_Address+8+w_Size+0);
+ w_Temp=w_EepromReadWord(w_PCIBoardEepromAddress,pc_PCIChipInformation,0x100+w_Address+8+w_Size+2) ;
+
+ //Read Resolution
+ s_Header->s_TimerDetails[i].b_Resolution=(BYTE)(w_Temp>>10)&0x3F;
+
+ //Read Mode
+ s_Header->s_TimerDetails[i].b_Mode =(BYTE) (w_Temp>>4)&0x3F;
+
+ w_Temp=w_EepromReadWord(w_PCIBoardEepromAddress,pc_PCIChipInformation,0x100+w_Address+8+w_Size+4) ;
+
+ //Read MinTiming
+ s_Header->s_TimerDetails[i].w_MinTiming =(w_Temp>>6)&0x3FF;
+
+ //Read Timebase
+ s_Header->s_TimerDetails[i].b_TimeBase =(BYTE)(w_Temp)&0x3F;
+ w_Size += s_Header->s_TimerDetails[i].w_HeaderSize;
+}
+
+return 0;
+}
+
+
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_EepromReadAnlogOutputHeader(WORD |
+| w_PCIBoardEepromAddress,PCHAR pc_PCIChipInformation, |
+| WORD w_Address,str_AnalogOutputHeader *s_Header) |
++----------------------------------------------------------------------------+
+| Task : Read Nalog Output Header |
++----------------------------------------------------------------------------+
+| Input Parameters : WORD w_PCIBoardEepromAddress : PCI eeprom address |
+| |
+| PCHAR pc_PCIChipInformation : PCI Chip Type. |
+| |
+| str_AnalogOutputHeader *s_Header:Anlog Output Header |
+| Pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
++----------------------------------------------------------------------------+
+*/
+
+INT i_EepromReadAnlogOutputHeader(WORD w_PCIBoardEepromAddress,PCHAR pc_PCIChipInformation,WORD w_Address,str_AnalogOutputHeader *s_Header)
+{
+ WORD w_Temp;
+ // No of channels for 1st hard component
+ w_Temp=w_EepromReadWord(w_PCIBoardEepromAddress,pc_PCIChipInformation,0x100+w_Address+10);
+ s_Header->w_Nchannel=(w_Temp>>4)& 0x03FF;
+ // Resolution for 1st hard component
+ w_Temp=w_EepromReadWord(w_PCIBoardEepromAddress,pc_PCIChipInformation,0x100+w_Address+16);
+ s_Header->b_Resolution=(BYTE)(w_Temp>>8) & 0xFF;
+ return 0;
+}
+
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_EepromReadAnlogInputHeader(WORD |
+| w_PCIBoardEepromAddress,PCHAR pc_PCIChipInformation, |
+| WORD w_Address,str_AnalogInputHeader *s_Header) |
++----------------------------------------------------------------------------+
+| Task : Read Nalog Output Header |
++----------------------------------------------------------------------------+
+| Input Parameters : WORD w_PCIBoardEepromAddress : PCI eeprom address |
+| |
+| PCHAR pc_PCIChipInformation : PCI Chip Type. |
+| |
+| str_AnalogInputHeader *s_Header:Anlog Input Header |
+| Pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
++----------------------------------------------------------------------------+
+*/
+
+// Reads only for ONE hardware component
+INT i_EepromReadAnlogInputHeader(WORD w_PCIBoardEepromAddress,PCHAR pc_PCIChipInformation,WORD w_Address,str_AnalogInputHeader *s_Header)
+{
+ WORD w_Temp,w_Offset;
+ w_Temp=w_EepromReadWord(w_PCIBoardEepromAddress,pc_PCIChipInformation,0x100+w_Address+10);
+ s_Header->w_Nchannel=(w_Temp>>4)& 0x03FF;
+ s_Header->w_MinConvertTiming=w_EepromReadWord(w_PCIBoardEepromAddress,pc_PCIChipInformation,0x100+w_Address+16);
+s_Header->w_MinDelayTiming=w_EepromReadWord(w_PCIBoardEepromAddress,pc_PCIChipInformation,0x100+w_Address+30);
+w_Temp=w_EepromReadWord(w_PCIBoardEepromAddress,pc_PCIChipInformation,0x100+w_Address+20);
+s_Header->b_HasDma=(w_Temp>>13) & 0x01; // whether dma present or not
+
+w_Temp=w_EepromReadWord(w_PCIBoardEepromAddress,pc_PCIChipInformation,0x100+w_Address+72);// reading Y
+w_Temp=w_Temp & 0x00FF;
+if(w_Temp)//Y>0
+{
+w_Offset=74+(2*w_Temp)+(10*(1+(w_Temp/16)));// offset of first analog input single header
+w_Offset= w_Offset+2; // resolution
+}
+else//Y=0
+{
+w_Offset=74;
+w_Offset= w_Offset+2; // resolution
+}
+
+// read Resolution
+w_Temp=w_EepromReadWord(w_PCIBoardEepromAddress,pc_PCIChipInformation,0x100+w_Address+w_Offset);
+s_Header->b_Resolution=w_Temp & 0x001F;// last 5 bits
+
+return 0;
+}
--- /dev/null
+/*
+ Modified by umesh on 16th may 2001
+ Modified by sarath on 22nd may 2001
+*/
+
+
+
+/*
+ comedi/drivers/amcc_s5933_v_58.h
+
+ Stuff for AMCC S5933 PCI Controller
+
+ Author: Michal Dobes <majkl@tesnet.cz>
+
+ Inspirated from general-purpose AMCC S5933 PCI Matchmaker driver
+ made by Andrea Cisternino <acister@pcape1.pi.infn.it>
+ and as result of espionage from MITE code made by David A. Schleef.
+ Thanks to AMCC for their on-line documentation and bus master DMA
+ example.
+*/
+
+#ifndef _AMCC_S5933_H_
+#define _AMCC_S5933_H_
+
+#include <linux/pci.h>
+#include <linux/comedidev.h>
+
+#ifdef PCI_SUPPORT_VER1
+#error Sorry, no support for 2.1.55 and older! :-((((
+#endif
+
+/***********Added by sarath for compatibility with APCI3120
+
+*************************/
+
+#define FIFO_ADVANCE_ON_BYTE_2 0x20000000 // written on base0
+
+#define AMWEN_ENABLE 0x02 // added for step 6 dma written on base2
+#define A2P_FIFO_WRITE_ENABLE 0x01
+
+#define AGCSTS_TC_ENABLE 0x10000000 // Added for transfer count enable bit
+
+// ADDON RELATED ADDITIONS
+// Constant
+ #define APCI3120_ENABLE_TRANSFER_ADD_ON_LOW 0x00
+ #define APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH 0x1200
+ #define APCI3120_A2P_FIFO_MANAGEMENT 0x04000400L
+ #define APCI3120_AMWEN_ENABLE 0x02
+ #define APCI3120_A2P_FIFO_WRITE_ENABLE 0x01
+ #define APCI3120_FIFO_ADVANCE_ON_BYTE_2 0x20000000L
+ #define APCI3120_ENABLE_WRITE_TC_INT 0x00004000L
+ #define APCI3120_CLEAR_WRITE_TC_INT 0x00040000L
+ #define APCI3120_DISABLE_AMWEN_AND_A2P_FIFO_WRITE 0x0
+ #define APCI3120_DISABLE_BUS_MASTER_ADD_ON 0x0
+ #define APCI3120_DISABLE_BUS_MASTER_PCI 0x0
+
+
+ // ADD_ON ::: this needed since apci supports 16 bit interface to add on
+ #define APCI3120_ADD_ON_AGCSTS_LOW 0x3C
+ #define APCI3120_ADD_ON_AGCSTS_HIGH APCI3120_ADD_ON_AGCSTS_LOW + 2
+ #define APCI3120_ADD_ON_MWAR_LOW 0x24
+ #define APCI3120_ADD_ON_MWAR_HIGH APCI3120_ADD_ON_MWAR_LOW + 2
+ #define APCI3120_ADD_ON_MWTC_LOW 0x058
+ #define APCI3120_ADD_ON_MWTC_HIGH APCI3120_ADD_ON_MWTC_LOW + 2
+
+// AMCC
+ #define APCI3120_AMCC_OP_MCSR 0x3C
+ #define APCI3120_AMCC_OP_REG_INTCSR 0x38
+
+/*******from here all upward definitions are added by sarath */
+
+
+
+/****************************************************************************/
+/* AMCC Operation Register Offsets - PCI */
+/****************************************************************************/
+
+#define AMCC_OP_REG_OMB1 0x00
+#define AMCC_OP_REG_OMB2 0x04
+#define AMCC_OP_REG_OMB3 0x08
+#define AMCC_OP_REG_OMB4 0x0c
+#define AMCC_OP_REG_IMB1 0x10
+#define AMCC_OP_REG_IMB2 0x14
+#define AMCC_OP_REG_IMB3 0x18
+#define AMCC_OP_REG_IMB4 0x1c
+#define AMCC_OP_REG_FIFO 0x20
+#define AMCC_OP_REG_MWAR 0x24
+#define AMCC_OP_REG_MWTC 0x28
+#define AMCC_OP_REG_MRAR 0x2c
+#define AMCC_OP_REG_MRTC 0x30
+#define AMCC_OP_REG_MBEF 0x34
+#define AMCC_OP_REG_INTCSR 0x38
+#define AMCC_OP_REG_INTCSR_SRC (AMCC_OP_REG_INTCSR + 2) /* INT source */
+#define AMCC_OP_REG_INTCSR_FEC (AMCC_OP_REG_INTCSR + 3) /* FIFO ctrl */
+#define AMCC_OP_REG_MCSR 0x3c
+#define AMCC_OP_REG_MCSR_NVDATA (AMCC_OP_REG_MCSR + 2) /* Data in byte 2 */
+#define AMCC_OP_REG_MCSR_NVCMD (AMCC_OP_REG_MCSR + 3) /* Command in byte 3 */
+
+#define AMCC_FIFO_DEPTH_DWORD 8
+#define AMCC_FIFO_DEPTH_BYTES (8 * sizeof (u32))
+
+/****************************************************************************/
+/* AMCC Operation Registers Size - PCI */
+/****************************************************************************/
+
+#define AMCC_OP_REG_SIZE 64 /* in bytes */
+
+/****************************************************************************/
+/* AMCC Operation Register Offsets - Add-on */
+/****************************************************************************/
+
+#define AMCC_OP_REG_AIMB1 0x00
+#define AMCC_OP_REG_AIMB2 0x04
+#define AMCC_OP_REG_AIMB3 0x08
+#define AMCC_OP_REG_AIMB4 0x0c
+#define AMCC_OP_REG_AOMB1 0x10
+#define AMCC_OP_REG_AOMB2 0x14
+#define AMCC_OP_REG_AOMB3 0x18
+#define AMCC_OP_REG_AOMB4 0x1c
+#define AMCC_OP_REG_AFIFO 0x20
+#define AMCC_OP_REG_AMWAR 0x24
+#define AMCC_OP_REG_APTA 0x28
+#define AMCC_OP_REG_APTD 0x2c
+#define AMCC_OP_REG_AMRAR 0x30
+#define AMCC_OP_REG_AMBEF 0x34
+#define AMCC_OP_REG_AINT 0x38
+#define AMCC_OP_REG_AGCSTS 0x3c
+#define AMCC_OP_REG_AMWTC 0x58
+#define AMCC_OP_REG_AMRTC 0x5c
+
+/****************************************************************************/
+/* AMCC - Add-on General Control/Status Register */
+/****************************************************************************/
+
+#define AGCSTS_CONTROL_MASK 0xfffff000
+#define AGCSTS_NV_ACC_MASK 0xe0000000
+#define AGCSTS_RESET_MASK 0x0e000000
+#define AGCSTS_NV_DA_MASK 0x00ff0000
+#define AGCSTS_BIST_MASK 0x0000f000
+#define AGCSTS_STATUS_MASK 0x000000ff
+#define AGCSTS_TCZERO_MASK 0x000000c0
+#define AGCSTS_FIFO_ST_MASK 0x0000003f
+
+#define AGCSTS_RESET_MBFLAGS 0x08000000
+#define AGCSTS_RESET_P2A_FIFO 0x04000000
+#define AGCSTS_RESET_A2P_FIFO 0x02000000
+#define AGCSTS_RESET_FIFOS (AGCSTS_RESET_A2P_FIFO | AGCSTS_RESET_P2A_FIFO)
+
+#define AGCSTS_A2P_TCOUNT 0x00000080
+#define AGCSTS_P2A_TCOUNT 0x00000040
+
+#define AGCSTS_FS_P2A_EMPTY 0x00000020
+#define AGCSTS_FS_P2A_HALF 0x00000010
+#define AGCSTS_FS_P2A_FULL 0x00000008
+
+#define AGCSTS_FS_A2P_EMPTY 0x00000004
+#define AGCSTS_FS_A2P_HALF 0x00000002
+#define AGCSTS_FS_A2P_FULL 0x00000001
+
+/****************************************************************************/
+/* AMCC - Add-on Interrupt Control/Status Register */
+/****************************************************************************/
+
+#define AINT_INT_MASK 0x00ff0000
+#define AINT_SEL_MASK 0x0000ffff
+#define AINT_IS_ENSEL_MASK 0x00001f1f
+
+#define AINT_INT_ASSERTED 0x00800000
+#define AINT_BM_ERROR 0x00200000
+#define AINT_BIST_INT 0x00100000
+
+#define AINT_RT_COMPLETE 0x00080000
+#define AINT_WT_COMPLETE 0x00040000
+
+#define AINT_OUT_MB_INT 0x00020000
+#define AINT_IN_MB_INT 0x00010000
+
+#define AINT_READ_COMPL 0x00008000
+#define AINT_WRITE_COMPL 0x00004000
+
+#define AINT_OMB_ENABLE 0x00001000
+#define AINT_OMB_SELECT 0x00000c00
+#define AINT_OMB_BYTE 0x00000300
+
+#define AINT_IMB_ENABLE 0x00000010
+#define AINT_IMB_SELECT 0x0000000c
+#define AINT_IMB_BYTE 0x00000003
+
+/* Enable Bus Mastering */
+#define EN_A2P_TRANSFERS 0x00000400
+/* FIFO Flag Reset */
+#define RESET_A2P_FLAGS 0x04000000L
+/* FIFO Relative Priority */
+#define A2P_HI_PRIORITY 0x00000100L
+/* Identify Interrupt Sources */
+#define ANY_S593X_INT 0x00800000L
+#define READ_TC_INT 0x00080000L
+#define WRITE_TC_INT 0x00040000L
+#define IN_MB_INT 0x00020000L
+#define MASTER_ABORT_INT 0x00100000L
+#define TARGET_ABORT_INT 0x00200000L
+#define BUS_MASTER_INT 0x00200000L
+
+/****************************************************************************/
+
+struct pcilst_struct{
+ struct pcilst_struct *next;
+ int used;
+ struct pci_dev *pcidev;
+ unsigned short vendor;
+ unsigned short device;
+ unsigned int master;
+ unsigned char pci_bus;
+ unsigned char pci_slot;
+ unsigned char pci_func;
+ unsigned int io_addr[5];
+ unsigned int irq;
+};
+
+struct pcilst_struct *amcc_devices; // ptr to root list of all amcc devices
+
+/****************************************************************************/
+
+void v_pci_card_list_init(unsigned short pci_vendor, char display);
+void v_pci_card_list_cleanup(unsigned short pci_vendor);
+struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id, unsigned short device_id);
+int i_find_free_pci_card_by_position(unsigned short vendor_id, unsigned short device_id, unsigned short pci_bus, unsigned short pci_slot, struct pcilst_struct **card);
+struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id, unsigned short device_id, unsigned short pci_bus, unsigned short pci_slot);
+
+int i_pci_card_alloc(struct pcilst_struct *amcc);
+int i_pci_card_free(struct pcilst_struct *amcc);
+void v_pci_card_list_display(void);
+int i_pci_card_data(struct pcilst_struct *amcc,
+ unsigned char *pci_bus, unsigned char *pci_slot, unsigned char *pci_func,
+ unsigned short *io_addr, unsigned short *irq, unsigned short *master);
+
+/****************************************************************************/
+
+/* build list of amcc cards in this system */
+void v_pci_card_list_init(unsigned short pci_vendor, char display)
+{
+ struct pci_dev *pcidev;
+ struct pcilst_struct *amcc,*last;
+ int i;
+
+ amcc_devices=NULL;
+ last=NULL;
+
+#if LINUX_VERSION_CODE < 0x020300
+ for(pcidev=pci_devices;pcidev;pcidev=pcidev->next){
+#else
+ pci_for_each_dev(pcidev){
+#endif
+ if(pcidev->vendor==pci_vendor){
+ amcc=kmalloc(sizeof(*amcc),GFP_KERNEL);
+ memset(amcc,0,sizeof(*amcc));
+
+ amcc->pcidev=pcidev;
+ if (last) { last->next=amcc; }
+ else { amcc_devices=amcc; }
+ last=amcc;
+
+#if LINUX_VERSION_CODE < 0x020300
+ amcc->vendor=pcidev->vendor;
+ amcc->device=pcidev->device;
+ amcc->master=pcidev->master;
+ amcc->pci_bus=pcidev->bus->number;
+ amcc->pci_slot=PCI_SLOT(pcidev->devfn);
+ amcc->pci_func=PCI_FUNC(pcidev->devfn);
+ for (i=0;i<5;i++)
+ amcc->io_addr[i]=pcidev->base_address[i] & ~3UL;
+ amcc->irq=pcidev->irq;
+#else
+ amcc->vendor=pcidev->vendor;
+ amcc->device=pcidev->device;
+#if 0
+ amcc->master=pcidev->master; // how get this information under 2.4 kernels?
+#endif
+ amcc->pci_bus=pcidev->bus->number;
+ amcc->pci_slot=PCI_SLOT(pcidev->devfn);
+ amcc->pci_func=PCI_FUNC(pcidev->devfn);
+ for (i=0;i<5;i++)
+ amcc->io_addr[i]=pcidev->resource[i].start & ~3UL;
+ amcc->irq=pcidev->irq;
+#endif
+
+ }
+ }
+
+ if (display) v_pci_card_list_display();
+}
+
+/****************************************************************************/
+/* free up list of amcc cards in this system */
+void v_pci_card_list_cleanup(unsigned short pci_vendor)
+{
+ struct pcilst_struct *amcc,*next;
+
+ for(amcc=amcc_devices;amcc;amcc=next){
+ next=amcc->next;
+ kfree(amcc);
+ }
+
+ amcc_devices=NULL;
+}
+
+/****************************************************************************/
+/* find first unused card with this device_id */
+struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id, unsigned short device_id)
+{
+ struct pcilst_struct *amcc,*next;
+
+ for (amcc=amcc_devices;amcc;amcc=next) {
+ next=amcc->next;
+ if ((!amcc->used)&&(amcc->device==device_id)&&(amcc->vendor==vendor_id)) return amcc;
+
+ }
+
+ return NULL;
+}
+
+/****************************************************************************/
+/* find card on requested position */
+int i_find_free_pci_card_by_position(unsigned short vendor_id, unsigned short device_id, unsigned short pci_bus, unsigned short pci_slot, struct pcilst_struct **card)
+{
+ struct pcilst_struct *amcc,*next;
+
+ *card=NULL;
+ for (amcc=amcc_devices;amcc;amcc=next) {
+ next=amcc->next;
+ if ((amcc->vendor==vendor_id)&&(amcc->device==device_id)&&(amcc->pci_bus==pci_bus)&&(amcc->pci_slot==pci_slot)) {
+ if (!(amcc->used)) {
+ *card=amcc;
+ return 0; // ok, card is found
+ } else {
+ rt_printk(" - \nCard on requested position is used b:s %d:%d!\n",pci_bus,pci_slot);
+ return 2; // card exist but is used
+ }
+ }
+ }
+
+ return 1; // no card found
+}
+
+/****************************************************************************/
+/* mark card as used */
+int i_pci_card_alloc(struct pcilst_struct *amcc)
+{
+ if (!amcc) return -1;
+
+ if (amcc->used) return 1;
+ amcc->used=1;
+ return 0;
+}
+
+/****************************************************************************/
+/* mark card as free */
+int i_pci_card_free(struct pcilst_struct *amcc)
+{
+ if (!amcc) return -1;
+
+ if (!amcc->used) return 1;
+ amcc->used=0;
+ return 0;
+}
+
+/****************************************************************************/
+/* display list of found cards */
+void v_pci_card_list_display(void)
+{
+ struct pcilst_struct *amcc,*next;
+
+ printk("List of pci cards\n");
+ printk("bus:slot:func vendor device master io_amcc io_daq irq used\n");
+
+ for (amcc=amcc_devices;amcc;amcc=next) {
+ next=amcc->next;
+ printk("%2d %2d %2d 0x%4x 0x%4x %3s 0x%4x 0x%4x %2d %2d\n",
+ amcc->pci_bus,amcc->pci_slot,amcc->pci_func,amcc->vendor,amcc->device,amcc->master?"yes":"no",
+ amcc->io_addr[0],amcc->io_addr[2],amcc->irq,amcc->used);
+
+ }
+}
+
+/****************************************************************************/
+/* return all card information for driver */
+int i_pci_card_data(struct pcilst_struct *amcc,
+ unsigned char *pci_bus, unsigned char *pci_slot, unsigned char *pci_func,
+ unsigned short *io_addr, unsigned short *irq, unsigned short *master)
+{
+ int i;
+
+ if (!amcc) return -1;
+ *pci_bus=amcc->pci_bus;
+ *pci_slot=amcc->pci_slot;
+ *pci_func=amcc->pci_func;
+ for (i=0;i<5;i++)
+ io_addr[i]=amcc->io_addr[i];
+ *irq=amcc->irq;
+ *master=amcc->master;
+ return 0;
+}
+
+/****************************************************************************/
+/* select and alloc card */
+struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id, unsigned short device_id, unsigned short pci_bus, unsigned short pci_slot)
+{
+ struct pcilst_struct *card;
+
+ if ((pci_bus<1)&(pci_slot<1)) { // use autodetection
+ if ((card=ptr_find_free_pci_card_by_device(vendor_id,device_id))==NULL) {
+ rt_printk(" - Unused card not found in system!\n");
+ return NULL;
+ }
+ } else {
+ switch (i_find_free_pci_card_by_position(vendor_id,device_id,pci_bus,pci_slot,&card)) {
+ case 1:
+ rt_printk(" - Card not found on requested position b:s %d:%d!\n",pci_bus,pci_slot);
+ return NULL;
+ case 2:
+ rt_printk(" - Card on requested position is used b:s %d:%d!\n",pci_bus,pci_slot);
+ return NULL;
+ }
+ }
+
+
+ if (i_pci_card_alloc(card)!=0) {
+ rt_printk(" - Can't allocate card!\n");
+ return NULL;
+ }
+
+ return card;
+}
+
+#endif
+
+
+
--- /dev/null
+ #include "hwdrv_APCI1710.h"\r
+ #include "APCI1710_Inp_cpt.c"\r
+ #include "APCI1710_Ssi.c"\r
+ #include "APCI1710_Tor.c"\r
+ #include "APCI1710_Ttl.c"
+ #include "APCI1710_Dig_io.c"
+ #include "APCI1710_82x54.c"
+ #include "APCI1710_Chrono.c"
+ #include "APCI1710_Pwm.c"
+ #include "APCI1710_INCCPT.c"
+
+int i_APCI1710_Reset(comedi_device *dev);
+VOID v_APCI1710_Interrupt(int irq, void *d, struct pt_regs *regs) ;
+//for 1710
+
+ int i_APCI1710_Reset(comedi_device *dev)
+{
+ int ret;
+ DWORD dw_Dummy;
+
+ /*********************************/
+ /* Read all module configuration */
+ /*********************************/
+ ret=inl(devpriv->s_BoardInfos.ui_Address+60);
+ devpriv->s_BoardInfos.dw_MolduleConfiguration [0]=ret;
+
+ ret=inl(devpriv->s_BoardInfos.ui_Address+124);
+ devpriv->s_BoardInfos.dw_MolduleConfiguration [1]=ret;
+
+ ret=inl(devpriv->s_BoardInfos.ui_Address+188);
+ devpriv->s_BoardInfos.dw_MolduleConfiguration [2]=ret;
+
+ ret=inl(devpriv->s_BoardInfos.ui_Address+252);
+ devpriv->s_BoardInfos.dw_MolduleConfiguration [3]=ret;
+
+ // outl(0x80808082,devpriv->s_BoardInfos.ui_Address+0x60);
+ outl(0x83838383,devpriv->s_BoardInfos.ui_Address+0x60);
+
+ // Enable the interrupt for the controler
+ dw_Dummy = inl(devpriv->s_BoardInfos.ui_Address+ 0x38);
+ outl(dw_Dummy | 0x2000,devpriv->s_BoardInfos.ui_Address+0x38);
+
+ return 0;
+}
+
+
+/*
++----------------------------------------------------------------------------+
+| Function's Name : __VOID__ v_APCI1710_InterruptFunction |
+| (BYTE b_Interrupt, __CPPARGS) |
++----------------------------------------------------------------------------+
+| Task : APCI-1710 interrupt function |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE b_Interrupt : Interrupt number |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0 : OK |
+| -1 : Error |
++----------------------------------------------------------------------------+
+*/
+
+
+
+
+
+VOID v_APCI1710_Interrupt(int irq, void *d, struct pt_regs *regs)
+{
+ comedi_device *dev = d;
+ comedi_subdevice *s = dev->subdevices + 0;
+ BYTE b_ModuleCpt = 0;
+ BYTE b_InterruptFlag = 0;
+ BYTE b_PWMCpt = 0;
+ BYTE b_ETMCpt = 0;
+ BYTE b_TorCounterCpt = 0;
+ BYTE b_PulseIncoderCpt = 0;
+ UINT ui_16BitValue;
+ ULONG ul_InterruptLatchReg;
+ ULONG ul_LatchRegisterValue;
+ ULONG ul_82X54InterruptStatus;
+ ULONG ul_StatusRegister;
+
+ str_ModuleInfo * ps_ModuleInfo;
+
+ printk("APCI1710 Interrupt\n");
+ for (b_ModuleCpt = 0; b_ModuleCpt < 4; b_ModuleCpt ++, ps_ModuleInfo ++)
+ {
+
+ /**************************/
+ /* 1199/0225 to 0100/0226 */
+ /**************************/
+ ps_ModuleInfo = &devpriv->s_ModuleInfo [b_ModuleCpt];
+
+
+ /***********************/
+ /* Test if 82X54 timer */
+ /***********************/
+
+ if ((devpriv->
+ s_BoardInfos.
+ dw_MolduleConfiguration [b_ModuleCpt] & 0xFFFF0000UL) == APCI1710_82X54_TIMER)
+ {
+
+ //printk("TIMER Interrupt Occurred\n");
+ ul_82X54InterruptStatus= inl(devpriv->s_BoardInfos.
+ ui_Address + 12 + (64 * b_ModuleCpt));
+
+ /***************************/
+ /* Test if interrupt occur */
+ /***************************/
+
+ if ((ul_82X54InterruptStatus & ps_ModuleInfo->
+ s_82X54ModuleInfo.
+ b_InterruptMask) != 0)
+ {
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldInterruptMask = (ul_82X54InterruptStatus & ps_ModuleInfo->
+ s_82X54ModuleInfo.
+ b_InterruptMask) << 4;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ b_OldModuleMask = 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldCounterLatchValue = 0;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur ++;
+
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write + 1) % APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO,devpriv->tsk_Current,0);
+
+ } // if ((ul_82X54InterruptStatus & 0x7) != 0)
+ } // 82X54 timer
+
+
+
+
+
+ /***************************/
+ /* Test if increm. counter */
+ /***************************/
+
+ if ((devpriv->
+ s_BoardInfos.
+ dw_MolduleConfiguration [b_ModuleCpt] & 0xFFFF0000UL) == APCI1710_INCREMENTAL_COUNTER)
+ {
+
+ ul_InterruptLatchReg=inl(devpriv->s_BoardInfos.
+ ui_Address + (64 * b_ModuleCpt));
+
+ /*********************/
+ /* Test if interrupt */
+ /*********************/
+
+ if ((ul_InterruptLatchReg & 0x22) && (ps_ModuleInfo->
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2 & 0x80))
+ {
+ /************************************/
+ /* Test if strobe latch I interrupt */
+ /************************************/
+
+ if (ul_InterruptLatchReg & 2)
+ {
+ ul_LatchRegisterValue=inl(devpriv->s_BoardInfos.
+ ui_Address + 4 + (64 * b_ModuleCpt));
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldInterruptMask = 1UL;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ b_OldModuleMask = 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldCounterLatchValue = ul_LatchRegisterValue;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur ++;
+
+ /****************************/
+ /* 0899/0224 to 1199/0225 */
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write + 1) % APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO,devpriv->tsk_Current,0);
+
+
+ }
+
+ /*************************************/
+ /* Test if strobe latch II interrupt */
+ /*************************************/
+
+ if (ul_InterruptLatchReg & 0x20)
+ {
+
+ ul_LatchRegisterValue=inl(devpriv->s_BoardInfos.
+ ui_Address + 8 + (64 * b_ModuleCpt));
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldInterruptMask = 2UL;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ b_OldModuleMask = 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldCounterLatchValue = ul_LatchRegisterValue;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur ++;
+
+ /****************************/
+ /* 0899/0224 to 1199/0225 */
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write + 1) % APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO,devpriv->tsk_Current,0);
+
+ }
+ }
+
+
+ ul_InterruptLatchReg=inl(devpriv-> s_BoardInfos.
+ ui_Address + 24 + (64 * b_ModuleCpt));
+
+ /***************************/
+ /* Test if index interrupt */
+ /***************************/
+
+ if (ul_InterruptLatchReg & 0x8)
+ {
+ ps_ModuleInfo->
+ s_SiemensCounterInfo.
+ s_InitFlag.
+ b_IndexInterruptOccur = 1;
+
+ if (ps_ModuleInfo->
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2 & APCI1710_INDEX_AUTO_MODE)
+ {
+
+ outl(ps_ModuleInfo->
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ dw_ModeRegister1_2_3_4,devpriv->
+ s_BoardInfos.
+ ui_Address + 20 + (64 * b_ModuleCpt));
+ }
+
+ /*****************************/
+ /* Test if interrupt enabled */
+ /*****************************/
+
+ if ((ps_ModuleInfo->
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3 & APCI1710_ENABLE_INDEX_INT) == APCI1710_ENABLE_INDEX_INT)
+ {
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldInterruptMask = 4UL;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ b_OldModuleMask = 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldCounterLatchValue = ul_LatchRegisterValue;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur ++;
+
+ /****************************/
+ /* 0899/0224 to 1199/0225 */
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write + 1) % APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO,devpriv->tsk_Current,0);
+
+ }
+ }
+
+ /*****************************/
+ /* Test if compare interrupt */
+ /*****************************/
+
+ if (ul_InterruptLatchReg & 0x10)
+ {
+ /*****************************/
+ /* Test if interrupt enabled */
+ /*****************************/
+
+ if ((ps_ModuleInfo->
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3 & APCI1710_ENABLE_COMPARE_INT) == APCI1710_ENABLE_COMPARE_INT)
+ {
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldInterruptMask = 8UL;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ b_OldModuleMask = 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldCounterLatchValue = ul_LatchRegisterValue;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur ++;
+
+ /****************************/
+ /* 0899/0224 to 1199/0225 */
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write + 1) % APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO,devpriv->tsk_Current,0);
+
+
+ }
+ }
+
+ /*******************************************/
+ /* Test if frequency measurement interrupt */
+ /*******************************************/
+
+ if (ul_InterruptLatchReg & 0x20)
+ {
+ /*******************/
+ /* Read the status */
+ /*******************/
+
+ ul_StatusRegister=inl(devpriv->s_BoardInfos.
+ ui_Address + 32 + (64 * b_ModuleCpt));
+
+ /******************/
+ /* Read the value */
+ /******************/
+
+
+ ul_LatchRegisterValue=inl(devpriv->s_BoardInfos.
+ ui_Address + 28 + (64 * b_ModuleCpt));
+
+ switch ((ul_StatusRegister >> 1) & 3)
+ {
+ case 0:
+ /*************************/
+ /* Test the counter mode */
+ /*************************/
+
+ if ((devpriv->
+ s_ModuleInfo [b_ModuleCpt].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister1 & APCI1710_16BIT_COUNTER) == APCI1710_16BIT_COUNTER)
+ {
+ /****************************************/
+ /* Test if 16-bit counter 1 pulse occur */
+ /****************************************/
+
+ if ((ul_LatchRegisterValue & 0xFFFFU) != 0)
+ {
+ ui_16BitValue = (UINT) ul_LatchRegisterValue & 0xFFFFU;
+ ul_LatchRegisterValue = (ul_LatchRegisterValue & 0xFFFF0000UL) | (0xFFFFU - ui_16BitValue);
+ }
+
+ /****************************************/
+ /* Test if 16-bit counter 2 pulse occur */
+ /****************************************/
+
+ if ((ul_LatchRegisterValue & 0xFFFF0000UL) != 0)
+ {
+ ui_16BitValue = (UINT) ((ul_LatchRegisterValue >> 16) & 0xFFFFU);
+ ul_LatchRegisterValue = (ul_LatchRegisterValue & 0xFFFFUL) | ((0xFFFFU - ui_16BitValue) << 16);
+ }
+ }
+ else
+ {
+ if (ul_LatchRegisterValue != 0)
+ {
+ ul_LatchRegisterValue = 0xFFFFFFFFUL - ul_LatchRegisterValue;
+ }
+ }
+ break;
+
+ case 1:
+ /****************************************/
+ /* Test if 16-bit counter 2 pulse occur */
+ /****************************************/
+
+ if ((ul_LatchRegisterValue & 0xFFFF0000UL) != 0)
+ {
+ ui_16BitValue = (UINT) ((ul_LatchRegisterValue >> 16) & 0xFFFFU);
+ ul_LatchRegisterValue = (ul_LatchRegisterValue & 0xFFFFUL) | ((0xFFFFU - ui_16BitValue) << 16);
+ }
+ break;
+
+ case 2:
+ /****************************************/
+ /* Test if 16-bit counter 1 pulse occur */
+ /****************************************/
+
+ if ((ul_LatchRegisterValue & 0xFFFFU) != 0)
+ {
+ ui_16BitValue = (UINT) ul_LatchRegisterValue & 0xFFFFU;
+ ul_LatchRegisterValue = (ul_LatchRegisterValue & 0xFFFF0000UL) | (0xFFFFU - ui_16BitValue);
+ }
+ break;
+ }
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldInterruptMask = 0x10000UL;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ b_OldModuleMask = 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldCounterLatchValue = ul_LatchRegisterValue;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur ++;
+
+ /****************************/
+ /* 0899/0224 to 1199/0225 */
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write + 1) % APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO,devpriv->tsk_Current,0);
+
+
+
+ }
+ } // Incremental counter
+
+
+
+
+
+
+ /***************/
+ /* Test if CDA */
+ /***************/
+
+ if ((devpriv->
+ s_BoardInfos.
+ dw_MolduleConfiguration [b_ModuleCpt] & 0xFFFF0000UL) == APCI1710_CDA)
+ {
+ /******************************************/
+ /* Test if CDA enable and functionality 0 */
+ /******************************************/
+
+ if ((devpriv->
+ s_ModuleInfo [b_ModuleCpt].
+ s_CDAModuleInfo.
+ b_CDAEnable == APCI1710_ENABLE) && (devpriv->
+ s_ModuleInfo [b_ModuleCpt].
+ s_CDAModuleInfo.
+ b_FctSelection == 0))
+ {
+ /****************************/
+ /* Get the interrupt status */
+ /****************************/
+
+
+ ul_StatusRegister=inl(devpriv->s_BoardInfos.
+ ui_Address + 16 + (64 * b_ModuleCpt));
+ /***************************/
+ /* Test if interrupt occur */
+ /***************************/
+
+ if (ul_StatusRegister & 1)
+ {
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldInterruptMask = 0x80000UL;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ b_OldModuleMask = 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldCounterLatchValue = 0;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur ++;
+
+
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write + 1) % APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO,devpriv->tsk_Current,0);
+
+ } // if (ul_StatusRegister & 1)
+
+ }
+ } // CDA
+
+
+ /***********************/
+ /* Test if PWM counter */
+ /***********************/
+
+ if ((devpriv->
+ s_BoardInfos.
+ dw_MolduleConfiguration [b_ModuleCpt] & 0xFFFF0000UL) == APCI1710_PWM)
+ {
+ for (b_PWMCpt = 0; b_PWMCpt < 2; b_PWMCpt ++)
+ {
+ /*************************************/
+ /* Test if PWM interrupt initialised */
+ /*************************************/
+
+ if (devpriv->
+ s_ModuleInfo [b_ModuleCpt].
+ s_PWMModuleInfo.
+ s_PWMInfo [b_PWMCpt].
+ b_InterruptEnable == APCI1710_ENABLE)
+ {
+ /*****************************/
+ /* Read the interrupt status */
+ /*****************************/
+
+ ul_StatusRegister=inl(devpriv->s_BoardInfos.
+ ui_Address + 16 + (20 * b_PWMCpt) + (64 * b_ModuleCpt));
+
+
+ /***************************/
+ /* Test if interrupt occur */
+ /***************************/
+
+ if (ul_StatusRegister & 0x1)
+ {
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldInterruptMask = 0x4000UL << b_PWMCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ b_OldModuleMask = 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur ++;
+
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write + 1) % APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO,devpriv->tsk_Current,0);
+
+
+ } // if (ul_StatusRegister & 0x1)
+ } // if (APCI1710_ENABLE)
+ } // for (b_PWMCpt == 0; b_PWMCpt < 0; b_PWMCpt ++)
+ } // PWM counter
+
+
+
+ /***********************/
+ /* Test if tor counter */
+ /***********************/
+
+ if ((devpriv->
+ s_BoardInfos.
+ dw_MolduleConfiguration [b_ModuleCpt] & 0xFFFF0000UL) == APCI1710_TOR_COUNTER)
+ {
+ for (b_TorCounterCpt = 0; b_TorCounterCpt < 2; b_TorCounterCpt ++)
+ {
+ /*************************************/
+ /* Test if tor interrupt initialised */
+ /*************************************/
+
+ if (devpriv->
+ s_ModuleInfo [b_ModuleCpt].
+ s_TorCounterModuleInfo.
+ s_TorCounterInfo [b_TorCounterCpt].
+ b_InterruptEnable == APCI1710_ENABLE)
+ {
+ /*****************************/
+ /* Read the interrupt status */
+ /*****************************/
+
+
+ ul_StatusRegister=inl(devpriv->s_BoardInfos.
+ ui_Address + 12 + (16 * b_TorCounterCpt) + (64 * b_ModuleCpt));
+
+ /***************************/
+ /* Test if interrupt occur */
+ /***************************/
+
+ if (ul_StatusRegister & 0x1)
+ {
+ /******************************/
+ /* Read the tor counter value */
+ /******************************/
+
+
+ ul_LatchRegisterValue=inl(devpriv->s_BoardInfos.
+ ui_Address + 0 + (16 * b_TorCounterCpt) + (64 * b_ModuleCpt));
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldInterruptMask = 0x1000UL << b_TorCounterCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ b_OldModuleMask = 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldCounterLatchValue = ul_LatchRegisterValue;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur ++;
+
+
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write + 1) % APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO,devpriv->tsk_Current,0);
+ } // if (ul_StatusRegister & 0x1)
+ } // if (APCI1710_ENABLE)
+ } // for (b_TorCounterCpt == 0; b_TorCounterCpt < 0; b_TorCounterCpt ++)
+ } // Tor counter
+
+
+
+
+ /***********************/
+ /* Test if chronometer */
+ /***********************/
+
+ if ((devpriv->
+ s_BoardInfos.
+ dw_MolduleConfiguration [b_ModuleCpt] & 0xFFFF0000UL) == APCI1710_CHRONOMETER)
+ {
+
+ //printk("APCI1710 Chrono Interrupt\n");
+ /*****************************/
+ /* Read the interrupt status */
+ /*****************************/
+
+
+ ul_InterruptLatchReg=inl(devpriv->s_BoardInfos.
+ ui_Address + 12 + (64 * b_ModuleCpt));
+
+ /***************************/
+ /* Test if interrupt occur */
+ /***************************/
+
+ if ((ul_InterruptLatchReg & 0x8) == 0x8)
+ {
+ /****************************/
+ /* Clear the interrupt flag */
+ /****************************/
+
+
+ outl(0,devpriv->s_BoardInfos.
+ ui_Address + 32 + (64 * b_ModuleCpt));
+
+ /***************************/
+ /* Test if continuous mode */
+ /***************************/
+
+ if (ps_ModuleInfo->
+ s_ChronoModuleInfo.
+ b_CycleMode == APCI1710_ENABLE)
+ {
+ /********************/
+ /* Clear the status */
+ /********************/
+
+
+ outl(0,devpriv->s_BoardInfos.
+ ui_Address + 36 + (64 * b_ModuleCpt));
+ }
+
+ /*************************/
+ /* Read the timing value */
+ /*************************/
+
+
+ ul_LatchRegisterValue=inl(devpriv->s_BoardInfos.
+ ui_Address + 4 + (64 * b_ModuleCpt));
+
+ /*****************************/
+ /* Test if interrupt enabled */
+ /*****************************/
+
+ if (ps_ModuleInfo->
+ s_ChronoModuleInfo.
+ b_InterruptMask)
+ {
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldInterruptMask = 0x80;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ b_OldModuleMask = 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldCounterLatchValue = ul_LatchRegisterValue;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur ++;
+
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write + 1) % APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO,devpriv->tsk_Current,0);
+
+ }
+ }
+ } // Chronometer
+
+
+
+ /*************************/
+ /* Test if pulse encoder */
+ /*************************/
+
+ if ((devpriv->
+ s_BoardInfos.
+ dw_MolduleConfiguration [b_ModuleCpt] & 0xFFFF0000UL) == APCI1710_PULSE_ENCODER)
+ {
+ /****************************/
+ /* Read the status register */
+ /****************************/
+
+
+ ul_StatusRegister=inl(devpriv->s_BoardInfos.
+ ui_Address + 20 + (64 * b_ModuleCpt));
+
+ if (ul_StatusRegister & 0xF)
+ {
+ for (b_PulseIncoderCpt = 0; b_PulseIncoderCpt < 4; b_PulseIncoderCpt ++)
+ {
+ /*************************************/
+ /* Test if pulse encoder initialised */
+ /*************************************/
+
+ if ((ps_ModuleInfo->
+ s_PulseEncoderModuleInfo.
+ s_PulseEncoderInfo [b_PulseIncoderCpt].
+ b_PulseEncoderInit == 1) &&
+ (((ps_ModuleInfo->
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister >> b_PulseIncoderCpt) & 1) == 1) &&
+ (((ul_StatusRegister >> (b_PulseIncoderCpt)) & 1) == 1))
+ {
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldInterruptMask = 0x100UL << b_PulseIncoderCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ b_OldModuleMask = 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldCounterLatchValue = ul_LatchRegisterValue;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur ++;
+
+ /****************************/
+ /* 0899/0224 to 1199/0225 */
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write + 1) % APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO,devpriv->tsk_Current,0);
+
+
+ }
+ }
+ }
+ }//pulse encoder
+
+ }
+ return ;
+
+}
+
--- /dev/null
+\r
+
+
+
+\r
+#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */
+#define COMEDI_SUBD_PWM 12 /* Pulse width Measurement */
+#define COMEDI_SUBD_SSI 13 /* Synchronous serial interface */
+#define COMEDI_SUBD_TOR 14 /* Tor counter */
+#define COMEDI_SUBD_CHRONO 15 /* Chrono meter*/
+#define COMEDI_SUBD_PULSEENCODER 16 /* Pulse Encoder INP CPT*/
+#define COMEDI_SUBD_INCREMENTALCOUNTER 17 /* Incremental Counter */
+\r
+\r
+ #define INT int\r
+ #define UINT unsigned int\r
+ #define BYTE unsigned char\r
+ #define CHAR char\r
+ #define LONG long\r
+ #define ULONG unsigned long\r
+ #define VOID void\r
+ #define PINT int *\r
+ #define PUINT unsigned int *\r
+ #define PBYTE unsigned char *\r
+ #define PCHAR char *\r
+ #define PLONG long *\r
+ #define PULONG unsigned long *\r
+ #define DWORD unsigned long\r
+ #define WORD unsigned short\r
+\r
+ #define APCI1710_BOARD_NAME "apci1710"\r
+ #define APCI1710_BOARD_VENDOR_ID 0x10E8\r
+ #define APCI1710_BOARD_DEVICE_ID 0x818F\r
+ #define APCI1710_ADDRESS_RANGE 256\r
+ #define APCI1710_CONFIG_ADDRESS_RANGE 8\r
+ #define APCI1710_INCREMENTAL_COUNTER 0x53430000UL\r
+ #define APCI1710_SSI_COUNTER 0x53490000UL\r
+ #define APCI1710_TTL_IO 0x544C0000UL\r
+ #define APCI1710_DIGITAL_IO 0x44490000UL\r
+ #define APCI1710_82X54_TIMER 0x49430000UL\r
+ #define APCI1710_CHRONOMETER 0x43480000UL\r
+ #define APCI1710_PULSE_ENCODER 0x495A0000UL\r
+ #define APCI1710_TOR_COUNTER 0x544F0000UL\r
+ #define APCI1710_PWM 0x50570000UL\r
+ #define APCI1710_ETM 0x45540000UL\r
+ #define APCI1710_CDA 0x43440000UL\r
+ #define APCI1710_DISABLE 0\r
+ #define APCI1710_ENABLE 1\r
+ #define APCI1710_SYNCHRONOUS_MODE 1\r
+ #define APCI1710_ASYNCHRONOUS_MODE 0\r
+\r
+\r
+//MODULE INFO STRUCTURE\r
+
+\rcomedi_lrange range_apci1710_ttl={ 4, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2),
+ BIP_RANGE(1)
+ }
+};
+\r
+\r
+\rcomedi_lrange range_apci1710_ssi={ 4, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2),
+ BIP_RANGE(1)
+ }
+};
+
+comedi_lrange range_apci1710_inccpt={ 4, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2),
+ BIP_RANGE(1)
+ }
+};
--- /dev/null
+/*\r
+ +-----------------------------------------------------------------------+\r
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |\r
+ +-----------------------------------------------------------------------+\r
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |\r
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |\r
+ +-------------------------------+---------------------------------------+\r
+ | Project : 13Card Linux Driver | Compiler : GCC |\r
+ | Module name : hwdrv_apci035.c| Version : 2.96 |\r
+ +-------------------------------+---------------------------------------+\r
+ | Author : Shitalkumar S Chavan | Date : 10.12.2001 |\r
+ +-------------------------------+---------------------------------------+\r
+ | Description : Hardware Layer Acces For APCI-035 |\r
+ +-----------------------------------------------------------------------+\r
+ | UPDATES |\r
+ +----------+-----------+------------------------------------------------+\r
+ | Date | Author | Description of updates |\r
+ +----------+-----------+------------------------------------------------+\r
+ | | | |\r
+ | | | |\r
+ | | | |\r
+ +----------+-----------+------------------------------------------------+\r
+*/\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Included files |\r
++----------------------------------------------------------------------------+\r
+*/\r
+#include "hwdrv_apci035.h"\r
+INT i_WatchdogNbr=0;
+INT i_Temp=0;
+INT i_Flag=1;
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI035_ConfigTimerWatchdog |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Configures The Timer , Counter or Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : 0 Configure As Timer |
+| 1 Configure As Watchdog |
+ data[1] : Watchdog number
+| data[2] : Time base Unit |
+| data[3] : Reload Value |
+ data[4] : External Trigger |
+ 1:Enable
+ 0:Disable
+ data[5] :External Trigger Level
+ 00 Trigger Disabled
+ 01 Trigger Enabled (Low level)
+ 10 Trigger Enabled (High Level)
+ 11 Trigger Enabled (High/Low level)
+ data[6] : External Gate |
+ 1:Enable
+ 0:Disable
+ data[7] : External Gate level
+ 00 Gate Disabled
+ 01 Gate Enabled (Low level)
+ 10 Gate Enabled (High Level)
+ data[8] :Warning Relay
+ 1: ENABLE
+ 0: DISABLE
+ data[9] :Warning Delay available
+ data[10] :Warning Relay Time unit
+ data[11] :Warning Relay Time Reload value
+ data[12] :Reset Relay
+ 1 : ENABLE
+ 0 : DISABLE
+ data[13] :Interrupt
+ 1 : ENABLE
+ 0 : DISABLE
+
+|
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI035_ConfigTimerWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+UINT ui_Status=0;
+UINT ui_Command=0;
+UINT ui_Mode=0;
+i_Temp=0;
+devpriv->tsk_Current=current;
+devpriv->b_TimerSelectMode=data[0];
+i_WatchdogNbr=data[1];
+if(data[0]==0)
+ {
+ ui_Mode=2;
+ }
+else
+ {
+ ui_Mode=0;
+ }
+//ui_Command = inl(devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
+ui_Command=0;
+//ui_Command = ui_Command & 0xFFFFF9FEUL;
+outl(ui_Command,devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
+ui_Command=0;
+ui_Command = inl(devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
+/************************/
+/* Set the reload value */
+/************************/
+outl( data[3],devpriv->iobase+((i_WatchdogNbr-1)*32) + 4);
+/*********************/
+/* Set the time unit */
+/*********************/
+outl(data[2],devpriv->iobase+((i_WatchdogNbr-1)*32) + 8);
+if (data[0] == ADDIDATA_TIMER)
+ {
+
+
+ /******************************/
+ /* Set the mode : */
+ /* - Disable the hardware */
+ /* - Disable the counter mode */
+ /* - Disable the warning */
+ /* - Disable the reset */
+ /* - Enable the timer mode */
+ /* - Set the timer mode */
+ /******************************/
+
+
+ ui_Command = (ui_Command & 0xFFF719E2UL) | ui_Mode << 13UL | 0x10UL;
+
+ }//if (data[0] == ADDIDATA_TIMER)\r
+ else
+ {
+ if(data[0]==ADDIDATA_WATCHDOG)
+ {
+
+ /******************************/
+ /* Set the mode : */
+ /* - Disable the hardware */
+ /* - Disable the counter mode */
+ /* - Disable the warning */
+ /* - Disable the reset */
+ /* - Disable the timer mode */
+ /******************************/
+
+
+ ui_Command = ui_Command & 0xFFF819E2UL;
+
+ }
+ else
+ {
+ printk("\n The parameter for Timer/watchdog selection is in error\n");
+ return -EINVAL;
+ }
+ }
+outl(ui_Command,devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
+ui_Command=0;
+ui_Command = inl(devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
+/********************************/
+/* Disable the hardware trigger */
+/********************************/
+ui_Command = ui_Command & 0xFFFFF89FUL;
+ if (data[4] == ADDIDATA_ENABLE)
+ {
+ /**********************************/
+ /* Set the hardware trigger level */
+ /**********************************/
+ ui_Command = ui_Command | ( data[5] << 5);
+ }
+outl(ui_Command,devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
+ui_Command=0;
+ui_Command = inl(devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
+/*****************************/
+/* Disable the hardware gate */
+/*****************************/
+ui_Command = ui_Command & 0xFFFFF87FUL;
+if (data[6] == ADDIDATA_ENABLE)
+ {
+/*******************************/
+/* Set the hardware gate level */
+/*******************************/
+ ui_Command = ui_Command |( data[7] << 7);
+ }
+outl(ui_Command,devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
+ui_Command=0;
+ui_Command = inl(devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
+/*******************************/
+/* Disable the hardware output */
+/*******************************/
+ui_Command = ui_Command & 0xFFFFF9FBUL;
+/*********************************/
+/* Set the hardware output level */
+/*********************************/
+ui_Command = ui_Command |( data[8] << 2);
+outl(ui_Command,devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
+if(data[9]==ADDIDATA_ENABLE)
+ {
+ /************************/
+ /* Set the reload value */
+ /************************/
+ outl (data[11],devpriv->iobase+((i_WatchdogNbr-1)*32) + 24);
+ /**********************/
+ /* Set the time unite */
+ /**********************/
+ outl(data[10],devpriv->iobase+((i_WatchdogNbr-1)*32)+ 28);
+ }
+
+ ui_Command=0;
+ ui_Command = inl(devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
+ /*******************************/
+ /* Disable the hardware output */
+ /*******************************/
+ ui_Command = ui_Command & 0xFFFFF9F7UL;
+ /*********************************/
+ /* Set the hardware output level */
+ /*********************************/
+ ui_Command = ui_Command |( data[12] << 3);
+ outl(ui_Command,devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
+ /*************************************/
+ /** Enable the watchdog interrupt **/
+ /*************************************/
+ui_Command=0;
+ui_Command = inl(devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
+/*******************************/
+/* Set the interrupt selection */
+/*******************************/
+ui_Status =inl(devpriv->iobase+((i_WatchdogNbr-1)*32) + 16);
+
+ui_Command = (ui_Command & 0xFFFFF9FDUL) | ( data[13] << 1);
+outl(ui_Command,devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
+
+return insn->n;
+}
+
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : int i_APCI035_StartStopWriteTimerWatchdog |\r
+| (comedi_device *dev,comedi_subdevice *s, | \r
+| comedi_insn *insn,lsampl_t *data) |\r
++----------------------------------------------------------------------------+\r
+| Task : Start / Stop The Selected Timer , or Watchdog |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : comedi_device *dev : Driver handle |\r
+| UINT *data : Data Pointer contains |\r
+| configuration parameters as below |\r
+| |\r
+| data[0] : 0 - Stop Selected Timer/Watchdog |\r
+| 1 - Start Selected Timer/Watchdog |\r
+| 2 - Trigger Selected Timer/Watchdog |\r
+| 3 - Stop All Timer/Watchdog |\r
+| 4 - Start All Timer/Watchdog |\r
+| 5 - Trigger All Timer/Watchdog |\r
+| |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : -- |\r
++----------------------------------------------------------------------------+\r
+| Return Value : TRUE : No error occur |\r
+| : FALSE : Error occur. Return the error | \r
+| |\r
++----------------------------------------------------------------------------+\r
+*/\r
+INT i_APCI035_StartStopWriteTimerWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)\r
+{\r
+ UINT ui_Command = 0; \r
+ INT i_Count=0;
+ if (data[0]==1) \r
+ { \r
+ ui_Command = inl(devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
+ /**********************/
+ /* Start the hardware */
+ /**********************/
+ ui_Command = (ui_Command & 0xFFFFF9FFUL) | 0x1UL;
+ outl(ui_Command,devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
+ } // if (data[0]==1)\r
+ if(data[0]==2)
+ {
+ ui_Command = inl(devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
+ /***************************/
+ /* Set the trigger command */
+ /***************************/
+ ui_Command = (ui_Command & 0xFFFFF9FFUL) | 0x200UL;
+ outl(ui_Command,devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
+ }
+
+ if (data[0]==0) //Stop The Watchdog \r
+ {\r
+ //Stop The Watchdog\r
+ ui_Command=0;
+ //ui_Command = inl(devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
+ //ui_Command = ui_Command & 0xFFFFF9FEUL;
+ outl(ui_Command,devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
+ } // if (data[1]==0)\r
+ if(data[0]==3)//stop all Watchdogs\r
+ {
+ ui_Command=0;
+ for(i_Count=1;i_Count<=4;i_Count++)
+ {\r
+ if(devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
+ {
+ ui_Command=0x2UL;
+ }
+ else
+ {
+ ui_Command = 0x10UL; \r
+ }
+ i_WatchdogNbr=i_Count;
+ outl(ui_Command,devpriv->iobase+((i_WatchdogNbr-1)*32) + 0);
+ }\r
+\r }
+ if(data[0]==4)//start all Watchdogs\r
+ {\r
+ ui_Command = 0;
+ for(i_Count=1;i_Count<=4;i_Count++)
+ {
+ if(devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
+ {
+ ui_Command = 0x1UL;
+ }
+ else
+ {
+ ui_Command = 0x8UL;
+ }
+ i_WatchdogNbr=i_Count;
+ outl(ui_Command,devpriv->iobase+((i_WatchdogNbr-1)*32) + 0);
+ }
+ }\r
+ if(data[0]==5)//trigger all Watchdogs\r
+ {\r
+ ui_Command =0;
+ for(i_Count=1;i_Count<=4;i_Count++)
+ {
+ if(devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
+ {
+ ui_Command=0x4UL;
+ }
+ else
+ {
+ ui_Command = 0x20UL;
+ }
+ \r i_WatchdogNbr=i_Count;
+ outl(ui_Command,devpriv->iobase+((i_WatchdogNbr-1)*32) + 0);
+ }
+ i_Temp=1;
+ }\r
+ return insn->n;\r
+}\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : int i_APCI035_ReadTimerWatchdog |\r
+| (comedi_device *dev,comedi_subdevice *s, | \r
+| comedi_insn *insn,lsampl_t *data) |\r
++----------------------------------------------------------------------------+\r
+| Task : Read The Selected Timer , Counter or Watchdog |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : comedi_device *dev : Driver handle |\r
+| UINT *data : Data Pointer contains |\r
+| configuration parameters as below |\r
+| | \r
+| |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : data[0] : software trigger status \r data[1] : hardware trigger status
+| data[2] : Software clear status
+ data[3] : Overflow status \r data[4] : Timer actual value
+
+
++----------------------------------------------------------------------------+\r
+| Return Value : TRUE : No error occur |\r
+| : FALSE : Error occur. Return the error |\r
+| |\r
++----------------------------------------------------------------------------+\r
+*/\r
+INT i_APCI035_ReadTimerWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)\r
+{\r
+UINT ui_Status = 0; // Status register \r
+ i_WatchdogNbr=insn->unused[0];
+ /******************/
+ /* Get the status */
+ /******************/
+ ui_Status =inl(devpriv->iobase+((i_WatchdogNbr-1)*32) + 16);\r
+ /***********************************/
+ /* Get the software trigger status */
+ /***********************************/
+ data[0] = ((ui_Status >> 1) & 1);
+ /***********************************/
+ /* Get the hardware trigger status */
+ /***********************************/
+ data[1] = ((ui_Status >> 2) & 1);
+ /*********************************/
+ /* Get the software clear status */
+ /*********************************/
+ data[2] = ((ui_Status >> 3) & 1);
+ /***************************/
+ /* Get the overflow status */
+ /***************************/
+ data[3] = ((ui_Status >> 0) & 1);
+ if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER) \r
+ {\r
+ data[4]=inl(devpriv->iobase+((i_WatchdogNbr-1)*32) + 0);
+
+ } // if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER) \r
+
+
+ return insn->n;\r
+}\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : INT i_APCI035_ConfigAnalogInput |\r
+| (comedi_device *dev,comedi_subdevice *s, | \r
+| comedi_insn *insn,lsampl_t *data) |\r
++----------------------------------------------------------------------------+\r
+| Task : Configures The Analog Input Subdevice |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : comedi_device *dev : Driver handle |\r
+| comedi_subdevice *s : Subdevice Pointer | \r
+| comedi_insn *insn : Insn Structure Pointer | \r
+| lsampl_t *data : Data Pointer contains |\r
+| configuration parameters as below |\r
+| data[0] : Warning delay value
+| | \r
++----------------------------------------------------------------------------+\r
+| Output Parameters : -- |\r
++----------------------------------------------------------------------------+\r
+| Return Value : TRUE : No error occur |\r
+| : FALSE : Error occur. Return the error |\r
+| |\r
++----------------------------------------------------------------------------+\r
+*/\r
+INT i_APCI035_ConfigAnalogInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) \r
+{\r
+devpriv->tsk_Current=current;
+outl(0x200 | 0, devpriv->iobase+128 + 0x4);
+outl(0, devpriv->iobase+128 + 0);
+/********************************/
+/* Initialise the warning value */
+/********************************/
+outl(0x300 | 0, devpriv->iobase+128 + 0x4);
+outl((data[0] << 8), devpriv->iobase+128 + 0);
+outl(0x200000UL , devpriv->iobase+128 + 12);
+
+return insn->n;\r
+} \r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : int i_APCI035_ReadAnalogInput |\r
+| (comedi_device *dev,comedi_subdevice *s, | \r
+| comedi_insn *insn,lsampl_t *data) |\r
++----------------------------------------------------------------------------+\r
+| Task : Read value of the selected channel |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : comedi_device *dev : Driver handle |\r
+| UINT ui_NoOfChannels : No Of Channels To read |\r
+| UINT *data : Data Pointer to read status |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : -- |\r
+| data[0] : Digital Value Of Input |\r
+| |\r
++----------------------------------------------------------------------------+\r
+| Return Value : TRUE : No error occur |\r
+| : FALSE : Error occur. Return the error |\r
+| |\r
++----------------------------------------------------------------------------+\r
+*/\r
+INT i_APCI035_ReadAnalogInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) \r
+{
+UINT ui_CommandRegister=0;
+/******************/
+/* Set the start */
+/******************/
+ui_CommandRegister =0x80000;
+ /******************************/
+ /* Write the command register */
+ /******************************/
+outl(ui_CommandRegister, devpriv->iobase+128 + 8);
+
+/***************************************/
+/* Read the digital value of the input */
+/***************************************/
+data[0] = inl (devpriv->iobase+ 128 + 28);
+return insn->n;\r
+}\r
+\r
+
+\r
+
+\r
+
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : int i_APCI035_Reset(comedi_device *dev) |\r
+| |\r
++----------------------------------------------------------------------------+\r
+| Task :Resets the registers of the card |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : -- |\r
++----------------------------------------------------------------------------+\r
+| Return Value : |\r
+| |\r
++----------------------------------------------------------------------------+\r
+*/\r
+INT i_APCI035_Reset(comedi_device *dev)\r
+{
+INT i_Count=0;
+for(i_Count=1;i_Count<=4;i_Count++)
+ {
+ i_WatchdogNbr=i_Count;
+ outl(0x0,devpriv->iobase+((i_WatchdogNbr-1)*32) + 0);//stop all timers
+ }
+outl(0x0 , devpriv->iobase+128 + 12);//Disable the warning delay
+
+ return 0;\r
+}\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : static void v_APCI035_Interrupt |\r
+| (int irq , void *d, struct pt_regs *regs) |\r
++----------------------------------------------------------------------------+\r
+| Task : Interrupt processing Routine |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : int irq : irq number |\r
+| void *d : void pointer |\r
+| struct pt_regs *regs : structure pointer |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : -- |\r
++----------------------------------------------------------------------------+\r
+| Return Value : TRUE : No error occur |\r
+| : FALSE : Error occur. Return the error |\r
+| |\r
++----------------------------------------------------------------------------+\r
+*/\r
+static void v_APCI035_Interrupt(int irq, void *d, struct pt_regs *regs) \r
+{ \r
+ comedi_device *dev = d;\r
+ UINT ui_StatusRegister1 = 0;
+ UINT ui_StatusRegister2=0;
+ UINT ui_ReadCommand =0;
+ UINT ui_ChannelNumber=0;
+ UINT ui_DigitalTemperature=0;
+ if(i_Temp==1)
+ {
+ i_WatchdogNbr=i_Flag;
+ i_Flag=i_Flag+1;
+ }
+ /**************************************/
+ /* Read the interrupt status register of temperature Warning */
+ /**************************************/
+ ui_StatusRegister1 = inl(devpriv->iobase+128 + 16);
+ /**************************************/
+ /* Read the interrupt status register for Watchdog/timer */
+ /**************************************/
+
+ ui_StatusRegister2 = inl (devpriv->iobase+((i_WatchdogNbr-1)*32) + 20);
+
+ if ((((ui_StatusRegister1 ) & 0x8) == 0x8))//Test if warning relay interrupt
+ {
+ /**********************************/
+ /* Disable the temperature warning */
+ /**********************************/
+ ui_ReadCommand = inl (devpriv->iobase+128 + 12);
+ ui_ReadCommand = ui_ReadCommand & 0xFFDF0000UL;
+ outl(ui_ReadCommand , devpriv->iobase+128 + 12);
+ /***************************/
+ /* Read the channel number */
+ /***************************/
+ ui_ChannelNumber = inl(devpriv->iobase+128 + 60);
+ /**************************************/
+ /* Read the digital temperature value */
+ /**************************************/
+ ui_DigitalTemperature = inl(devpriv->iobase+128 + 60);
+ send_sig(SIGIO,devpriv->tsk_Current,0); // send signal to the sample
+ }//if (((ui_StatusRegister1 & 0x8) == 0x8))
+
+ else
+ {
+ if((ui_StatusRegister2 & 0x1) == 0x1)
+ {
+ send_sig(SIGIO,devpriv->tsk_Current,0); // send signal to the sample
+ }
+ }//else if (((ui_StatusRegister1 & 0x8) == 0x8))
+
+
+return;\r
+}\r
+\r
+
+\r
+
+
--- /dev/null
+// Card Specific information\r
+#define APCI035_BOARD_VENDOR_ID 0x15B8\r
+#define APCI035_ADDRESS_RANGE 255\r
+\r
+INT i_TW_Number;
+struct
+{
+ INT i_Gain ;
+ INT i_Polarity;
+ INT i_OffsetRange;
+ INT i_Coupling;
+ INT i_SingleDiff;
+ INT i_AutoCalibration;
+ UINT ui_ReloadValue;
+ UINT ui_TimeUnitReloadVal;
+ INT i_Interrupt;
+ INT i_ModuleSelection;
+}Config_Parameters_Main;
+
+
+
+//ANALOG INPUT RANGE
+comedi_lrange range_apci035_ai={ 8, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2),
+ BIP_RANGE(1),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2),
+ UNI_RANGE(1)
+ }
+};
+
+// Timer / Watchdog Related Defines \r
+\r
+#define APCI035_TCW_SYNC_ENABLEDISABLE 0\r
+#define APCI035_TCW_RELOAD_VALUE 4\r
+#define APCI035_TCW_TIMEBASE 8\r
+#define APCI035_TCW_PROG 12\r
+#define APCI035_TCW_TRIG_STATUS 16\r
+#define APCI035_TCW_IRQ 20\r
+#define APCI035_TCW_WARN_TIMEVAL 24\r
+#define APCI035_TCW_WARN_TIMEBASE 28\r
+\r
+#define ADDIDATA_TIMER 0\r
+#define ADDIDATA_WATCHDOG 1
+\r
+#define APCI035_TW1 0\r
+#define APCI035_TW2 32\r
+#define APCI035_TW3 64\r
+#define APCI035_TW4 96\r
+\r
+#define APCI035_AI_OFFSET 0\r
+#define APCI035_TEMP 128\r
+#define APCI035_ALR_SEQ 4\r
+#define APCI035_START_STOP_INDEX 8\r
+#define APCI035_ALR_START_STOP 12\r
+#define APCI035_ALR_IRQ 16\r
+#define APCI035_EOS 20\r
+#define APCI035_CHAN_NO 24\r
+#define APCI035_CHAN_VAL 28\r
+#define APCI035_CONV_TIME_TIME_BASE 36\r
+#define APCI035_RELOAD_CONV_TIME_VAL 32\r
+#define APCI035_DELAY_TIME_TIME_BASE 44\r
+#define APCI035_RELOAD_DELAY_TIME_VAL 40\r
+#define ENABLE_EXT_TRIG 1
+#define ENABLE_EXT_GATE 2
+#define ENABLE_EXT_TRIG_GATE 3
+
+#define ANALOG_INPUT 0
+#define TEMPERATURE 1
+#define RESISTANCE 2
+
+#define ADDIDATA_GREATER_THAN_TEST 0
+#define ADDIDATA_LESS_THAN_TEST 1
+
+
+#define APCI035_MAXVOLT 2.5\r
+\r
+#define ADDIDATA_UNIPOLAR 1\r
+#define ADDIDATA_BIPOLAR 2\r
+\r
+//ADDIDATA Enable Disable\r
+#define ADDIDATA_ENABLE 1\r
+#define ADDIDATA_DISABLE 0\r
+\r
+\r
+\r
+\r
+\r
+\r
+// Hardware Layer functions for Apci035\r
+\r
+\r
+\r
+// TIMER \r
+// timer value is passed as u seconds\r
+INT i_APCI035_ConfigTimerWatchdog (comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);\r
+INT i_APCI035_StartStopWriteTimerWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);\r
+INT i_APCI035_ReadTimerWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);\r
+
+
+//Temperature Related Defines (Analog Input Subdevice)
+
+INT i_APCI035_ConfigAnalogInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+INT i_APCI035_ReadAnalogInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+
+
+//Interrupt\r
+static void v_APCI035_Interrupt(int irq, void *d, struct pt_regs *regs) ;\r
+\r
+//Reset functions\r
+INT i_APCI035_Reset(comedi_device *dev); \r
+\r
+\r
+
+
+
+
+
+\r
+\r
+\r
--- /dev/null
+/*
+ +-----------------------------------------------------------------------+
+ | (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 : 13Card Linux Driver | Compiler : GCC |
+ | Module name : hwdrv_apci1032.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Author : Shitalkumar S Chavan | Date : 31.10.2001 |
+ +-------------------------------+---------------------------------------+
+ | Description : Hardware Layer Acces For APCI-1032 |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +----------+-----------+------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+#include "hwdrv_apci1032.h"
+#include <linux/delay.h>
+//Global variables
+ UINT ui_InterruptStatus=0 ;
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1032_ConfigDigitalInput |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Configures the digital input Subdevice |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| lsampl_t *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : 1 Enable Digital Input Interrupt |
+| 0 Disable Digital Input Interrupt |
+| data[1] : 0 ADDIDATA Interrupt OR LOGIC |
+| : 1 ADDIDATA Interrupt AND LOGIC |
+| data[2] : Interrupt mask for the mode 1 |
+| data[3] : Interrupt mask for the mode 2 |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1032_ConfigDigitalInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ UINT ui_TmpValue;
+
+ ULONG ul_Command1 = 0;
+ ULONG ul_Command2 = 0;
+ devpriv->tsk_Current=current;
+ /*******************************/
+ /* Set the digital input logic */
+ /*******************************/
+ if ( data[0] == ADDIDATA_ENABLE)
+ {
+ ul_Command1 = ul_Command1 | data[2];
+ ul_Command2 = ul_Command2 | data[3];
+ outl (ul_Command1 , devpriv->iobase+APCI1032_DIGITAL_IP_INTERRUPT_MODE1);
+ outl (ul_Command2 , devpriv->iobase+APCI1032_DIGITAL_IP_INTERRUPT_MODE2);
+ if (data[1] == ADDIDATA_OR)
+ {
+ outl(0x4 ,devpriv->iobase+APCI1032_DIGITAL_IP_IRQ);
+ ui_TmpValue=inl(devpriv->iobase+APCI1032_DIGITAL_IP_IRQ);
+ }//if (data[1] == ADDIDATA_OR)
+ else
+ {
+ outl(0x6 ,devpriv->iobase+APCI1032_DIGITAL_IP_IRQ);
+ }//else if(data[1] == ADDIDATA_OR)
+ }// if( data[0] == ADDIDATA_ENABLE)
+ else
+ {
+ ul_Command1 = ul_Command1 & 0xFFFF0000;
+ ul_Command2 = ul_Command2 & 0xFFFF0000;
+ outl (ul_Command1 , devpriv->iobase+APCI1032_DIGITAL_IP_INTERRUPT_MODE1);
+ outl (ul_Command2 , devpriv->iobase+APCI1032_DIGITAL_IP_INTERRUPT_MODE2);
+ outl(0x0 ,devpriv->iobase+APCI1032_DIGITAL_IP_IRQ);
+ }//else if ( data[0] == ADDIDATA_ENABLE)
+
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1032_Read1DigitalInput |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Return the status of the digital input |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| UINT ui_Channel : Channel number to read |
+| lsampl_t *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1032_Read1DigitalInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ UINT ui_TmpValue=0;
+ UINT ui_Channel;
+ ui_Channel=CR_CHAN(insn->chanspec);
+ if (ui_Channel >= 0 && ui_Channel <=31)
+ {
+ ui_TmpValue=(UINT) inl(devpriv->iobase + APCI1032_DIGITAL_IP);
+ // since only 1 channel reqd to bring it to last bit it is rotated
+ // 8 +(chan - 1) times then ANDed with 1 for last bit.
+ *data = (ui_TmpValue >> ui_Channel)&0x1 ;
+ }//if(ui_Channel >= 0 && ui_Channel <=31)
+ else
+ {
+ //comedi_error(dev," \n chan spec wrong\n");
+ return -EINVAL; // "sorry channel spec wrong "
+ }//else if(ui_Channel >= 0 && ui_Channel <=31)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1032_ReadMoreDigitalInput |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Return the status of the Requested digital inputs |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To be Read |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1032_ReadMoreDigitalInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ UINT ui_PortValue=data[0];
+ UINT ui_Mask=0;
+ UINT ui_NoOfChannels;
+
+ ui_NoOfChannels=CR_CHAN(insn->chanspec);
+ if (data[1]==0)
+ {
+ *data=(UINT)inl(devpriv->iobase + APCI1032_DIGITAL_IP );
+ switch (ui_NoOfChannels)
+ {
+ case 2:ui_Mask=3;
+ *data=(*data >>(2*ui_PortValue))&ui_Mask;
+ break;
+ case 4:ui_Mask=15;
+ *data=(*data >>(4*ui_PortValue))&ui_Mask;
+ break;
+ case 8:ui_Mask=255;
+ *data=(*data >>(8*ui_PortValue))&ui_Mask;
+ break;
+ case 16:ui_Mask=65535;
+ *data=(*data >>(16*ui_PortValue))&ui_Mask;
+ break;
+ case 31: break;
+ default:
+ //comedi_error(dev," \nchan spec wrong\n");
+ return -EINVAL; // "sorry channel spec wrong "
+ break;
+ }//switch(ui_NoOfChannels)
+ }//if(data[1]==0)
+ else
+ {
+ if (data[1]==1)
+ {
+ *data=ui_InterruptStatus;
+ }//if(data[1]==1)
+ }//else if(data[1]==0)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : static void v_APCI1032_Interrupt |
+| (int irq , void *d, struct pt_regs *regs) |
++----------------------------------------------------------------------------+
+| Task : Interrupt handler for the interruptible digital inputs |
++----------------------------------------------------------------------------+
+| Input Parameters : int irq : irq number |
+| void *d : void pointer |
+| struct pt_regs *regs : structure pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+static VOID v_APCI1032_Interrupt(int irq,void* d, struct pt_regs *regs)
+{
+ comedi_device *dev =d;
+
+ UINT ui_Temp;
+ //disable the interrupt
+ ui_Temp=inl(devpriv->iobase+APCI1032_DIGITAL_IP_IRQ);
+ outl(ui_Temp& APCI1032_DIGITAL_IP_INTERRUPT_DISABLE ,devpriv->iobase+APCI1032_DIGITAL_IP_IRQ);
+ ui_InterruptStatus=inl(devpriv->iobase+APCI1032_DIGITAL_IP_INTERRUPT_STATUS);
+ ui_InterruptStatus=ui_InterruptStatus & 0X0000FFFF;
+ send_sig(SIGIO,devpriv->tsk_Current,0); // send signal to the sample
+ outl(ui_Temp ,devpriv->iobase+APCI1032_DIGITAL_IP_IRQ);//enable the interrupt
+return;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1032_Reset(comedi_device *dev) | |
++----------------------------------------------------------------------------+
+| Task :resets all the registers |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1032_Reset(comedi_device *dev)
+{
+ outl(0x0 ,devpriv->iobase+APCI1032_DIGITAL_IP_IRQ);//disable the interrupts
+ inl(devpriv->iobase+APCI1032_DIGITAL_IP_INTERRUPT_STATUS);//Reset the interrupt status register
+ outl (0x0 , devpriv->iobase+APCI1032_DIGITAL_IP_INTERRUPT_MODE1);//Disable the and/or interrupt
+ outl (0x0 , devpriv->iobase+APCI1032_DIGITAL_IP_INTERRUPT_MODE2);
+ return 0;
+}
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+/********* Definitions for APCI-1032 card *****/
+
+#define APCI1032_BOARD_VENDOR_ID 0x15B8
+#define APCI1032_ADDRESS_RANGE 20
+//DIGITAL INPUT DEFINE
+
+#define APCI1032_DIGITAL_IP 0
+#define APCI1032_DIGITAL_IP_INTERRUPT_MODE1 4
+#define APCI1032_DIGITAL_IP_INTERRUPT_MODE2 8
+#define APCI1032_DIGITAL_IP_IRQ 16
+
+//Digital Input IRQ Function Selection
+#define ADDIDATA_OR 0
+#define ADDIDATA_AND 1
+
+//Digital Input Interrupt Status
+#define APCI1032_DIGITAL_IP_INTERRUPT_STATUS 12
+
+
+
+//Digital Input Interrupt Enable Disable.
+#define APCI1032_DIGITAL_IP_INTERRUPT_ENABLE 0x4
+#define APCI1032_DIGITAL_IP_INTERRUPT_DISABLE 0xFFFFFFFB
+
+
+
+//ADDIDATA Enable Disable
+
+#define ADDIDATA_ENABLE 1
+#define ADDIDATA_DISABLE 0
+
+
+
+
+// Hardware Layer functions for Apci1032
+
+
+//DI
+// for di read
+
+INT i_APCI1032_ConfigDigitalInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+
+INT i_APCI1032_Read1DigitalInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+
+INT i_APCI1032_ReadMoreDigitalInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+
+
+
+
+
+
+
+// Interrupt functions.....
+
+static VOID v_APCI1032_Interrupt(int irq, void *d, struct pt_regs *regs) ;
+//Reset
+INT i_APCI1032_Reset(comedi_device *dev);
+
+
\ No newline at end of file
--- /dev/null
+/*
+ +-----------------------------------------------------------------------+
+ | (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 : 13Card Linux Driver | Compiler : GCC |
+ | Module name : hwdrv_apci1500.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Author : Karl Andrade | Date : 13.12.2001 |
+ +-------------------------------+---------------------------------------+
+ | Description : Hardware Layer Acces For APCI-1500 |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +----------+-----------+------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+#include "hwdrv_apci1500.h"
+
+int i_TimerCounter1Init=0;
+int i_TimerCounter2Init=0;
+int i_WatchdogCounter3Init=0;
+int i_Event1Status=0,i_Event2Status=0;
+int i_TimerCounterWatchdogInterrupt=0;
+int i_Logic=0,i_CounterLogic=0;
+int i_InterruptMask=0;
+int i_InputChannel=0;
+ int i_TimerCounter1Enabled=0, i_TimerCounter2Enabled=0,i_WatchdogCounter3Enabled=0;
+
+
+
+/*
+ +----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_ConfigDigitalInputEvent |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : An event can be generated for each port. |
+| The first event is related to the first 8 channels |
+| (port 1) and the second to the following 6 channels |
+| (port 2). An interrupt is generated when one or both |
+| events have occurred |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| lsampl_t *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] :Number of the input port on |
+| which the event will take place |
+| (1 or 2)
+ data[1] : The event logic for port 1 has |
+| three possibilities |
+| :0 APCI1500_AND :This logic |
+| links |
+| the inputs |
+| with an AND |
+| logic. |
+| 1 APCI1500_OR :This logic |
+| links |
+| the inputs |
+| with a |
+| OR logic. |
+| 2 APCI1500_OR_PRIORITY |
+| :This logic |
+| links |
+| the inputs |
+| with a |
+| priority |
+| OR logic. |
+| Input 1 |
+| has the |
+| highest |
+| priority |
+| level and |
+| input 8 |
+| the smallest|
+| For the second port the user has|
+| 1 possibility: |
+| APCI1500_OR :This logic |
+| links |
+| the inputs |
+| with a |
+| polarity |
+| OR logic |
+| data[2] : These 8-character word for port1|
+| and 6-character word for port 2 |
+| give the mask of the event. |
+| Each place gives the state |
+| of the input channels and can |
+| have one of these six characters|
+| |
+| 0 : This input must be on 0 |
+| 1 : This input must be on 1 |
+| 2 : This input reacts to |
+| a falling edge |
+| 3 : This input reacts to a |
+| rising edge |
+| 4 : This input reacts to both edges |
+|
+| 5 : This input is not |
+| used for event |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1500_ConfigDigitalInputEvent(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+int i_PatternPolarity=0,i_PatternTransition=0,i_PatternMask=0;
+int i_MaxChannel=0,i_Count=0,i_EventMask=0;
+int i_PatternTransitionCount=0,i_RegValue;
+int i;
+
+ /*************************************************/
+ /* Selects the master interrupt control register */
+ /*************************************************/
+ outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /**********************************************/
+ /* Disables the main interrupt on the board */
+ /**********************************************/
+ outb(0x00,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ if (data[0] == 1)
+ {
+ i_MaxChannel = 8;
+ }// if (data[0] == 1)
+ else
+ {
+ if(data[0]==2)
+ {
+ i_MaxChannel = 6;
+ }// if(data[0]==2)
+ else
+ {
+ printk("\nThe specified port event does not exist\n");
+ return -EINVAL;
+ }//else if(data[0]==2)
+ }//else if (data[0] == 1)
+switch(data[1])
+ {
+ case 0: data[1]= APCI1500_AND;
+ break;
+ case 1: data[1]= APCI1500_OR;
+ break;
+ case 2: data[1]= APCI1500_OR_PRIORITY;
+ break;
+ default:printk("\nThe specified interrupt logic does not exist\n");
+ return -EINVAL;
+ }//switch(data[1]);
+
+i_Logic=data[1];
+for (i_Count = i_MaxChannel,i=0; i_Count >0;i_Count --,i++)
+ {
+ i_EventMask=data[2+i];
+ switch(i_EventMask)
+ {
+ case 0 : i_PatternMask = i_PatternMask | (1 << (i_MaxChannel-i_Count));
+ break;
+ case 1 : i_PatternMask = i_PatternMask | (1 << (i_MaxChannel-i_Count));
+ i_PatternPolarity = i_PatternPolarity |(1 << (i_MaxChannel-i_Count));
+ break;
+ case 2 : i_PatternMask = i_PatternMask |(1 << (i_MaxChannel-i_Count));
+ i_PatternTransition = i_PatternTransition |(1 << (i_MaxChannel-i_Count));
+ break;
+ case 3 : i_PatternMask = i_PatternMask | (1 << (i_MaxChannel-i_Count));
+ i_PatternPolarity = i_PatternPolarity |(1 << (i_MaxChannel-i_Count));
+ i_PatternTransition = i_PatternTransition |(1 << (i_MaxChannel-i_Count));
+ break;
+ case 4 : i_PatternTransition = i_PatternTransition |(1 << (i_MaxChannel-i_Count));
+ break;
+ case 5 : break;
+ default : printk("\nThe option indicated in the event mask does not exist\n");
+ return -EINVAL;
+ }// switch(i_EventMask)
+ }//for (i_Count = i_MaxChannel; i_Count >0;i_Count --)
+
+ if (data[0]== 1)
+ {
+ /****************************/
+ /* Test the interrupt logic */
+ /****************************/
+
+ if (data[1] == APCI1500_AND ||
+ data[1] == APCI1500_OR ||
+ data[1] == APCI1500_OR_PRIORITY)
+ {
+ /**************************************/
+ /* Tests if a transition was declared */
+ /* for a OR PRIORITY logic */
+ /**************************************/
+
+ if (data[1]== APCI1500_OR_PRIORITY && i_PatternTransition != 0)
+ {
+ /********************************************/
+ /* Transition error on an OR PRIORITY logic */
+ /********************************************/
+ printk("\nTransition error on an OR PRIORITY logic\n");
+ return -EINVAL;
+ }// if (data[1]== APCI1500_OR_PRIORITY && i_PatternTransition != 0)
+
+
+
+ /*************************************/
+ /* Tests if more than one transition */
+ /* was declared for an AND logic */
+ /*************************************/
+
+ if (data[1]== APCI1500_AND)
+ {
+ for (i_Count = 0; i_Count < 8; i_Count++)
+ {
+ i_PatternTransitionCount=i_PatternTransitionCount+((i_PatternTransition>>i_Count)&0x1);
+
+ } //for (i_Count = 0; i_Count < 8; i_Count++)
+
+ if (i_PatternTransitionCount > 1)
+ {
+ /****************************************/
+ /* Transition error on an AND logic */
+ /****************************************/
+ printk("\n Transition error on an AND logic\n");
+ return -EINVAL;
+ }// if (i_PatternTransitionCount > 1)
+ }// if (data[1]== APCI1500_AND)
+
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /******************/
+ /* Disable Port A */
+ /******************/
+ outb(0xF0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /**********************************************/
+ /* Selects the polarity register of port 1 */
+ /**********************************************/
+ outb(APCI1500_RW_PORT_A_PATTERN_POLARITY,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_PatternPolarity,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*********************************************/
+ /* Selects the pattern mask register of */
+ /* port 1 */
+ /*********************************************/
+ outb(APCI1500_RW_PORT_A_PATTERN_MASK,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_PatternMask,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /********************************************/
+ /* Selects the pattern transition register */
+ /* of port 1 */
+ /********************************************/
+ outb(APCI1500_RW_PORT_A_PATTERN_TRANSITION,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_PatternTransition,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /******************************************/
+ /* Selects the mode specification mask */
+ /* register of port 1 */
+ /******************************************/
+ outb(APCI1500_RW_PORT_A_SPECIFICATION,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue=inb(devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /******************************************/
+ /* Selects the mode specification mask */
+ /* register of port 1 */
+ /******************************************/
+ outb(APCI1500_RW_PORT_A_SPECIFICATION,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /**********************/
+ /* Port A new mode */
+ /**********************/
+
+ i_RegValue=(i_RegValue & 0xF9) | data[1]|0x9;
+ outb(i_RegValue,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ i_Event1Status=1;
+
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************/
+ /* Enable Port A */
+ /*****************/
+ outb(0xF4,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ }// if(data[1]==APCI1500_AND||data[1]==APCI1500_OR||data[1]==APCI1500_OR_PRIORITY)
+ else
+ {
+ printk("\nThe choice for interrupt logic does not exist\n");
+ return -EINVAL;
+ }// else }// if(data[1]==APCI1500_AND||data[1]==APCI1500_OR||data[1]==APCI1500_OR_PRIORITY)
+ }// if (data[0]== 1)
+
+
+ /************************************/
+ /* Test if event setting for port 2 */
+ /************************************/
+
+ if (data[0] == 2)
+ {
+ /************************/
+ /* Test the event logic */
+ /************************/
+
+ if (data[1] == APCI1500_OR)
+ {
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /******************/
+ /* Disable Port B */
+ /******************/
+ outb(0x74,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /****************************************/
+ /* Selects the mode specification mask */
+ /* register of port B */
+ /****************************************/
+ outb( APCI1500_RW_PORT_B_SPECIFICATION,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue=inb(devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+
+ /******************************************/
+ /* Selects the mode specification mask */
+ /* register of port B */
+ /******************************************/
+ outb(APCI1500_RW_PORT_B_SPECIFICATION,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue=i_RegValue & 0xF9;
+ outb(i_RegValue,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /**********************************/
+ /* Selects error channels 1 and 2 */
+ /**********************************/
+
+ i_PatternMask = (i_PatternMask | 0xC0);
+ i_PatternPolarity = (i_PatternPolarity | 0xC0);
+ i_PatternTransition = (i_PatternTransition | 0xC0);
+
+ /**********************************************/
+ /* Selects the polarity register of port 2 */
+ /**********************************************/
+ outb(APCI1500_RW_PORT_B_PATTERN_POLARITY,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb( i_PatternPolarity,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /**********************************************/
+ /* Selects the pattern transition register */
+ /* of port 2 */
+ /**********************************************/
+ outb(APCI1500_RW_PORT_B_PATTERN_TRANSITION,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_PatternTransition,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /**********************************************/
+ /* Selects the pattern Mask register */
+ /* of port 2 */
+ /**********************************************/
+
+ outb(APCI1500_RW_PORT_B_PATTERN_MASK,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_PatternMask,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /******************************************/
+ /* Selects the mode specification mask */
+ /* register of port 2 */
+ /******************************************/
+ outb(APCI1500_RW_PORT_B_SPECIFICATION,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue=inb(devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /******************************************/
+ /* Selects the mode specification mask */
+ /* register of port 2 */
+ /******************************************/
+ outb( APCI1500_RW_PORT_B_SPECIFICATION,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue=(i_RegValue & 0xF9) | 4;
+ outb(i_RegValue,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ i_Event2Status=1;
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************/
+ /* Enable Port B */
+ /*****************/
+
+ outb(0xF4,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ }// if (data[1] == APCI1500_OR)
+ else
+ {
+ printk("\nThe choice for interrupt logic does not exist\n");
+ return -EINVAL;
+ }//elseif (data[1] == APCI1500_OR)
+ }//if(data[0]==2)
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_StartStopInputEvent |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Allows or disallows a port event |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| UINT ui_Channel : Channel number to read |
+| lsampl_t *data : Data Pointer to read status |
+ data[0] :0 Start input event
+ 1 Stop input event
+ data[1] :No of port (1 or 2)
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI1500_StartStopInputEvent(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+int i_Event1InterruptStatus=0,i_Event2InterruptStatus=0,i_RegValue;
+switch(data[0])
+ {
+ case START :
+ /*************************/
+ /* Tests the port number */
+ /*************************/
+
+ if (data[1] == 1 || data[1] == 2)
+ {
+ /***************************/
+ /* Test if port 1 selected */
+ /***************************/
+
+ if ( data[1] == 1)
+ {
+ /*****************************/
+ /* Test if event initialised */
+ /*****************************/
+ if(i_Event1Status==1)
+ {
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /******************/
+ /* Disable Port A */
+ /******************/
+ outb(0xF0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /***************************************************/
+ /* Selects the command and status register of */
+ /* port 1 */
+ /***************************************************/
+ outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /*************************************/
+ /* Allows the pattern interrupt */
+ /*************************************/
+ outb(0xC0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************/
+ /* Enable Port A */
+ /*****************/
+ outb(0xF4,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_Event1InterruptStatus=1;
+ outb(APCI1500_RW_PORT_A_SPECIFICATION,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue=inb(devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /* Selects the master interrupt control register */
+ /*************************************************/
+ outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /**********************************************/
+ /* Authorizes the main interrupt on the board */
+ /**********************************************/
+ outb(0xD0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ }// if(i_Event1Status==1)
+ else
+ {
+ printk("\nEvent 1 not initialised\n");
+ return -EINVAL;
+ }//else if(i_Event1Status==1)
+ }//if (data[1]==1)
+ if(data[1]==2)
+ {
+
+ if(i_Event2Status==1)
+ {
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /******************/
+ /* Disable Port B */
+ /******************/
+ outb(0x74,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /***************************************************/
+ /* Selects the command and status register of */
+ /* port 2 */
+ /***************************************************/
+ outb( APCI1500_RW_PORT_B_COMMAND_AND_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /*************************************/
+ /* Allows the pattern interrupt */
+ /*************************************/
+ outb(0xC0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************/
+ /* Enable Port B */
+ /*****************/
+ outb(0xF4,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /* Selects the master interrupt control register */
+ /*************************************************/
+ outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /**********************************************/
+ /* Authorizes the main interrupt on the board */
+ /**********************************************/
+ outb(0xD0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_Event2InterruptStatus=1;
+ }// if(i_Event2Status==1)
+ else
+ {
+ printk("\nEvent 2 not initialised\n");
+ return -EINVAL;
+ }//else if(i_Event2Status==1)
+ }// if(data[1]==2)
+ }// if (data[1] == 1 || data[0] == 2)
+ else
+ {
+ printk("\nThe port parameter is in error\n");
+ return -EINVAL;
+ }//else if (data[1] == 1 || data[0] == 2)
+
+ break;
+
+ case STOP :
+ /*************************/
+ /* Tests the port number */
+ /*************************/
+
+ if (data[1] == 1 || data[1] == 2)
+ {
+ /***************************/
+ /* Test if port 1 selected */
+ /***************************/
+
+ if ( data[1] == 1)
+ {
+ /*****************************/
+ /* Test if event initialised */
+ /*****************************/
+ if(i_Event1Status==1)
+ {
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /******************/
+ /* Disable Port A */
+ /******************/
+ outb(0xF0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /***************************************************/
+ /* Selects the command and status register of */
+ /* port 1 */
+ /***************************************************/
+ outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /*************************************/
+ /* Inhibits the pattern interrupt */
+ /*************************************/
+ outb(0xE0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************/
+ /* Enable Port A */
+ /*****************/
+ outb(0xF4,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_Event1InterruptStatus=0;
+ }// if(i_Event1Status==1)
+ else
+ {
+ printk("\nEvent 1 not initialised\n");
+ return -EINVAL;
+ }//else if(i_Event1Status==1)
+ }//if (data[1]==1)
+ if(data[1]==2)
+ {
+ /*****************************/
+ /* Test if event initialised */
+ /*****************************/
+ if(i_Event2Status==1)
+ {
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /******************/
+ /* Disable Port B */
+ /******************/
+ outb(0x74,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /***************************************************/
+ /* Selects the command and status register of */
+ /* port 2 */
+ /***************************************************/
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /*************************************/
+ /* Inhibits the pattern interrupt */
+ /*************************************/
+ outb(0xE0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************/
+ /* Enable Port B */
+ /*****************/
+ outb(0xF4,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_Event2InterruptStatus=0;
+ }// if(i_Event2Status==1)
+ else
+ {
+ printk("\nEvent 2 not initialised\n");
+ return -EINVAL;
+ }//else if(i_Event2Status==1)
+ }//if(data[1]==2)
+
+ }// if (data[1] == 1 || data[1] == 2)
+ else
+ {
+ printk("\nThe port parameter is in error\n");
+ return -EINVAL;
+ }//else if (data[1] == 1 || data[1] == 2)
+ break;
+ default :printk("\nThe option of START/STOP logic does not exist\n");
+ return -EINVAL;
+ }//switch(data[0])
+
+return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_Initialisation |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Return the status of the digital input |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| UINT ui_Channel : Channel number to read |
+| lsampl_t *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1500_Initialisation(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+int i_DummyRead=0;
+ /******************/
+ /* Software reset */
+ /******************/
+ i_DummyRead=inb(devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_DummyRead=inb(devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(1,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the master configuration control register */
+ /*****************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0xF4,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the mode specification register of port A */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_A_SPECIFICATION,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0x10,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /* Selects the data path polarity register of port A */
+ outb( APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* High level of port A means 1 */
+ outb(0xFF,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /* Selects the data direction register of port A */
+ outb(APCI1500_RW_PORT_A_DATA_DIRECTION,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* All bits used as inputs */
+ outb(0xFF,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of port A */
+ outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes IP and IUS */
+ outb(0x20,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of port A */
+ outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deactivates the interrupt management of port A: */
+ outb(0xE0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the handshake specification register of port A */
+ outb(APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes the register */
+ outb(0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the mode specification register of port B */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_B_SPECIFICATION,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0x10,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the data path polarity register of port B */
+ outb(APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* A high level of port B means 1 */
+ outb(0x7F,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the data direction register of port B */
+ outb(APCI1500_RW_PORT_B_DATA_DIRECTION,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* All bits used as inputs */
+ outb(0xFF,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of port B */
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes IP and IUS */
+ outb(0x20,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of port B */
+ outb( APCI1500_RW_PORT_B_COMMAND_AND_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deactivates the interrupt management of port B: */
+ outb(0xE0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the handshake specification register of port B */
+ outb(APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes the register */
+ outb(0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the data path polarity register of port C */
+ /*****************************************************/
+ outb( APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* High level of port C means 1 */
+ outb(0x9,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the data direction register of port C */
+ outb(APCI1500_RW_PORT_C_DATA_DIRECTION,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* All bits used as inputs except channel 1 */
+ outb(0x0E,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the special IO register of port C */
+ outb( APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes it */
+ outb(0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /******************************************************/
+ /* Selects the command and status register of timer 1 */
+ /******************************************************/
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes IP and IUS */
+ outb(0x20,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of timer 1 */
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deactivates the interrupt management of timer 1 */
+ outb(0xE0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /******************************************************/
+ /* Selects the command and status register of timer 2 */
+ /******************************************************/
+ outb( APCI1500_RW_CPT_TMR2_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes IP and IUS */
+ outb(0x20,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of timer 2 */
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deactivates Timer 2 interrupt management: */
+ outb(0xE0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /******************************************************/
+ /* Selects the command and status register of timer 3 */
+ /******************************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes IP and IUS */
+ outb(0x20,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of Timer 3 */
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deactivates interrupt management of timer 3: */
+ outb(0xE0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /*************************************************/
+ /* Selects the master interrupt control register */
+ /*************************************************/
+ outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes all interrupts */
+ outb(0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_ReadMoreDigitalInput |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Return the status of the Requested digital inputs |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To be Read |
+| UINT *data : Data Pointer
+ data[0] : 0 Read a single channel
+ 1 read a port value
+ data[1] : port value
++----------------------------------------------------------------------------+
+| Output Parameters : -- data[0] :The read status value
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1500_ReadMoreDigitalInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ UINT ui_PortValue=data[1];
+ UINT ui_Mask=0;
+ UINT ui_Channel;
+ UINT ui_TmpValue=0;
+ ui_Channel=CR_CHAN(insn->chanspec);
+
+
+ switch(data[0])
+ {
+ case 0:
+ if (ui_Channel >= 0 && ui_Channel <=15)
+ {
+ ui_TmpValue=(UINT) inw(devpriv->i_IobaseAddon + APCI1500_DIGITAL_IP);
+ *data = (ui_TmpValue >> ui_Channel)&0x1 ;
+ }//if(ui_Channel >= 0 && ui_Channel <=15)
+ else
+ {
+ printk("\nThe channel specification are in error\n");
+ return -EINVAL; // "sorry channel spec wrong "
+ }//else if(ui_Channel >= 0 && ui_Channel <=15)
+ break;
+ case 1:
+
+ *data=(UINT)inw(devpriv->i_IobaseAddon + APCI1500_DIGITAL_IP );
+ switch (ui_Channel)
+ {
+ case 2:ui_Mask=3;
+ *data=(*data >>(2*ui_PortValue))&ui_Mask;
+ break;
+ case 4:ui_Mask=15;
+ *data=(*data >>(4*ui_PortValue))&ui_Mask;
+ break;
+ case 8:ui_Mask=255;
+ *data=(*data >>(8*ui_PortValue))&ui_Mask;
+ break;
+ case 15: break;
+
+ default:
+ printk("\nSpecified channel cannot be read \n");
+ return -EINVAL; // "sorry channel spec wrong "
+ break;
+ }//switch(ui_Channel)
+ break;
+ default:
+ printk("\nThe specified functionality does not exist\n");
+ return -EINVAL;
+ }//switch(data[0])
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_ConfigDigitalOutputErrorInterrupt
+ (comedi_device *dev,comedi_subdevice *s comedi_insn
+ *insn,lsampl_t *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : Configures the digital output memory and the digital
+ output error interrupt |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| lsampl_t *data : Data Pointer contains |
+| configuration parameters as below |
+| comedi_subdevice *s, :pointer to subdevice structure
+ comedi_insn *insn :pointer to insn structure |
+| data[0] :1:Memory on |
+| 0:Memory off |
+ data[1] :1 Enable the voltage error interrupt
+| :0 Disable the voltage error interrupt |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI1500_ConfigDigitalOutputErrorInterrupt(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+devpriv->b_OutputMemoryStatus=data[0];
+return insn->n;
+}
+
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_WriteDigitalOutput |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Writes port value To the selected port |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To Write |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1500_WriteDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+static UINT ui_Temp=0;
+UINT ui_Temp1;
+
+UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
+
+ if(!devpriv->b_OutputMemoryStatus )
+ {
+ ui_Temp=0;
+
+ }//if(!devpriv->b_OutputMemoryStatus )
+if(data[3]==0)
+ {
+ if(data[1]==0)
+ {
+ data[0]=(data[0] << ui_NoOfChannel)|ui_Temp;
+ outw(data[0],devpriv->i_IobaseAddon+APCI1500_DIGITAL_OP);
+ }//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 4:data[0]=(data[0] << (4*data[2]))|ui_Temp;
+ break;
+
+ case 8:
+ data[0]=(data[0] <<(8*data[2]))|ui_Temp;
+ break;
+
+ case 15:data[0]=data[0]|ui_Temp;
+ break;
+
+ default:
+ comedi_error(dev," chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+
+ }//switch(ui_NoOfChannels)
+
+ outw(data[0],devpriv->i_IobaseAddon+APCI1500_DIGITAL_OP);
+ }// 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)^0xffffffff;
+ data[0]=data[0]& ui_Temp;
+ outw(data[0],devpriv->i_IobaseAddon+APCI1500_DIGITAL_OP);
+ }//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]))^0xffffffff)& ui_Temp;
+ break;
+
+
+ case 4:data[0]=~data[0]&0xf;
+ ui_Temp1=15;
+ ui_Temp1=ui_Temp1<<4*data[2];
+ ui_Temp=ui_Temp|ui_Temp1;
+ data[0]=((data[0] << (4*data[2]))^0xffffffff)&ui_Temp;
+ break;
+
+ case 8:data[0]=~data[0]&0xff;
+ ui_Temp1=255;
+ ui_Temp1=ui_Temp1<<8*data[2];
+ ui_Temp=ui_Temp|ui_Temp1;
+ data[0]=((data[0] << (8*data[2]))^0xffffffff)&ui_Temp;
+ break;
+
+ case 15:break;
+
+
+ default:
+ comedi_error(dev," chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+
+ }//switch(ui_NoOfChannels)
+
+ outw(data[0],devpriv->i_IobaseAddon+APCI1500_DIGITAL_OP);
+ }// 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)
+ ui_Temp=data[0];
+ return (insn->n);;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_ConfigCounterTimerWatchdog(comedi_device
+ *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)|
+| |
++----------------------------------------------------------------------------+
+| Task : Configures The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s, :pointer to subdevice structure
+ comedi_insn *insn :pointer to insn structure |
+| lsampl_t *data : Data Pointer to read status data[0] : 2 APCI1500_1_8_KHZ
+| 1 APCI1500_3_6_KHZ |
+| 0 APCI1500_115_KHZ
+ data[1] : 0 Counter1/Timer1
+ 1 Counter2/Timer2
+ 2 Counter3/Watchdog
+ data[2] : 0 Counter
+ 1 Timer/Watchdog
+ data[3] : This parameter has |
+| two meanings. |
+| - If the counter/timer |
+| is used as a counter |
+| the limit value of |
+| the counter is given |
+| |
+| - If the counter/timer |
+| is used as a timer, |
+| the divider factor |
+| for the output is |
+| given.
+ data[4] : 0 APCI1500_CONTINUOUS
+ 1 APCI1500_SINGLE
+ data[5] : 0 Software Trigger
+ 1 Hardware Trigger
+
+ data[6] :0 Software gate
+ 1 Hardware gate
+ data[7] :0 Interrupt Disable
+ 1 Interrupt Enable
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI1500_ConfigCounterTimerWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+int i_TimerCounterMode,i_MasterConfiguration;
+
+ devpriv->tsk_Current=current;
+
+//Selection of the input clock
+if(data[0]==0||data[0]==1||data[0]==2)
+ {
+ outw(data[0],devpriv->i_IobaseAddon+APCI1500_CLK_SELECT);
+ }// if(data[0]==0||data[0]==1||data[0]==2)
+else
+ {
+ if(data[0]!=3)
+ {
+ printk("\nThe option for input clock selection does not exist\n");
+ return -EINVAL;
+ }// if(data[0]!=3)
+ }//elseif(data[0]==0||data[0]==1||data[0]==2)
+ //Select the counter/timer
+switch(data[1])
+ {
+ case COUNTER1:
+ //selecting counter or timer
+ switch(data[2])
+ {
+ case 0: data[2]=APCI1500_COUNTER ;
+ break;
+ case 1: data[2]=APCI1500_TIMER;
+ break;
+ default:printk("\nThis choice is not a timer nor a counter\n");
+ return -EINVAL;
+ }// switch(data[2])
+
+ //Selecting single or continuous mode
+ switch(data[4])
+ {
+ case 0: data[4]= APCI1500_CONTINUOUS;
+ break;
+ case 1: data[4]= APCI1500_SINGLE;
+ break;
+ default:printk("\nThis option for single/continuous mode does not exist\n");
+ return -EINVAL;
+ }// switch(data[4])
+
+
+ i_TimerCounterMode = data[2]|data[4]|7;
+ /*************************/
+ /* Test the reload value */
+ /*************************/
+
+ if ((data[3]>= 0) && (data[3] <= 65535))
+ {
+ if(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE)
+ {
+
+ /************************************************/
+ /* Selects the mode register of timer/counter 1 */
+ /************************************************/
+ outb(APCI1500_RW_CPT_TMR1_MODE_SPECIFICATION,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************/
+ /* Writes the new mode */
+ /***********************/
+ outb(i_TimerCounterMode,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /****************************************************/
+ /* Selects the constant register of timer/counter 1 */
+ /****************************************************/
+
+ outb(APCI1500_RW_CPT_TMR1_TIME_CST_LOW,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*************************/
+ /* Writes the low value */
+ /*************************/
+
+ outb( data[3],devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /****************************************************/
+ /* Selects the constant register of timer/counter 1 */
+ /****************************************************/
+
+ outb( APCI1500_RW_CPT_TMR1_TIME_CST_HIGH,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /**************************/
+ /* Writes the high value */
+ /**************************/
+
+ data[3]=data[3]>>8;
+ outb(data[3],devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*********************************************/
+ /* Selects the master configuration register */
+ /*********************************************/
+
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /**********************/
+ /* Reads the register */
+ /**********************/
+
+ i_MasterConfiguration=inb(devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /********************************************************/
+ /* Enables timer/counter 1 and triggers timer/counter 1 */
+ /********************************************************/
+
+ i_MasterConfiguration = i_MasterConfiguration | 0x40;
+
+ /*********************************************/
+ /* Selects the master configuration register */
+ /*********************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /********************************/
+ /* Writes the new configuration */
+ /********************************/
+ outb(i_MasterConfiguration,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /****************************************/
+ /* Selects the commands register of */
+ /* timer/counter 1 */
+ /****************************************/
+
+ outb( APCI1500_RW_CPT_TMR1_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /***************************/
+ /* Disable timer/counter 1 */
+ /***************************/
+
+ outb(0x0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /****************************************/
+ /* Selects the commands register of */
+ /* timer/counter 1 */
+ /****************************************/
+ outb( APCI1500_RW_CPT_TMR1_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /***************************/
+ /* Trigger timer/counter 1 */
+ /***************************/
+ outb(0x2,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ }//if(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE)
+ else
+ {
+ printk("\nError in selection of interrupt enable or disable\n");
+ return -EINVAL;
+ }//elseif(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE)
+ }// if ((data[3]>= 0) && (data[3] <= 65535))
+ else
+ {
+ printk("\nError in selection of reload value\n");
+ return -EINVAL;
+ }//else if ((data[3]>= 0) && (data[3] <= 65535))
+ i_TimerCounterWatchdogInterrupt=data[7];
+ i_TimerCounter1Init=1;
+ break;
+
+
+
+ case COUNTER2: //selecting counter or timer
+ switch(data[2])
+ {
+ case 0: data[2]=APCI1500_COUNTER ;
+ break;
+ case 1: data[2]=APCI1500_TIMER;
+ break;
+ default:printk("\nThis choice is not a timer nor a counter\n");
+ return -EINVAL;
+ }// switch(data[2])
+
+ //Selecting single or continuous mode
+ switch(data[4])
+ {
+ case 0: data[4]= APCI1500_CONTINUOUS;
+ break;
+ case 1: data[4]= APCI1500_SINGLE;
+ break;
+ default:printk("\nThis option for single/continuous mode does not exist\n");
+ return -EINVAL;
+ }// switch(data[4])
+
+ //Selecting software or hardware trigger
+ switch(data[5])
+ {
+ case 0: data[5]= APCI1500_SOFTWARE_TRIGGER ;
+ break;
+ case 1: data[5]= APCI1500_HARDWARE_TRIGGER ;
+ break;
+ default:printk("\nThis choice for software or hardware trigger does not exist\n");
+ return -EINVAL;
+ }// switch(data[5])
+
+ //Selecting software or hardware gate
+ switch(data[6])
+ {
+ case 0: data[6]= APCI1500_SOFTWARE_GATE ;
+ break;
+ case 1: data[6]= APCI1500_HARDWARE_GATE ;
+ break;
+ default:printk("\nThis choice for software or hardware gate does not exist\n");
+ return -EINVAL;
+ }// switch(data[6])
+
+
+ i_TimerCounterMode=data[2]|data[4]|data[5]|data[6]|7;
+
+ /*************************/
+ /* Test the reload value */
+ /*************************/
+
+ if ((data[3]>= 0) && (data[3] <= 65535))
+ {
+ if(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE)
+ {
+
+ /************************************************/
+ /* Selects the mode register of timer/counter 2 */
+ /************************************************/
+ outb( APCI1500_RW_CPT_TMR2_MODE_SPECIFICATION,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************/
+ /* Writes the new mode */
+ /***********************/
+ outb(i_TimerCounterMode,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /****************************************************/
+ /* Selects the constant register of timer/counter 2 */
+ /****************************************************/
+
+ outb(APCI1500_RW_CPT_TMR2_TIME_CST_LOW,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*************************/
+ /* Writes the low value */
+ /*************************/
+
+ outb( data[3],devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /****************************************************/
+ /* Selects the constant register of timer/counter 2 */
+ /****************************************************/
+
+ outb(APCI1500_RW_CPT_TMR2_TIME_CST_HIGH,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /**************************/
+ /* Writes the high value */
+ /**************************/
+
+ data[3]=data[3]>>8;
+ outb(data[3],devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*********************************************/
+ /* Selects the master configuration register */
+ /*********************************************/
+
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /**********************/
+ /* Reads the register */
+ /**********************/
+
+ i_MasterConfiguration=inb(devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /********************************************************/
+ /* Enables timer/counter 2 and triggers timer/counter 2 */
+ /********************************************************/
+
+ i_MasterConfiguration = i_MasterConfiguration | 0x20;
+
+ /*********************************************/
+ /* Selects the master configuration register */
+ /*********************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /********************************/
+ /* Writes the new configuration */
+ /********************************/
+ outb(i_MasterConfiguration,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /****************************************/
+ /* Selects the commands register of */
+ /* timer/counter 2 */
+ /****************************************/
+
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /***************************/
+ /* Disable timer/counter 2 */
+ /***************************/
+
+ outb(0x0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /****************************************/
+ /* Selects the commands register of */
+ /* timer/counter 2 */
+ /****************************************/
+ outb( APCI1500_RW_CPT_TMR2_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /***************************/
+ /* Trigger timer/counter 1 */
+ /***************************/
+ outb(0x2,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ }//if(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE)
+ else
+ {
+ printk("\nError in selection of interrupt enable or disable\n");
+ return -EINVAL;
+ }//elseif(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE)
+ }// if ((data[3]>= 0) && (data[3] <= 65535))
+ else
+ {
+ printk("\nError in selection of reload value\n");
+ return -EINVAL;
+ }//else if ((data[3]>= 0) && (data[3] <= 65535))
+ i_TimerCounterWatchdogInterrupt=data[7];
+ i_TimerCounter2Init=1;
+ break;
+
+
+
+
+ case COUNTER3://selecting counter or watchdog
+ switch(data[2])
+ {
+ case 0: data[2]=APCI1500_COUNTER ;
+ break;
+ case 1: data[2]= APCI1500_WATCHDOG;
+ break;
+ default:printk("\nThis choice is not a watchdog nor a counter\n");
+ return -EINVAL;
+ }// switch(data[2])
+
+ //Selecting single or continuous mode
+ switch(data[4])
+ {
+ case 0: data[4]= APCI1500_CONTINUOUS;
+ break;
+ case 1: data[4]= APCI1500_SINGLE;
+ break;
+ default:printk("\nThis option for single/continuous mode does not exist\n");
+ return -EINVAL;
+ }// switch(data[4])
+
+
+
+
+ //Selecting software or hardware gate
+ switch(data[6])
+ {
+ case 0: data[6]= APCI1500_SOFTWARE_GATE ;
+ break;
+ case 1: data[6]= APCI1500_HARDWARE_GATE ;
+ break;
+ default:printk("\nThis choice for software or hardware gate does not exist\n");
+ return -EINVAL;
+ }// switch(data[6])
+
+
+
+ /*****************************/
+ /* Test if used for watchdog */
+ /*****************************/
+
+ if (data[2] == APCI1500_WATCHDOG)
+ {
+ /*****************************/
+ /* - Enables the output line */
+ /* - Enables retrigger */
+ /* - Pulses output */
+ /*****************************/
+ i_TimerCounterMode=data[2]|data[4]|0x54;
+ }//if (data[2] == APCI1500_WATCHDOG)
+ else
+ {
+ i_TimerCounterMode=data[2]|data[4]|data[6]|7;
+ }//elseif (data[2] == APCI1500_WATCHDOG)
+ /*************************/
+ /* Test the reload value */
+ /*************************/
+
+ if ((data[3]>= 0) && (data[3] <= 65535))
+ {
+ if(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE)
+ {
+
+ /************************************************/
+ /* Selects the mode register of watchdog/counter 3 */
+ /************************************************/
+ outb(APCI1500_RW_CPT_TMR3_MODE_SPECIFICATION,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************/
+ /* Writes the new mode */
+ /***********************/
+ outb(i_TimerCounterMode,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /****************************************************/
+ /* Selects the constant register of watchdog/counter 3 */
+ /****************************************************/
+
+ outb(APCI1500_RW_CPT_TMR3_TIME_CST_LOW,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*************************/
+ /* Writes the low value */
+ /*************************/
+
+ outb( data[3],devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /****************************************************/
+ /* Selects the constant register of watchdog/counter 3 */
+ /****************************************************/
+
+ outb(APCI1500_RW_CPT_TMR3_TIME_CST_HIGH,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /**************************/
+ /* Writes the high value */
+ /**************************/
+
+ data[3]=data[3]>>8;
+ outb(data[3],devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*********************************************/
+ /* Selects the master configuration register */
+ /*********************************************/
+
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /**********************/
+ /* Reads the register */
+ /**********************/
+
+ i_MasterConfiguration=inb(devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /********************************************************/
+ /* Enables watchdog/counter 3 and triggers watchdog/counter 3 */
+ /********************************************************/
+
+ i_MasterConfiguration = i_MasterConfiguration | 0x10;
+
+ /*********************************************/
+ /* Selects the master configuration register */
+ /*********************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /********************************/
+ /* Writes the new configuration */
+ /********************************/
+ outb(i_MasterConfiguration,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /********************/
+ /* Test if COUNTER */
+ /********************/
+ if(data[2]==APCI1500_COUNTER)
+ {
+
+ /*************************************/
+ /* Selects the command register of */
+ /* watchdog/counter 3 */
+ /*************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /*************************************************/
+ /* Disable the watchdog/counter 3 and starts it */
+ /*************************************************/
+ outb(0x0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*************************************/
+ /* Selects the command register of */
+ /* watchdog/counter 3 */
+ /*************************************/
+
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /*************************************************/
+ /* Trigger the watchdog/counter 3 and starts it */
+ /*************************************************/
+ outb(0x2,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ }//elseif(data[2]==APCI1500_COUNTER)
+
+
+ }//if(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE)
+ else
+ {
+ printk("\nError in selection of interrupt enable or disable\n");
+ return -EINVAL;
+ }//elseif(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE)
+ }// if ((data[3]>= 0) && (data[3] <= 65535))
+ else
+ {
+ printk("\nError in selection of reload value\n");
+ return -EINVAL;
+ }//else if ((data[3]>= 0) && (data[3] <= 65535))
+ i_TimerCounterWatchdogInterrupt=data[7];
+ i_WatchdogCounter3Init=1;
+ break;
+
+ default:printk("\nThe specified counter\timer option does not exist\n");
+ }//switch(data[1])
+i_CounterLogic=data[2];
+return insn->n;
+}
+
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_StartStopTriggerTimerCounterWatchdog |
+| (comedi_device *dev,comedi_subdevice *s,
+ comedi_insn *insn,lsampl_t *data); |
++----------------------------------------------------------------------------+
+| Task : Start / Stop or trigger the timer counter or Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s, :pointer to subdevice structure
+ comedi_insn *insn :pointer to insn structure |
+| lsampl_t *data : Data Pointer to read status |
+ data[0] : 0 Counter1/Timer1
+ 1 Counter2/Timer2
+ 2 Counter3/Watchdog
+ data[1] : 0 start
+ 1 stop
+ 2 Trigger
+ data[2] : 0 Counter
+ 1 Timer/Watchdog
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI1500_StartStopTriggerTimerCounterWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+int i_CommandAndStatusValue;
+
+switch(data[0])
+ {
+ case COUNTER1:
+ switch(data[1])
+ {
+ case START:
+ if( i_TimerCounter1Init==1)
+ {
+ if(i_TimerCounterWatchdogInterrupt==1)
+ {
+ i_CommandAndStatusValue = 0xC4;//Enable the interrupt
+ }// if(i_TimerCounterWatchdogInterrupt==1)
+ else
+ {
+ i_CommandAndStatusValue =0xE4;//disable the interrupt
+ }//elseif(i_TimerCounterWatchdogInterrupt==1)
+ /**************************/
+ /* Starts timer/counter 1 */
+ /**************************/
+ i_TimerCounter1Enabled=1;
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb( APCI1500_RW_CPT_TMR1_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_CommandAndStatusValue ,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ }//if( i_TimerCounter1Init==1)
+ else
+ {
+ printk("\nCounter/Timer1 not configured\n");
+ return -EINVAL;
+ }
+ break;
+
+ case STOP :
+
+
+ /**************************/
+ /* Stop timer/counter 1 */
+ /**************************/
+
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb( APCI1500_RW_CPT_TMR1_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0x00,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_TimerCounter1Enabled=0;
+ break;
+
+ case TRIGGER:
+ if( i_TimerCounter1Init==1)
+ {
+ if( i_TimerCounter1Enabled==1)
+ {
+ /************************/
+ /* Set Trigger and gate */
+ /************************/
+
+ i_CommandAndStatusValue = 0x6;
+ }//if( i_TimerCounter1Enabled==1)
+ else
+ {
+ /***************/
+ /* Set Trigger */
+ /***************/
+
+ i_CommandAndStatusValue = 0x2;
+ }//elseif(i_TimerCounter1Enabled==1)
+
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb( APCI1500_RW_CPT_TMR1_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_CommandAndStatusValue ,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ }//if( i_TimerCounter1Init==1)
+ else
+ {
+ printk("\nCounter/Timer1 not configured\n");
+ return -EINVAL;
+ }
+ break;
+
+ default :printk("\nThe specified option for start/stop/trigger does not exist\n");
+ return -EINVAL;
+ }//switch(data[1])
+ break;
+
+ case COUNTER2:
+ switch(data[1])
+ {
+ case START:
+ if( i_TimerCounter2Init==1)
+ {
+ if(i_TimerCounterWatchdogInterrupt==1)
+ {
+ i_CommandAndStatusValue = 0xC4;//Enable the interrupt
+ }// if(i_TimerCounterWatchdogInterrupt==1)
+ else
+ {
+ i_CommandAndStatusValue =0xE4;//disable the interrupt
+ }//elseif(i_TimerCounterWatchdogInterrupt==1)
+ /**************************/
+ /* Starts timer/counter 2 */
+ /**************************/
+ i_TimerCounter2Enabled=1;
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb( APCI1500_RW_CPT_TMR2_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_CommandAndStatusValue ,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ }//if( i_TimerCounter2Init==1)
+ else
+ {
+ printk("\nCounter/Timer2 not configured\n");
+ return -EINVAL;
+ }
+ break;
+
+ case STOP :
+
+
+ /**************************/
+ /* Stop timer/counter 2 */
+ /**************************/
+
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb( APCI1500_RW_CPT_TMR2_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0x00 ,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_TimerCounter2Enabled=0;
+ break;
+ case TRIGGER:
+ if( i_TimerCounter2Init==1)
+ {
+ if( i_TimerCounter2Enabled==1)
+ {
+ /************************/
+ /* Set Trigger and gate */
+ /************************/
+
+ i_CommandAndStatusValue = 0x6;
+ }//if( i_TimerCounter2Enabled==1)
+ else
+ {
+ /***************/
+ /* Set Trigger */
+ /***************/
+
+ i_CommandAndStatusValue = 0x2;
+ }//elseif(i_TimerCounter2Enabled==1)
+
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb( APCI1500_RW_CPT_TMR2_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_CommandAndStatusValue ,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ }//if( i_TimerCounter2Init==1)
+ else
+ {
+ printk("\nCounter/Timer2 not configured\n");
+ return -EINVAL;
+ }
+ break;
+ default :printk("\nThe specified option for start/stop/trigger does not exist\n");
+ return -EINVAL;
+ }//switch(data[1])
+ break;
+ case COUNTER3:
+ switch(data[1])
+ {
+ case START:
+ if( i_WatchdogCounter3Init==1)
+ {
+
+ if(i_TimerCounterWatchdogInterrupt==1)
+ {
+ i_CommandAndStatusValue = 0xC4;//Enable the interrupt
+ }// if(i_TimerCounterWatchdogInterrupt==1)
+ else
+ {
+ i_CommandAndStatusValue =0xE4;//disable the interrupt
+ }//elseif(i_TimerCounterWatchdogInterrupt==1)
+ /**************************/
+ /* Starts Watchdog/counter 3 */
+ /**************************/
+ i_WatchdogCounter3Enabled=1;
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb( APCI1500_RW_CPT_TMR3_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_CommandAndStatusValue ,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ }// if( i_WatchdogCounter3init==1)
+ else
+ {
+ printk("\nWatchdog/Counter3 not configured\n");
+ return -EINVAL;
+ }
+ break;
+
+ case STOP :
+
+
+ /**************************/
+ /* Stop Watchdog/counter 3 */
+ /**************************/
+
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb( APCI1500_RW_CPT_TMR3_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0x00 ,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_WatchdogCounter3Enabled=0;
+ break;
+
+ case TRIGGER:
+ switch(data[2])
+ {
+ case 0://triggering counter 3
+ if( i_WatchdogCounter3Init==1)
+ {
+ if( i_WatchdogCounter3Enabled==1)
+ {
+ /************************/
+ /* Set Trigger and gate */
+ /************************/
+
+ i_CommandAndStatusValue = 0x6;
+ }//if( i_WatchdogCounter3Enabled==1)
+ else
+ {
+ /***************/
+ /* Set Trigger */
+ /***************/
+
+ i_CommandAndStatusValue = 0x2;
+ }//elseif(i_WatchdogCounter3Enabled==1)
+
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_CommandAndStatusValue ,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ }//if( i_WatchdogCounter3Init==1)
+ else
+ {
+ printk("\nCounter3 not configured\n");
+ return -EINVAL;
+ }
+ break;
+ case 1 :
+ //triggering Watchdog 3
+ if( i_WatchdogCounter3Init==1)
+ {
+
+
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0x6 ,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ }//if( i_WatchdogCounter3Init==1)
+ else
+ {
+ printk("\nWatchdog 3 not configured\n");
+ return -EINVAL;
+ }
+ break;
+ default :printk("\nWrong choice of watchdog/counter3\n");
+ return -EINVAL;
+ }//switch(data[2])
+ break;
+ default:printk("\nThe specified option for start/stop/trigger does not exist\n");
+ return -EINVAL;
+ }//switch(data[1])
+ break;
+ default : printk("\nThe specified choice for counter/watchdog/timer does not exist\n");
+ return -EINVAL;
+ }//switch(data[0])
+return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_ReadCounterTimerWatchdog |
+| (comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,
+ lsampl_t *data); |
++----------------------------------------------------------------------------+
+| Task : Read The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s, :pointer to subdevice structure
+ comedi_insn *insn :pointer to insn structure |
+| lsampl_t *data : Data Pointer to read status |
+ data[0] : 0 Counter1/Timer1
+ 1 Counter2/Timer2
+ 2 Counter3/Watchdog
+
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI1500_ReadCounterTimerWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ int i_CommandAndStatusValue;
+switch(data[0])
+ {
+ case COUNTER1:
+ //Read counter/timer1
+ if( i_TimerCounter1Init==1)
+ {
+ if( i_TimerCounter1Enabled==1)
+ {
+ /************************/
+ /* Set RCC and gate */
+ /************************/
+
+ i_CommandAndStatusValue = 0xC;
+ }//if( i_TimerCounter1Init==1)
+ else
+ {
+ /***************/
+ /* Set RCC */
+ /***************/
+
+ i_CommandAndStatusValue = 0x8;
+ }//elseif(i_TimerCounter1Init==1)
+
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb( APCI1500_RW_CPT_TMR1_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_CommandAndStatusValue ,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /***************************************/
+ /* Selects the counter register (high) */
+ /***************************************/
+ outb(APCI1500_R_CPT_TMR1_VALUE_HIGH,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ data[0]=inb(devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ data[0]=data[0]<<8;
+ data[0]=data[0]&0xff00;
+ outb(APCI1500_R_CPT_TMR1_VALUE_LOW,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ data[0]=data[0]|inb(devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ }//if( i_TimerCounter1Init==1)
+ else
+ {
+ printk("\nTimer/Counter1 not configured\n");
+ return -EINVAL;
+ }//elseif( i_TimerCounter1Init==1)
+ break;
+ case COUNTER2 :
+ //Read counter/timer2
+ if( i_TimerCounter2Init==1)
+ {
+ if( i_TimerCounter2Enabled==1)
+ {
+ /************************/
+ /* Set RCC and gate */
+ /************************/
+
+ i_CommandAndStatusValue = 0xC;
+ }//if( i_TimerCounter2Init==1)
+ else
+ {
+ /***************/
+ /* Set RCC */
+ /***************/
+
+ i_CommandAndStatusValue = 0x8;
+ }//elseif(i_TimerCounter2Init==1)
+
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb( APCI1500_RW_CPT_TMR2_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_CommandAndStatusValue ,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /***************************************/
+ /* Selects the counter register (high) */
+ /***************************************/
+ outb(APCI1500_R_CPT_TMR2_VALUE_HIGH,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ data[0]=inb(devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ data[0]=data[0]<<8;
+ data[0]=data[0]&0xff00;
+ outb(APCI1500_R_CPT_TMR2_VALUE_LOW,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ data[0]=data[0]|inb(devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ }//if( i_TimerCounter2Init==1)
+ else
+ {
+ printk("\nTimer/Counter2 not configured\n");
+ return -EINVAL;
+ }//elseif( i_TimerCounter2Init==1)
+ break;
+ case COUNTER3:
+ //Read counter/watchdog2
+ if( i_WatchdogCounter3Init==1)
+ {
+ if( i_WatchdogCounter3Enabled==1)
+ {
+ /************************/
+ /* Set RCC and gate */
+ /************************/
+
+ i_CommandAndStatusValue = 0xC;
+ }//if( i_TimerCounter2Init==1)
+ else
+ {
+ /***************/
+ /* Set RCC */
+ /***************/
+
+ i_CommandAndStatusValue = 0x8;
+ }//elseif(i_WatchdogCounter3Init==1)
+
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_CommandAndStatusValue ,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /***************************************/
+ /* Selects the counter register (high) */
+ /***************************************/
+ outb( APCI1500_R_CPT_TMR3_VALUE_HIGH,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ data[0]=inb(devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ data[0]=data[0]<<8;
+ data[0]=data[0]&0xff00;
+ outb(APCI1500_R_CPT_TMR3_VALUE_LOW,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ data[0]=data[0]|inb(devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ }//if( i_WatchdogCounter3Init==1)
+ else
+ {
+ printk("\nWatchdogCounter3 not configured\n");
+ return -EINVAL;
+ }//elseif( i_WatchdogCounter3Init==1)
+ break;
+ default :
+ printk("\nThe choice of timer/counter/watchdog does not exist\n");
+ return -EINVAL;
+ }//switch(data[0])
+
+
+return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_ReadInterruptMask |
+| (comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,
+ lsampl_t *data); |
++----------------------------------------------------------------------------+
+| Task : Read the interrupt mask |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s, :pointer to subdevice structure
+ comedi_insn *insn :pointer to insn structure |
+| lsampl_t *data : Data Pointer to read status |
+
+
++----------------------------------------------------------------------------+
+| Output Parameters : -- data[0]:The interrupt mask value data[1]:Channel no
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI1500_ReadInterruptMask(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ data[0]=i_InterruptMask;
+ data[1]=i_InputChannel;
+ i_InterruptMask=0;
+ return insn->n;
+}
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_ConfigureInterrupt |
+| (comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,
+ lsampl_t *data); |
++----------------------------------------------------------------------------+
+| Task : Configures the interrupt registers |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s, :pointer to subdevice structure
+ comedi_insn *insn :pointer to insn structure |
+| lsampl_t *data : Data Pointer |
+
+
++----------------------------------------------------------------------------+
+| Output Parameters : --
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI1500_ConfigureInterrupt(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ UINT ui_Status;
+int i_RegValue;
+int i_Constant;
+devpriv->tsk_Current=current;
+outl(0x0,devpriv->i_IobaseAmcc+0x38);
+if(data[0]==1)
+ {
+ i_Constant=0xC0;
+ }//if(data[0]==1)
+else
+ {
+ if(data[0]==0)
+ {
+ i_Constant=0x00;
+ }//if{data[0]==0)
+ else
+ {
+ printk("\nThe parameter passed to driver is in error for enabling the voltage interrupt\n");
+ return -EINVAL;
+ }//else if(data[0]==0)
+ }//elseif(data[0]==1)
+
+
+ /*****************************************************/
+ /* Selects the mode specification register of port B */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_B_SPECIFICATION,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue=inb(devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(APCI1500_RW_PORT_B_SPECIFICATION,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /*********************************************/
+ /* Writes the new configuration (APCI1500_OR) */
+ /*********************************************/
+ i_RegValue =(i_RegValue & 0xF9) | APCI1500_OR;
+
+ outb(i_RegValue,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************************************************/
+ /* Selects the command and status register of port B */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************************************/
+ /* Authorises the interrupt on the board */
+ /*****************************************/
+ outb(0xC0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /***************************************************/
+ /* Selects the pattern polarity register of port B */
+ /***************************************************/
+ outb(APCI1500_RW_PORT_B_PATTERN_POLARITY,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_Constant,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************************************************/
+ /* Selects the pattern transition register of port B */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_B_PATTERN_TRANSITION,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_Constant ,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************************/
+ /* Selects the pattern mask register of port B */
+ /***********************************************/
+ outb( APCI1500_RW_PORT_B_PATTERN_MASK,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_Constant ,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the command and status register of port A */
+ /*****************************************************/
+ outb( APCI1500_RW_PORT_A_COMMAND_AND_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue=inb(devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb( APCI1500_RW_PORT_A_COMMAND_AND_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************/
+ /* Deletes the interrupt of port A */
+ /***********************************/
+
+ i_RegValue=(i_RegValue & 0x0F)| 0x20;
+ outb(i_RegValue,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************************************************/
+ /* Selects the command and status register of port B */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue=inb(devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************/
+ /* Deletes the interrupt of port B */
+ /***********************************/
+
+ i_RegValue=(i_RegValue & 0x0F)| 0x20;
+ outb(i_RegValue,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the command and status register of timer 1*/
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue=inb(devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************/
+ /* Deletes the interrupt of timer 1 */
+ /***********************************/
+
+ i_RegValue=(i_RegValue & 0x0F)| 0x20;
+ outb(i_RegValue,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the command and status register of timer 2*/
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue=inb(devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************/
+ /* Deletes the interrupt of timer 2 */
+ /***********************************/
+
+ i_RegValue=(i_RegValue & 0x0F)| 0x20;
+ outb(i_RegValue,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+
+ /*****************************************************/
+ /* Selects the command and status register of timer 3*/
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue=inb(devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb( APCI1500_RW_CPT_TMR3_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************/
+ /* Deletes the interrupt of timer 3 */
+ /***********************************/
+
+ i_RegValue=(i_RegValue & 0x0F)| 0x20;
+ outb(i_RegValue,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*************************************************/
+ /* Selects the master interrupt control register */
+ /*************************************************/
+ outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /**********************************************/
+ /* Authorizes the main interrupt on the board */
+ /**********************************************/
+ outb(0xD0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+
+ /***************************/
+ /* Enables the PCI interrupt */
+ /*****************************/
+ outl(0x3000,devpriv->i_IobaseAmcc+0x38);
+ ui_Status=inl(devpriv->i_IobaseAmcc+0x10);
+ ui_Status=inl(devpriv->i_IobaseAmcc+0x38);
+ outl(0x23000,devpriv->i_IobaseAmcc+0x38);
+
+
+return insn->n;
+}
+
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : static void v_APCI1500_Interrupt |
+| (int irq , void *d, struct pt_regs *regs) |
++----------------------------------------------------------------------------+
+| Task : Interrupt handler |
++----------------------------------------------------------------------------+
+| Input Parameters : int irq : irq number |
+| void *d : void pointer |
+| struct pt_regs *regs : structure pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+static VOID v_APCI1500_Interrupt(int irq,void* d, struct pt_regs *regs)
+{
+
+ comedi_device *dev =d;
+ UINT ui_InterruptStatus=0;
+ int i_RegValue=0;
+ i_InterruptMask=0;
+
+ /***********************************/
+ /* Read the board interrupt status */
+ /***********************************/
+ ui_InterruptStatus=inl(devpriv->i_IobaseAmcc+0x38);
+
+ /***************************************/
+ /* Test if board generated a interrupt */
+ /***************************************/
+ if ((ui_InterruptStatus & 0x800000) == 0x800000)
+ {
+ /************************/
+ /* Disable all Interrupt*/
+ /************************/
+ /*************************************************/
+ /* Selects the master interrupt control register */
+ /*************************************************/
+ //outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /**********************************************/
+ /* Disables the main interrupt on the board */
+ /**********************************************/
+ //outb(0x00,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the command and status register of port A */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue=inb(devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ if ((i_RegValue & 0x60) == 0x60)
+ {
+ /*****************************************************/
+ /* Selects the command and status register of port A */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************/
+ /* Deletes the interrupt of port A */
+ /***********************************/
+ i_RegValue = (i_RegValue & 0x0F) | 0x20;
+ outb(i_RegValue,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_InterruptMask=i_InterruptMask | 1;
+ if(i_Logic==APCI1500_OR_PRIORITY)
+ {
+ outb(APCI1500_RW_PORT_A_SPECIFICATION,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue=inb(devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /***************************************************/
+ /* Selects the interrupt vector register of port A */
+ /***************************************************/
+ outb(APCI1500_RW_PORT_A_INTERRUPT_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue=inb(devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ i_InputChannel = 1 + (i_RegValue >> 1);
+
+ }// if(i_Logic==APCI1500_OR_PRIORITY)
+ else
+ {
+ i_InputChannel=0;
+ }//elseif(i_Logic==APCI1500_OR_PRIORITY)
+ }// if ((i_RegValue & 0x60) == 0x60)
+
+ /*****************************************************/
+ /* Selects the command and status register of port B*/
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue=inb(devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ if ((i_RegValue & 0x60) == 0x60)
+ {
+ /*****************************************************/
+ /* Selects the command and status register of port B */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************/
+ /* Deletes the interrupt of port B */
+ /***********************************/
+ i_RegValue = (i_RegValue & 0x0F) | 0x20;
+ outb(i_RegValue,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ printk("\n\n\n");
+ /****************/
+ /* Reads port B */
+ /****************/
+ i_RegValue=inb((UINT)devpriv->iobase+APCI1500_Z8536_PORT_B);
+
+ i_RegValue = i_RegValue & 0xC0;
+ /**************************************/
+ /* Tests if this is an external error */
+ /**************************************/
+
+ if (i_RegValue)
+ {
+ //Disable the interrupt
+ /*****************************************************/
+ /* Selects the command and status register of port B */
+ /*****************************************************/
+ outl(0x0,devpriv->i_IobaseAmcc+0x38);
+
+
+ if (i_RegValue & 0x80)
+ {
+ i_InterruptMask = i_InterruptMask | 0x40;
+ }//if (i_RegValue & 0x80)
+
+ if (i_RegValue & 0x40)
+ {
+ i_InterruptMask = i_InterruptMask | 0x80;
+ }//if (i_RegValue & 0x40)
+ }// if (i_RegValue)
+ else
+ {
+ i_InterruptMask = i_InterruptMask | 2;
+ }// if (i_RegValue)
+ }//if ((i_RegValue & 0x60) == 0x60)
+
+ /*****************************************************/
+ /* Selects the command and status register of timer 1*/
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue=inb(devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ if ((i_RegValue & 0x60) == 0x60)
+ {
+ /*****************************************************/
+ /* Selects the command and status register of timer 1 */
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************/
+ /* Deletes the interrupt of timer 1*/
+ /***********************************/
+ i_RegValue = (i_RegValue & 0x0F) | 0x20;
+ outb(i_RegValue,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_InterruptMask = i_InterruptMask | 4;
+ } // if ((i_RegValue & 0x60) == 0x60)
+ /*****************************************************/
+ /* Selects the command and status register of timer 2*/
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue=inb(devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ if ((i_RegValue & 0x60) == 0x60)
+ {
+ /*****************************************************/
+ /* Selects the command and status register of timer 2 */
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************/
+ /* Deletes the interrupt of timer 2*/
+ /***********************************/
+ i_RegValue = (i_RegValue & 0x0F) | 0x20;
+ outb(i_RegValue,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_InterruptMask = i_InterruptMask | 8;
+ } // if ((i_RegValue & 0x60) == 0x60)
+
+ /*****************************************************/
+ /* Selects the command and status register of timer 3*/
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue=inb(devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ if ((i_RegValue & 0x60) == 0x60)
+ {
+ /*****************************************************/
+ /* Selects the command and status register of timer 3 */
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************/
+ /* Deletes the interrupt of timer 3*/
+ /***********************************/
+ i_RegValue = (i_RegValue & 0x0F) | 0x20;
+ outb(i_RegValue,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ if(i_CounterLogic==APCI1500_COUNTER)
+ {
+ i_InterruptMask = i_InterruptMask | 0x10;
+ }//if(i_CounterLogic==APCI1500_COUNTER)
+ else
+ {
+ i_InterruptMask =i_InterruptMask | 0x20;
+ }
+ } // if ((i_RegValue & 0x60) == 0x60)
+
+ send_sig(SIGIO,devpriv->tsk_Current,0); // send signal to the sample
+ /***********************/
+ /* Enable all Interrupts */
+ /***********************/
+
+ /*************************************************/
+ /* Selects the master interrupt control register */
+ /*************************************************/
+ outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /**********************************************/
+ /* Authorizes the main interrupt on the board */
+ /**********************************************/
+ outb(0xD0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ }// if ((ui_InterruptStatus & 0x800000) == 0x800000)
+ else
+ {
+ printk("\nInterrupt from unknown source\n");
+
+ }//else if ((ui_InterruptStatus & 0x800000) == 0x800000)
+return;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_Reset(comedi_device *dev) | |
++----------------------------------------------------------------------------+
+| Task :resets all the registers |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1500_Reset(comedi_device *dev)
+{
+int i_DummyRead=0;
+i_TimerCounter1Init=0;
+i_TimerCounter2Init=0;
+i_WatchdogCounter3Init=0;
+i_Event1Status=0;
+i_Event2Status=0;
+i_TimerCounterWatchdogInterrupt=0;
+i_Logic=0;
+i_CounterLogic=0;
+i_InterruptMask=0;
+i_InputChannel=0;;
+ i_TimerCounter1Enabled=0;
+ i_TimerCounter2Enabled=0;
+i_WatchdogCounter3Enabled=0;
+
+
+ /******************/
+ /* Software reset */
+ /******************/
+ i_DummyRead=inb(devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ i_DummyRead=inb(devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(1,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the master configuration control register */
+ /*****************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0xF4,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the mode specification register of port A */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_A_SPECIFICATION,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0x10,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /* Selects the data path polarity register of port A */
+ outb( APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* High level of port A means 1 */
+ outb(0xFF,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /* Selects the data direction register of port A */
+ outb(APCI1500_RW_PORT_A_DATA_DIRECTION,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* All bits used as inputs */
+ outb(0xFF,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of port A */
+ outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes IP and IUS */
+ outb(0x20,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of port A */
+ outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deactivates the interrupt management of port A: */
+ outb(0xE0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the handshake specification register of port A */
+ outb(APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes the register */
+ outb(0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the mode specification register of port B */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_B_SPECIFICATION,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0x10,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the data path polarity register of port B */
+ outb(APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* A high level of port B means 1 */
+ outb(0x7F,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the data direction register of port B */
+ outb(APCI1500_RW_PORT_B_DATA_DIRECTION,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* All bits used as inputs */
+ outb(0xFF,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of port B */
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes IP and IUS */
+ outb(0x20,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of port B */
+ outb( APCI1500_RW_PORT_B_COMMAND_AND_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deactivates the interrupt management of port B: */
+ outb(0xE0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the handshake specification register of port B */
+ outb(APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes the register */
+ outb(0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the data path polarity register of port C */
+ /*****************************************************/
+ outb( APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* High level of port C means 1 */
+ outb(0x9,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the data direction register of port C */
+ outb(APCI1500_RW_PORT_C_DATA_DIRECTION,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* All bits used as inputs except channel 1 */
+ outb(0x0E,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the special IO register of port C */
+ outb( APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes it */
+ outb(0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /******************************************************/
+ /* Selects the command and status register of timer 1 */
+ /******************************************************/
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes IP and IUS */
+ outb(0x20,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of timer 1 */
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deactivates the interrupt management of timer 1 */
+ outb(0xE0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /******************************************************/
+ /* Selects the command and status register of timer 2 */
+ /******************************************************/
+ outb( APCI1500_RW_CPT_TMR2_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes IP and IUS */
+ outb(0x20,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of timer 2 */
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deactivates Timer 2 interrupt management: */
+ outb(0xE0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /******************************************************/
+ /* Selects the command and status register of timer 3 */
+ /******************************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes IP and IUS */
+ outb(0x20,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of Timer 3 */
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deactivates interrupt management of timer 3: */
+ outb(0xE0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /*************************************************/
+ /* Selects the master interrupt control register */
+ /*************************************************/
+ outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes all interrupts */
+ outb(0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ //reset all the digital outputs
+outw(0x0,devpriv->i_IobaseAddon+APCI1500_DIGITAL_OP);
+/*******************************/
+/* Disable the board interrupt */
+/*******************************/
+ /*************************************************/
+ /* Selects the master interrupt control register */
+ /*************************************************/
+outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+/****************************/
+/* Deactivates all interrupts */
+/******************************/
+outb(0,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************************************************/
+ /* Selects the command and status register of port A */
+ /*****************************************************/
+outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+/****************************/
+/* Deactivates all interrupts */
+/******************************/
+outb(0x00,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+/*****************************************************/
+ /* Selects the command and status register of port B */
+ /*****************************************************/
+outb( APCI1500_RW_PORT_B_COMMAND_AND_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+/****************************/
+/* Deactivates all interrupts */
+/******************************/
+outb(0x00,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+/*****************************************************/
+ /* Selects the command and status register of timer 1*/
+ /*****************************************************/
+outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+/****************************/
+/* Deactivates all interrupts */
+/******************************/
+outb(0x00,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+/*****************************************************/
+ /* Selects the command and status register of timer 2*/
+ /*****************************************************/
+outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+/****************************/
+/* Deactivates all interrupts */
+/******************************/
+outb(0x00,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+/*****************************************************/
+/* Selects the command and status register of timer 3*/
+/*****************************************************/
+outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+/****************************/
+/* Deactivates all interrupts */
+/******************************/
+outb(0x00,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+return 0;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
--- /dev/null
+/********* Definitions for APCI-1500 card *****/
+
+// Card Specific information
+#define APCI1500_BOARD_VENDOR_ID 0x10e8
+#define APCI1500_ADDRESS_RANGE 4
+
+
+//DIGITAL INPUT-OUTPUT DEFINE
+
+#define APCI1500_DIGITAL_OP 2
+#define APCI1500_DIGITAL_IP 0
+#define APCI1500_AND 2
+#define APCI1500_OR 4
+#define APCI1500_OR_PRIORITY 6
+#define APCI1500_CLK_SELECT 0
+#define COUNTER1 0
+#define COUNTER2 1
+#define COUNTER3 2
+#define APCI1500_COUNTER 0x20
+#define APCI1500_TIMER 0
+#define APCI1500_WATCHDOG 0
+#define APCI1500_SINGLE 0
+#define APCI1500_CONTINUOUS 0x80
+#define APCI1500_DISABLE 0
+#define APCI1500_ENABLE 1
+#define APCI1500_SOFTWARE_TRIGGER 0x4
+#define APCI1500_HARDWARE_TRIGGER 0x10
+#define APCI1500_SOFTWARE_GATE 0
+#define APCI1500_HARDWARE_GATE 0x8
+#define START 0
+#define STOP 1
+#define TRIGGER 2
+ /**************************/
+ /* Zillog I/O enumeration */
+ /**************************/
+ enum
+ {
+ APCI1500_Z8536_PORT_C,
+ APCI1500_Z8536_PORT_B,
+ APCI1500_Z8536_PORT_A,
+ APCI1500_Z8536_CONTROL_REGISTER
+ };
+
+ /******************************/
+ /* Z8536 CIO Internal Address */
+ /******************************/
+
+ enum
+ {
+ APCI1500_RW_MASTER_INTERRUPT_CONTROL,
+ APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+ APCI1500_RW_PORT_A_INTERRUPT_CONTROL,
+ APCI1500_RW_PORT_B_INTERRUPT_CONTROL,
+ APCI1500_RW_TIMER_COUNTER_INTERRUPT_VECTOR,
+ APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY,
+ APCI1500_RW_PORT_C_DATA_DIRECTION,
+ APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL,
+
+ APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+ APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+ APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ APCI1500_RW_PORT_A_DATA,
+ APCI1500_RW_PORT_B_DATA,
+ APCI1500_RW_PORT_C_DATA,
+
+ APCI1500_R_CPT_TMR1_VALUE_HIGH,
+ APCI1500_R_CPT_TMR1_VALUE_LOW,
+ APCI1500_R_CPT_TMR2_VALUE_HIGH,
+ APCI1500_R_CPT_TMR2_VALUE_LOW,
+ APCI1500_R_CPT_TMR3_VALUE_HIGH,
+ APCI1500_R_CPT_TMR3_VALUE_LOW,
+ APCI1500_RW_CPT_TMR1_TIME_CST_HIGH,
+ APCI1500_RW_CPT_TMR1_TIME_CST_LOW,
+ APCI1500_RW_CPT_TMR2_TIME_CST_HIGH,
+ APCI1500_RW_CPT_TMR2_TIME_CST_LOW,
+ APCI1500_RW_CPT_TMR3_TIME_CST_HIGH,
+ APCI1500_RW_CPT_TMR3_TIME_CST_LOW,
+ APCI1500_RW_CPT_TMR1_MODE_SPECIFICATION,
+ APCI1500_RW_CPT_TMR2_MODE_SPECIFICATION,
+ APCI1500_RW_CPT_TMR3_MODE_SPECIFICATION,
+ APCI1500_R_CURRENT_VECTOR,
+
+ APCI1500_RW_PORT_A_SPECIFICATION,
+ APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION,
+ APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY,
+ APCI1500_RW_PORT_A_DATA_DIRECTION,
+ APCI1500_RW_PORT_A_SPECIAL_IO_CONTROL,
+ APCI1500_RW_PORT_A_PATTERN_POLARITY,
+ APCI1500_RW_PORT_A_PATTERN_TRANSITION,
+ APCI1500_RW_PORT_A_PATTERN_MASK,
+
+ APCI1500_RW_PORT_B_SPECIFICATION,
+ APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION,
+ APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY,
+ APCI1500_RW_PORT_B_DATA_DIRECTION,
+ APCI1500_RW_PORT_B_SPECIAL_IO_CONTROL,
+ APCI1500_RW_PORT_B_PATTERN_POLARITY,
+ APCI1500_RW_PORT_B_PATTERN_TRANSITION,
+ APCI1500_RW_PORT_B_PATTERN_MASK
+ };
+
+ /*----------DIGITAL INPUT----------------*/
+static int i_APCI1500_Initialisation(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+ static int i_APCI1500_ConfigDigitalInputEvent(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+
+static int i_APCI1500_StartStopInputEvent(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+static int i_APCI1500_ReadMoreDigitalInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+
+/*---------- DIGITAL OUTPUT------------*/
+static int i_APCI1500_ConfigDigitalOutputErrorInterrupt(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+static int i_APCI1500_WriteDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+
+/*----------TIMER----------------*/
+ static int i_APCI1500_ConfigCounterTimerWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+static int i_APCI1500_StartStopTriggerTimerCounterWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+static int i_APCI1500_ReadCounterTimerWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+static int i_APCI1500_ReadInterruptMask(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+
+/*----------INTERRUPT HANDLER------*/
+static void v_APCI1500_Interrupt(int irq, void *d, struct pt_regs *regs);
+static int i_APCI1500_ConfigureInterrupt(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+/*----------RESET---------------*/
+static int i_APCI1500_Reset(comedi_device *dev) ;
+
\ No newline at end of file
--- /dev/null
+/*\r
+ +-----------------------------------------------------------------------+\r
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |\r
+ +-----------------------------------------------------------------------+\r
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |\r
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |\r
+ +-------------------------------+---------------------------------------+\r
+ | Project : 13Card Linux Driver | Compiler : GCC |\r
+ | Module name : hwdrv_apci1516.c| Version : 2.96 |\r
+ +-------------------------------+---------------------------------------+\r
+ | Author : Shitalkumar S Chavan | Date : 31.10.2001 |\r
+ +-------------------------------+---------------------------------------+\r
+ | Description : Hardware Layer Acces For APCI-1516 |\r
+ +-----------------------------------------------------------------------+\r
+ | UPDATES |\r
+ +----------+-----------+------------------------------------------------+\r
+ | Date | Author | Description of updates |\r
+ +----------+-----------+------------------------------------------------+\r
+ | | | |\r
+ | | | |\r
+ | | | |\r
+ +----------+-----------+------------------------------------------------+\r
+*/\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Included files |\r
++----------------------------------------------------------------------------+\r
+*/\r
+#include "hwdrv_apci1516.h"\r
+\r
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1516_Read1DigitalInput |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Return the status of the digital input |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s, :pointer to subdevice structure
+ comedi_insn *insn :pointer to insn structure |
+| lsampl_t *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1516_Read1DigitalInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ UINT ui_TmpValue=0;
+ UINT ui_Channel;
+ ui_Channel=CR_CHAN(insn->chanspec);
+ if (ui_Channel >= 0 && ui_Channel <=7)
+ {
+ ui_TmpValue=(UINT) inw(devpriv->iobase + APCI1516_DIGITAL_IP);
+ // since only 1 channel reqd to bring it to last bit it is rotated
+ // 8 +(chan - 1) times then ANDed with 1 for last bit.
+ *data = (ui_TmpValue >> ui_Channel)&0x1 ;
+ }//if(ui_Channel >= 0 && ui_Channel <=7)
+ else
+ {
+ //comedi_error(dev," \n chan spec wrong\n");
+ return -EINVAL; // "sorry channel spec wrong "
+ }//else if(ui_Channel >= 0 && ui_Channel <=7)
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1516_ReadMoreDigitalInput |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Return the status of the Requested digital inputs |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s, :pointer to subdevice structure
+ comedi_insn *insn :pointer to insn structure |
+| lsampl_t *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1516_ReadMoreDigitalInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+
+ UINT ui_PortValue=data[0];
+ UINT ui_Mask=0;
+ UINT ui_NoOfChannels;
+
+ ui_NoOfChannels=CR_CHAN(insn->chanspec);
+
+ *data=(UINT)inw(devpriv->iobase + APCI1516_DIGITAL_IP );
+ switch (ui_NoOfChannels)
+ {
+ case 2:ui_Mask=3;
+ *data=(*data >>(2*ui_PortValue))&ui_Mask;
+ break;
+ case 4:ui_Mask=15;
+ *data=(*data >>(4*ui_PortValue))&ui_Mask;
+ break;
+ case 7:break;
+
+ default:
+ printk("\nWrong parameters\n");
+ return -EINVAL; // "sorry channel spec wrong "
+ break;
+ }//switch(ui_NoOfChannels)
+
+
+ return insn->n;
+}
+\r
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1516_ConfigDigitalOutput (comedi_device *dev,
+ comedi_subdevice *s comedi_insn *insn,lsampl_t *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : Configures The Digital Output Subdevice. |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| lsampl_t *data : Data Pointer contains |
+| configuration parameters as below |
+| comedi_subdevice *s, :pointer to subdevice structure
+ comedi_insn *insn :pointer to insn structure |
+| data[0] :1:Memory on |
+| 0:Memory off |
+| |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI1516_ConfigDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data){
+ devpriv->b_OutputMemoryStatus=data[0];
+return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1516_WriteDigitalOutput |
+| (comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,
+ lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Writes port value To the selected port |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s, :pointer to subdevice structure
+ comedi_insn *insn :pointer to insn structure |
+| lsampl_t *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1516_WriteDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+UINT ui_Temp,ui_Temp1;
+UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
+ if(devpriv->b_OutputMemoryStatus )
+ {
+ ui_Temp=inw(devpriv->iobase+APCI1516_DIGITAL_OP);
+
+ }//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;
+ outw(data[0],devpriv->iobase+APCI1516_DIGITAL_OP);
+ }//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 4:data[0]=(data[0] << (4*data[2]))|ui_Temp;
+ break;
+
+ case 7:data[0]=data[0]|ui_Temp;
+ break;
+
+ default:
+ comedi_error(dev," chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+
+ }//switch(ui_NoOfChannels)
+
+ outw(data[0],devpriv->iobase+APCI1516_DIGITAL_OP);
+ }// 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)^0xff;
+ data[0]=data[0]& ui_Temp;
+ outw(data[0],devpriv->iobase+APCI1516_DIGITAL_OP);
+ }//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]))^0xff)& ui_Temp;
+ break;
+
+
+ case 4:data[0]=~data[0]&0xf;
+ ui_Temp1=15;
+ ui_Temp1=ui_Temp1<<4*data[2];
+ ui_Temp=ui_Temp|ui_Temp1;
+ data[0]=((data[0] << (4*data[2]))^0xff)&ui_Temp;
+ break;
+
+ case 7: break;
+
+ default:
+ comedi_error(dev," chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+
+ }//switch(ui_NoOfChannels)
+
+ outw(data[0],devpriv->iobase+APCI1516_DIGITAL_OP);
+ }// 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_APCI1516_ReadDigitalOutput |
+| (comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,
+ lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Read value of the selected channel or port |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s, :pointer to subdevice structure
+ comedi_insn *insn :pointer to insn structure |
+| lsampl_t *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1516_ReadDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+
+UINT ui_Temp;
+UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
+ui_Temp=data[0];
+*data=inw(devpriv->iobase+APCI1516_DIGITAL_OP_RW);
+if(ui_Temp==0)
+ {
+ *data=(*data >> ui_NoOfChannel)&0x1;
+ }//if(ui_Temp==0)
+else
+ {
+ if(ui_Temp==1)
+ {
+ switch( ui_NoOfChannel)
+ {
+
+ case 2:*data=(*data >>(2*data[1]))&3;
+ break;
+
+
+ case 4:*data=(*data >>(4*data[1]))&15;
+ break;
+
+ case 7: 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)
+ }//elseif(ui_Temp==0)
+return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1516_ConfigWatchdog(comedi_device *dev,
+ comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : Configures The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s, :pointer to subdevice structure
+ comedi_insn *insn :pointer to insn structure |
+| lsampl_t *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI1516_ConfigWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+if(data[0]==0)
+ {
+ //Disable the watchdog
+ outw(0x0,devpriv->i_IobaseAddon+ APCI1516_WATCHDOG_ENABLEDISABLE);
+ //Loading the Reload value
+ outw(data[1],devpriv->i_IobaseAddon+APCI1516_WATCHDOG_RELOAD_VALUE);
+ data[1]=data[1]>>16;
+ outw(data[1],devpriv->i_IobaseAddon+APCI1516_WATCHDOG_RELOAD_VALUE+2);
+ }//if(data[0]==0)
+else
+ {
+ printk("\nThe input parameters are wrong\n");
+ return -EINVAL;
+ }//elseif(data[0]==0)
+
+return insn->n;
+}
+
+ /*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1516_StartStopWriteWatchdog |
+| (comedi_device *dev,comedi_subdevice *s,
+ comedi_insn *insn,lsampl_t *data); |
++----------------------------------------------------------------------------+
+| Task : Start / Stop The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s, :pointer to subdevice structure
+ comedi_insn *insn :pointer to insn structure |
+| lsampl_t *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI1516_StartStopWriteWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ switch(data[0])
+ {
+ case 0://stop the watchdog
+ outw(0x0,devpriv->i_IobaseAddon+ APCI1516_WATCHDOG_ENABLEDISABLE);//disable the watchdog
+ break;
+ case 1://start the watchdog
+ outw(0x0001,devpriv->i_IobaseAddon+ APCI1516_WATCHDOG_ENABLEDISABLE);
+ break;
+ case 2://Software trigger
+ outw(0x0201,devpriv->i_IobaseAddon+ APCI1516_WATCHDOG_ENABLEDISABLE);
+ break;
+ default:printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ }// switch(data[0])
+return insn->n;
+}
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1516_ReadWatchdog |
+| (comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,
+ lsampl_t *data); |
++----------------------------------------------------------------------------+
+| Task : Read The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s, :pointer to subdevice structure
+ comedi_insn *insn :pointer to insn structure |
+| lsampl_t *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI1516_ReadWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+ {
+ data[0]= inw(devpriv->i_IobaseAddon+APCI1516_WATCHDOG_STATUS)&0x1;
+return insn->n;
+}
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1516_Reset(comedi_device *dev) | |
++----------------------------------------------------------------------------+
+| Task :resets all the registers |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1516_Reset(comedi_device *dev)
+{
+ outw(0x0 ,devpriv->iobase+APCI1516_DIGITAL_OP);//RESETS THE DIGITAL OUTPUTS
+ outw(0x0,devpriv->i_IobaseAddon+ APCI1516_WATCHDOG_ENABLEDISABLE);
+ outw(0x0,devpriv->i_IobaseAddon+APCI1516_WATCHDOG_RELOAD_VALUE);
+ outw(0x0,devpriv->i_IobaseAddon+APCI1516_WATCHDOG_RELOAD_VALUE+2);
+ return 0;
+}
+
+
--- /dev/null
+/********* Definitions for APCI-1516 card *****/\r
+\r
+// Card Specific information
+#define APCI1516_BOARD_VENDOR_ID 0x15B8
+#define APCI1516_ADDRESS_RANGE 8
+
+
+//DIGITAL INPUT-OUTPUT DEFINE \r
+\r
+#define APCI1516_DIGITAL_OP 4 \r
+#define APCI1516_DIGITAL_OP_RW 4 \r
+#define APCI1516_DIGITAL_IP 0 \r
+\r
+\r
+
+\r
+// TIMER COUNTER WATCHDOG DEFINES \r
+\r
+#define ADDIDATA_WATCHDOG 2\r
+#define APCI1516_DIGITAL_OP_WATCHDOG 0\r
+#define APCI1516_WATCHDOG_ENABLEDISABLE 12\r
+#define APCI1516_WATCHDOG_RELOAD_VALUE 4\r
+#define APCI1516_WATCHDOG_STATUS 16\r
+\r
+\r
+// Hardware Layer functions for Apci1516\r
+\r
+\r
+//Digital Input\r
+INT i_APCI1516_ReadMoreDigitalInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+INT i_APCI1516_Read1DigitalInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);\r
+\r
+
+\r
+\r
+//Digital Output
+int i_APCI1516_ConfigDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+INT i_APCI1516_WriteDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+INT i_APCI1516_ReadDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) ;
+\r
+\r
+// TIMER \r
+// timer value is passed as u seconds\r
+int i_APCI1516_ConfigWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+int i_APCI1516_StartStopWriteWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data); \r
+int i_APCI1516_ReadWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+
+
+//reset
+INT i_APCI1516_Reset(comedi_device *dev);
+
--- /dev/null
+/*\r
+ +-----------------------------------------------------------------------+\r
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |\r
+ +-----------------------------------------------------------------------+\r
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |\r
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |\r
+ +-------------------------------+---------------------------------------+\r
+ | Project : 13Card Linux Driver | Compiler : GCC |\r
+ | Module name : hwdrv_apci1564.c| Version : 2.96 |\r
+ +-------------------------------+---------------------------------------+\r
+ | Author : Shitalkumar S Chavan | Date : 31.10.2001 |\r
+ +-------------------------------+---------------------------------------+\r
+ | Description : Hardware Layer Acces For APCI-1564 |\r
+ +-----------------------------------------------------------------------+\r
+ | UPDATES |\r
+ +----------+-----------+------------------------------------------------+\r
+ | Date | Author | Description of updates |\r
+ +----------+-----------+------------------------------------------------+\r
+ | | | |\r
+ | | | |\r
+ | | | |\r
+ +----------+-----------+------------------------------------------------+\r
+*/\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Included files |\r
++----------------------------------------------------------------------------+\r
+*/\r
+
+#include <linux/delay.h>
+#include "hwdrv_apci1564.h"
+
+//Global variables
+UINT ui_InterruptStatus_1564=0 ;
+UINT ui_InterruptData,ui_Type;
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_ConfigDigitalInput |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Configures the digital input Subdevice |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| lsampl_t *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : 1 Enable Digital Input Interrupt |
+| 0 Disable Digital Input Interrupt |
+| data[1] : 0 ADDIDATA Interrupt OR LOGIC |
+| : 1 ADDIDATA Interrupt AND LOGIC |
+| data[2] : Interrupt mask for the mode 1 |
+| data[3] : Interrupt mask for the mode 2 |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_ConfigDigitalInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ devpriv->tsk_Current=current;
+ /*******************************/
+ /* Set the digital input logic */
+ /*******************************/
+ if ( data[0] == ADDIDATA_ENABLE)
+ {
+ data[2]=data[2]<<4;
+ data[3]=data[3]<<4;
+ outl (data[2] , devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + APCI1564_DIGITAL_IP_INTERRUPT_MODE1);
+ outl (data[3] , devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + APCI1564_DIGITAL_IP_INTERRUPT_MODE2);
+ if (data[1] == ADDIDATA_OR)
+ {
+ outl(0x4 ,devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + APCI1564_DIGITAL_IP_IRQ);
+ } // if (data[1] == ADDIDATA_OR)
+ else
+ {
+ outl(0x6 ,devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + APCI1564_DIGITAL_IP_IRQ);
+ } // else if (data[1] == ADDIDATA_OR)
+ } // if (data[0] == ADDIDATA_ENABLE)
+ else
+ {
+ outl (0x0, devpriv->i_IobaseAmcc +APCI1564_DIGITAL_IP +APCI1564_DIGITAL_IP_INTERRUPT_MODE1);
+ outl (0x0, devpriv->i_IobaseAmcc +APCI1564_DIGITAL_IP +APCI1564_DIGITAL_IP_INTERRUPT_MODE2);
+ outl(0x0 ,devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +APCI1564_DIGITAL_IP_IRQ);
+ } // else if (data[0] == ADDIDATA_ENABLE)
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_Read1DigitalInput |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Return the status of the digital input |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| UINT ui_Channel : Channel number to read |
+| lsampl_t *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_Read1DigitalInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ UINT ui_TmpValue=0;
+ UINT ui_Channel;
+
+ ui_Channel=CR_CHAN(insn->chanspec);
+ if (ui_Channel >= 0 && ui_Channel <=31)
+ {
+ ui_TmpValue=(UINT) inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP );
+ // since only 1 channel reqd to bring it to last bit it is rotated
+ // 8 +(chan - 1) times then ANDed with 1 for last bit.
+ *data = (ui_TmpValue >> ui_Channel)&0x1 ;
+ } // if (ui_Channel >= 0 && ui_Channel <=31)
+ else
+ {
+ comedi_error(dev,"Not a valid channel number !!! \n");
+ return -EINVAL; // "sorry channel spec wrong "
+ } //else if (ui_Channel >= 0 && ui_Channel <=31)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_ReadMoreDigitalInput |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Return the status of the Requested digital inputs |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To be Read |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_ReadMoreDigitalInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ UINT ui_PortValue=data[0];
+ UINT ui_Mask=0;
+ UINT ui_NoOfChannels;
+
+ ui_NoOfChannels=CR_CHAN(insn->chanspec);
+ if (data[1]==0)
+ {
+ *data=(UINT)inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP );
+ switch (ui_NoOfChannels)
+ {
+ case 2: ui_Mask=3;
+ *data=(*data >>(2*ui_PortValue))&ui_Mask;
+ break;
+ case 4: ui_Mask=15;
+ *data=(*data >>(4*ui_PortValue))&ui_Mask;
+ break;
+ case 8: ui_Mask=255;
+ *data=(*data >>(8*ui_PortValue))&ui_Mask;
+ break;
+ case 16:ui_Mask=65535;
+ *data=(*data >>(16*ui_PortValue))&ui_Mask;
+ break;
+ case 31:break;
+ default:
+ comedi_error(dev,"Not a valid Channel number !!!\n");
+ return -EINVAL; // "sorry channel spec wrong "
+ break;
+ } // switch (ui_NoOfChannels)
+ } // if (data[1]==0)
+ else
+ {
+ if (data[1]==1)
+ {
+ *data=ui_InterruptStatus_1564;
+ } // if (data[1]==1)
+ } // else if (data[1]==0)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_ConfigDigitalOutput |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Configures The Digital Output Subdevice. |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[1] : 1 Enable VCC Interrupt |
+| 0 Disable VCC Interrupt |
+| data[2] : 1 Enable CC Interrupt |
+| 0 Disable CC Interrupt |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_ConfigDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ ULONG ul_Command = 0;
+
+ 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])
+ if (data[1] == ADDIDATA_ENABLE)
+ {
+ ul_Command = ul_Command | 0x1;
+ } // if (data[1] == ADDIDATA_ENABLE)
+ else
+ {
+ ul_Command = ul_Command & 0xFFFFFFFE;
+ } // else if (data[1] == ADDIDATA_ENABLE)
+ if (data[2] == ADDIDATA_ENABLE)
+ {
+ ul_Command = ul_Command | 0x2;
+ } // if (data[2] == ADDIDATA_ENABLE)
+ else
+ {
+ ul_Command = ul_Command & 0xFFFFFFFD;
+ } // else if (data[2] == ADDIDATA_ENABLE)
+ outl( ul_Command , devpriv->i_IobaseAmcc+APCI1564_DIGITAL_OP+APCI1564_DIGITAL_OP_INTERRUPT);
+ ui_InterruptData=inl( devpriv->i_IobaseAmcc+APCI1564_DIGITAL_OP+APCI1564_DIGITAL_OP_INTERRUPT);
+ devpriv->tsk_Current=current;
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_WriteDigitalOutput |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Writes port value To the selected port |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To Write |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_WriteDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) {
+ UINT ui_Temp,ui_Temp1;
+ UINT ui_NoOfChannel;
+
+ ui_NoOfChannel=CR_CHAN(insn->chanspec);
+ if (devpriv->b_OutputMemoryStatus )
+ {
+ ui_Temp=inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + APCI1564_DIGITAL_OP_RW);
+ } // if (devpriv->b_OutputMemoryStatus )
+ else
+ {
+ ui_Temp=0;
+ } // else 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_IobaseAmcc + APCI1564_DIGITAL_OP + APCI1564_DIGITAL_OP_RW);
+ } // 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 4: data[0]=(data[0] << (4*data[2]))|ui_Temp;
+ break;
+ case 8: data[0]=(data[0] <<(8*data[2]))|ui_Temp;
+ break;
+ case 16: data[0]=(data[0] <<(16*data[2]))|ui_Temp;
+ break;
+ case 31: data[0]=data[0]|ui_Temp;
+ break;
+ default: comedi_error(dev," chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+ } // switch (ui_NoOfChannels)
+ outl(data[0],devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + APCI1564_DIGITAL_OP_RW);
+ } // if (data[1]==1)
+ else
+ {
+ printk("\nSpecified channel not supported\n");
+ } // else if (data[1]==1)
+ } // else if (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)^0xffffffff;
+ data[0]=data[0]& ui_Temp;
+ outl(data[0],devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + APCI1564_DIGITAL_OP_RW);
+ } // 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]))^0xffffffff)& ui_Temp;
+ break;
+ case 4: data[0]=~data[0]&0xf;
+ ui_Temp1=15;
+ ui_Temp1=ui_Temp1<<4*data[2];
+ ui_Temp=ui_Temp|ui_Temp1;
+ data[0]=((data[0] << (4*data[2]))^0xffffffff)&ui_Temp;
+ break;
+ case 8: data[0]=~data[0]&0xff;
+ ui_Temp1=255;
+ ui_Temp1=ui_Temp1<<8*data[2];
+ ui_Temp=ui_Temp|ui_Temp1;
+ data[0]=((data[0] << (8*data[2]))^0xffffffff)&ui_Temp;
+ break;
+ case 16: data[0]=~data[0]&0xffff;
+ ui_Temp1=65535;
+ ui_Temp1=ui_Temp1<<16*data[2];
+ ui_Temp=ui_Temp|ui_Temp1;
+ data[0]=((data[0] << (16*data[2]))^0xffffffff)&ui_Temp;
+ break;
+ case 31: break;
+ default: comedi_error(dev," chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+ }//switch(ui_NoOfChannels)
+ outl(data[0],devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + APCI1564_DIGITAL_OP_RW);
+ } // if (data[1]==1)
+ else
+ {
+ printk("\nSpecified channel not supported\n");
+ } // else if (data[1]==1)
+ } // else if (data[1]==0)
+ } // if (data[3]==1);
+ else
+ {
+ printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ } // else if (data[3]==1)
+ } // else if (data[3]==0)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_ReadDigitalOutput |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Read value of the selected channel or port |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To read |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_ReadDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ UINT ui_Temp;
+ UINT ui_NoOfChannel;
+
+ ui_NoOfChannel=CR_CHAN(insn->chanspec);
+ ui_Temp=data[0];
+ *data=inl(devpriv->i_IobaseAmcc+APCI1564_DIGITAL_OP+APCI1564_DIGITAL_OP_RW);
+ if (ui_Temp==0)
+ {
+ *data=(*data >> ui_NoOfChannel)&0x1;
+ } // if (ui_Temp==0)
+ else
+ {
+ if (ui_Temp==1)
+ {
+ switch (ui_NoOfChannel)
+ {
+ case 2:
+ *data=(*data >>(2*data[1]))&3;
+ break;
+
+ case 4:
+ *data=(*data >>(4*data[1]))&15;
+ break;
+
+ case 8:
+ *data=(*data >>(8*data[1]))&255;
+ break;
+
+ case 16:
+ *data=(*data >>(16*data[1]))&65535;
+ break;
+
+ case 31: 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_APCI1564_ConfigTimerCounterWatchdog |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Configures The Timer , Counter or Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : 0 Configure As Timer |
+| 1 Configure As Counter |
+| 2 Configure As Watchdog |
+| data[1] : 1 Enable Interrupt |
+| 0 Disable Interrupt |
+| data[2] : Time Unit |
+| data[3] : Reload Value |
+| data[4] : Timer Mode |
+| data[5] : Timer Counter Watchdog Number|
+ data[6] : Counter Direction
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_ConfigTimerCounterWatchdog (comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ ULONG ul_Command1 = 0;
+ devpriv->tsk_Current=current;
+ if (data[0]==ADDIDATA_WATCHDOG)
+ {
+ devpriv->b_TimerSelectMode = ADDIDATA_WATCHDOG;
+
+ //Disable the watchdog
+ outl(0x0,devpriv->i_IobaseAmcc+ APCI1564_DIGITAL_OP_WATCHDOG+ APCI1564_TCW_PROG);
+ //Loading the Reload value
+ outl(data[3],devpriv->i_IobaseAmcc+APCI1564_DIGITAL_OP_WATCHDOG+APCI1564_TCW_RELOAD_VALUE);
+ } // if (data[0]==ADDIDATA_WATCHDOG)
+ else if (data[0]==ADDIDATA_TIMER)
+ {
+ //First Stop The Timer
+ ul_Command1 =inl(devpriv->i_IobaseAmcc+ APCI1564_TIMER+ APCI1564_TCW_PROG);
+ ul_Command1 =ul_Command1 & 0xFFFFF9FEUL;
+ outl(ul_Command1,devpriv->i_IobaseAmcc+ APCI1564_TIMER+ APCI1564_TCW_PROG);//Stop The Timer
+
+ devpriv->b_TimerSelectMode =ADDIDATA_TIMER;
+ if (data[1]==1)
+ {
+ outl(0x02,devpriv->i_IobaseAmcc+ APCI1564_TIMER+ APCI1564_TCW_PROG);//Enable TIMER int & DISABLE ALL THE OTHER int SOURCES
+ outl(0x0,devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + APCI1564_DIGITAL_IP_IRQ);
+ outl(0x0,devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + APCI1564_DIGITAL_OP_IRQ);
+ outl(0x0,devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG + APCI1564_TCW_IRQ);
+ outl(0x0,devpriv->iobase+APCI1564_COUNTER1 + APCI1564_TCW_IRQ);
+ outl(0x0,devpriv->iobase+APCI1564_COUNTER2 + APCI1564_TCW_IRQ);
+ outl(0x0,devpriv->iobase+APCI1564_COUNTER3 + APCI1564_TCW_IRQ);
+ outl(0x0,devpriv->iobase+APCI1564_COUNTER4 + APCI1564_TCW_IRQ);
+ } // if (data[1]==1)
+ else
+ {
+ outl(0x0,devpriv->i_IobaseAmcc+ APCI1564_TIMER+ APCI1564_TCW_PROG);//disable Timer interrupt
+ } // else if (data[1]==1)
+
+ // Loading Timebase
+
+ outl(data[2],devpriv->i_IobaseAmcc+APCI1564_TIMER+APCI1564_TCW_TIMEBASE);
+
+ //Loading the Reload value
+ outl(data[3],devpriv->i_IobaseAmcc+APCI1564_TIMER+APCI1564_TCW_RELOAD_VALUE);
+
+ ul_Command1 =inl(devpriv->i_IobaseAmcc+ APCI1564_TIMER+ APCI1564_TCW_PROG);
+ ul_Command1 = (ul_Command1 & 0xFFF719E2UL) | 2UL << 13UL | 0x10UL;
+ outl(ul_Command1,devpriv->i_IobaseAmcc+ APCI1564_TIMER+ APCI1564_TCW_PROG);//mode 2
+ } // else if (data[0]==ADDIDATA_TIMER)
+ else if (data[0]==ADDIDATA_COUNTER)
+ {
+ devpriv->b_TimerSelectMode =ADDIDATA_COUNTER;
+ devpriv->b_ModeSelectRegister=data[5];
+
+ //First Stop The Counter
+ ul_Command1 =inl(devpriv->iobase+((data[5]-1)*0x20)+APCI1564_TCW_PROG);
+ ul_Command1 =ul_Command1 & 0xFFFFF9FEUL;
+ outl(ul_Command1,devpriv->iobase+((data[5]-1)*0x20)+APCI1564_TCW_PROG);//Stop The Timer
+
+ /************************/
+ /* Set the reload value */
+ /************************/
+ outl(data[3] , devpriv->iobase+((data[5]-1)*0x20)+APCI1564_TCW_RELOAD_VALUE);
+
+ /******************************/
+ /* Set the mode : */
+ /* - Disable the hardware */
+ /* - Disable the counter mode */
+ /* - Disable the warning */
+ /* - Disable the reset */
+ /* - Disable the timer mode */
+ /* - Enable the counter mode */
+ /******************************/
+ ul_Command1 = (ul_Command1 & 0xFFFC19E2UL) | 0x80000UL | (ULONG) ((ULONG) data[4] << 16UL);
+ outl(ul_Command1 , devpriv->iobase+((data[5]-1)*0x20)+APCI1564_TCW_PROG);
+
+ // Enable or Disable Interrupt
+ ul_Command1= (ul_Command1 & 0xFFFFF9FD) | (data[1] << 1);
+ outl(ul_Command1 , devpriv->iobase+((data[5]-1)*0x20)+APCI1564_TCW_PROG);
+
+ /*****************************/
+ /* Set the Up/Down selection */
+ /*****************************/
+ ul_Command1 = (ul_Command1 & 0xFFFBF9FFUL) | (data[6] << 18);
+ outl(ul_Command1 , devpriv->iobase+((data[5]-1)*0x20)+APCI1564_TCW_PROG);
+ } // else if (data[0]==ADDIDATA_COUNTER)
+ else
+ {
+ printk(" Invalid subdevice.");
+ } // else if (data[0]==ADDIDATA_WATCHDOG)
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_StartStopWriteTimerCounterWatchdog |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Start / Stop The Selected Timer , Counter or Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : 0 Timer |
+| 1 Counter |
+| 2 Watchdog | | data[1] : 1 Start |
+| 0 Stop |
+| 2 Trigger |
+| Clear (Only Counter) |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_StartStopWriteTimerCounterWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ ULONG ul_Command1 = 0;
+ if (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
+ {
+ switch (data[1])
+ {
+ case 0: //stop the watchdog
+ outl(0x0,devpriv->i_IobaseAmcc+ APCI1564_DIGITAL_OP_WATCHDOG+ APCI1564_TCW_PROG );//disable the watchdog
+ break;
+ case 1: //start the watchdog
+ outl(0x0001,devpriv->i_IobaseAmcc+ APCI1564_DIGITAL_OP_WATCHDOG+ APCI1564_TCW_PROG);
+ break;
+ case 2: //Software trigger
+ outl(0x0201,devpriv->i_IobaseAmcc+ APCI1564_DIGITAL_OP_WATCHDOG+ APCI1564_TCW_PROG);
+ break;
+ default: printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ } // switch (data[1])
+ } // if (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
+ if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
+ {
+ if (data[1]==1)
+ {
+ ul_Command1=inl(devpriv->i_IobaseAmcc+ APCI1564_TIMER+ APCI1564_TCW_PROG);
+ ul_Command1=(ul_Command1& 0xFFFFF9FFUL) | 0x1UL;
+
+ //Enable the Timer
+ outl(ul_Command1,devpriv->i_IobaseAmcc+ APCI1564_TIMER+ APCI1564_TCW_PROG);
+ } // if (data[1]==1)
+ else if(data[1]==0)
+ {
+ //Stop The Timer
+
+ ul_Command1=inl(devpriv->i_IobaseAmcc+ APCI1564_TIMER+ APCI1564_TCW_PROG);
+ ul_Command1 =ul_Command1 & 0xFFFFF9FEUL;
+ outl(ul_Command1,devpriv->i_IobaseAmcc+ APCI1564_TIMER+ APCI1564_TCW_PROG);
+ } // else if(data[1]==0)
+ } // if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
+ if (devpriv->b_TimerSelectMode==ADDIDATA_COUNTER)
+ {
+ ul_Command1=inl(devpriv->iobase+((devpriv->b_ModeSelectRegister-1)*0x20)+APCI1564_TCW_PROG);
+ if (data[1] == 1)
+ {
+ //Start the Counter subdevice
+ ul_Command1= (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
+ } // if (data[1] == 1)
+ else if (data[1] == 0)
+ {
+ // Stops the Counter subdevice
+ ul_Command1 = 0;
+
+ } // else if (data[1] == 0)
+ else if (data[1] == 2)
+ {
+ // Clears the Counter subdevice
+ ul_Command1= (ul_Command1 & 0xFFFFF9FFUL)|0x400;
+ } // else if (data[1] == 3)
+ outl(ul_Command1 , devpriv->iobase+((devpriv->b_ModeSelectRegister-1)*0x20)+APCI1564_TCW_PROG);
+ } // if (devpriv->b_TimerSelectMode==ADDIDATA_COUNTER)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_ReadTimerCounterWatchdog |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Read The Selected Timer , Counter or Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_ReadTimerCounterWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ ULONG ul_Command1 = 0;
+
+ if (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
+ {
+ // Stores the status of the Watchdog
+ data[0]= inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG + APCI1564_TCW_TRIG_STATUS)&0x1;
+ data[1]= inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG);
+ } // if (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
+ else if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
+ {
+ // Stores the status of the Timer
+ data[0]= inl(devpriv->i_IobaseAmcc+APCI1564_TIMER+APCI1564_TCW_TRIG_STATUS)&0x1;
+
+ // Stores the Actual value of the Timer
+ data[1]= inl(devpriv->i_IobaseAmcc + APCI1564_TIMER);
+ } // else if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
+ else if (devpriv->b_TimerSelectMode==ADDIDATA_COUNTER)
+ {
+ // Read the Counter Actual Value.
+ data[0] = inl(devpriv->iobase+((devpriv->b_ModeSelectRegister-1)*0x20)+APCI1564_TCW_SYNC_ENABLEDISABLE);
+ ul_Command1 = inl(devpriv->iobase+((devpriv->b_ModeSelectRegister-1)*0x20)+APCI1564_TCW_TRIG_STATUS);
+
+ /***********************************/
+ /* Get the software trigger status */
+ /***********************************/
+ data[1]= (BYTE) ((ul_Command1 >> 1) & 1);
+
+ /***********************************/
+ /* Get the hardware trigger status */
+ /***********************************/
+ data[2]= (BYTE) ((ul_Command1 >> 2) & 1);
+
+ /*********************************/
+ /* Get the software clear status */
+ /*********************************/
+ data[3]= (BYTE) ((ul_Command1 >> 3) & 1);
+
+ /***************************/
+ /* Get the overflow status */
+ /***************************/
+ data[4]= (BYTE) ((ul_Command1 >> 0) & 1);
+ } // else if (devpriv->b_TimerSelectMode==ADDIDATA_COUNTER)
+ else if ((devpriv->b_TimerSelectMode!=ADDIDATA_TIMER) && (devpriv->b_TimerSelectMode!=ADDIDATA_WATCHDOG)&& (devpriv->b_TimerSelectMode!=ADDIDATA_COUNTER))
+ {
+ printk ("\n Invalid Subdevice !!!\n");
+ } // else if ((devpriv->b_TimerSelectMode!=ADDIDATA_TIMER) && (devpriv->b_TimerSelectMode!=ADDIDATA_WATCHDOG)&& (devpriv->b_TimerSelectMode!=ADDIDATA_COUNTER))
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_ReadInterruptStatus |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task :Reads the interrupt status register |
++----------------------------------------------------------------------------+
+| Input Parameters : |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI1564_ReadInterruptStatus(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ *data=ui_Type;
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : static void v_APCI1564_Interrupt |
+| (int irq , void *d, struct pt_regs *regs) |
++----------------------------------------------------------------------------+
+| Task : Interrupt handler for the interruptible digital inputs |
++----------------------------------------------------------------------------+
+| Input Parameters : int irq : irq number |
+| void *d : void pointer |
+| struct pt_regs *regs : structure pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+static VOID v_APCI1564_Interrupt(int irq,void* d, struct pt_regs *regs)
+{
+ comedi_device *dev =d;
+ UINT ui_DO, ui_DI;
+ UINT ui_Timer;
+ UINT ui_C1, ui_C2, ui_C3, ui_C4;
+ ULONG ul_Command2=0;
+ ui_DI = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + APCI1564_DIGITAL_IP_IRQ) & 0x01;
+ ui_DO = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + APCI1564_DIGITAL_OP_IRQ) & 0x01;
+ ui_Timer = inl(devpriv->i_IobaseAmcc + APCI1564_TIMER+ APCI1564_TCW_IRQ) & 0x01;
+ ui_C1=inl(devpriv->iobase + APCI1564_COUNTER1 + APCI1564_TCW_IRQ ) & 0x1;
+ ui_C2=inl(devpriv->iobase + APCI1564_COUNTER2 + APCI1564_TCW_IRQ ) & 0x1;
+ ui_C3=inl(devpriv->iobase + APCI1564_COUNTER3 + APCI1564_TCW_IRQ ) & 0x1;
+ ui_C4=inl(devpriv->iobase + APCI1564_COUNTER4 + APCI1564_TCW_IRQ ) & 0x1;
+ if(ui_DI==0 && ui_DO==0 && ui_Timer==0 && ui_C1==0 && ui_C2==0 && ui_C3==0 && ui_C4==0)
+ {
+ printk("\nInterrupt from unknown source\n");
+ }// if(ui_DI==0 && ui_DO==0 && ui_Timer==0 && ui_C1==0 && ui_C2==0 && ui_C3==0 && ui_C4==0)
+
+ if (ui_DI == 1)
+ {
+ ui_DI = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + APCI1564_DIGITAL_IP_IRQ);
+ outl(0x0 ,devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + APCI1564_DIGITAL_IP_IRQ);
+ ui_InterruptStatus_1564=inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + APCI1564_DIGITAL_IP_INTERRUPT_STATUS);
+ ui_InterruptStatus_1564=ui_InterruptStatus_1564 & 0X000FFFF0;
+ send_sig(SIGIO,devpriv->tsk_Current,0); // send signal to the sample
+ outl(ui_DI ,devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + APCI1564_DIGITAL_IP_IRQ);//enable the interrupt
+ return;
+ }
+
+ if (ui_DO == 1)
+ {
+ // Check for Digital Output interrupt Type - 1: Vcc interrupt 2: CC interrupt.
+ ui_Type=inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + APCI1564_DIGITAL_OP_INTERRUPT_STATUS) & 0x3;
+ //Disable the Interrupt
+ outl(0x0,devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + APCI1564_DIGITAL_OP_INTERRUPT);
+
+ //Sends signal to user space
+ send_sig(SIGIO,devpriv->tsk_Current,0);
+
+ } // if (ui_DO)
+
+ if ((ui_Timer == 1) && (devpriv->b_TimerSelectMode =ADDIDATA_TIMER))
+ {
+ // Disable Timer Interrupt
+ ul_Command2=inl(devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG);
+ outl(0x0 , devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG);
+
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO,devpriv->tsk_Current,0);
+
+ // Enable Timer Interrupt
+
+ outl(ul_Command2 , devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG);
+ } // if ((ui_Timer == 1) && (devpriv->b_TimerSelectMode =ADDIDATA_TIMER))
+
+
+ if ((ui_C1 == 1) && (devpriv->b_TimerSelectMode = ADDIDATA_COUNTER))
+ {
+ // Disable Counter Interrupt
+ ul_Command2=inl(devpriv->iobase + APCI1564_COUNTER1 + APCI1564_TCW_PROG);
+ outl(0x0 , devpriv->iobase + APCI1564_COUNTER1 + APCI1564_TCW_PROG);
+
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO,devpriv->tsk_Current,0);
+
+ // Enable Counter Interrupt
+ outl(ul_Command2 , devpriv->iobase + APCI1564_COUNTER1 + APCI1564_TCW_PROG);
+ } // if ((ui_C1 == 1) && (devpriv->b_TimerSelectMode = ADDIDATA_COUNTER))
+
+ if ((ui_C2 == 1) && (devpriv->b_TimerSelectMode =ADDIDATA_COUNTER))
+ {
+ // Disable Counter Interrupt
+ ul_Command2=inl(devpriv->iobase + APCI1564_COUNTER2 + APCI1564_TCW_PROG);
+ outl(0x0 , devpriv->iobase + APCI1564_COUNTER2 + APCI1564_TCW_PROG);
+
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO,devpriv->tsk_Current,0);
+
+ // Enable Counter Interrupt
+ outl(ul_Command2 , devpriv->iobase + APCI1564_COUNTER2 + APCI1564_TCW_PROG);
+ } // if ((ui_C2 == 1) && (devpriv->b_TimerSelectMode =ADDIDATA_COUNTER))
+
+ if ((ui_C3 == 1) && (devpriv->b_TimerSelectMode =ADDIDATA_COUNTER))
+ {
+ // Disable Counter Interrupt
+ ul_Command2=inl(devpriv->iobase + APCI1564_COUNTER3 + APCI1564_TCW_PROG);
+ outl(0x0 , devpriv->iobase + APCI1564_COUNTER3 + APCI1564_TCW_PROG);
+
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO,devpriv->tsk_Current,0);
+
+ // Enable Counter Interrupt
+ outl(ul_Command2 , devpriv->iobase + APCI1564_COUNTER3 + APCI1564_TCW_PROG);
+ } // if ((ui_C3 == 1) && (devpriv->b_TimerSelectMode =ADDIDATA_COUNTER))
+
+ if ((ui_C4 == 1) && (devpriv->b_TimerSelectMode =ADDIDATA_COUNTER))
+ {
+ // Disable Counter Interrupt
+ ul_Command2=inl(devpriv->iobase + APCI1564_COUNTER4 + APCI1564_TCW_PROG);
+ outl(0x0 , devpriv->iobase + APCI1564_COUNTER4 + APCI1564_TCW_PROG);
+
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO,devpriv->tsk_Current,0);
+
+ // Enable Counter Interrupt
+ outl(ul_Command2 , devpriv->iobase + APCI1564_COUNTER4 + APCI1564_TCW_PROG);
+ } // if ((ui_C4 == 1) && (devpriv->b_TimerSelectMode =ADDIDATA_COUNTER))
+ return;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_Reset(comedi_device *dev) | |
++----------------------------------------------------------------------------+
+| Task :resets all the registers |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1564_Reset(comedi_device *dev)
+{
+ outl(0x0 ,devpriv->i_IobaseAmcc+APCI1564_DIGITAL_IP_IRQ);//disable the interrupts
+ inl(devpriv->i_IobaseAmcc+APCI1564_DIGITAL_IP_INTERRUPT_STATUS);//Reset the interrupt status register
+ outl (0x0 , devpriv->i_IobaseAmcc+APCI1564_DIGITAL_IP_INTERRUPT_MODE1);//Disable the and/or interrupt
+ outl (0x0 , devpriv->i_IobaseAmcc+APCI1564_DIGITAL_IP_INTERRUPT_MODE2);
+ devpriv->b_DigitalOutputRegister=0;
+ ui_Type=0;
+ outl(0x0,devpriv->i_IobaseAmcc+APCI1564_DIGITAL_OP);//Resets the output channels
+ outl(0x0,devpriv->i_IobaseAmcc+APCI1564_DIGITAL_OP_INTERRUPT);//Disables the interrupt.
+ outl(0x0,devpriv->i_IobaseAmcc+APCI1564_DIGITAL_OP_WATCHDOG+APCI1564_TCW_RELOAD_VALUE);
+ outl(0x0,devpriv->i_IobaseAmcc+APCI1564_TIMER);
+ outl(0x0 , devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG);
+
+ outl(0x0 , devpriv->iobase + APCI1564_COUNTER1 + APCI1564_TCW_PROG);
+ outl(0x0 , devpriv->iobase + APCI1564_COUNTER2 + APCI1564_TCW_PROG);
+ outl(0x0 , devpriv->iobase + APCI1564_COUNTER3 + APCI1564_TCW_PROG);
+ outl(0x0 , devpriv->iobase + APCI1564_COUNTER4 + APCI1564_TCW_PROG);
+ return 0;
+}
--- /dev/null
+/********* Definitions for APCI-1564 card *****/\r
+\r
+#define APCI1564_BOARD_VENDOR_ID 0x15B8
+#define APCI1564_ADDRESS_RANGE 128
+
+//DIGITAL INPUT-OUTPUT DEFINE
+// Input defines
+#define APCI1564_DIGITAL_IP 0x04
+#define APCI1564_DIGITAL_IP_INTERRUPT_MODE1 4
+#define APCI1564_DIGITAL_IP_INTERRUPT_MODE2 8
+#define APCI1564_DIGITAL_IP_IRQ 16
+\r
+// Output defines
+#define APCI1564_DIGITAL_OP 0x18\r
+#define APCI1564_DIGITAL_OP_RW 0 \r
+#define APCI1564_DIGITAL_OP_INTERRUPT 4 \r
+#define APCI1564_DIGITAL_OP_IRQ 12
+
+\r
+//Digital Input IRQ Function Selection\r
+#define ADDIDATA_OR 0\r
+#define ADDIDATA_AND 1\r
+\r
+//Digital Input Interrupt Status\r
+#define APCI1564_DIGITAL_IP_INTERRUPT_STATUS 12\r
+\r
+//Digital Output Interrupt Status\r
+#define APCI1564_DIGITAL_OP_INTERRUPT_STATUS 8 \r
+\r
+//Digital Input Interrupt Enable Disable. \r
+#define APCI1564_DIGITAL_IP_INTERRUPT_ENABLE 0x4 \r
+#define APCI1564_DIGITAL_IP_INTERRUPT_DISABLE 0xFFFFFFFB\r
+\r
+//Digital Output Interrupt Enable Disable.\r
+#define APCI1564_DIGITAL_OP_VCC_INTERRUPT_ENABLE 0x1\r
+#define APCI1564_DIGITAL_OP_VCC_INTERRUPT_DISABLE 0xFFFFFFFE\r
+#define APCI1564_DIGITAL_OP_CC_INTERRUPT_ENABLE 0x2\r
+#define APCI1564_DIGITAL_OP_CC_INTERRUPT_DISABLE 0xFFFFFFFD\r
+\r
+//ADDIDATA Enable Disable\r
+\r
+#define ADDIDATA_ENABLE 1\r
+#define ADDIDATA_DISABLE 0\r
+\r
+// TIMER COUNTER WATCHDOG DEFINES \r
+\r
+#define ADDIDATA_TIMER 0\r
+#define ADDIDATA_COUNTER 1\r
+#define ADDIDATA_WATCHDOG 2\r
+#define APCI1564_DIGITAL_OP_WATCHDOG 0x28\r
+#define APCI1564_TIMER 0x48\r
+#define APCI1564_COUNTER1 0x0\r
+#define APCI1564_COUNTER2 0x20\r
+#define APCI1564_COUNTER3 0x40\r
+#define APCI1564_COUNTER4 0x60 \r
+#define APCI1564_TCW_SYNC_ENABLEDISABLE 0\r
+#define APCI1564_TCW_RELOAD_VALUE 4\r
+#define APCI1564_TCW_TIMEBASE 8\r
+#define APCI1564_TCW_PROG 12\r
+#define APCI1564_TCW_TRIG_STATUS 16\r
+#define APCI1564_TCW_IRQ 20\r
+#define APCI1564_TCW_WARN_TIMEVAL 24\r
+#define APCI1564_TCW_WARN_TIMEBASE 28\r
+
+\r
+// Hardware Layer functions for Apci1564\r
+\r\r
+//DI
+// for di read
+INT i_APCI1564_ConfigDigitalInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+INT i_APCI1564_Read1DigitalInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+INT i_APCI1564_ReadMoreDigitalInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+
+//DO
+int i_APCI1564_ConfigDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+INT i_APCI1564_WriteDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+INT i_APCI1564_ReadDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+int i_APCI1564_ReadInterruptStatus(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data); \r
+\r
+\r
+// TIMER \r
+// timer value is passed as u seconds\r
+INT i_APCI1564_ConfigTimerCounterWatchdog (comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+int i_APCI1564_StartStopWriteTimerCounterWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+int i_APCI1564_ReadTimerCounterWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+
+// INTERRUPT
+static VOID v_APCI1564_Interrupt(int irq, void *d, struct pt_regs *regs) ;
+
+// RESET
+INT i_APCI1564_Reset(comedi_device *dev);
--- /dev/null
+/*\r
+ +-----------------------------------------------------------------------+\r
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |\r
+ +-----------------------------------------------------------------------+\r
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |\r
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |\r
+ +-------------------------------+---------------------------------------+\r
+ | Project : 13Card Linux Driver | Compiler : GCC |\r
+ | Module name : hwdrv_apci2016.c| Version : 2.96 |\r
+ +-------------------------------+---------------------------------------+\r
+ | Author : Shitalkumar S Chavan | Date : 31.10.2001 |\r
+ +-------------------------------+---------------------------------------+\r
+ | Description : Hardware Layer Acces For APCI-2016 |\r
+ +-----------------------------------------------------------------------+\r
+ | UPDATES |\r
+ +----------+-----------+------------------------------------------------+\r
+ | Date | Author | Description of updates |\r
+ +----------+-----------+------------------------------------------------+\r
+ | | | |\r
+ | | | |\r
+ | | | |\r
+ +----------+-----------+------------------------------------------------+\r
+*/\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Included files |\r
++----------------------------------------------------------------------------+\r
+*/\r
+#include "hwdrv_apci2016.h"
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : int i_APCI2016_ConfigDigitalOutput |\r
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+\r
+| Task : Configures The Digital Output Subdevice. |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : comedi_device *dev : Driver handle |\r
+| UINT *data : Data Pointer contains |\r
+| configuration parameters as below |\r
+| | \r
+| data[0] : 1 Digital Memory On | \r
+| 0 Digital Memory Off | \r
++----------------------------------------------------------------------------+\r
+| Output Parameters : -- |\r
++----------------------------------------------------------------------------+\r
+| Return Value : TRUE : No error occur |\r
+| : FALSE : Error occur. Return the error |\r
+| |\r
++----------------------------------------------------------------------------+\r
+*/\r
+int i_APCI2016_ConfigDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) \r
+{\r
+ 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;\r
+}\r
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : int i_APCI2016_WriteDigitalOutput |\r
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+\r
+| Task : Writes port value To the selected port |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : comedi_device *dev : Driver handle |\r
+| UINT ui_NoOfChannels : No Of Channels To Write |\r
+| UINT *data : Data Pointer to read status |\r
++----------------------------------------------------------------------------+\r
+| Output Parameters : -- |\r
++----------------------------------------------------------------------------+\r
+| Return Value : TRUE : No error occur |\r
+| : FALSE : Error occur. Return the error |\r
+| |\r
++----------------------------------------------------------------------------+\r
+*/\r
+int i_APCI2016_WriteDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) \r
+{\r
+ UINT ui_NoOfChannel;
+ UINT ui_Temp,ui_Temp1;
+ ui_NoOfChannel=CR_CHAN(insn->chanspec);
+ if ((ui_NoOfChannel<0) || (ui_NoOfChannel>15))
+ {
+ comedi_error(dev,"Invalid Channel Numbers !!!, Channel Numbers must be between 0 and 15\n");
+ return -EINVAL;
+ } // if ((ui_NoOfChannel<0) || (ui_NoOfChannel>15))
+ if (devpriv->b_OutputMemoryStatus )
+ {
+ ui_Temp=inw(devpriv->iobase+APCI2016_DIGITAL_OP);
+ } // if (devpriv->b_OutputMemoryStatus )
+ else
+ {
+ ui_Temp=0;
+ } // else if (devpriv->b_OutputMemoryStatus )
+ if ((data[1]!=0) && (data[1]!=1))
+ {
+ comedi_error(dev,"Invalid Data[1] value !!!, Data[1] should be 0 or 1\n");
+ return -EINVAL;
+ } // if ((data[1]!=0) && (data[1]!=1))
+
+ if (data[3]==0)
+ {
+ if (data[1]==0)
+ {
+ data[0]=(data[0] << ui_NoOfChannel)|ui_Temp;
+ outw(data[0],devpriv->iobase+APCI2016_DIGITAL_OP);
+ } // 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 4: data[0]=(data[0] << (4*data[2]))|ui_Temp;
+ break;
+ case 8: data[0]=(data[0] << (8*data[2]))|ui_Temp;
+ break;
+ case 15: data[0]=data[0]|ui_Temp;
+ break;
+ default: comedi_error(dev," chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+ }//switch(ui_NoOfChannels)
+ outw(data[0],devpriv->iobase+APCI2016_DIGITAL_OP);
+ }// if (data[1]==1)
+ else
+ {
+ printk("\nSpecified channel not supported\n");
+ } // else if (data[1]==1)
+ } // else if (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)^0xffff;
+ data[0]=data[0]& ui_Temp;
+ outw(data[0],devpriv->iobase+APCI2016_DIGITAL_OP);
+ } // 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]))^0xffff)& ui_Temp;
+ break;
+ case 4: data[0]=~data[0]&0xf;
+ ui_Temp1=15;
+ ui_Temp1=ui_Temp1<<4*data[2];
+ ui_Temp=ui_Temp|ui_Temp1;
+ data[0]=((data[0] << (4*data[2]))^0xffff)&ui_Temp;
+ break;
+ case 8: data[0]=~data[0]&0xff;
+ ui_Temp1=255;
+ ui_Temp1=ui_Temp1<<8*data[2];
+ ui_Temp=ui_Temp|ui_Temp1;
+ data[0]=((data[0] << (8*data[2]))^0xffff)&ui_Temp;
+ break;
+ case 15: break;
+ default: comedi_error(dev," chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+ }//switch(ui_NoOfChannels)
+ outw(data[0],devpriv->iobase+APCI2016_DIGITAL_OP);
+ }// 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;
+}
+\r
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2016_BitsDigitalOutput |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Read value of the selected channel or port |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To read |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI2016_BitsDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ UINT ui_Temp;
+ UINT ui_NoOfChannel;
+ ui_NoOfChannel=CR_CHAN(insn->chanspec);
+ if ((ui_NoOfChannel<0) || (ui_NoOfChannel>15))
+ {
+ comedi_error(dev,"Invalid Channel Numbers !!!, Channel Numbers must be between 0 and 15\n");
+ return -EINVAL;
+ } // if ((ui_NoOfChannel<0) || (ui_NoOfChannel>15))
+ if ((data[0]!=0) && (data[0]!=1))
+ {
+ comedi_error(dev,"Invalid Data[0] value !!!, Data[0] should be 0 or 1\n");
+ return -EINVAL;
+ } // if ((data[0]!=0) && (data[0]!=1))
+ ui_Temp=data[0];
+ *data=inw(devpriv->iobase+APCI2016_DIGITAL_OP_RW);
+ if (ui_Temp==0)
+ {
+ *data=(*data >> ui_NoOfChannel)&0x1;
+ } // if (ui_Temp==0)
+ else
+ {
+ if (ui_Temp==1)
+ {
+ switch (ui_NoOfChannel)
+ {
+ case 2: *data=(*data >>(2*data[1]))&3;
+ break;
+
+ case 4: *data=(*data >>(4*data[1]))&15;
+ break;
+
+ case 8: *data=(*data >>(8*data[1]))&255;
+ break;
+
+ case 15: break;
+
+ default:
+ comedi_error(dev," chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+ }//switch(ui_NoOfChannel)
+ } // if (ui_Temp==1)
+ else
+ {
+ printk("\nSpecified channel not supported \n");
+ } // else if (ui_Temp==1)
+ } // if (ui_Temp==0)
+ return insn->n;
+}
+
+
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : int i_APCI2016_ConfigWatchdog |\r
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+\r
+| Task : Configures The Watchdog |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s, :pointer to subdevice structure |
+| comedi_insn *insn :pointer to insn structure |
+| lsampl_t *data : Data Pointer to read status |
++----------------------------------------------------------------------------+\r
+| Output Parameters : -- |\r
++----------------------------------------------------------------------------+\r
+| Return Value : TRUE : No error occur |\r
+| : FALSE : Error occur. Return the error |\r
+| |\r
++----------------------------------------------------------------------------+\r
+*/\r
+int i_APCI2016_ConfigWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) \r
+{
+
+ if (data[0]==0)
+ {
+ //Disable the watchdog
+ outw(0x0,devpriv->i_IobaseAddon+ APCI2016_WATCHDOG_ENABLEDISABLE);
+ //Loading the Reload value
+ outw(data[1],devpriv->i_IobaseAddon+APCI2016_WATCHDOG_RELOAD_VALUE);
+ data[1]=data[1]>>16;
+ outw(data[1],devpriv->i_IobaseAddon+APCI2016_WATCHDOG_RELOAD_VALUE+2);
+ }
+ else
+ {
+ printk("\nThe input parameters are wrong\n");
+ }
+ return insn->n;
+}
+
+
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : int i_APCI2016_StartStopWriteWatchdog |\r
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+\r
+| Task : Start / Stop The Watchdog |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s, :pointer to subdevice structure |
+| comedi_insn *insn :pointer to insn structure |
+| lsampl_t *data : Data Pointer to read status |
++----------------------------------------------------------------------------+\r
+| Output Parameters : -- |\r
++----------------------------------------------------------------------------+\r
+| Return Value : TRUE : No error occur |\r
+| : FALSE : Error occur. Return the error |\r
+| |\r
++----------------------------------------------------------------------------+\r
+*/\r
+int i_APCI2016_StartStopWriteWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)\r
+{
+
+ switch(data[0])
+ {
+ case 0://stop the watchdog
+ outw(0x0,devpriv->i_IobaseAddon+ APCI2016_WATCHDOG_ENABLEDISABLE);//disable the watchdog
+ break;
+ case 1://start the watchdog
+ outw(0x0001,devpriv->i_IobaseAddon+ APCI2016_WATCHDOG_ENABLEDISABLE);
+ break;
+ case 2://Software trigger
+ outw(0x0201,devpriv->i_IobaseAddon+ APCI2016_WATCHDOG_ENABLEDISABLE);
+ break;
+ default:printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ }// switch(data[0])
+
+ return insn->n;
+}
+\r
+/*\r
++----------------------------------------------------------------------------+\r
+| Function Name : int i_APCI2016_ReadWatchdog |\r
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+\r
+| Task : Read The Watchdog |\r
++----------------------------------------------------------------------------+\r
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s, :pointer to subdevice structure |
+| comedi_insn *insn :pointer to insn structure |
+| lsampl_t *data : Data Pointer to read status |
++----------------------------------------------------------------------------+\r
+| Output Parameters : -- |\r
++----------------------------------------------------------------------------+\r
+| Return Value : TRUE : No error occur |\r
+| : FALSE : Error occur. Return the error |\r
+| |\r
++----------------------------------------------------------------------------+\r
+*/\r\r
+int i_APCI2016_ReadWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ udelay(5);
+ data[0]= inw(devpriv->i_IobaseAddon+APCI2016_WATCHDOG_STATUS)&0x1;
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2016_Reset(comedi_device *dev) | |
++----------------------------------------------------------------------------+
+| Task :resets all the registers |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI2016_Reset(comedi_device *dev)
+{
+ outw(0x0,devpriv->iobase+APCI2016_DIGITAL_OP); // Resets the digital output channels
+ outw(0x0,devpriv->i_IobaseAddon+ APCI2016_WATCHDOG_ENABLEDISABLE);
+ outw(0x0,devpriv->i_IobaseAddon+APCI2016_WATCHDOG_RELOAD_VALUE);
+ outw(0x0,devpriv->i_IobaseAddon+APCI2016_WATCHDOG_RELOAD_VALUE+2);
+ return 0;
+}
\ No newline at end of file
--- /dev/null
+/********* Definitions for APCI-2016 card *****/\r
+\r
+#define APCI2016_BOARD_VENDOR_ID 0x15B8
+#define APCI2016_ADDRESS_RANGE 8
+
+\r
+//DIGITAL INPUT-OUTPUT DEFINE \r
+\r
+#define APCI2016_DIGITAL_OP 0x04 \r
+#define APCI2016_DIGITAL_OP_RW 4 \r
+\r
+//ADDIDATA Enable Disable\r
+\r
+#define ADDIDATA_ENABLE 1\r
+#define ADDIDATA_DISABLE 0\r
+\r
+// TIMER COUNTER WATCHDOG DEFINES \r
+\r
+#define ADDIDATA_WATCHDOG 2\r
+#define APCI2016_DIGITAL_OP_WATCHDOG 0\r
+#define APCI2016_WATCHDOG_ENABLEDISABLE 12\r
+#define APCI2016_WATCHDOG_RELOAD_VALUE 4\r
+#define APCI2016_WATCHDOG_STATUS 16\r
+\r
+
+// Hardware Layer functions for Apci2016\r
+\r
+//DO\r
+int i_APCI2016_ConfigDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) ;\r
+\r
+int i_APCI2016_WriteDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+
+int i_APCI2016_BitsDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);\r
+\r
+\r
+// TIMER \r
+// timer value is passed as u seconds\r
+\r
+
+int i_APCI2016_ConfigWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) ;\r
+\r
+int i_APCI2016_StartStopWriteWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);\r
+\r
+int i_APCI2016_ReadWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+
+
+// Interrupt functions.....
+
+// VOID v_APCI2016_Interrupt(int irq, void *d, struct pt_regs *regs) ;
+
+ //VOID v_APCI2016_Interrupt(int irq, void *d, struct pt_regs *regs);
+// RESET
+INT i_APCI2016_Reset(comedi_device *dev);
--- /dev/null
+/*
+ +-----------------------------------------------------------------------+
+ | (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 : 13Card Linux Driver | Compiler : GCC |
+ | Module name : hwdrv_apci2032.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Author : Shitalkumar S Chavan | Date : 31.10.2001 |
+ +-------------------------------+---------------------------------------+
+ | Description : Hardware Layer Acces For APCI-2032 |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +----------+-----------+------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+
+#include "hwdrv_apci2032.h"
+UINT ui_InterruptData,ui_Type;
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2032_ConfigDigitalOutput |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Configures The Digital Output Subdevice. |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[1] : 1 Enable VCC Interrupt |
+| 0 Disable VCC Interrupt |
+| data[2] : 1 Enable CC Interrupt |
+| 0 Disable CC Interrupt |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI2032_ConfigDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ ULONG ul_Command = 0;
+ devpriv->tsk_Current=current;
+
+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])
+
+
+
+ if (data[1] == ADDIDATA_ENABLE)
+ {
+ ul_Command = ul_Command | 0x1;
+ }//if (data[1] == ADDIDATA_ENABLE)
+ else
+ {
+ ul_Command = ul_Command & 0xFFFFFFFE;
+ }//elseif (data[1] == ADDIDATA_ENABLE)
+ if (data[2] == ADDIDATA_ENABLE)
+ {
+ ul_Command = ul_Command | 0x2;
+ }//if (data[2] == ADDIDATA_ENABLE)
+ else
+ {
+ ul_Command = ul_Command & 0xFFFFFFFD;
+ }//elseif (data[2] == ADDIDATA_ENABLE)
+ outl( ul_Command , devpriv->iobase+APCI2032_DIGITAL_OP_INTERRUPT);
+ ui_InterruptData=inl( devpriv->iobase+APCI2032_DIGITAL_OP_INTERRUPT);
+return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2032_WriteDigitalOutput |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Writes port value To the selected port |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To Write |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI2032_WriteDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+UINT ui_Temp,ui_Temp1;
+UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
+ if(devpriv->b_OutputMemoryStatus )
+ {
+ ui_Temp=inl(devpriv->iobase+APCI2032_DIGITAL_OP);
+
+ }//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->iobase+APCI2032_DIGITAL_OP);
+ }//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 4:data[0]=(data[0] << (4*data[2]))|ui_Temp;
+ break;
+
+ case 8:
+ data[0]=(data[0] <<(8*data[2]))|ui_Temp;
+ break;
+
+ case 16:
+ data[0]=(data[0] <<(16*data[2]))|ui_Temp;
+ break;
+ case 31:data[0]=data[0]|ui_Temp;
+ break;
+
+ default:
+ comedi_error(dev," chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+
+ }//switch(ui_NoOfChannels)
+
+ outl(data[0],devpriv->iobase+APCI2032_DIGITAL_OP);
+ }// 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)^0xffffffff;
+ data[0]=data[0]& ui_Temp;
+ outl(data[0],devpriv->iobase+APCI2032_DIGITAL_OP);
+ }//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]))^0xffffffff)& ui_Temp;
+ break;
+
+
+ case 4:data[0]=~data[0]&0xf;
+ ui_Temp1=15;
+ ui_Temp1=ui_Temp1<<4*data[2];
+ ui_Temp=ui_Temp|ui_Temp1;
+ data[0]=((data[0] << (4*data[2]))^0xffffffff)&ui_Temp;
+ break;
+
+ case 8:data[0]=~data[0]&0xff;
+ ui_Temp1=255;
+ ui_Temp1=ui_Temp1<<8*data[2];
+ ui_Temp=ui_Temp|ui_Temp1;
+ data[0]=((data[0] << (8*data[2]))^0xffffffff)&ui_Temp;
+ break;
+
+ case 16:data[0]=~data[0]&0xffff;
+ ui_Temp1=65535;
+ ui_Temp1=ui_Temp1<<16*data[2];
+ ui_Temp=ui_Temp|ui_Temp1;
+ data[0]=((data[0] << (16*data[2]))^0xffffffff)&ui_Temp;
+ break;
+
+ case 31: break;
+ default:
+ comedi_error(dev," chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+
+ }//switch(ui_NoOfChannels)
+
+ outl(data[0],devpriv->iobase+APCI2032_DIGITAL_OP);
+ }// 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_APCI2032_ReadDigitalOutput |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Read value of the selected channel or port |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To read |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI2032_ReadDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ UINT ui_Temp;
+ UINT ui_NoOfChannel;
+ ui_NoOfChannel=CR_CHAN(insn->chanspec);
+ ui_Temp=data[0];
+ *data=inl(devpriv->iobase+APCI2032_DIGITAL_OP_RW);
+ if (ui_Temp==0)
+ {
+ *data=(*data >> ui_NoOfChannel)&0x1;
+ } //if (ui_Temp==0)
+ else
+ {
+ if (ui_Temp==1)
+ {
+ switch( ui_NoOfChannel)
+ {
+
+ case 2:
+ *data=(*data >>(2*data[1]))&3;
+ break;
+
+
+ case 4:
+ *data=(*data >>(4*data[1]))&15;
+ break;
+
+ case 8:
+ *data=(*data >>(8*data[1]))&255;
+ break;
+
+ case 16:
+ *data=(*data >>(16*data[1]))&65535;
+ break;
+
+ case 31: 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_APCI2032_ConfigWatchdog(comedi_device
+ *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)|
+| |
++----------------------------------------------------------------------------+
+| Task : Configures The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s, :pointer to subdevice structure
+ comedi_insn *insn :pointer to insn structure |
+| lsampl_t *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI2032_ConfigWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+if(data[0]==0)
+ {
+ //Disable the watchdog
+ outl(0x0,devpriv->iobase+APCI2032_DIGITAL_OP_WATCHDOG+APCI2032_TCW_PROG);
+ //Loading the Reload value
+ outl(data[1],devpriv->iobase+APCI2032_DIGITAL_OP_WATCHDOG+APCI2032_TCW_RELOAD_VALUE);
+ }
+else
+ {
+ printk("\nThe input parameters are wrong\n");
+ return -EINVAL;
+ }
+
+return insn->n;
+}
+
+
+
+
+
+ /*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2032_StartStopWriteWatchdog |
+| (comedi_device *dev,comedi_subdevice *s,
+ comedi_insn *insn,lsampl_t *data); |
++----------------------------------------------------------------------------+
+| Task : Start / Stop The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s, :pointer to subdevice structure
+ comedi_insn *insn :pointer to insn structure |
+| lsampl_t *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI2032_StartStopWriteWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ switch(data[0])
+ {
+ case 0://stop the watchdog
+ outl(0x0,devpriv->iobase +APCI2032_DIGITAL_OP_WATCHDOG+APCI2032_TCW_PROG );//disable the watchdog
+ break;
+ case 1://start the watchdog
+ outl(0x0001,devpriv->iobase+APCI2032_DIGITAL_OP_WATCHDOG+APCI2032_TCW_PROG);
+ break;
+ case 2://Software trigger
+ outl(0x0201,devpriv->iobase+APCI2032_DIGITAL_OP_WATCHDOG+APCI2032_TCW_PROG);
+ break;
+ default:printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ }
+return insn->n;
+}
+
+
+
+
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2032_ReadWatchdog |
+| (comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,
+ lsampl_t *data); |
++----------------------------------------------------------------------------+
+| Task : Read The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s, :pointer to subdevice structure
+ comedi_insn *insn :pointer to insn structure |
+| lsampl_t *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI2032_ReadWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+ {
+
+ data[0]= inl(devpriv->iobase+APCI2032_DIGITAL_OP_WATCHDOG+APCI2032_TCW_TRIG_STATUS )&0x1;
+return insn->n;
+}
+
+
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : void v_APCI2032_Interrupt |
+| (int irq , void *d, struct pt_regs *regs) |
++----------------------------------------------------------------------------+
+| Task : Writes port value To the selected port |
++----------------------------------------------------------------------------+
+| Input Parameters : int irq : irq number |
+| void *d : void pointer |
+| struct pt_regs *regs : structure pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+ void v_APCI2032_Interrupt(int irq, void *d, struct pt_regs *regs)
+{
+ comedi_device *dev = d;
+ unsigned int ui_DO;
+
+ ui_DO=inl(devpriv->iobase+APCI2032_DIGITAL_OP_IRQ)&0x1;//Check if VCC OR CC interrupt has occured.
+
+ if(ui_DO==0)
+ {
+ printk("\nInterrupt from unKnown source\n");
+ }// if(ui_DO==0)
+ if (ui_DO)
+ {
+ // Check for Digital Output interrupt Type - 1: Vcc interrupt 2: CC interrupt.
+ ui_Type=inl(devpriv->iobase+ APCI2032_DIGITAL_OP_INTERRUPT_STATUS)&0x3;
+ outl(0x0,devpriv->iobase+APCI2032_DIGITAL_OP+APCI2032_DIGITAL_OP_INTERRUPT);
+ if (ui_Type==1)
+ {
+ //Sends signal to user space
+ send_sig(SIGIO,devpriv->tsk_Current,0);
+ }// if (ui_Type==1)
+ else
+ {
+ if (ui_Type==2)
+ {
+ // Sends signal to user space
+ send_sig(SIGIO,devpriv->tsk_Current,0);
+ }//if (ui_Type==2)
+ }//else if (ui_Type==1)
+ } //if(ui_DO)
+
+ return;
+
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2032_ReadInterruptStatus |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task :Reads the interrupt status register |
++----------------------------------------------------------------------------+
+| Input Parameters : |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI2032_ReadInterruptStatus(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ *data=ui_Type;
+ return insn->n;
+}
+
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2032_Reset(comedi_device *dev) |
+| |
++----------------------------------------------------------------------------+
+| Task :Resets the registers of the card |
++----------------------------------------------------------------------------+
+| Input Parameters : |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI2032_Reset(comedi_device *dev)
+{
+devpriv->b_DigitalOutputRegister=0;
+ui_Type=0;
+outl(0x0,devpriv->iobase+APCI2032_DIGITAL_OP);//Resets the output channels
+outl(0x0,devpriv->iobase+APCI2032_DIGITAL_OP_INTERRUPT);//Disables the interrupt.
+outl(0x0,devpriv->iobase+APCI2032_DIGITAL_OP_WATCHDOG+APCI2032_TCW_PROG);//disable the watchdog
+outl(0x0,devpriv->iobase+APCI2032_DIGITAL_OP_WATCHDOG+APCI2032_TCW_RELOAD_VALUE);//reload=0
+return 0;
+}
+
+
--- /dev/null
+/********* Definitions for APCI-2032 card *****/\r
+
+// Card Specific information
+#define APCI2032_BOARD_VENDOR_ID 0x15B8
+#define APCI2032_ADDRESS_RANGE 63
+
+\r
+//DIGITAL INPUT-OUTPUT DEFINE \r
+\r
+#define APCI2032_DIGITAL_OP 0 \r
+#define APCI2032_DIGITAL_OP_RW 0 \r
+#define APCI2032_DIGITAL_OP_INTERRUPT 4\r
+#define APCI2032_DIGITAL_OP_IRQ 12\r
+
+//Digital Output Interrupt Status\r
+#define APCI2032_DIGITAL_OP_INTERRUPT_STATUS 8\r
+\r
+//Digital Output Interrupt Enable Disable.\r
+#define APCI2032_DIGITAL_OP_VCC_INTERRUPT_ENABLE 0x1\r
+#define APCI2032_DIGITAL_OP_VCC_INTERRUPT_DISABLE 0xFFFFFFFE\r
+#define APCI2032_DIGITAL_OP_CC_INTERRUPT_ENABLE 0x2\r
+#define APCI2032_DIGITAL_OP_CC_INTERRUPT_DISABLE 0xFFFFFFFD\r
+\r
+//ADDIDATA Enable Disable\r
+\r
+#define ADDIDATA_ENABLE 1\r
+#define ADDIDATA_DISABLE 0\r
+\r
+// TIMER COUNTER WATCHDOG DEFINES \r
+\r
+#define ADDIDATA_WATCHDOG 2\r
+#define APCI2032_DIGITAL_OP_WATCHDOG 16
+#define APCI2032_TCW_RELOAD_VALUE 4\r
+#define APCI2032_TCW_TIMEBASE 8\r
+#define APCI2032_TCW_PROG 12\r
+#define APCI2032_TCW_TRIG_STATUS 16\r
+#define APCI2032_TCW_IRQ 20\r
+
+\r
+\r
+\r
+// Hardware Layer functions for Apci2032\r
+\r
+\r
+//DO\r
+int i_APCI2032_ConfigDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);\r
+INT i_APCI2032_WriteDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+INT i_APCI2032_ReadDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+int i_APCI2032_ReadInterruptStatus(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+\r
+// TIMER \r
+// timer value is passed as u seconds\r
+INT i_APCI2032_ConfigWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);\r
+int i_APCI2032_StartStopWriteWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+int i_APCI2032_ReadWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+
+// Interrupt functions.....\r
+\r
+void v_APCI2032_Interrupt(int irq, void *d, struct pt_regs *regs) ;\r
+
+//Reset functions
+ int i_APCI2032_Reset(comedi_device *dev);
--- /dev/null
+/*
+ +-----------------------------------------------------------------------+
+ | (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 : 13Card Linux Driver | Compiler : GCC |
+ | Module name : hwdrv_apci2200.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Author : Karl Andrade | Date : 18.12.2001 |
+ +-------------------------------+---------------------------------------+
+ | Description : Hardware Layer Acces For APCI-2200 |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +----------+-----------+------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+#include "hwdrv_apci2200.h"
+
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2200_Read1DigitalInput |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Return the status of the digital input |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s, :pointer to subdevice structure
+ comedi_insn *insn :pointer to insn structure |
+| lsampl_t *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI2200_Read1DigitalInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ UINT ui_TmpValue=0;
+ UINT ui_Channel;
+ ui_Channel=CR_CHAN(insn->chanspec);
+ if (ui_Channel >= 0 && ui_Channel <=7)
+ {
+ ui_TmpValue=(UINT) inw(devpriv->iobase + APCI2200_DIGITAL_IP);
+ *data = (ui_TmpValue >> ui_Channel)&0x1 ;
+ }//if(ui_Channel >= 0 && ui_Channel <=7)
+ else
+ {
+ printk("\nThe specified channel does not exist\n");
+ return -EINVAL; // "sorry channel spec wrong "
+ }//else if(ui_Channel >= 0 && ui_Channel <=7)
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2200_ReadMoreDigitalInput |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Return the status of the Requested digital inputs |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s, :pointer to subdevice structure
+ comedi_insn *insn :pointer to insn structure |
+| lsampl_t *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI2200_ReadMoreDigitalInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+
+ UINT ui_PortValue=data[0];
+ UINT ui_Mask=0;
+ UINT ui_NoOfChannels;
+
+ ui_NoOfChannels=CR_CHAN(insn->chanspec);
+
+ *data=(UINT)inw(devpriv->iobase + APCI2200_DIGITAL_IP );
+ switch (ui_NoOfChannels)
+ {
+ case 2:ui_Mask=3;
+ *data=(*data >>(2*ui_PortValue))&ui_Mask;
+ break;
+ case 4:ui_Mask=15;
+ *data=(*data >>(4*ui_PortValue))&ui_Mask;
+ break;
+ case 7:break;
+
+ default:
+ printk("\nWrong parameters\n");
+ return -EINVAL; // "sorry channel spec wrong "
+ break;
+ }//switch(ui_NoOfChannels)
+
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2200_ConfigDigitalOutput (comedi_device *dev,
+ comedi_subdevice *s comedi_insn *insn,lsampl_t *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : Configures The Digital Output Subdevice. |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| lsampl_t *data : Data Pointer contains |
+| configuration parameters as below |
+| comedi_subdevice *s, :pointer to subdevice structure
+ comedi_insn *insn :pointer to insn structure |
+| data[0] :1:Memory on |
+| 0:Memory off |
+| |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI2200_ConfigDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data){
+ devpriv->b_OutputMemoryStatus=data[0];
+return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2200_WriteDigitalOutput |
+| (comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,
+ lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Writes port value To the selected port |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s, :pointer to subdevice structure
+ comedi_insn *insn :pointer to insn structure |
+| lsampl_t *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI2200_WriteDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+UINT ui_Temp,ui_Temp1;
+UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
+ if(devpriv->b_OutputMemoryStatus )
+ {
+ ui_Temp=inw(devpriv->iobase+APCI2200_DIGITAL_OP);
+
+ }//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;
+ outw(data[0],devpriv->iobase+APCI2200_DIGITAL_OP);
+ }//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 4:data[0]=(data[0] << (4*data[2]))|ui_Temp;
+ break;
+
+ case 8: data[0]=(data[0] << (8*data[2]))|ui_Temp;
+ break;
+ case 15: data[0]=data[0]|ui_Temp;
+ break;
+ default:
+ comedi_error(dev," chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+
+ }//switch(ui_NoOfChannels)
+
+ outw(data[0],devpriv->iobase+APCI2200_DIGITAL_OP);
+ }// 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)^0xffff;
+ data[0]=data[0]& ui_Temp;
+ outw(data[0],devpriv->iobase+APCI2200_DIGITAL_OP);
+ }//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]))^0xffff)& ui_Temp;
+ break;
+
+
+ case 4:data[0]=~data[0]&0xf;
+ ui_Temp1=15;
+ ui_Temp1=ui_Temp1<<4*data[2];
+ ui_Temp=ui_Temp|ui_Temp1;
+ data[0]=((data[0] << (4*data[2]))^0xffff)&ui_Temp;
+ break;
+
+ case 8: data[0]=~data[0]&0xff;
+ ui_Temp1=255;
+ ui_Temp1=ui_Temp1<<8*data[2];
+ ui_Temp=ui_Temp|ui_Temp1;
+ data[0]=((data[0] << (8*data[2]))^0xffff)&ui_Temp;
+ break;
+ case 15: break;
+
+ default:
+ comedi_error(dev," chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+
+ }//switch(ui_NoOfChannels)
+
+ outw(data[0],devpriv->iobase+APCI2200_DIGITAL_OP);
+ }// 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_APCI2200_ReadDigitalOutput |
+| (comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,
+ lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Read value of the selected channel or port |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s, :pointer to subdevice structure
+ comedi_insn *insn :pointer to insn structure |
+| lsampl_t *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI2200_ReadDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+
+UINT ui_Temp;
+UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
+ui_Temp=data[0];
+*data=inw(devpriv->iobase+APCI2200_DIGITAL_OP);
+if(ui_Temp==0)
+ {
+ *data=(*data >> ui_NoOfChannel)&0x1;
+ }//if(ui_Temp==0)
+else
+ {
+ if(ui_Temp==1)
+ {
+ switch( ui_NoOfChannel)
+ {
+
+ case 2:*data=(*data >>(2*data[1]))&3;
+ break;
+
+
+ case 4:*data=(*data >>(4*data[1]))&15;
+ break;
+
+ case 8: *data=(*data >>(8*data[1]))&255;
+ break;
+
+ case 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)
+ }//elseif(ui_Temp==0)
+return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2200_ConfigWatchdog(comedi_device *dev,
+ comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : Configures The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s, :pointer to subdevice structure
+ comedi_insn *insn :pointer to insn structure |
+| lsampl_t *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI2200_ConfigWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+if(data[0]==0)
+ {
+ //Disable the watchdog
+ outw(0x0,devpriv->iobase+APCI2200_WATCHDOG + APCI2200_WATCHDOG_ENABLEDISABLE);
+ //Loading the Reload value
+ outw(data[1],devpriv->iobase+APCI2200_WATCHDOG + APCI2200_WATCHDOG_RELOAD_VALUE);
+ data[1]=data[1]>>16;
+ outw(data[1],devpriv->iobase+APCI2200_WATCHDOG + APCI2200_WATCHDOG_RELOAD_VALUE+2);
+ }//if(data[0]==0)
+else
+ {
+ printk("\nThe input parameters are wrong\n");
+ return -EINVAL;
+ }//elseif(data[0]==0)
+
+return insn->n;
+}
+
+ /*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2200_StartStopWriteWatchdog |
+| (comedi_device *dev,comedi_subdevice *s,
+ comedi_insn *insn,lsampl_t *data); |
++----------------------------------------------------------------------------+
+| Task : Start / Stop The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s, :pointer to subdevice structure
+ comedi_insn *insn :pointer to insn structure |
+| lsampl_t *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI2200_StartStopWriteWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ switch(data[0])
+ {
+ case 0://stop the watchdog
+ outw(0x0,devpriv->iobase+APCI2200_WATCHDOG + APCI2200_WATCHDOG_ENABLEDISABLE);//disable the watchdog
+ break;
+ case 1://start the watchdog
+ outw(0x0001,devpriv->iobase+APCI2200_WATCHDOG + APCI2200_WATCHDOG_ENABLEDISABLE);
+ break;
+ case 2://Software trigger
+ outw(0x0201,devpriv->iobase+APCI2200_WATCHDOG + APCI2200_WATCHDOG_ENABLEDISABLE);
+ break;
+ default:printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ }// switch(data[0])
+return insn->n;
+}
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2200_ReadWatchdog |
+| (comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,
+ lsampl_t *data); |
++----------------------------------------------------------------------------+
+| Task : Read The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s, :pointer to subdevice structure
+ comedi_insn *insn :pointer to insn structure |
+| lsampl_t *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI2200_ReadWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+ {
+ data[0]= inw(devpriv->iobase+APCI2200_WATCHDOG +APCI2200_WATCHDOG_STATUS)&0x1;
+return insn->n;
+}
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2200_Reset(comedi_device *dev) | |
++----------------------------------------------------------------------------+
+| Task :resets all the registers |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI2200_Reset(comedi_device *dev)
+{
+ outw(0x0 ,devpriv->iobase+APCI2200_DIGITAL_OP);//RESETS THE DIGITAL OUTPUTS
+ outw(0x0,devpriv->iobase+APCI2200_WATCHDOG + APCI2200_WATCHDOG_ENABLEDISABLE);
+ outw(0x0,devpriv->iobase+APCI2200_WATCHDOG +APCI2200_WATCHDOG_RELOAD_VALUE);
+ outw(0x0,devpriv->iobase+APCI2200_WATCHDOG +APCI2200_WATCHDOG_RELOAD_VALUE+2);
+ return 0;
+}
+
+
--- /dev/null
+/********* Definitions for APCI-2200 card *****/
+
+// Card Specific information
+#define APCI2200_BOARD_VENDOR_ID 0x15b8
+#define APCI2200_ADDRESS_RANGE 64
+
+
+//DIGITAL INPUT-OUTPUT DEFINE
+
+#define APCI2200_DIGITAL_OP 4
+#define APCI2200_DIGITAL_IP 0
+
+
+
+
+// TIMER COUNTER WATCHDOG DEFINES
+
+#define APCI2200_WATCHDOG 0x08
+#define APCI2200_WATCHDOG_ENABLEDISABLE 12
+#define APCI2200_WATCHDOG_RELOAD_VALUE 4
+#define APCI2200_WATCHDOG_STATUS 16
+
+
+// Hardware Layer functions for Apci2200
+
+
+//Digital Input
+INT i_APCI2200_ReadMoreDigitalInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+INT i_APCI2200_Read1DigitalInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+
+
+
+
+//Digital Output
+int i_APCI2200_ConfigDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+INT i_APCI2200_WriteDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+INT i_APCI2200_ReadDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) ;
+
+
+// TIMER
+int i_APCI2200_ConfigWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+int i_APCI2200_StartStopWriteWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+int i_APCI2200_ReadWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+
+
+//reset
+INT i_APCI2200_Reset(comedi_device *dev);
+
--- /dev/null
+
+
+
+/*
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstrasse 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 : ADDI DATA | Compiler : GCC |
+ | Modulname : hwdrv_apci3120.c | Version : 2.96 Redhat Linux |
+ | | kernel-2.4.2 |
+ +-------------------------------+---------------------------------------+
+ | Author : | Date : |
+ +-----------------------------------------------------------------------+
+ | Description :APCI3120 Module . Hardware abstraction Layer for APCI3120|
+ +-----------------------------------------------------------------------+
+ | UPDATE'S |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+
+
+
+
+#include "hwdrv_apci3120.h"
+static UINT ui_Temp=0;
+
+// FUNCTION DEFINITIONS
+
+/*
++----------------------------------------------------------------------------+
+| ANALOG INPUT SUBDEVICE |
++----------------------------------------------------------------------------+
+*/
+
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InsnConfigAnalogInput(comedi_device *dev,|
+| comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : Calls card specific function |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev |
+| comedi_subdevice *s |
+| comedi_insn *insn |
+| lsampl_t *data |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+
+
+
+int i_APCI3120_InsnConfigAnalogInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,
+ lsampl_t *data)
+{
+ UINT i;
+
+ if((data[0] != APCI3120_EOC_MODE) && (data[0] != APCI3120_EOS_MODE))
+ return -1 ;
+
+ // Check for Conversion time to be added ??
+ devpriv->ui_EocEosConversionTime=data[2];
+
+ if(data[0] == APCI3120_EOS_MODE)
+ {
+
+ //Test the number of the channel
+ for(i=0;i<data[3];i++)
+ {
+
+ if(CR_CHAN(data[4+i])>=this_board->i_NbrAiChannel)
+ {
+ printk("bad channel list\n");
+ return -2;
+ }
+ }
+
+ devpriv->b_InterruptMode= APCI3120_EOS_MODE;
+
+ if(data[1])
+ {
+ devpriv->b_EocEosInterrupt=APCI3120_ENABLE;
+ }
+ else devpriv->b_EocEosInterrupt=APCI3120_DISABLE;
+ // Copy channel list and Range List to devpriv
+
+ devpriv->ui_AiNbrofChannels= data[3];
+ for(i=0;i< devpriv->ui_AiNbrofChannels;i++)
+ {
+ devpriv->ui_AiChannelList[i]=data[4+i];
+ }
+
+
+ }
+ else // EOC
+ {
+ devpriv->b_InterruptMode=APCI3120_EOC_MODE;
+ if(data[1])
+ {
+ devpriv->b_EocEosInterrupt=APCI3120_ENABLE;
+ }
+ else
+ {
+ devpriv->b_EocEosInterrupt=APCI3120_DISABLE;
+ }
+ }
+
+ return insn->n;
+}
+
+
+
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InsnReadAnalogInput(comedi_device *dev, |
+| comedi_subdevice *s,comedi_insn *insn, lsampl_t *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : card specific function |
+| Reads analog input in synchronous mode |
+| EOC and EOS is selected as per configured |
+| if no conversion time is set uses default conversion |
+| time 10 microsec. |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev |
+| comedi_subdevice *s |
+| comedi_insn *insn |
+| lsampl_t *data |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_InsnReadAnalogInput(comedi_device *dev, comedi_subdevice *s,
+ comedi_insn *insn, lsampl_t *data)
+{
+ USHORT us_ConvertTiming,us_TmpValue,i;
+ BYTE b_Tmp;
+
+ // fix convertion time to 10 us
+ if(!devpriv->ui_EocEosConversionTime)
+ {
+ printk("No timer0 Value using 10 us\n");
+ us_ConvertTiming=10;
+ }
+ else us_ConvertTiming =(USHORT) (devpriv->ui_EocEosConversionTime/1000);// nano to useconds
+
+ // this_board->i_hwdrv_InsnReadAnalogInput(dev,us_ConvertTiming,insn->n,&insn->chanspec,data,insn->unused[0]);
+
+ // Clear software registers
+ devpriv->b_TimerSelectMode=0;
+ devpriv->b_ModeSelectRegister=0;
+ devpriv->us_OutputRegister=0;
+ devpriv->b_DigitalOutputRegister=0;
+
+ if(insn->unused[0]==222)// second insn read
+ {
+
+ for(i=0;i< insn->n;i++)
+ {
+ data[i]=devpriv->ui_AiReadData[i];
+ }
+
+ }
+ else
+ {
+ devpriv->tsk_Current=current; // Save the current process task structure
+ //Testing if board have the new Quartz and calculate the time value
+ //to set in the timer
+
+ us_TmpValue=(USHORT) inw(devpriv->iobase+APCI3120_RD_STATUS);
+ if((us_TmpValue & 0x00B0)==0x00B0)
+ {
+ us_ConvertTiming=(us_ConvertTiming * 2) -2;
+ }
+ else
+ {
+ us_ConvertTiming=((us_ConvertTiming * 12926)/10000) -1;
+
+ }
+
+ us_TmpValue=(USHORT)devpriv->b_InterruptMode;
+
+ switch(us_TmpValue)
+ {
+
+ case APCI3120_EOC_MODE:
+
+
+
+ // Testing the interrupt flag and set the EOC bit
+ // Clears the FIFO
+ inw(devpriv->iobase+APCI3120_RESET_FIFO);
+
+
+ // Initialize the sequence array
+
+ //if (!i_APCI3120_SetupChannelList(dev,s,1,chanlist,0)) return -EINVAL;
+
+ if (!i_APCI3120_SetupChannelList(dev,s,1,&insn->chanspec,0)) return -EINVAL;
+
+ //Initialize Timer 0 mode 4
+ devpriv->b_TimerSelectMode=(devpriv->b_TimerSelectMode & 0xFC) |APCI3120_TIMER_0_MODE_4;
+ outb(devpriv->b_TimerSelectMode,devpriv->iobase+APCI3120_TIMER_CRT1);
+
+ // Reset the scan bit and Disables the EOS, DMA, EOC interrupt
+ devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister & APCI3120_DISABLE_SCAN;
+
+ if(devpriv->b_EocEosInterrupt==APCI3120_ENABLE)
+ {
+
+ //Disables the EOS,DMA and enables the EOC interrupt
+ devpriv->b_ModeSelectRegister=(devpriv->b_ModeSelectRegister & APCI3120_DISABLE_EOS_INT) | APCI3120_ENABLE_EOC_INT;
+ inw(devpriv->iobase);
+
+ }
+ else
+ {
+ devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister & APCI3120_DISABLE_ALL_INTERRUPT_WITHOUT_TIMER;
+ }
+
+ outb(devpriv->b_ModeSelectRegister,devpriv->iobase+APCI3120_WRITE_MODE_SELECT);
+
+ // Sets gate 0
+ devpriv->us_OutputRegister=(devpriv->us_OutputRegister & APCI3120_CLEAR_PA_PR) | APCI3120_ENABLE_TIMER0;
+ outw(devpriv->us_OutputRegister,devpriv->iobase+APCI3120_WR_ADDRESS);
+
+ // Select Timer 0
+ b_Tmp=((devpriv->b_DigitalOutputRegister<<4) & 0xF0) | APCI3120_SELECT_TIMER_0_WORD;
+ outb(b_Tmp,devpriv->iobase+APCI3120_TIMER_CRT0);
+
+
+ //Set the convertion time
+ outw(us_ConvertTiming,devpriv->iobase+APCI3120_TIMER_VALUE);
+
+ us_TmpValue=(USHORT) inw(dev->iobase+APCI3120_RD_STATUS);
+
+
+ if(devpriv->b_EocEosInterrupt==APCI3120_DISABLE)
+ {
+
+ do
+ {
+ // Waiting for the end of conversion
+ us_TmpValue=inw(devpriv->iobase+APCI3120_RD_STATUS);
+ }while((us_TmpValue & APCI3120_EOC)==APCI3120_EOC);
+
+ //Read the result in FIFO and put it in insn data pointer
+ us_TmpValue=inw(devpriv->iobase+0);
+ *data=us_TmpValue;
+
+ inw(devpriv->iobase+APCI3120_RESET_FIFO);
+ }
+
+ break;
+
+
+ case APCI3120_EOS_MODE:
+
+ inw(devpriv->iobase);
+ // Clears the FIFO
+ inw(devpriv->iobase+APCI3120_RESET_FIFO);
+ // clear PA PR and disable timer 0
+
+ devpriv->us_OutputRegister=(devpriv->us_OutputRegister & APCI3120_CLEAR_PA_PR) | APCI3120_DISABLE_TIMER0;
+
+ outw(devpriv->us_OutputRegister,devpriv->iobase+APCI3120_WR_ADDRESS);
+
+
+ if (!i_APCI3120_SetupChannelList(dev,s,devpriv->ui_AiNbrofChannels,devpriv->ui_AiChannelList,0)) return -EINVAL;
+
+ //Initialize Timer 0 mode 2
+ devpriv->b_TimerSelectMode = (devpriv->b_TimerSelectMode & 0xFC) | APCI3120_TIMER_0_MODE_2;
+ outb(devpriv->b_TimerSelectMode,devpriv->iobase+APCI3120_TIMER_CRT1);
+
+
+ //Select Timer 0
+ b_Tmp=((devpriv->b_DigitalOutputRegister<<4) & 0xF0) | APCI3120_SELECT_TIMER_0_WORD;
+ outb(b_Tmp,devpriv->iobase+APCI3120_TIMER_CRT0);
+
+ //Set the convertion time
+ outw(us_ConvertTiming,devpriv->iobase+APCI3120_TIMER_VALUE);
+
+ //Set the scan bit
+ devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister | APCI3120_ENABLE_SCAN;
+ outb(devpriv->b_ModeSelectRegister,devpriv->iobase+APCI3120_WRITE_MODE_SELECT);
+
+ //If Interrupt function is loaded
+ if(devpriv->b_EocEosInterrupt==APCI3120_ENABLE)
+ {
+ //Disables the EOC,DMA and enables the EOS interrupt
+ devpriv->b_ModeSelectRegister=(devpriv->b_ModeSelectRegister & APCI3120_DISABLE_EOC_INT) | APCI3120_ENABLE_EOS_INT;
+ inw(devpriv->iobase);
+
+
+ }
+ else
+ devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister & APCI3120_DISABLE_ALL_INTERRUPT_WITHOUT_TIMER;
+
+ outb(devpriv->b_ModeSelectRegister,devpriv->iobase+APCI3120_WRITE_MODE_SELECT);
+
+ inw(devpriv->iobase+APCI3120_RD_STATUS);
+
+ //Sets gate 0
+
+ devpriv->us_OutputRegister=devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER0;
+ outw(devpriv->us_OutputRegister,devpriv->iobase+APCI3120_WR_ADDRESS);
+
+ //Start conversion
+ outw(0,devpriv->iobase+APCI3120_START_CONVERSION);
+
+ //Waiting of end of convertion if interrupt is not installed
+ if(devpriv->b_EocEosInterrupt==APCI3120_DISABLE)
+ {
+ //Waiting the end of convertion
+ do
+ {
+ us_TmpValue=inw(devpriv->iobase+APCI3120_RD_STATUS);
+ }
+ while((us_TmpValue & APCI3120_EOS)!=APCI3120_EOS);
+
+ for(i=0;i< devpriv->ui_AiNbrofChannels;i++)
+ {
+ //Read the result in FIFO and write them in shared memory
+ us_TmpValue=inw(devpriv->iobase);
+ data[i]=(UINT) us_TmpValue;
+
+ }
+
+ devpriv->b_InterruptMode = APCI3120_EOC_MODE; // Restore defaults.
+ }
+ break;
+
+ default:
+ printk("inputs wrong\n");
+
+ }
+ devpriv->ui_EocEosConversionTime=0;// re initializing the variable;
+ }
+
+ return insn->n;
+
+}
+
+
+
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_StopCyclicAcquisition(comedi_device *dev,|
+| comedi_subdevice *s)|
+| |
++----------------------------------------------------------------------------+
+| Task : Stops Cyclic acquisition |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev |
+| comedi_subdevice *s |
+| |
++----------------------------------------------------------------------------+
+| Return Value :0 |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_StopCyclicAcquisition(comedi_device *dev,comedi_subdevice *s)
+{
+ // Disable A2P Fifo write and AMWEN signal
+ outw(0,devpriv->i_IobaseAddon + 4);
+
+ //Disable Bus Master ADD ON
+ outw(APCI3120_ADD_ON_AGCSTS_LOW,devpriv->i_IobaseAddon+0);
+ outw(0,devpriv->i_IobaseAddon+2);
+ outw(APCI3120_ADD_ON_AGCSTS_HIGH,devpriv->i_IobaseAddon+0);
+ outw(0,devpriv->i_IobaseAddon+2);
+
+ //Disable BUS Master PCI
+ outl(0,devpriv->i_IobaseAmcc+AMCC_OP_REG_MCSR );
+
+ //outl(inl(devpriv->i_IobaseAmcc+AMCC_OP_REG_INTCSR)&(~AINT_WRITE_COMPL), devpriv->i_IobaseAmcc+AMCC_OP_REG_INTCSR); // stop amcc irqs
+ //outl(inl(devpriv->i_IobaseAmcc+AMCC_OP_REG_MCSR)&(~EN_A2P_TRANSFERS), devpriv->i_IobaseAmcc+AMCC_OP_REG_MCSR); // stop DMA
+
+
+ //Disable ext trigger
+ i_APCI3120_ExttrigDisable(dev);
+
+ devpriv->us_OutputRegister=0;
+ //stop counters
+ outw(devpriv->us_OutputRegister & APCI3120_DISABLE_TIMER0 & APCI3120_DISABLE_TIMER1,dev->iobase+APCI3120_WR_ADDRESS);
+
+ outw(APCI3120_DISABLE_ALL_TIMER,dev->iobase+APCI3120_WR_ADDRESS);
+
+ //DISABLE_ALL_INTERRUPT
+ outb(APCI3120_DISABLE_ALL_INTERRUPT,dev->iobase+APCI3120_WRITE_MODE_SELECT);
+ //Flush FIFO
+ inb(dev->iobase+APCI3120_RESET_FIFO);
+ inw(dev->iobase+APCI3120_RD_STATUS);
+ devpriv->ui_AiActualScan=0;
+ devpriv->ui_AiActualScanPosition=0;
+ s->async->cur_chan=0;
+ devpriv->ui_AiBufferPtr=0;
+ devpriv->b_AiContinuous=0;
+ devpriv->ui_DmaActualBuffer=0;
+
+ devpriv->b_AiCyclicAcquisition=APCI3120_DISABLE;
+ devpriv->b_InterruptMode=APCI3120_EOC_MODE;
+ devpriv->b_EocEosInterrupt=APCI3120_DISABLE;
+ i_APCI3120_Reset(dev);
+ //printk("Stopped cyclic acquisition\n");
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_CommandTestAnalogInput(comedi_device *dev|
+| ,comedi_subdevice *s,comedi_cmd *cmd) |
+| |
++----------------------------------------------------------------------------+
+| Task : Test validity for a command for cyclic anlog input |
+| acquisition |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev |
+| comedi_subdevice *s |
+| comedi_cmd *cmd |
++----------------------------------------------------------------------------+
+| Return Value :0 |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_CommandTestAnalogInput(comedi_device *dev,comedi_subdevice *s,comedi_cmd *cmd)
+ {
+ int err=0;
+ int tmp;// divisor1,divisor2;
+
+ // 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(err) return 1;
+
+
+ //step 2: make sure trigger sources are unique and mutually compatible
+
+ if(cmd->start_src!=TRIG_NOW && cmd->start_src!=TRIG_EXT)
+ {
+ err++;
+ }
+
+
+ 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) return 2;
+
+
+ // step 3: make sure arguments are trivially compatible
+
+ if(cmd->start_arg!=0)
+ {
+ cmd->start_arg=0;
+ err++;
+ }
+
+ if(cmd->scan_begin_src==TRIG_TIMER) // Test Delay timing
+ {
+ if(cmd->scan_begin_arg<this_board->ui_MinDelaytimeNs)
+ {
+ cmd->scan_begin_arg=this_board->ui_MinDelaytimeNs;
+ err++;
+ }
+ }
+
+
+
+
+ if(cmd->convert_src==TRIG_TIMER) // Test Acquisition timing
+ {
+ if (cmd->scan_begin_src==TRIG_TIMER)
+ {
+ if((cmd->convert_arg)&&(cmd->convert_arg<this_board->ui_MinAcquisitiontimeNs))
+ {
+ cmd->convert_arg=this_board->ui_MinAcquisitiontimeNs;
+ err++;
+ }
+ }
+ else
+ {
+ if(cmd->convert_arg<this_board->ui_MinAcquisitiontimeNs)
+ {
+ cmd->convert_arg=this_board->ui_MinAcquisitiontimeNs;
+ err++;
+
+ }
+ }
+ }
+
+
+ if(!cmd->chanlist_len)
+ {
+ cmd->chanlist_len=1;
+ err++;
+ }
+ if(cmd->chanlist_len > this_board->i_AiChannelList)
+ {
+ cmd->chanlist_len=this_board->i_AiChannelList;
+ err++;
+ }
+ if(cmd->stop_src==TRIG_COUNT)
+ {
+ if(!cmd->stop_arg)
+ {
+ cmd->stop_arg=1;
+ err++;
+ }
+ }
+ else
+ { // TRIG_NONE
+ if(cmd->stop_arg!=0){
+ cmd->stop_arg=0;
+ err++;
+ }
+ }
+
+ if(err) return 3;
+
+ // step 4: fix up any arguments
+
+
+
+ if(cmd->convert_src==TRIG_TIMER)
+ {
+
+ if(cmd->scan_begin_src==TRIG_TIMER &&
+ cmd->scan_begin_arg<cmd->convert_arg*cmd->scan_end_arg)
+ {
+ cmd->scan_begin_arg=cmd->convert_arg*cmd->scan_end_arg;
+ err++;
+ }
+ }
+
+ if(err)return 4;
+
+
+ return 0;
+ }
+
+
+/*
++----------------------------------------------------------------------------+
+| Function name : int i_APCI3120_CommandAnalogInput(comedi_device *dev, |
+| comedi_subdevice *s) |
+| |
++----------------------------------------------------------------------------+
+| Task : Does asynchronous acquisition |
+| Determines the mode 1 or 2. |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev |
+| comedi_subdevice *s |
+| |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+ int i_APCI3120_CommandAnalogInput(comedi_device *dev,comedi_subdevice *s)
+{
+ comedi_cmd *cmd=&s->async->cmd;
+
+ //loading private structure with cmd structure inputs
+ devpriv->ui_AiFlags=cmd->flags;
+ devpriv->ui_AiNbrofChannels=cmd->chanlist_len;
+ devpriv->ui_AiScanLength=cmd->scan_end_arg;
+ devpriv->pui_AiChannelList=cmd->chanlist;
+ devpriv->AiData=s->async->data;
+ devpriv->ui_AiDataLength=s->async->data_len;
+
+ if (cmd->stop_src==TRIG_COUNT)
+ {
+ devpriv->ui_AiNbrofScans=cmd->stop_arg;
+ }
+ else
+ {
+ devpriv->ui_AiNbrofScans=0;
+ }
+
+ devpriv->ui_AiTimer0=0; // variables changed to timer0,timer1
+ devpriv->ui_AiTimer1=0;
+ if ((devpriv->ui_AiNbrofScans==0)||(devpriv->ui_AiNbrofScans==-1))
+ devpriv->b_AiContinuous=1; // user want neverending analog acquisition
+ // stopped using cancel
+
+ if(cmd->start_src==TRIG_EXT)
+ devpriv->b_ExttrigEnable = APCI3120_ENABLE;
+ else
+ devpriv->b_ExttrigEnable = APCI3120_DISABLE;
+
+ if(cmd->scan_begin_src==TRIG_FOLLOW)
+ {
+ // mode 1 or 3
+ if (cmd->convert_src==TRIG_TIMER)
+ {
+ // mode 1
+
+ devpriv->ui_AiTimer0=cmd->convert_arg;// timer constant in nano seconds
+ //return this_board->i_hwdrv_CommandAnalogInput(1,dev,s);
+ return i_APCI3120_CyclicAnalogInput(1,dev,s);
+ }
+
+ }
+ if((cmd->scan_begin_src==TRIG_TIMER)&&(cmd->convert_src==TRIG_TIMER))
+ {
+ // mode 2
+ devpriv->ui_AiTimer1=cmd->scan_begin_arg;
+ devpriv->ui_AiTimer0=cmd->convert_arg;// variable changed timer2 to timer0
+ //return this_board->i_hwdrv_CommandAnalogInput(2,dev,s);
+ return i_APCI3120_CyclicAnalogInput(2,dev,s);
+ }
+ return -1;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name : int i_APCI3120_CyclicAnalogInput(int mode, |
+| comedi_device * dev,comedi_subdevice * s) |
++----------------------------------------------------------------------------+
+| Task : This is used for analog input cyclic acquisition |
+| Performs the command operations. |
+| If DMA is configured does DMA initialization |
+| otherwise does the acquisition with EOS interrupt. |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : |
+| |
+| |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_CyclicAnalogInput(int mode, comedi_device * dev,comedi_subdevice * s)
+{
+ float f_DelayValue,f_ConvertValue;
+ BYTE b_Tmp;
+ UINT ui_Tmp,ui_DelayTiming=0,ui_TimerValue1=0,dmalen0=0,dmalen1=0,ui_TimerValue2=0,ui_TimerValue0,ui_ConvertTiming;
+ USHORT us_TmpValue;
+
+ devpriv->b_AiCyclicAcquisition=APCI3120_ENABLE;
+ //Flush FIFO
+ inb(dev->iobase+APCI3120_RESET_FIFO);
+ inw(dev->iobase+APCI3120_RD_STATUS);
+
+
+ // clear software registers
+
+ devpriv->b_TimerSelectMode=0;
+ devpriv->b_DigitalOutputRegister=0;
+ devpriv->us_OutputRegister=0;
+ devpriv->b_ModeSelectRegister=0;
+
+ /****************************/
+ /* Clear Timer Write TC INT */
+ /****************************/
+
+ outl(APCI3120_CLEAR_WRITE_TC_INT,devpriv->i_IobaseAmcc+ APCI3120_AMCC_OP_REG_INTCSR);
+
+ /************************************/
+ /* Clears the timer status register */
+ /************************************/
+ inw(dev->iobase+APCI3120_TIMER_STATUS_REGISTER);
+
+
+ /**************************/
+ /* Disables All Timer */
+ /* Sets PR and PA to 0 */
+ /**************************/
+
+ devpriv->us_OutputRegister = devpriv->us_OutputRegister &APCI3120_DISABLE_TIMER0 & APCI3120_DISABLE_TIMER1 &APCI3120_CLEAR_PA_PR ;
+ outw(devpriv->us_OutputRegister,dev->iobase+APCI3120_WR_ADDRESS);
+
+
+ devpriv->ui_AiActualScan=0;
+ devpriv->ui_AiActualScanPosition=0;
+ s->async->cur_chan=0;
+ devpriv->ui_AiBufferPtr=0;
+ devpriv->ui_DmaActualBuffer=0;
+
+
+
+
+ ui_TimerValue2 = devpriv->ui_AiNbrofScans-2; // value for timer2 minus -2 has to be done .....dunno y??
+ ui_ConvertTiming=devpriv->ui_AiTimer0;
+
+ if(mode==2) ui_DelayTiming = devpriv->ui_AiTimer1;
+
+
+ // initialise sequence ram
+
+ if (!i_APCI3120_SetupChannelList(dev, s, devpriv->ui_AiNbrofChannels, devpriv->pui_AiChannelList, 0))
+ return -EINVAL;
+
+ us_TmpValue=(USHORT) inw(dev->iobase+APCI3120_RD_STATUS);
+ if((us_TmpValue & 0x00B0)==0x00B0)
+ {
+ f_ConvertValue=(((float)ui_ConvertTiming * 0.002) - 2);
+ ui_TimerValue0=(UINT)f_ConvertValue;
+ if (mode==2)
+ {
+ f_DelayValue = (((float)ui_DelayTiming * 0.00002) - 2);
+ ui_TimerValue1 = (UINT) f_DelayValue;
+ }
+ }
+ else
+ {
+ f_ConvertValue=(((float)ui_ConvertTiming * 0.0012926) - 1);
+ ui_TimerValue0=(UINT)f_ConvertValue;
+ if (mode == 2)
+ {
+ f_DelayValue = (((float)ui_DelayTiming * 0.000012926) - 1);
+ ui_TimerValue1 = (UINT) f_DelayValue;
+ }
+ }
+
+ if(devpriv->b_ExttrigEnable==APCI3120_ENABLE)
+ {
+ i_APCI3120_ExttrigEnable(dev); // activate EXT trigger
+ }
+ switch(mode)
+ {
+ case 1:
+ // init timer0 in mode 2
+ devpriv->b_TimerSelectMode=(devpriv->b_TimerSelectMode& 0xFC) | APCI3120_TIMER_0_MODE_2;
+ outb(devpriv->b_TimerSelectMode,dev->iobase+APCI3120_TIMER_CRT1);
+
+ //Select Timer 0
+ b_Tmp=((devpriv->b_DigitalOutputRegister<<4) & 0xF0) | APCI3120_SELECT_TIMER_0_WORD;
+ outb(b_Tmp,dev->iobase+APCI3120_TIMER_CRT0);
+
+ //Set the convertion time
+ outw(((USHORT)ui_TimerValue0),dev->iobase+APCI3120_TIMER_VALUE);
+ break;
+
+ case 2:
+ // init timer1 in mode 2
+ devpriv->b_TimerSelectMode=(devpriv->b_TimerSelectMode& 0xF3) | APCI3120_TIMER_1_MODE_2;
+ outb(devpriv->b_TimerSelectMode,dev->iobase+APCI3120_TIMER_CRT1);
+
+ //Select Timer 1
+ b_Tmp=((devpriv->b_DigitalOutputRegister) & 0xF0) | APCI3120_SELECT_TIMER_1_WORD;
+ outb(b_Tmp,dev->iobase+APCI3120_TIMER_CRT0);
+
+ //Set the convertion time
+ outw(((USHORT)ui_TimerValue1),dev->iobase+APCI3120_TIMER_VALUE);
+
+ // init timer0 in mode 2
+ devpriv->b_TimerSelectMode=(devpriv->b_TimerSelectMode& 0xFC) | APCI3120_TIMER_0_MODE_2;
+ outb(devpriv->b_TimerSelectMode,dev->iobase+APCI3120_TIMER_CRT1);
+
+ //Select Timer 0
+ b_Tmp=((devpriv->b_DigitalOutputRegister<<4) & 0xF0) | APCI3120_SELECT_TIMER_0_WORD;
+ outb(b_Tmp,dev->iobase+APCI3120_TIMER_CRT0);
+
+ //Set the convertion time
+ outw(((USHORT)ui_TimerValue0),dev->iobase+APCI3120_TIMER_VALUE);
+ break;
+
+ }
+ // ##########common for all modes#################
+
+ //disable the scan bit
+ devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister | APCI3120_DISABLE_SCAN;
+ outb(devpriv->b_ModeSelectRegister,dev->iobase+APCI3120_WRITE_MODE_SELECT);
+
+ // If DMA is disabled
+ if(devpriv->us_UseDma==APCI3120_DISABLE)
+ {
+ // disable EOC and enable EOS
+ devpriv->b_InterruptMode=APCI3120_EOS_MODE;
+ devpriv->b_EocEosInterrupt=APCI3120_ENABLE;
+
+ devpriv->b_ModeSelectRegister = (devpriv->b_ModeSelectRegister & APCI3120_DISABLE_EOC_INT) | APCI3120_ENABLE_EOS_INT;
+ outb(devpriv->b_ModeSelectRegister,dev->iobase+APCI3120_WRITE_MODE_SELECT);
+
+
+ if (!devpriv->b_AiContinuous)
+ {
+ // configure Timer2 For counting EOS
+ //Reset gate 2 of Timer 2 to disable it (Set Bit D14 to 0)
+ devpriv->us_OutputRegister=devpriv->us_OutputRegister & APCI3120_DISABLE_TIMER2 ;
+ outw(devpriv->us_OutputRegister,dev->iobase+APCI3120_WR_ADDRESS);
+
+ // DISABLE TIMER INTERRUPT
+ devpriv->b_ModeSelectRegister = devpriv->b_ModeSelectRegister & APCI3120_DISABLE_TIMER_INT & 0xEF;
+ outb(devpriv->b_ModeSelectRegister,dev->iobase + APCI3120_WRITE_MODE_SELECT);
+
+ //(1) Init timer 2 in mode 0 and write timer value
+ devpriv->b_TimerSelectMode=(devpriv->b_TimerSelectMode & 0x0F) | APCI3120_TIMER_2_MODE_0;
+ outb(devpriv->b_TimerSelectMode,dev->iobase+APCI3120_TIMER_CRT1);
+
+ //Writing LOW WORD
+ b_Tmp=((devpriv->b_DigitalOutputRegister<<4) & 0xF0) | APCI3120_SELECT_TIMER_2_LOW_WORD;
+ outb(b_Tmp,dev->iobase+APCI3120_TIMER_CRT0);
+ outw(LOWORD(ui_TimerValue2),dev->iobase+APCI3120_TIMER_VALUE);
+
+ //Writing HIGH WORD
+ b_Tmp=((devpriv->b_DigitalOutputRegister<<4) & 0xF0) | APCI3120_SELECT_TIMER_2_HIGH_WORD;
+ outb(b_Tmp,dev->iobase+APCI3120_TIMER_CRT0);
+ outw(HIWORD(ui_TimerValue2),dev->iobase+APCI3120_TIMER_VALUE);
+
+ //(2) Reset FC_TIMER BIT Clearing timer status register
+ inb(dev->iobase+APCI3120_TIMER_STATUS_REGISTER);
+ // enable timer counter and disable watch dog
+ devpriv->b_ModeSelectRegister=(devpriv->b_ModeSelectRegister| APCI3120_ENABLE_TIMER_COUNTER) & APCI3120_DISABLE_WATCHDOG;
+ // select EOS clock input for timer 2
+ devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister| APCI3120_TIMER2_SELECT_EOS;
+ // Enable timer2 interrupt
+ devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister| APCI3120_ENABLE_TIMER_INT;
+ outb(devpriv->b_ModeSelectRegister,dev->iobase+APCI3120_WRITE_MODE_SELECT);
+ devpriv->b_Timer2Mode=APCI3120_COUNTER;
+ devpriv->b_Timer2Interrupt=APCI3120_ENABLE;
+ }
+ }
+ else
+ {
+ // If DMA Enabled
+ inw(dev->iobase+0);// reset EOC bit
+ devpriv->b_InterruptMode=APCI3120_DMA_MODE;
+
+ // disable EOC and EOS interrupt
+ devpriv->b_ModeSelectRegister = devpriv->b_ModeSelectRegister & APCI3120_DISABLE_EOC_INT & APCI3120_DISABLE_EOS_INT;
+
+ outb(devpriv->b_ModeSelectRegister,dev->iobase+APCI3120_WRITE_MODE_SELECT);
+
+
+ dmalen0=devpriv->ui_DmaBufferSize[0];
+ dmalen1=devpriv->ui_DmaBufferSize[1];
+
+ if (!devpriv->b_AiContinuous)
+ {
+
+ if (dmalen0>(devpriv->ui_AiNbrofScans*devpriv->ui_AiScanLength*2))
+ { // must we fill full first buffer?
+ dmalen0=devpriv->ui_AiNbrofScans*devpriv->ui_AiScanLength*2;
+ }
+ else
+ if (dmalen1>(devpriv->ui_AiNbrofScans*devpriv->ui_AiScanLength*2-dmalen0)) // and must we fill full second buffer when first is once filled?
+ dmalen1=devpriv->ui_AiNbrofScans*devpriv->ui_AiScanLength*2-dmalen0;
+ }
+
+ if (devpriv->ui_AiFlags & TRIG_WAKE_EOS)
+ {
+ // don't we want wake up every scan?
+ if (dmalen0>(devpriv->ui_AiScanLength*2))
+ {
+ dmalen0=devpriv->ui_AiScanLength*2;
+ if (devpriv->ui_AiScanLength&1) dmalen0+=2;
+ }
+ if (dmalen1>(devpriv->ui_AiScanLength*2))
+ {
+ dmalen1=devpriv->ui_AiScanLength*2;
+ if (devpriv->ui_AiScanLength&1) dmalen1-=2;
+ if (dmalen1<4) dmalen1=4;
+ }
+ }
+ else
+ { // isn't output buff smaller that our DMA buff?
+ if (dmalen0>(devpriv->ui_AiDataLength))
+ {
+ dmalen0=devpriv->ui_AiDataLength;
+ }
+ if (dmalen1>(devpriv->ui_AiDataLength))
+ {
+ dmalen1=devpriv->ui_AiDataLength;
+ }
+ }
+ devpriv->ui_DmaBufferUsesize[0]=dmalen0;
+ devpriv->ui_DmaBufferUsesize[1]=dmalen1;
+
+
+ //Initialize DMA
+
+ // Set Transfer count enable bit and A2P_fifo reset bit in AGCSTS register
+ //1
+ ui_Tmp=AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO ;
+ outl(ui_Tmp,devpriv->i_IobaseAmcc+AMCC_OP_REG_AGCSTS);
+
+ // changed since 16 bit interface for add on
+ outw(APCI3120_ADD_ON_AGCSTS_LOW,devpriv->i_IobaseAddon+0);
+ outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW,devpriv->i_IobaseAddon+2);
+ outw(APCI3120_ADD_ON_AGCSTS_HIGH,devpriv->i_IobaseAddon+0);
+ outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH,devpriv->i_IobaseAddon+2);
+ //2 No change
+ // A2P FIFO MANAGEMENT
+ // A2P fifo reset & transfer control enable
+ outl(APCI3120_A2P_FIFO_MANAGEMENT,devpriv->i_IobaseAmcc+AMCC_OP_REG_MCSR );
+
+ //3
+ //beginning address of dma buf
+ //The 32 bit address of dma buffer is converted into two 16 bit addresses
+ // Can done by using _attach and put into into an array
+ // array used may be for differnet pages
+
+ // DMA Start Adress Low
+ outw(APCI3120_ADD_ON_MWAR_LOW,devpriv->i_IobaseAddon+0);
+ outw((devpriv->ul_DmaBufferHw[0]& 0xFFFF),devpriv->i_IobaseAddon+2);
+
+ // DMA Start Adress High
+ outw(APCI3120_ADD_ON_MWAR_HIGH,devpriv->i_IobaseAddon+0);
+
+ // outw((devpriv->ul_DmaBufferHw[0]/65536),devpriv->i_IobaseAddon+2);
+ outw((devpriv->ul_DmaBufferHw[0]/65536),devpriv->i_IobaseAddon+2);
+
+ //4
+ // amount of bytes to be transfered set transfer count
+ // used ADDON MWTC register
+ //commented testing outl(devpriv->ui_DmaBufferUsesize[0], devpriv->i_IobaseAddon+AMCC_OP_REG_AMWTC);
+ // Nbr of acquisition LOW
+
+ outw(APCI3120_ADD_ON_MWTC_LOW,devpriv->i_IobaseAddon + 0);
+ outw((devpriv->ui_DmaBufferUsesize[0] & 0xFFFF),devpriv->i_IobaseAddon + 2);
+
+ // Nbr of acquisition HIGH
+ outw(APCI3120_ADD_ON_MWTC_HIGH,devpriv->i_IobaseAddon + 0);
+ outw((devpriv->ui_DmaBufferUsesize[0]/65536),devpriv->i_IobaseAddon + 2);
+
+ //5
+ // To configure A2P FIFO
+ // testing outl( FIFO_ADVANCE_ON_BYTE_2,devpriv->i_IobaseAmcc+AMCC_OP_REG_INTCSR);
+
+ //6
+ //ENABLE A2P FIFO WRITE AND ENABLE AMWEN
+ // AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03
+ outw(3,devpriv->i_IobaseAddon + 4);
+
+ //7
+ //initialise end of dma interrupt AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI)
+ outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2| APCI3120_ENABLE_WRITE_TC_INT), devpriv->i_IobaseAmcc+AMCC_OP_REG_INTCSR);
+
+ }
+
+ if ((devpriv->us_UseDma==APCI3120_DISABLE) && !devpriv->b_AiContinuous)
+ {
+ // set gate 2 to start conversion
+ devpriv->us_OutputRegister = devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER2;
+ outw(devpriv->us_OutputRegister,dev->iobase+APCI3120_WR_ADDRESS);
+ }
+
+
+ switch(mode)
+ {
+ case 1:
+ // set gate 0 to start conversion
+ devpriv->us_OutputRegister = devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER0;
+ outw(devpriv->us_OutputRegister,dev->iobase+APCI3120_WR_ADDRESS);
+ break;
+ case 2:
+ // set gate 0 and gate 1
+ devpriv->us_OutputRegister= devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER1;
+ devpriv->us_OutputRegister= devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER0;
+ outw(devpriv->us_OutputRegister,dev->iobase+APCI3120_WR_ADDRESS);
+ break;
+
+ }
+
+ return 0;
+
+}
+
+
+
+
+
+/*
++----------------------------------------------------------------------------+
+| INTERNAL FUNCTIONS |
++----------------------------------------------------------------------------+
+*/
+
+
+/*
++----------------------------------------------------------------------------+
+| Function name : int i_APCI3120_Reset(comedi_device *dev) |
+| |
+| |
++----------------------------------------------------------------------------+
+| Task : Hardware reset function |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev |
+| |
+| |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_Reset(comedi_device *dev)
+{
+ unsigned int i;
+ unsigned short us_TmpValue;
+ devpriv->b_AiCyclicAcquisition=APCI3120_DISABLE;
+ devpriv->b_EocEosInterrupt=APCI3120_DISABLE;
+ devpriv->b_InterruptMode=APCI3120_EOC_MODE;
+ devpriv->ui_EocEosConversionTime=0; // set eoc eos conv time to 0
+ devpriv->b_OutputMemoryStatus =0;
+
+ // variables used in timer subdevice
+ devpriv->b_Timer2Mode=0;
+ devpriv->b_Timer2Interrupt=0;
+ devpriv->b_ExttrigEnable=0; // Disable ext trigger
+
+ /* Disable all interrupts, watchdog for the anolog output */
+ devpriv->b_ModeSelectRegister=0;
+ outb(devpriv->b_ModeSelectRegister,dev->iobase+APCI3120_WRITE_MODE_SELECT);
+
+ // Disables all counters, ext trigger and clears PA, PR
+ devpriv->us_OutputRegister=0;
+ outw(devpriv->us_OutputRegister,dev->iobase+APCI3120_WR_ADDRESS);
+
+ //Code to set the all anolog o/p channel to 0v
+ //8191 is decimal value for zero(0 v)volt in bipolar mode(default)
+ outw(8191|APCI3120_ANALOG_OP_CHANNEL_1, dev->iobase+APCI3120_ANALOG_OUTPUT_1);//channel 1
+ outw(8191|APCI3120_ANALOG_OP_CHANNEL_2, dev->iobase+APCI3120_ANALOG_OUTPUT_1);//channel 2
+ outw(8191|APCI3120_ANALOG_OP_CHANNEL_3, dev->iobase+APCI3120_ANALOG_OUTPUT_1);//channel 3
+ outw(8191|APCI3120_ANALOG_OP_CHANNEL_4, dev->iobase+APCI3120_ANALOG_OUTPUT_1);//channel 4
+
+ outw(8191|APCI3120_ANALOG_OP_CHANNEL_5, dev->iobase+APCI3120_ANALOG_OUTPUT_2);//channel 5
+ outw(8191|APCI3120_ANALOG_OP_CHANNEL_6, dev->iobase+APCI3120_ANALOG_OUTPUT_2);//channel 6
+ outw(8191|APCI3120_ANALOG_OP_CHANNEL_7, dev->iobase+APCI3120_ANALOG_OUTPUT_2);//channel 7
+ outw(8191|APCI3120_ANALOG_OP_CHANNEL_8, dev->iobase+APCI3120_ANALOG_OUTPUT_2);//channel 8
+
+ // Reset digital output to L0W
+
+ outb(0x0,dev->iobase+APCI3120_DIGITAL_OUTPUT);
+ udelay(10);
+
+ inw(dev->iobase+0); //make a dummy read
+ inb(dev->iobase+APCI3120_RESET_FIFO); // flush FIFO
+ inw(dev->iobase+APCI3120_RD_STATUS); // flush A/D status register
+
+ //code to reset the RAM sequence
+ for (i=0;i<16;i++)
+ {
+ us_TmpValue = i<<8; //select the location
+ outw(us_TmpValue,dev->iobase+APCI3120_SEQ_RAM_ADDRESS);
+ }
+ return 0;
+}
+
+
+
+
+/*
++----------------------------------------------------------------------------+
+| Function name : int i_APCI3120_SetupChannelList(comedi_device * dev, |
+| comedi_subdevice * s, int n_chan,unsigned int *chanlist|
+| ,char check) |
+| |
++----------------------------------------------------------------------------+
+| Task :This function will first check channel list is ok or not|
+|and then initialize the sequence RAM with the polarity, Gain,Channel number |
+|If the last argument of function "check"is 1 then it only checks the channel|
+|list is ok or not. |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device * dev |
+| comedi_subdevice * s |
+| int n_chan |
+ unsigned int *chanlist
+ char check
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_SetupChannelList(comedi_device * dev, comedi_subdevice * s, int n_chan, unsigned int *chanlist,char check)
+{
+ unsigned int i;//, differencial=0, bipolar=0;
+ unsigned int gain;
+ unsigned short us_TmpValue;
+ /* correct channel and range number check itself comedi/range.c */
+ if (n_chan<1)
+ {
+ if (!check) comedi_error(dev,"range/channel list is empty!");
+ return 0;
+ }
+
+ // All is ok, so we can setup channel/range list
+ if (check) return 1;
+
+ //Code to set the PA and PR...Here it set PA to 0..
+ devpriv->us_OutputRegister=devpriv->us_OutputRegister & APCI3120_CLEAR_PA_PR;
+ devpriv->us_OutputRegister= ((n_chan-1) & 0xf)<<8;
+ outw(devpriv->us_OutputRegister,dev->iobase+APCI3120_WR_ADDRESS);
+
+ for (i=0; i<n_chan; i++)
+ {
+ // store range list to card
+ us_TmpValue=CR_CHAN(chanlist[i]); // get channel number;
+
+ if (CR_RANGE(chanlist[i])<APCI3120_BIPOLAR_RANGES)
+ {
+ us_TmpValue&=((~APCI3120_UNIPOLAR)&0xff); // set bipolar
+ }
+ else
+ {
+ us_TmpValue|=APCI3120_UNIPOLAR; // enable unipolar......
+ }
+ gain=CR_RANGE(chanlist[i]); // get gain number
+
+ us_TmpValue|=((gain & 0x03)<<4); //<<4 for G0 and G1 bit in RAM
+ us_TmpValue|= i<<8; //To select the RAM LOCATION....
+
+ outw(us_TmpValue,dev->iobase+APCI3120_SEQ_RAM_ADDRESS);
+ }
+ return 1; // we can serve this with scan logic
+}
+
+
+
+
+
+/*
++----------------------------------------------------------------------------+
+| Function name : int i_APCI3120_ExttrigEnable(comedi_device * dev) |
+| |
+| |
++----------------------------------------------------------------------------+
+| Task : Enable the external trigger |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device * dev |
+| |
+| |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_ExttrigEnable(comedi_device * dev)
+{
+ devpriv->us_OutputRegister|=APCI3120_ENABLE_EXT_TRIGGER;
+ outw(devpriv->us_OutputRegister,dev->iobase+APCI3120_WR_ADDRESS);
+ return 0;
+}
+
+
+
+/*
++----------------------------------------------------------------------------+
+| Function name : int i_APCI3120_ExttrigDisable(comedi_device * dev) |
+| |
++----------------------------------------------------------------------------+
+| Task : Disables the external trigger |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device * dev |
+| |
+| |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_ExttrigDisable(comedi_device * dev)
+{
+ devpriv->us_OutputRegister&=~APCI3120_ENABLE_EXT_TRIGGER;
+ outw(devpriv->us_OutputRegister,dev->iobase+APCI3120_WR_ADDRESS);
+ return 0;
+}
+
+
+
+
+
+
+/*
++----------------------------------------------------------------------------+
+| INTERRUPT FUNCTIONS |
++----------------------------------------------------------------------------+
+*/
+
+
+/*
++----------------------------------------------------------------------------+
+| Function name : void v_APCI3120_Interrupt(int irq, void *d, |
+| struct pt_regs *regs) |
+| |
+| |
++----------------------------------------------------------------------------+
+| Task :Interrupt handler for APCI3120 |
+| When interrupt occurs this gets called. |
+| First it finds which interrupt has been generated and |
+| handles corresponding interrupt |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : int irq |
+| void *d |
+| struct pt_regs *regs |
+| |
++----------------------------------------------------------------------------+
+| Return Value : void |
+| |
++----------------------------------------------------------------------------+
+*/
+
+
+ void v_APCI3120_Interrupt(int irq, void *d, struct pt_regs *regs)
+{
+ comedi_device *dev = d;
+ USHORT int_daq;
+
+ unsigned int int_amcc,ui_Check,i;
+ USHORT us_TmpValue;
+ BYTE b_DummyRead;
+
+ comedi_subdevice *s = dev->subdevices + 0;
+ ui_Check=1;
+
+ int_daq=inw(dev->iobase+APCI3120_RD_STATUS) & 0xf000; // get IRQ reasons
+ int_amcc=inl(devpriv->i_IobaseAmcc+AMCC_OP_REG_INTCSR); // get AMCC INT register
+
+
+
+ if ((!int_daq)&&(!(int_amcc&ANY_S593X_INT)))
+ {
+ comedi_error(dev,"IRQ from unknow source");
+ return;
+ }
+
+ outl(int_amcc|0x00ff0000, devpriv->i_IobaseAmcc+AMCC_OP_REG_INTCSR);// shutdown IRQ reasons in AMCC
+
+ int_daq = (int_daq >> 12) & 0xF;
+
+
+ if(devpriv->b_ExttrigEnable == APCI3120_ENABLE)
+ {
+ //Disable ext trigger
+ i_APCI3120_ExttrigDisable(dev);
+ devpriv->b_ExttrigEnable = APCI3120_DISABLE;
+ }
+
+ //clear the timer 2 interrupt
+ inb(devpriv->i_IobaseAmcc+ APCI3120_TIMER_STATUS_REGISTER);
+
+ if (int_amcc&MASTER_ABORT_INT)
+ comedi_error(dev,"AMCC IRQ - MASTER DMA ABORT!");
+ if (int_amcc&TARGET_ABORT_INT)
+ comedi_error(dev,"AMCC IRQ - TARGET DMA ABORT!");
+
+ // Ckeck if EOC interrupt
+ if(((int_daq & 0x8) == 0) && (devpriv->b_InterruptMode==APCI3120_EOC_MODE))
+ {
+ if(devpriv->b_EocEosInterrupt==APCI3120_ENABLE)
+ {
+
+ // Read the AI Value
+
+ devpriv->ui_AiReadData[0]=(UINT)inw(devpriv->iobase+0);
+ devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
+ send_sig(SIGIO,devpriv->tsk_Current,0); // send signal to the sample
+ }
+ else
+ {
+ //Disable EOC Interrupt
+ devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister & APCI3120_DISABLE_EOC_INT;
+ outb(devpriv->b_ModeSelectRegister,devpriv->iobase+APCI3120_WRITE_MODE_SELECT);
+
+ }
+ }
+
+
+ // Check If EOS interrupt
+ if( (int_daq & 0x2) && (devpriv->b_InterruptMode==APCI3120_EOS_MODE) )
+ {
+
+ if(devpriv->b_EocEosInterrupt==APCI3120_ENABLE)// enable this in without DMA ???
+ {
+
+ if(devpriv->b_AiCyclicAcquisition==APCI3120_ENABLE)
+ {
+ ui_Check=0;
+ i_APCI3120_InterruptHandleEos(dev);
+ devpriv->ui_AiActualScan++;
+ devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister | APCI3120_ENABLE_EOS_INT;
+ outb(devpriv->b_ModeSelectRegister,dev->iobase+APCI3120_WRITE_MODE_SELECT);
+ }
+ else
+ {
+ ui_Check=0;
+ for(i=0;i< devpriv->ui_AiNbrofChannels;i++)
+ {
+ us_TmpValue=inw(devpriv->iobase+0);
+ devpriv->ui_AiReadData[i]=(UINT) us_TmpValue;
+ }
+ devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
+ devpriv->b_InterruptMode=APCI3120_EOC_MODE;
+
+ send_sig(SIGIO,devpriv->tsk_Current,0); // send signal to the sample
+
+ }
+
+ }
+ else
+ {
+ devpriv->b_ModeSelectRegister= devpriv->b_ModeSelectRegister & APCI3120_DISABLE_EOS_INT;
+ outb(devpriv->b_ModeSelectRegister,dev->iobase+APCI3120_WRITE_MODE_SELECT);
+ devpriv->b_EocEosInterrupt = APCI3120_DISABLE; //Default settings
+ devpriv->b_InterruptMode=APCI3120_EOC_MODE;
+ }
+
+ }
+
+ //Timer2 interrupt
+ if(int_daq & 0x1)
+ {
+
+ switch(devpriv->b_Timer2Mode)
+ {
+ case APCI3120_COUNTER:
+
+ devpriv->b_AiCyclicAcquisition=APCI3120_DISABLE;
+ devpriv->b_ModeSelectRegister= devpriv->b_ModeSelectRegister & APCI3120_DISABLE_EOS_INT;
+ outb(devpriv->b_ModeSelectRegister,dev->iobase+APCI3120_WRITE_MODE_SELECT);
+
+ // stop timer 2
+ devpriv->us_OutputRegister=devpriv->us_OutputRegister & APCI3120_DISABLE_ALL_TIMER;
+ outw(devpriv->us_OutputRegister,dev->iobase+APCI3120_WR_ADDRESS);
+
+ //stop timer 0 and timer 1
+ i_APCI3120_StopCyclicAcquisition(dev,s);
+ devpriv->b_AiCyclicAcquisition=APCI3120_DISABLE;
+ comedi_done(dev,s);
+ break;
+
+
+ case APCI3120_TIMER:
+
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO,devpriv->tsk_Current,0);
+ break;
+
+ case APCI3120_WATCHDOG:
+
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO,devpriv->tsk_Current,0);
+ break;
+
+ default :
+
+ // disable Timer Interrupt
+
+ devpriv->b_ModeSelectRegister = devpriv-> b_ModeSelectRegister & APCI3120_DISABLE_TIMER_INT;
+
+ outb(devpriv->b_ModeSelectRegister, dev->iobase+ APCI3120_WRITE_MODE_SELECT);
+
+
+
+
+ }
+
+ b_DummyRead= inb(dev->iobase+APCI3120_TIMER_STATUS_REGISTER);
+
+ }
+
+
+ if ((int_daq & 0x4) &&(devpriv->b_InterruptMode == APCI3120_DMA_MODE))
+ {
+
+ //DPRINTK("\n interrupt is DMA\n");
+ if(devpriv->b_AiCyclicAcquisition==APCI3120_ENABLE)
+ {
+
+ /****************************/
+ /* Clear Timer Write TC INT */
+ /****************************/
+
+ outl(APCI3120_CLEAR_WRITE_TC_INT,devpriv->i_IobaseAmcc+ APCI3120_AMCC_OP_REG_INTCSR);
+
+ /************************************/
+ /* Clears the timer status register */
+ /************************************/
+ inw(dev->iobase+APCI3120_TIMER_STATUS_REGISTER);
+ v_APCI3120_InterruptDma(irq,d,regs); // do some data transfer
+ }
+ else
+ {
+ outw(devpriv->us_OutputRegister & APCI3120_DISABLE_TIMER0 & APCI3120_DISABLE_TIMER1,dev->iobase+APCI3120_WR_ADDRESS);
+ }
+
+ }
+
+ return;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InterruptHandleEos(comedi_device *dev) |
+| |
+| |
++----------------------------------------------------------------------------+
+| Task : This function handles EOS interrupt. |
+| This function copies the acquired data(from FIFO) |
+| to Comedi buffer. |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev |
+| |
+| |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_InterruptHandleEos(comedi_device *dev)
+{
+ int n_chan,i;
+ sampl_t *data;
+ comedi_subdevice *s=dev->subdevices+0;
+ comedi_async *async = s->async;
+ data=async->data+async->buf_int_ptr;//new samples added from here onwards
+ n_chan=devpriv->ui_AiNbrofChannels;
+ for(i=0;i<n_chan;i++)
+ {
+ data[i]=inw(dev->iobase+0);
+ }
+ async->buf_int_count+=n_chan*sizeof(sampl_t);
+ async->buf_int_ptr+=n_chan*sizeof(sampl_t);
+ comedi_eos(dev,s);
+ 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);
+ }
+ return 0;
+}
+
+
+
+
+
+
+/*
++----------------------------------------------------------------------------+
+| Function name : void v_APCI3120_InterruptDma(int irq, void *d, |
+| struct pt_regs *regs) |
+| |
++----------------------------------------------------------------------------+
+| Task : This is a handler for the DMA interrupt |
+| This function copies the data to Comedi Buffer. |
+| For continuous DMA it reinitializes the DMA operation. |
+| For single mode DMA it stop the acquisition. |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : int irq, void *d, struct pt_regs *regs |
+| |
++----------------------------------------------------------------------------+
+| Return Value : void |
+| |
++----------------------------------------------------------------------------+
+*/
+
+ void v_APCI3120_InterruptDma(int irq, void *d, struct pt_regs *regs)
+{
+ comedi_device *dev = d;
+ comedi_subdevice *s = dev->subdevices + 0;
+ sampl_t *ptr;
+ unsigned int next_dma_buf, samplesinbuf,m;
+ unsigned long low_word,high_word,var;
+ UINT ui_Tmp;
+ samplesinbuf=devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer]-inl(devpriv->i_IobaseAmcc+AMCC_OP_REG_MWTC);
+ //rt_printk("\nSamples in buffer=%d \n", samplesinbuf);
+ if (samplesinbuf<devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer])
+ {
+ comedi_error(dev,"Interrupted DMA transfer!");
+ }
+ if (samplesinbuf & 1)
+ {
+ comedi_error(dev,"Odd count of bytes in DMA ring!");
+ i_APCI3120_StopCyclicAcquisition(dev,s);
+ devpriv->b_AiCyclicAcquisition=APCI3120_DISABLE;
+ comedi_error_done(dev,s);
+ return;
+ }
+ samplesinbuf=samplesinbuf>>1; // number of received samples
+ if (devpriv->b_DmaDoubleBuffer)
+ {
+ // switch DMA buffers if is used double buffering
+ next_dma_buf=1-devpriv->ui_DmaActualBuffer;
+ ui_Tmp=AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO ;
+ outl(ui_Tmp,devpriv->i_IobaseAddon+AMCC_OP_REG_AGCSTS);
+ // changed since 16 bit interface for add on
+ outw(APCI3120_ADD_ON_AGCSTS_LOW,devpriv->i_IobaseAddon+0);
+ outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW,devpriv->i_IobaseAddon+2);
+ outw(APCI3120_ADD_ON_AGCSTS_HIGH,devpriv->i_IobaseAddon+0);
+ outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH ,devpriv->i_IobaseAddon+2); // 0x1000 is out putted in windows driver
+
+ // A2P FIFO MANAGEMENT
+ // A2P fifo reset & transfer control enable
+ outl(APCI3120_A2P_FIFO_MANAGEMENT,devpriv->i_IobaseAmcc+AMCC_OP_REG_MCSR );
+ var=devpriv->ul_DmaBufferHw[next_dma_buf];
+ low_word=var & 0xffff;
+ var=devpriv->ul_DmaBufferHw[next_dma_buf];
+ high_word=var /65536;
+ outw(APCI3120_ADD_ON_MWAR_LOW,devpriv->i_IobaseAddon+0);
+ outw(low_word,devpriv->i_IobaseAddon+2);
+ outw(APCI3120_ADD_ON_MWAR_HIGH,devpriv->i_IobaseAddon+0);
+ outw(high_word,devpriv->i_IobaseAddon+2);
+ var=devpriv->ui_DmaBufferUsesize[next_dma_buf];
+ low_word=var & 0xffff;
+ var=devpriv->ui_DmaBufferUsesize[next_dma_buf];
+ high_word=var /65536;
+ outw(APCI3120_ADD_ON_MWTC_LOW,devpriv->i_IobaseAddon+0);
+ outw(low_word,devpriv->i_IobaseAddon+2);
+ outw(APCI3120_ADD_ON_MWTC_HIGH,devpriv->i_IobaseAddon+0);
+ outw(high_word,devpriv->i_IobaseAddon+2);
+ // To configure A2P FIFO
+ // ENABLE A2P FIFO WRITE AND ENABLE AMWEN
+ // AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03
+ outw(3,devpriv->i_IobaseAddon + 4);
+ //initialise end of dma interrupt AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI)
+ outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2| APCI3120_ENABLE_WRITE_TC_INT), devpriv->i_IobaseAmcc+AMCC_OP_REG_INTCSR);
+
+ }
+
+ ptr=(sampl_t *)devpriv->ul_DmaBufferVirtual[devpriv->ui_DmaActualBuffer];
+
+
+ if(s->async->buf_int_ptr+samplesinbuf*sizeof(sampl_t)>=devpriv->ui_AiDataLength)
+ {
+ m=(devpriv->ui_AiDataLength-s->async->buf_int_ptr)/sizeof(sampl_t);
+ v_APCI3120_InterruptDmaMoveBlock16bit(dev,s,(void *)ptr,((void *)(devpriv->AiData))+s->async->buf_int_ptr,m);
+ s->async->buf_int_count+=m*sizeof(sampl_t);
+ ptr+=m*sizeof(sampl_t);
+ samplesinbuf-=m;
+ s->async->buf_int_ptr=0;
+ comedi_eobuf(dev,s);
+ }
+
+ if (samplesinbuf)
+ {
+ v_APCI3120_InterruptDmaMoveBlock16bit(dev,s,(void *)ptr,((void *)(devpriv->AiData))+s->async->buf_int_ptr,samplesinbuf);
+
+ s->async->buf_int_count+=samplesinbuf*sizeof(sampl_t);
+ s->async->buf_int_ptr+=samplesinbuf*sizeof(sampl_t);
+ if (!(devpriv->ui_AiFlags & TRIG_WAKE_EOS))
+ {
+ comedi_bufcheck(dev,s);
+ }
+ }
+ if (!devpriv->b_AiContinuous)
+ if ( devpriv->ui_AiActualScan>=devpriv->ui_AiNbrofScans )
+ {
+ // all data sampled
+ i_APCI3120_StopCyclicAcquisition(dev,s);
+ devpriv->b_AiCyclicAcquisition=APCI3120_DISABLE;
+ //DPRINTK("\n Single DMA completed..\n");
+ comedi_done(dev,s);
+ return;
+ }
+
+ if (devpriv->b_DmaDoubleBuffer)
+ { // switch dma buffers
+ devpriv->ui_DmaActualBuffer=1-devpriv->ui_DmaActualBuffer;
+
+ }
+ else
+ {
+ // restart DMA if is not used double buffering
+ //ADDED REINITIALISE THE DMA
+ ui_Tmp=AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO ;
+ outl(ui_Tmp,devpriv->i_IobaseAddon+AMCC_OP_REG_AGCSTS);
+
+ // changed since 16 bit interface for add on
+ outw(APCI3120_ADD_ON_AGCSTS_LOW,devpriv->i_IobaseAddon+0);
+ outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW,devpriv->i_IobaseAddon+2);
+ outw(APCI3120_ADD_ON_AGCSTS_HIGH,devpriv->i_IobaseAddon+0);
+ outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH ,devpriv->i_IobaseAddon+2); //
+ // A2P FIFO MANAGEMENT
+ // A2P fifo reset & transfer control enable
+ outl(APCI3120_A2P_FIFO_MANAGEMENT,devpriv->i_IobaseAmcc+AMCC_OP_REG_MCSR );
+
+ var=devpriv->ul_DmaBufferHw[0];
+ low_word=var & 0xffff;
+ var=devpriv->ul_DmaBufferHw[0];
+ high_word=var/65536;
+ outw(APCI3120_ADD_ON_MWAR_LOW,devpriv->i_IobaseAddon+0);
+ outw(low_word,devpriv->i_IobaseAddon+2);
+ outw(APCI3120_ADD_ON_MWAR_HIGH,devpriv->i_IobaseAddon+0);
+ outw(high_word,devpriv->i_IobaseAddon+2);
+
+ var=devpriv->ui_DmaBufferUsesize[0];
+ low_word=var & 0xffff;//changed
+ var=devpriv->ui_DmaBufferUsesize[0];
+ high_word=var/65536;
+ outw(APCI3120_ADD_ON_MWTC_LOW,devpriv->i_IobaseAddon+0);
+ outw(low_word,devpriv->i_IobaseAddon+2);
+ outw(APCI3120_ADD_ON_MWTC_HIGH,devpriv->i_IobaseAddon+0);
+ outw(high_word,devpriv->i_IobaseAddon+2);
+
+
+ // To configure A2P FIFO
+ //ENABLE A2P FIFO WRITE AND ENABLE AMWEN
+ // AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03
+ outw(3,devpriv->i_IobaseAddon + 4);
+ //initialise end of dma interrupt AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI)
+ outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2| APCI3120_ENABLE_WRITE_TC_INT), devpriv->i_IobaseAmcc+AMCC_OP_REG_INTCSR);
+ }
+}
+
+
+/*
++----------------------------------------------------------------------------+
+| Function name :void v_APCI3120_InterruptDmaMoveBlock16bit(comedi_device|
+|*dev,comedi_subdevice *s,sampl_t *dma,sampl_t *data,int n) |
+| |
++----------------------------------------------------------------------------+
+| Task : This function copies the data from DMA buffer to the |
+| Comedi buffer |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev |
+| comedi_subdevice *s |
+| sampl_t *dma |
+| sampl_t *data,int n |
++----------------------------------------------------------------------------+
+| Return Value : void |
+| |
++----------------------------------------------------------------------------+
+*/
+
+void v_APCI3120_InterruptDmaMoveBlock16bit(comedi_device *dev,comedi_subdevice *s,sampl_t *dma,sampl_t *data,int n)
+{
+ int i,j,m;
+
+ j=s->async->cur_chan;
+ m=devpriv->ui_AiActualScanPosition;
+ for(i=0;i<n;i++)
+ {
+ *data=*dma;
+ data++; dma++;
+ j++;
+ if(j>=devpriv->ui_AiNbrofChannels)
+ {
+ m+=j;
+ j=0;
+ if(m>=devpriv->ui_AiScanLength)
+ {
+ m=0;
+ devpriv->ui_AiActualScan++;
+ if (devpriv->ui_AiFlags & TRIG_WAKE_EOS)
+ comedi_eos(dev,s);
+ }
+ }
+ }
+ devpriv->ui_AiActualScanPosition=m;
+ s->async->cur_chan=j;
+
+}
+
+
+
+
+
+
+/*
++----------------------------------------------------------------------------+
+| TIMER SUBDEVICE |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InsnConfigTimer(comedi_device *dev, |
+| comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) |
+| |
++----------------------------------------------------------------------------+
+| Task :Configure Timer 2 |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev |
+| comedi_subdevice *s |
+| comedi_insn *insn |
+| lsampl_t *data |
+| |
+| data[0]= TIMER configure as timer |
+| = WATCHDOG configure as watchdog |
+| data[1] = Timer constant |
+| data[2] = Timer2 interrupt (1)enable or(0) disable |
+| |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+
+int i_APCI3120_InsnConfigTimer(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+
+ UINT ui_Timervalue2;
+ USHORT us_TmpValue;
+ BYTE b_Tmp;
+
+
+ if(!data[1]) comedi_error(dev,"config:No timer constant !");
+
+ devpriv->b_Timer2Interrupt=(BYTE)data[2]; // save info whether to enable or disable interrupt
+
+ ui_Timervalue2=data[1]/1000; // convert nano seconds to u seconds
+
+ //this_board->i_hwdrv_InsnConfigTimer(dev, ui_Timervalue2,(BYTE)data[0]);
+ us_TmpValue=(USHORT) inw(devpriv->iobase+APCI3120_RD_STATUS);
+
+ //Testing if board have the new Quartz and calculate the time value to set in the timer
+ if((us_TmpValue & 0x00B0)==0x00B0)
+ {
+ //Calculate the time value to set in the timer
+ ui_Timervalue2=ui_Timervalue2 / 50;
+ }
+ else
+ {
+ //Calculate the time value to set in the timer
+ ui_Timervalue2=ui_Timervalue2 / 70;
+ }
+
+ //Reset gate 2 of Timer 2 to disable it (Set Bit D14 to 0)
+ devpriv->us_OutputRegister=devpriv->us_OutputRegister & APCI3120_DISABLE_TIMER2 ;
+ outw(devpriv->us_OutputRegister,devpriv->iobase+APCI3120_WR_ADDRESS);
+
+ // Disable TIMER Interrupt
+ devpriv->b_ModeSelectRegister = devpriv->b_ModeSelectRegister & APCI3120_DISABLE_TIMER_INT & 0xEF;
+
+ // Disable Eoc and Eos Interrupts
+ devpriv->b_ModeSelectRegister = devpriv->b_ModeSelectRegister & APCI3120_DISABLE_EOC_INT & APCI3120_DISABLE_EOS_INT;
+ outb(devpriv->b_ModeSelectRegister,devpriv->iobase + APCI3120_WRITE_MODE_SELECT);
+ if(data[0]==APCI3120_TIMER)//initialize timer
+ {
+
+ //devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister| APCI3120_ENABLE_TIMER_INT ;
+ //outb(devpriv->b_ModeSelectRegister,devpriv->iobase+APCI3120_WRITE_MODE_SELECT);
+
+ //Set the Timer 2 in mode 2(Timer)
+ devpriv->b_TimerSelectMode=(devpriv->b_TimerSelectMode & 0x0F) | APCI3120_TIMER_2_MODE_2;
+ outb(devpriv->b_TimerSelectMode,devpriv->iobase + APCI3120_TIMER_CRT1);
+
+ //Configure the timer 2 for writing the LOW WORD of timer is Delay value
+ //You must make a b_tmp variable with DigitalOutPutRegister because at Address_1+APCI3120_TIMER_CRT0
+ //you can set the digital output and configure the timer 2,and if you don't make this, digital output
+ //are erase (Set to 0)
+
+ //Writing LOW WORD
+ b_Tmp=((devpriv->b_DigitalOutputRegister<<4) & 0xF0) | APCI3120_SELECT_TIMER_2_LOW_WORD;
+ outb(b_Tmp,devpriv->iobase+APCI3120_TIMER_CRT0);
+ outw(LOWORD(ui_Timervalue2),devpriv->iobase+APCI3120_TIMER_VALUE);
+
+ //Writing HIGH WORD
+ b_Tmp=((devpriv->b_DigitalOutputRegister<<4) & 0xF0) | APCI3120_SELECT_TIMER_2_HIGH_WORD;
+ outb(b_Tmp,devpriv->iobase+APCI3120_TIMER_CRT0);
+ outw(HIWORD(ui_Timervalue2),devpriv->iobase+APCI3120_TIMER_VALUE);
+ // timer2 in Timer mode enabled
+ devpriv->b_Timer2Mode=APCI3120_TIMER;
+
+ }
+ else // Initialize Watch dog
+ {
+
+
+ //Set the Timer 2 in mode 5(Watchdog)
+
+ devpriv->b_TimerSelectMode=(devpriv->b_TimerSelectMode & 0x0F) | APCI3120_TIMER_2_MODE_5;
+ outb(devpriv->b_TimerSelectMode,devpriv->iobase + APCI3120_TIMER_CRT1);
+
+ //Configure the timer 2 for writing the LOW WORD of timer is Delay value
+ //You must make a b_tmp variable with DigitalOutPutRegister because at Address_1+APCI3120_TIMER_CRT0
+ //you can set the digital output and configure the timer 2,and if you don't make this, digital output
+ //are erase (Set to 0)
+
+ //Writing LOW WORD
+ b_Tmp=((devpriv->b_DigitalOutputRegister<<4) & 0xF0) | APCI3120_SELECT_TIMER_2_LOW_WORD;
+ outb(b_Tmp,devpriv->iobase+APCI3120_TIMER_CRT0);
+ outw(LOWORD(ui_Timervalue2),devpriv->iobase+APCI3120_TIMER_VALUE);
+
+ //Writing HIGH WORD
+ b_Tmp=((devpriv->b_DigitalOutputRegister<<4) & 0xF0) | APCI3120_SELECT_TIMER_2_HIGH_WORD;
+ outb(b_Tmp,devpriv->iobase+APCI3120_TIMER_CRT0);
+ outw(HIWORD(ui_Timervalue2),devpriv->iobase+APCI3120_TIMER_VALUE);
+ //watchdog enabled
+ devpriv->b_Timer2Mode=APCI3120_WATCHDOG;
+
+ }
+
+
+ return insn->n;
+
+}
+
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InsnWriteTimer(comedi_device *dev, |
+| comedi_subdevice *s, comedi_insn *insn,lsampl_t *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : To start and stop the timer |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev |
+| comedi_subdevice *s |
+| comedi_insn *insn |
+| lsampl_t *data |
+| |
+| data[0] = 1 (start) |
+| data[0] = 0 (stop ) |
+| data[0] = 2 (write new value) |
+| data[1]= new value |
+| |
+| devpriv->b_Timer2Mode = 0 DISABLE |
+| 1 Timer |
+| 2 Watch dog |
+| |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+
+int i_APCI3120_InsnWriteTimer(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn,lsampl_t *data)
+{
+
+ UINT ui_Timervalue2=0;
+ USHORT us_TmpValue;
+ BYTE b_Tmp;
+
+
+
+
+ if((devpriv->b_Timer2Mode!=APCI3120_WATCHDOG) && (devpriv->b_Timer2Mode!=APCI3120_TIMER))
+ {
+ comedi_error(dev,"\nwrite:timer2 not configured ");
+ return -EINVAL;
+ }
+
+ if(data[0]==2) // write new value
+ {
+ if(devpriv->b_Timer2Mode!=APCI3120_TIMER)
+ {
+ comedi_error(dev,"write :timer2 not configured in TIMER MODE");
+ return -EINVAL;
+ }
+
+ if(data[1]) ui_Timervalue2=data[1];
+ else ui_Timervalue2=0;
+ }
+
+
+ //this_board->i_hwdrv_InsnWriteTimer(dev,data[0],ui_Timervalue2);
+
+ switch(data[0])
+ {
+ case APCI3120_START:
+
+ // Reset FC_TIMER BIT
+ inb(devpriv->iobase+APCI3120_TIMER_STATUS_REGISTER);
+ if(devpriv->b_Timer2Mode==APCI3120_TIMER) //start timer
+ {
+ //Enable Timer
+ devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister & 0x0B;
+ }
+ else //start watch dog
+ {
+ //Enable WatchDog
+ devpriv->b_ModeSelectRegister=(devpriv->b_ModeSelectRegister & 0x0B) | APCI3120_ENABLE_WATCHDOG;
+ }
+
+ //enable disable interrupt
+ if((devpriv->b_Timer2Interrupt)==APCI3120_ENABLE)
+ {
+
+ devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister| APCI3120_ENABLE_TIMER_INT ;
+ // save the task structure to pass info to user
+ devpriv->tsk_Current=current;
+ }
+ else
+ {
+
+ devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister & APCI3120_DISABLE_TIMER_INT;
+ }
+ outb(devpriv->b_ModeSelectRegister,devpriv->iobase+APCI3120_WRITE_MODE_SELECT);
+
+
+ if(devpriv->b_Timer2Mode==APCI3120_TIMER) //start timer
+ {
+ //For Timer mode is Gate2 must be activated **timer started
+ devpriv->us_OutputRegister=devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER2;
+ outw(devpriv->us_OutputRegister,devpriv->iobase+APCI3120_WR_ADDRESS);
+ }
+
+ break;
+
+ case APCI3120_STOP:
+ if(devpriv->b_Timer2Mode==APCI3120_TIMER)
+ {
+ //Disable timer
+ devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister & APCI3120_DISABLE_TIMER_COUNTER;
+ }
+ else
+ {
+ //Disable WatchDog
+ devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister & APCI3120_DISABLE_WATCHDOG;
+ }
+ // Disable timer interrupt
+ devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister & APCI3120_DISABLE_TIMER_INT;
+
+ // Write above states to register
+ outb(devpriv->b_ModeSelectRegister,devpriv->iobase+APCI3120_WRITE_MODE_SELECT);
+
+ // Reset Gate 2
+ devpriv->us_OutputRegister=devpriv->us_OutputRegister & APCI3120_DISABLE_TIMER_INT ;
+ outw(devpriv->us_OutputRegister,devpriv->iobase+APCI3120_WR_ADDRESS);
+
+ // Reset FC_TIMER BIT
+ inb(devpriv->iobase+APCI3120_TIMER_STATUS_REGISTER);
+
+ // Disable timer
+ //devpriv->b_Timer2Mode=APCI3120_DISABLE;
+
+ break;
+
+ case 2: //write new value to Timer
+ if( devpriv->b_Timer2Mode!=APCI3120_TIMER)
+ {
+ comedi_error(dev,"write :timer2 not configured in TIMER MODE");
+ return -EINVAL;
+ }
+ // ui_Timervalue2=data[1]; // passed as argument
+ us_TmpValue=(USHORT) inw(devpriv->iobase+APCI3120_RD_STATUS);
+
+ //Testing if board have the new Quartz and calculate the time value to set in the timer
+ if((us_TmpValue & 0x00B0)==0x00B0)
+ {
+ //Calculate the time value to set in the timer
+ ui_Timervalue2=ui_Timervalue2 / 50;
+ }
+ else
+ {
+ //Calculate the time value to set in the timer
+ ui_Timervalue2=ui_Timervalue2 / 70;
+ }
+ //Writing LOW WORD
+ b_Tmp=((devpriv->b_DigitalOutputRegister<<4) & 0xF0) | APCI3120_SELECT_TIMER_2_LOW_WORD;
+ outb(b_Tmp,devpriv->iobase+APCI3120_TIMER_CRT0);
+ outw(LOWORD(ui_Timervalue2),devpriv->iobase+APCI3120_TIMER_VALUE);
+
+ //Writing HIGH WORD
+ b_Tmp=((devpriv->b_DigitalOutputRegister<<4) & 0xF0) | APCI3120_SELECT_TIMER_2_HIGH_WORD;
+ outb(b_Tmp,devpriv->iobase+APCI3120_TIMER_CRT0);
+ outw(HIWORD(ui_Timervalue2),devpriv->iobase+APCI3120_TIMER_VALUE);
+
+ break;
+ default:
+ return -EINVAL;// Not a valid input
+ }
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name : int i_APCI3120_InsnReadTimer(comedi_device *dev, |
+| comedi_subdevice *s,comedi_insn *insn, lsampl_t *data) |
+| |
+| |
++----------------------------------------------------------------------------+
+| Task : read the Timer value |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev |
+| comedi_subdevice *s |
+| comedi_insn *insn |
+| lsampl_t *data |
+| |
++----------------------------------------------------------------------------+
+| Return Value : |
+| for Timer: data[0]= Timer constant |
+| |
+| for watchdog: data[0]=0 (still running) |
+| data[0]=1 (run down) |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI3120_InsnReadTimer(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data)
+{
+ BYTE b_Tmp;
+ USHORT us_TmpValue,us_TmpValue_2,us_StatusValue;
+
+ if((devpriv->b_Timer2Mode!=APCI3120_WATCHDOG) && (devpriv->b_Timer2Mode!=APCI3120_TIMER))
+ {
+ comedi_error(dev,"\nread:timer2 not configured ");
+ }
+
+
+ //this_board->i_hwdrv_InsnReadTimer(dev,data);
+ if(devpriv->b_Timer2Mode==APCI3120_TIMER)
+ {
+
+ //Read the LOW WORD of Timer 2 register
+ b_Tmp=((devpriv->b_DigitalOutputRegister<<4) & 0xF0) | APCI3120_SELECT_TIMER_2_LOW_WORD;
+ outb(b_Tmp,devpriv->iobase+APCI3120_TIMER_CRT0);
+ us_TmpValue=inw(devpriv->iobase+APCI3120_TIMER_VALUE);
+
+ //Read the HIGH WORD of Timer 2 register
+ b_Tmp=((devpriv->b_DigitalOutputRegister<<4) & 0xF0) | APCI3120_SELECT_TIMER_2_HIGH_WORD;
+ outb(b_Tmp,devpriv->iobase+APCI3120_TIMER_CRT0);
+ us_TmpValue_2=inw(devpriv->iobase+APCI3120_TIMER_VALUE);
+
+ // combining both words
+ data[0]=(UINT) ( (us_TmpValue)|((us_TmpValue_2)<<16));
+
+ }
+ else // Read watch dog status
+ {
+
+ us_StatusValue= inw(devpriv->iobase+APCI3120_RD_STATUS);
+ us_StatusValue=((us_StatusValue & APCI3120_FC_TIMER) >> 12) & 1;
+ if(us_StatusValue==1)
+ {
+ // RESET FC_TIMER BIT
+ inb(devpriv->iobase+APCI3120_TIMER_STATUS_REGISTER);
+ }
+ data[0]= us_StatusValue;// when data[0] = 1 then the watch dog has rundown
+ }
+ return insn->n;
+}
+
+
+/*
++----------------------------------------------------------------------------+
+| DIGITAL INPUT SUBDEVICE |
++----------------------------------------------------------------------------+
+*/
+
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InsnReadDigitalInput(comedi_device *dev, |
+| comedi_subdevice *s, comedi_insn *insn,lsampl_t *data) |
+| |
+| |
++----------------------------------------------------------------------------+
+| Task : Reads the value of the specified Digital input channel|
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev |
+| comedi_subdevice *s |
+| comedi_insn *insn |
+| lsampl_t *data |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+
+
+
+int i_APCI3120_InsnReadDigitalInput(comedi_device *dev,comedi_subdevice
+ *s, comedi_insn *insn,lsampl_t *data)
+ {
+ UINT ui_Chan,ui_TmpValue;
+
+ ui_Chan = CR_CHAN(insn->chanspec); // channel specified
+ //this_board->i_hwdrv_InsnReadDigitalInput(dev,ui_Chan,data);
+ if(ui_Chan >= 0 && ui_Chan <= 3)
+ {
+ ui_TmpValue=(UINT) inw(devpriv->iobase + APCI3120_RD_STATUS);
+
+ // since only 1 channel reqd to bring it to last bit it is rotated
+ // 8 +(chan - 1) times then ANDed with 1 for last bit.
+ *data = (ui_TmpValue >> (ui_Chan + 8)) & 1;
+ //return 0;
+ }
+ else
+ {
+ // comedi_error(dev," chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+ }
+ return insn->n;
+
+ }
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InsnBitsDigitalInput(comedi_device *dev, |
+|comedi_subdevice *s, comedi_insn *insn,lsampl_t *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : Reads the value of the Digital input Port i.e.4channels|
+| value is returned in data[0] |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev |
+| comedi_subdevice *s |
+| comedi_insn *insn |
+| lsampl_t *data |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI3120_InsnBitsDigitalInput(comedi_device *dev,comedi_subdevice *s,
+ comedi_insn *insn,lsampl_t *data)
+{
+ UINT ui_TmpValue;
+ ui_TmpValue=(UINT) inw(devpriv->iobase+APCI3120_RD_STATUS);
+ /***** state of 4 channels in the 11, 10, 9, 8 bits of status reg
+ rotated right 8 times to bring them to last four bits
+ ANDed with oxf for value.
+ *****/
+ *data=(ui_TmpValue >>8) & 0xf;
+ //this_board->i_hwdrv_InsnBitsDigitalInput(dev,data);
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| DIGITAL OUTPUT SUBDEVICE |
++----------------------------------------------------------------------------+
+*/
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InsnConfigDigitalOutput(comedi_device |
+| *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) |
+| |
++----------------------------------------------------------------------------+
+| Task :Configure the output memory ON or OFF |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters :comedi_device *dev |
+| comedi_subdevice *s |
+| comedi_insn *insn |
+| lsampl_t *data |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+
+
+int i_APCI3120_InsnConfigDigitalOutput(comedi_device *dev,comedi_subdevice *s,
+ comedi_insn *insn,lsampl_t *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])
+ {
+ devpriv->b_OutputMemoryStatus = APCI3120_ENABLE;
+
+ }
+ else
+ {
+ devpriv->b_OutputMemoryStatus = APCI3120_DISABLE;
+
+ }
+ if(!devpriv->b_OutputMemoryStatus )
+ {
+ ui_Temp=0;
+
+ }//if(!devpriv->b_OutputMemoryStatus )
+
+ return insn->n;
+}
+
+
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InsnBitsDigitalOutput(comedi_device *dev, |
+| comedi_subdevice *s, comedi_insn *insn,lsampl_t *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : write diatal output port |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev |
+| comedi_subdevice *s |
+| comedi_insn *insn |
+| lsampl_t *data |
+ data[0] Value to be written
+ data[1] :1 Set digital o/p ON
+ data[1] 2 Set digital o/p OFF with memory ON
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+
+int i_APCI3120_InsnBitsDigitalOutput(comedi_device *dev,comedi_subdevice
+ *s, comedi_insn *insn,lsampl_t *data)
+{
+
+
+ if ((data[0] > this_board->i_DoMaxdata) || (data[0]<0))
+ {
+
+ comedi_error(dev,"Data is not valid !!! \n");
+ return -EINVAL;
+ }
+
+
+ switch(data[1])
+ {
+ case 1 :data[0]=(data[0]<<4)|ui_Temp;
+ break;
+
+ case 2 :data[0]=data[0]<<4;
+ break;
+ default :printk("\nThe parameter passed is in error \n");
+ return -EINVAL;
+ }// switch(data[1])
+ outb(data[0], devpriv->iobase + APCI3120_DIGITAL_OUTPUT);
+ ui_Temp=data[0]&0xF0;
+
+ return insn->n;
+
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InsnWriteDigitalOutput(comedi_device *dev,|
+|comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : Write digiatl output |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev |
+| comedi_subdevice *s |
+| comedi_insn *insn |
+| lsampl_t *data |
+ data[0] Value to be written
+ data[1] :1 Set digital o/p ON
+ data[1] 2 Set digital o/p OFF with memory ON
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+
+int i_APCI3120_InsnWriteDigitalOutput(comedi_device *dev,comedi_subdevice
+ *s,comedi_insn *insn,lsampl_t *data)
+{
+
+ UINT ui_Temp1;
+
+ UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
+
+ if ( (data[0]!=0) && (data[0]!=1) )
+ {
+ comedi_error(dev,"Not a valid Data !!! ,Data should be 1 or 0\n");
+ return -EINVAL;
+ }
+ if ( (ui_NoOfChannel > (this_board->i_NbrDoChannel-1)) || (ui_NoOfChannel < 0) )
+ {
+ comedi_error(dev,"This board doesn't have specified channel !!! \n");
+ return -EINVAL;
+ }
+
+
+
+ switch(data[1])
+ {
+ case 1 :data[0]=(data[0] << ui_NoOfChannel);
+ data[0]=(data[0]<<4)|ui_Temp;
+ break;
+
+ case 2 :
+ data[0]=~data[0]&0x1;
+ ui_Temp1=1;
+ ui_Temp1=ui_Temp1<<ui_NoOfChannel;
+ ui_Temp1=ui_Temp1<<4;
+ ui_Temp=ui_Temp|ui_Temp1;
+ data[0]=(data[0] << ui_NoOfChannel)^0xf;
+ data[0]=data[0]<<4;
+ data[0]=data[0]& ui_Temp;
+ break;
+ default :printk("\nThe parameter passed is in error \n");
+ return -EINVAL;
+ }// switch(data[1])
+ outb(data[0], devpriv->iobase + APCI3120_DIGITAL_OUTPUT);
+ ui_Temp=data[0] & 0xf0;
+ return (insn->n);
+
+}
+
+
+
+
+
+
+/*
++----------------------------------------------------------------------------+
+| ANALOG OUTPUT SUBDEVICE |
++----------------------------------------------------------------------------+
+*/
+
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InsnWriteAnalogOutput(comedi_device *dev,|
+|comedi_subdevice *s, comedi_insn *insn,lsampl_t *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : Write analog output |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev |
+| comedi_subdevice *s |
+| comedi_insn *insn |
+| lsampl_t *data |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_InsnWriteAnalogOutput(comedi_device *dev,comedi_subdevice
+ *s, comedi_insn *insn,lsampl_t *data)
+{
+ UINT ui_Range,ui_Channel;
+ USHORT us_TmpValue;
+
+ ui_Range = CR_RANGE(insn->chanspec);
+ ui_Channel = CR_CHAN(insn->chanspec);
+
+ //this_board->i_hwdrv_InsnWriteAnalogOutput(dev, ui_Range, ui_Channel,data[0]);
+ if(ui_Range) // if 1 then unipolar
+ {
+
+ if(data[0]!=0)
+ data[0]=((((ui_Channel & 0x03)<<14) & 0xC000) | (1<<13) | (data[0]+8191));
+ else
+ data[0]=((((ui_Channel & 0x03)<<14) & 0xC000) | (1<<13) | 8192);
+
+ }
+ else // if 0 then bipolar
+ {
+ data[0]= ((((ui_Channel & 0x03)<<14) & 0xC000) | (0<<13) | data[0]);
+
+ }
+
+
+
+ //out put n values at the given channel.
+ // rt_printk("\nwaiting for DA_READY BIT");
+ do //Waiting of DA_READY BIT
+ {
+ us_TmpValue=((USHORT) inw(devpriv->iobase+APCI3120_RD_STATUS)) & 0x0001;
+ } while(us_TmpValue!=0x0001);
+
+ if(ui_Channel<=3)
+ // for channel 0-3 out at the register 1 (wrDac1-8)
+ // data[i] typecasted to ushort since word write is to be done
+ outw((USHORT)data[0],devpriv->iobase+ APCI3120_ANALOG_OUTPUT_1);
+ else
+ // for channel 4-7 out at the register 2 (wrDac5-8)
+ //data[i] typecasted to ushort since word write is to be done
+ outw((USHORT)data[0],devpriv->iobase+ APCI3120_ANALOG_OUTPUT_2);
+
+ return insn->n;
+}
+
+
--- /dev/null
+
+// hwdrv_apci3120.h
+
+
+/*
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstrasse 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 : ADDI DATA | Compiler : GCC |
+ | Modulname : hwdrv_apci3120.h | Version : 2.96 Redhat Linux |
+ | | kernel-2.4.2 |
+ +-------------------------------+---------------------------------------+
+ | Author : | Date : |
+ +-----------------------------------------------------------------------+
+ | Description :Header file for apci3120 hardware abstraction layer |
+ +-----------------------------------------------------------------------+
+ | UPDATE'S |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+
+
+
+
+// comedi related defines
+
+//ANALOG INPUT RANGE
+comedi_lrange range_apci3120_ai={ 8, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2),
+ BIP_RANGE(1),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2),
+ UNI_RANGE(1)
+ }
+};
+
+// ANALOG OUTPUT RANGE
+comedi_lrange range_apci3120_ao= { 2, {
+ BIP_RANGE(10),
+ UNI_RANGE(10)
+ }
+};
+
+#define APCI3120_BIPOLAR_RANGES 4 // used for test on mixture of BIP/UNI ranges
+
+
+#define APCI3120_BOARD_VENDOR_ID 0x10E8
+#define APCI3120_ADDRESS_RANGE 16
+
+#define APCI3120_DISABLE 0
+#define APCI3120_ENABLE 1
+
+#define APCI3120_START 1
+#define APCI3120_STOP 0
+
+#define APCI3120_EOC_MODE 1
+#define APCI3120_EOS_MODE 2
+#define APCI3120_DMA_MODE 3
+
+//DIGITAL INPUT-OUTPUT DEFINE
+
+#define APCI3120_DIGITAL_OUTPUT 0x0D
+#define APCI3120_RD_STATUS 0x02
+#define APCI3120_RD_FIFO 0x00
+
+// digital output insn_write ON /OFF selection
+#define APCI3120_SET4DIGITALOUTPUTON 1
+#define APCI3120_SET4DIGITALOUTPUTOFF 0
+
+// analog output SELECT BIT
+#define APCI3120_ANALOG_OP_CHANNEL_1 0x0000
+#define APCI3120_ANALOG_OP_CHANNEL_2 0x4000
+#define APCI3120_ANALOG_OP_CHANNEL_3 0x8000
+#define APCI3120_ANALOG_OP_CHANNEL_4 0xC000
+#define APCI3120_ANALOG_OP_CHANNEL_5 0x0000
+#define APCI3120_ANALOG_OP_CHANNEL_6 0x4000
+#define APCI3120_ANALOG_OP_CHANNEL_7 0x8000
+#define APCI3120_ANALOG_OP_CHANNEL_8 0xC000
+
+// Enable external trigger bit in nWrAddress
+#define APCI3120_ENABLE_EXT_TRIGGER 0x8000
+
+//ANALOG OUTPUT AND INPUT DEFINE
+#define APCI3120_UNIPOLAR 0x80 //$$ RAM sequence polarity BIT
+#define APCI3120_BIPOLAR 0x00 //$$ RAM sequence polarity BIT
+#define APCI3120_ANALOG_OUTPUT_1 0x08 // (ADDRESS )
+#define APCI3120_ANALOG_OUTPUT_2 0x0A // (ADDRESS )
+#define APCI3120_1_GAIN 0x00 //$$ RAM sequence Gain Bits for gain 1
+#define APCI3120_2_GAIN 0x10 //$$ RAM sequence Gain Bits for gain 2
+#define APCI3120_5_GAIN 0x20 //$$ RAM sequence Gain Bits for gain 5
+#define APCI3120_10_GAIN 0x30 //$$ RAM sequence Gain Bits for gain 10
+#define APCI3120_SEQ_RAM_ADDRESS 0x06 //$$ EARLIER NAMED APCI3120_FIFO_ADDRESS
+#define APCI3120_RESET_FIFO 0x0C //(ADDRESS)
+#define APCI3120_TIMER_0_MODE_2 0x01 //$$ Bits for timer mode
+#define APCI3120_TIMER_0_MODE_4 0x2
+#define APCI3120_SELECT_TIMER_0_WORD 0x00
+#define APCI3120_ENABLE_TIMER0 0x1000 //$$Gatebit 0 in nWrAddress
+#define APCI3120_CLEAR_PR 0xF0FF
+#define APCI3120_CLEAR_PA 0xFFF0
+#define APCI3120_CLEAR_PA_PR (APCI3120_CLEAR_PR & APCI3120_CLEAR_PA)
+
+// nWrMode_Select
+#define APCI3120_ENABLE_SCAN 0x8 //$$ bit in nWrMode_Select
+#define APCI3120_DISABLE_SCAN (~APCI3120_ENABLE_SCAN)
+#define APCI3120_ENABLE_EOS_INT 0x2 //$$ bit in nWrMode_Select
+
+#define APCI3120_DISABLE_EOS_INT (~APCI3120_ENABLE_EOS_INT)
+#define APCI3120_ENABLE_EOC_INT 0x1
+#define APCI3120_DISABLE_EOC_INT (~APCI3120_ENABLE_EOC_INT)
+#define APCI3120_DISABLE_ALL_INTERRUPT_WITHOUT_TIMER (APCI3120_DISABLE_EOS_INT & APCI3120_DISABLE_EOC_INT)
+#define APCI3120_DISABLE_ALL_INTERRUPT (APCI3120_DISABLE_TIMER_INT & APCI3120_DISABLE_EOS_INT & APCI3120_DISABLE_EOC_INT)
+
+//status register bits
+#define APCI3120_EOC 0x8000
+#define APCI3120_EOS 0x2000
+
+// software trigger dummy register
+#define APCI3120_START_CONVERSION 0x02 //(ADDRESS)
+
+//TIMER DEFINE
+#define APCI3120_QUARTZ_A 70
+#define APCI3120_QUARTZ_B 50
+#define APCI3120_TIMER 1
+#define APCI3120_WATCHDOG 2
+#define APCI3120_TIMER_DISABLE 0
+#define APCI3120_TIMER_ENABLE 1
+#define APCI3120_ENABLE_TIMER2 0x4000 //$$ gatebit 2 in nWrAddress
+#define APCI3120_DISABLE_TIMER2 (~APCI3120_ENABLE_TIMER2)
+#define APCI3120_ENABLE_TIMER_INT 0x04 //$$ ENAIRQ_FC_Bit in nWrModeSelect
+#define APCI3120_DISABLE_TIMER_INT (~APCI3120_ENABLE_TIMER_INT)
+#define APCI3120_WRITE_MODE_SELECT 0x0E // (ADDRESS)
+#define APCI3120_SELECT_TIMER_0_WORD 0x00
+#define APCI3120_SELECT_TIMER_1_WORD 0x01
+#define APCI3120_TIMER_1_MODE_2 0x4
+
+//$$ BIT FOR MODE IN nCsTimerCtr1
+#define APCI3120_TIMER_2_MODE_0 0x0
+#define APCI3120_TIMER_2_MODE_2 0x10
+#define APCI3120_TIMER_2_MODE_5 0x30
+
+//$$ BIT FOR MODE IN nCsTimerCtr0
+#define APCI3120_SELECT_TIMER_2_LOW_WORD 0x02
+#define APCI3120_SELECT_TIMER_2_HIGH_WORD 0x03
+
+#define APCI3120_TIMER_CRT0 0x0D //(ADDRESS for cCsTimerCtr0)
+#define APCI3120_TIMER_CRT1 0x0C //(ADDRESS for cCsTimerCtr1)
+
+#define APCI3120_TIMER_VALUE 0x04 //ADDRESS for nCsTimerWert
+#define APCI3120_TIMER_STATUS_REGISTER 0x0D //ADDRESS for delete timer 2 interrupt
+#define APCI3120_RD_STATUS 0x02 //ADDRESS
+#define APCI3120_WR_ADDRESS 0x00 //ADDRESS
+#define APCI3120_ENABLE_WATCHDOG 0x20 //$$BIT in nWrMode_Select
+#define APCI3120_DISABLE_WATCHDOG (~APCI3120_ENABLE_WATCHDOG)
+#define APCI3120_ENABLE_TIMER_COUNTER 0x10 //$$BIT in nWrMode_Select
+#define APCI3120_DISABLE_TIMER_COUNTER (~APCI3120_ENABLE_TIMER_COUNTER)
+#define APCI3120_FC_TIMER 0x1000 //bit in status register
+#define APCI3120_ENABLE_TIMER0 0x1000
+#define APCI3120_ENABLE_TIMER1 0x2000
+#define APCI3120_ENABLE_TIMER2 0x4000
+#define APCI3120_DISABLE_TIMER0 (~APCI3120_ENABLE_TIMER0)
+#define APCI3120_DISABLE_TIMER1 (~APCI3120_ENABLE_TIMER1)
+#define APCI3120_DISABLE_TIMER2 (~APCI3120_ENABLE_TIMER2)
+
+#define APCI3120_TIMER2_SELECT_EOS 0xC0 // ADDED on 20-6
+#define APCI3120_COUNTER 3 // on 20-6
+#define APCI3120_DISABLE_ALL_TIMER ( APCI3120_DISABLE_TIMER0 & APCI3120_DISABLE_TIMER1 & APCI3120_DISABLE_TIMER2 )// on 20-6
+
+
+
+
+#define MAX_ANALOGINPUT_CHANNELS 32
+
+typedef struct
+{
+ BYTE b_Type ; /* EOC or EOS */
+ BYTE b_InterruptFlag ; /* Interrupt use or not */
+ UINT ui_ConvertTiming ; /* Selection of the convertion time */
+ BYTE b_NbrOfChannel ; /* Number of channel to read */
+ UINT ui_ChannelList[MAX_ANALOGINPUT_CHANNELS] ; /* Number of the channel to be read */
+ UINT ui_RangeList[MAX_ANALOGINPUT_CHANNELS] ; /* Gain of each channel */
+
+}str_AnalogReadInformation;
+
+
+
+
+
+
+// Function Declaration For APCI-3120
+
+// Internal functions
+int i_APCI3120_SetupChannelList(comedi_device * dev, comedi_subdevice * s, int n_chan, unsigned int *chanlist,char check);
+int i_APCI3120_ExttrigEnable(comedi_device * dev);
+int i_APCI3120_ExttrigDisable(comedi_device * dev);
+int i_APCI3120_StopCyclicAcquisition(comedi_device *dev,comedi_subdevice *s);
+int i_APCI3120_Reset(comedi_device *dev);
+int i_APCI3120_CyclicAnalogInput(int mode, comedi_device * dev,comedi_subdevice * s);
+// Interrupt functions
+void v_APCI3120_Interrupt(int irq, void *d, struct pt_regs *regs) ;
+void v_APCI3120_InterruptDmaMoveBlock16bit(comedi_device *dev,comedi_subdevice *s,sampl_t *dma,sampl_t *data,int n);
+int i_APCI3120_InterruptHandleEos(comedi_device *dev);
+void v_APCI3120_InterruptDma(int irq, void *d, struct pt_regs *regs) ;
+
+
+
+
+// TIMER
+
+int i_APCI3120_InsnConfigTimer(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+int i_APCI3120_InsnWriteTimer(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn,lsampl_t *data);
+int i_APCI3120_InsnReadTimer(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data);
+
+
+//DI
+// for di read
+
+
+int i_APCI3120_InsnBitsDigitalInput(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn,lsampl_t *data);
+int i_APCI3120_InsnReadDigitalInput(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn,lsampl_t *data);
+
+//DO
+//int i_APCI3120_WriteDigitalOutput(comedi_device *dev, BYTE data);
+int i_APCI3120_InsnConfigDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+int i_APCI3120_InsnBitsDigitalOutput(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn,lsampl_t *data);
+int i_APCI3120_InsnWriteDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+
+
+
+//AO
+//int i_APCI3120_Write1AnalogValue(comedi_device *dev,UINT ui_Range,UINT ui_Channel,UINT data );
+int i_APCI3120_InsnWriteAnalogOutput(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn,lsampl_t *data);
+
+
+//AI HArdware layer
+
+int i_APCI3120_InsnConfigAnalogInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+int i_APCI3120_InsnReadAnalogInput(comedi_device *dev, comedi_subdevice *s,comedi_insn *insn, lsampl_t *data);
+int i_APCI3120_CommandTestAnalogInput(comedi_device *dev,comedi_subdevice *s,comedi_cmd *cmd) ;
+int i_APCI3120_CommandAnalogInput(comedi_device *dev,comedi_subdevice *s);
+//int i_APCI3120_CancelAnalogInput(comedi_device * dev, comedi_subdevice * s);
+int i_APCI3120_StopCyclicAcquisition(comedi_device *dev,comedi_subdevice *s);
+
--- /dev/null
+/*
+ +-----------------------------------------------------------------------+
+ | (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 : 13Card Linux Driver | Compiler : GCC |
+ | Module name : hwdrv_apci3200.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Author : Shitalkumar S Chavan | Date : 10.12.2001 |
+ +-------------------------------+---------------------------------------+
+ | Description : Hardware Layer Acces For APCI-3200 |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +----------+-----------+------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+#include "hwdrv_apci3200.h"
+INT i_CJCAvailable=1;
+INT i_CJCPolarity=0;
+INT i_CJCGain=0;
+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
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3200_ReadDigitalInput |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Read value of the selected channel or port |
++----------------------------------------------------------------------------+
+| Input Parameters : 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(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *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 |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Configures The Digital Output Subdevice. |
++----------------------------------------------------------------------------+
+| Input Parameters : 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(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *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 |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : writes To the digital Output Subdevice |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s : Subdevice Pointer |
+| comedi_insn *insn : Insn Structure Pointer |
+| lsampl_t *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(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *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 |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Read value of the selected channel or port |
++----------------------------------------------------------------------------+
+| Input Parameters : 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(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *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 |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Configures The Analog Input Subdevice |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s : Subdevice Pointer |
+| comedi_insn *insn : Insn Structure Pointer |
+| lsampl_t *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(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+
+ UINT ul_Config = 0,ul_Temp=0 ;
+ UINT ui_ChannelNo=0;
+ UINT ui_Dummy=0;
+ INT i_err=0;
+ 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)
+
+
+ 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];
+ while(i_InterruptFlag==1)
+ {
+ udelay(1);
+ }
+
+ ui_ChannelNo = CR_CHAN(insn->chanspec); // get the channel
+ i_ChannelNo=ui_ChannelNo;
+ ui_Channel_num =ui_ChannelNo;
+ 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)
+ {
+ i_Offset=0;
+ }//if(ui_ChannelNo >=0 && ui_ChannelNo <=3)
+ if(ui_ChannelNo >=4 && ui_ChannelNo <=7)
+ {
+ i_Offset=64;
+ }//if(ui_ChannelNo >=4 && ui_ChannelNo <=7)
+ if(ui_ChannelNo >=8 && ui_ChannelNo <=11)
+ {
+ i_Offset=128;
+ }//if(ui_ChannelNo >=8 && ui_ChannelNo <=11)
+ if(ui_ChannelNo >=12 && ui_ChannelNo <=15)
+ {
+ i_Offset=192;
+ }//if(ui_ChannelNo >=12 && ui_ChannelNo <=15)
+ break;
+ case 1:
+ if(data[14]==2)
+ {
+ if(ui_ChannelNo ==0 )
+ {
+ i_Offset=0;
+ }//if(ui_ChannelNo ==0 )
+ if(ui_ChannelNo ==1)
+ {
+ i_Offset=64;
+ }// if(ui_ChannelNo ==1)
+ if(ui_ChannelNo ==2 )
+ {
+ i_Offset=128;
+ }//if(ui_ChannelNo ==2 )
+ if(ui_ChannelNo ==3)
+ {
+ i_Offset=192;
+ }//if(ui_ChannelNo ==3)
+ i_ChannelNo=0;
+ ui_ChannelNo=0;
+ break;
+ }//if(data[14]==2)
+ if(ui_ChannelNo >=0 && ui_ChannelNo <=1)
+ {
+ i_Offset=0;
+ }//if(ui_ChannelNo >=0 && ui_ChannelNo <=1)
+ if(ui_ChannelNo >=2 && ui_ChannelNo <=3)
+ {
+ i_ChannelNo=i_ChannelNo-2;
+ ui_ChannelNo=ui_ChannelNo-2;
+ i_Offset=64;
+ }//if(ui_ChannelNo >=2 && ui_ChannelNo <=3)
+ if(ui_ChannelNo >=4 && ui_ChannelNo <=5)
+ {
+ i_ChannelNo=i_ChannelNo-4;
+ ui_ChannelNo=ui_ChannelNo-4;
+ i_Offset=128;
+ }//if(ui_ChannelNo >=4 && ui_ChannelNo <=5)
+ if(ui_ChannelNo >=6 && ui_ChannelNo <=7)
+ {
+ i_ChannelNo=i_ChannelNo-6;
+ ui_ChannelNo=ui_ChannelNo-6;
+ i_Offset=192;
+ }//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:i_Offset=0;
+ break;
+ case 2:i_Offset=64;
+ break;
+ case 3:i_Offset=128;
+ break;
+ case 4:i_Offset=192;
+ 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)
+ {
+ i_Count=0;
+ i_Sum=0;
+ }//if(i_ScanType!=1)
+
+
+
+ ul_Config = data[1] |(data[2] << 6) |(data[5]<< 7) |(data[3] << 8) |(data[4] << 9);
+
+
+
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ /*********************************/
+ /* Write the channel to configure*/
+ /*********************************/
+ outl(0 | ui_ChannelNo , devpriv->iobase+i_Offset + 0x4);
+
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ /**************************/
+ /* Reset the configuration */
+ /**************************/
+ outl(0 , devpriv->iobase+i_Offset + 0x0);
+
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+
+ /***************************/
+ /* Write the configuration */
+ /***************************/
+ outl(ul_Config , devpriv->iobase+i_Offset + 0x0);
+
+ /***************************/
+ /*Reset the calibration bit*/
+ /***************************/
+ ul_Temp = inl(devpriv->iobase+i_Offset + 12);
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ outl((ul_Temp & 0xFFF9FFFF) , devpriv->iobase+i_Offset + 12);
+ if(data[9]==1)
+ {
+ devpriv->tsk_Current=current;
+ i_InterruptFlag=1;
+ }// if(data[9]==1)
+ else
+ {
+ i_InterruptFlag=0;
+ }//else if(data[9]==1)
+ i_Initialised=1;
+ if(i_ScanType==1)
+ {
+ i_Sum=i_Sum+1;
+ insn->unused[0]=0;
+ i_APCI3200_ReadAnalogInput(dev,s,insn,&ui_Dummy);
+ }
+return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3200_ReadAnalogInput |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Read value of the selected channel |
++----------------------------------------------------------------------------+
+| Input Parameters : 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
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI3200_ReadAnalogInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ UINT ui_DummyValue=0;
+ int i_ConvertCJCCalibration;
+ int i=0;
+
+
+ if(i_Initialised==0)
+ {
+ printk("\nThe channel is not initialised\n");
+ i_APCI3200_Reset(dev);
+ return -EINVAL;
+ }//if(i_Initialised==0);
+
+
+ switch(insn->unused[0])
+ {
+ case 0:
+
+ i_APCI3200_Read1AnalogInputChannel(dev,s,insn,&ui_DummyValue);
+ ui_InterruptChannelValue[i_Count+0]=ui_DummyValue;
+
+ if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE) && (i_CJCAvailable==1))
+ {
+ i_APCI3200_ReadCJCValue(dev,&ui_DummyValue);
+ ui_InterruptChannelValue[i_Count + 3]=ui_DummyValue;
+ }//if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE))
+ else
+ {
+ ui_InterruptChannelValue[i_Count + 3]=0;
+ }//elseif((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE) && (i_CJCAvailable==1))
+ if (( i_AutoCalibration == FALSE) && (i_InterruptFlag == FALSE))
+ {
+ i_APCI3200_ReadCalibrationOffsetValue(dev,&ui_DummyValue);
+ ui_InterruptChannelValue[i_Count + 1]=ui_DummyValue;
+ i_APCI3200_ReadCalibrationGainValue(dev,&ui_DummyValue);
+ ui_InterruptChannelValue[i_Count + 2]=ui_DummyValue;
+ }//if (( i_AutoCalibration == FALSE) && (i_InterruptFlag == FALSE))
+ if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)&& (i_CJCAvailable==1))
+ {
+ /**********************************************************/
+ /*Test if the Calibration channel must be read for the CJC*/
+ /**********************************************************/
+ /**********************************/
+ /*Test if the polarity is the same*/
+ /**********************************/
+ if(i_CJCPolarity!=i_ADDIDATAPolarity)
+ {
+ i_ConvertCJCCalibration=1;
+ }//if(i_CJCPolarity!=i_ADDIDATAPolarity)
+ else
+ {
+ if(i_CJCGain==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)
+ {
+ i_APCI3200_ReadCJCCalOffset(dev,&ui_DummyValue);
+ ui_InterruptChannelValue[i_Count+4]=ui_DummyValue;
+ i_APCI3200_ReadCJCCalGain(dev,&ui_DummyValue);
+ ui_InterruptChannelValue[i_Count+5]=ui_DummyValue;
+ }//if(i_ConvertCJCCalibration==1)
+ else
+ {
+ ui_InterruptChannelValue[i_Count+4]=0;
+ ui_InterruptChannelValue[i_Count+5]=0;
+ }//elseif(i_ConvertCJCCalibration==1)
+ }//if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE))
+ if(i_ScanType!=1)
+ {
+ i_Count=0;
+ }//if(i_ScanType!=1)
+ else
+ {
+ i_Count=i_Count +6;
+ }//else if(i_ScanType!=1)
+ if((i_ScanType==1) &&(i_InterruptFlag==1))
+ {
+ i_Count=i_Count-6;
+ }
+ if(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];
+
+
+ }
+ break;
+ case 1 :
+ for(i=0;i<insn->n;i++)
+ {
+ data[i]=ui_InterruptChannelValue[i];
+ }
+
+ i_Count=0;
+ i_Sum=0;
+ if(i_ScanType==1)
+ {
+ i_Initialised=0;
+ i_InterruptFlag=0;
+ }
+ 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 |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Read value of the selected channel |
++----------------------------------------------------------------------------+
+| Input Parameters : 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(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data){
+UINT ui_EOC=0;
+UINT ui_ChannelNo=0;
+UINT ui_CommandRegister=0;
+
+ ui_ChannelNo=i_ChannelNo;
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ /*********************************/
+ /* Write the channel to configure*/
+ /*********************************/
+ outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4);
+
+/*******************************/
+/* Set the convert timing unit */
+/*******************************/
+while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36);
+/**************************/
+/* Set the convert timing */
+/**************************/
+while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+outl(i_ADDIDATAConversionTime , devpriv->iobase+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)
+ {
+ /************************/
+ /* 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);
+ outl(ui_CommandRegister, devpriv->iobase+i_Offset + 8);
+ /*****************************/
+ /*Test if interrupt is enable*/
+ /*****************************/
+if (i_InterruptFlag == ADDIDATA_DISABLE)
+ {
+ do
+ {
+ /*************************/
+ /*Read the EOC Status bit*/
+ /*************************/
+
+ ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1;
+
+ } while (ui_EOC != 1);
+
+
+ /***************************************/
+ /* Read the digital value of the input */
+ /***************************************/
+
+
+ data[0] = inl (devpriv->iobase+i_Offset + 28);
+
+
+ }// if (i_InterruptFlag == ADDIDATA_DISABLE)
+return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3200_ReadCalibrationOffsetValue |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Read calibration offset value of the selected channel|
++----------------------------------------------------------------------------+
+| Input Parameters : 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(comedi_device *dev,UINT *data)
+{
+ UINT ui_Temp=0 , ui_EOC=0;
+ UINT ui_CommandRegister=0;
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ /*********************************/
+ /* Write the channel to configure*/
+ /*********************************/
+ outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4);
+
+ /*******************************/
+ /* Set the convert timing unit */
+ /*******************************/
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36);
+ /**************************/
+ /* Set the convert timing */
+ /**************************/
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32);
+ /*****************************/
+ /*Read the calibration offset*/
+ /*****************************/
+ ui_Temp = inl(devpriv->iobase+i_Offset + 12);
+
+ /*********************************/
+ /*Configure the Offset Conversion*/
+ /*********************************/
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ outl((ui_Temp | 0x00020000), devpriv->iobase+i_Offset + 12);
+ /*******************************/
+ /*Initialise ui_CommandRegister*/
+ /*******************************/
+
+ ui_CommandRegister = 0;
+
+ /*********************************/
+ /*Test if the interrupt is enable*/
+ /*********************************/
+
+ if (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);
+ outl(ui_CommandRegister, devpriv->iobase+i_Offset + 8);
+
+ /*****************************/
+ /*Test if interrupt is enable*/
+ /*****************************/
+
+ if (i_InterruptFlag == ADDIDATA_DISABLE)
+ {
+
+ do
+ {
+ /*******************/
+ /*Read the EOC flag*/
+ /*******************/
+
+ ui_EOC = inl (devpriv->iobase+i_Offset + 20) & 1;
+
+ } while (ui_EOC != 1);
+
+
+ /**************************************************/
+ /*Read the digital value of the calibration Offset*/
+ /**************************************************/
+
+
+ data[0] = inl(devpriv->iobase+i_Offset+ 28);
+ }//if (i_InterruptFlag == ADDIDATA_DISABLE)
+return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3200_ReadCalibrationGainValue |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Read calibration gain value of the selected channel |
++----------------------------------------------------------------------------+
+| Input Parameters : 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(comedi_device *dev,UINT *data)
+{
+ UINT ui_EOC=0;
+ INT ui_CommandRegister=0;
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ /*********************************/
+ /* Write the channel to configure*/
+ /*********************************/
+ outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4);
+
+ /***************************/
+ /*Read the calibration gain*/
+ /***************************/
+ /*******************************/
+ /* Set the convert timing unit */
+ /*******************************/
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36);
+ /**************************/
+ /* Set the convert timing */
+ /**************************/
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32);
+ /*******************************/
+ /*Configure the Gain Conversion*/
+ /*******************************/
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ outl(0x00040000 , devpriv->iobase+i_Offset + 12);
+
+
+ /*******************************/
+ /*Initialise ui_CommandRegister*/
+ /*******************************/
+
+ ui_CommandRegister = 0;
+
+ /*********************************/
+ /*Test if the interrupt is enable*/
+ /*********************************/
+
+ if (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);
+ outl(ui_CommandRegister , devpriv->iobase+i_Offset + 8);
+
+ /*****************************/
+ /*Test if interrupt is enable*/
+ /*****************************/
+
+ if (i_InterruptFlag == ADDIDATA_DISABLE)
+ {
+
+ do
+ {
+
+ /*******************/
+ /*Read the EOC flag*/
+ /*******************/
+
+ ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1;
+
+ } while (ui_EOC != 1);
+
+ /************************************************/
+ /*Read the digital value of the calibration Gain*/
+ /************************************************/
+
+ data[0] = inl(devpriv->iobase+i_Offset + 28);
+
+ }//if (i_InterruptFlag == ADDIDATA_DISABLE)
+return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3200_ReadCJCValue |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Read CJC value of the selected channel |
++----------------------------------------------------------------------------+
+| Input Parameters : 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(comedi_device *dev,lsampl_t *data)
+{
+ UINT ui_EOC=0;
+ INT ui_CommandRegister=0;
+
+ /******************************/
+ /*Set the converting time unit*/
+ /******************************/
+
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36);
+ /**************************/
+ /* Set the convert timing */
+ /**************************/
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32);
+
+ /******************************/
+ /*Configure the CJC Conversion*/
+ /******************************/
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ outl( 0x00000400 , devpriv->iobase+i_Offset + 4);
+ /*******************************/
+ /*Initialise dw_CommandRegister*/
+ /*******************************/
+ ui_CommandRegister = 0;
+ /*********************************/
+ /*Test if the interrupt is enable*/
+ /*********************************/
+ if (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);
+ outl(ui_CommandRegister , devpriv->iobase+i_Offset + 8);
+
+ /*****************************/
+ /*Test if interrupt is enable*/
+ /*****************************/
+
+ if (i_InterruptFlag == ADDIDATA_DISABLE)
+ {
+ do
+ {
+
+ /*******************/
+ /*Read the EOC flag*/
+ /*******************/
+
+ ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1;
+
+ } while (ui_EOC != 1);
+
+ /***********************************/
+ /*Read the digital value of the CJC*/
+ /***********************************/
+
+ data[0] = inl(devpriv->iobase+i_Offset + 28);
+
+ }//if (i_InterruptFlag == ADDIDATA_DISABLE)
+return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3200_ReadCJCCalOffset |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Read CJC calibration offset value of the selected channel
++----------------------------------------------------------------------------+
+| Input Parameters : 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(comedi_device *dev,lsampl_t *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);
+ outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36);
+ /**************************/
+ /* Set the convert timing */
+ /**************************/
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32);
+ /******************************/
+ /*Configure the CJC Conversion*/
+ /******************************/
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ outl(0x00000400 , devpriv->iobase+i_Offset + 4);
+ /*********************************/
+ /*Configure the Offset Conversion*/
+ /*********************************/
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ outl(0x00020000, devpriv->iobase+i_Offset + 12);
+
+ /*******************************/
+ /*Initialise ui_CommandRegister*/
+ /*******************************/
+ ui_CommandRegister = 0;
+ /*********************************/
+ /*Test if the interrupt is enable*/
+ /*********************************/
+
+ if (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);
+ outl(ui_CommandRegister,devpriv->iobase+i_Offset + 8);
+ if (i_InterruptFlag == ADDIDATA_DISABLE)
+ {
+ do
+ {
+ /*******************/
+ /*Read the EOC flag*/
+ /*******************/
+ ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1;
+ } while (ui_EOC != 1);
+
+ /**************************************************/
+ /*Read the digital value of the calibration Offset*/
+ /**************************************************/
+ data[0] = inl(devpriv->iobase+i_Offset + 28);
+ }//if (i_InterruptFlag == ADDIDATA_DISABLE)
+return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3200_ReadCJCGainValue |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Read CJC calibration gain value
++----------------------------------------------------------------------------+
+| Input Parameters : 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(comedi_device *dev,lsampl_t *data)
+{
+ UINT ui_EOC=0;
+ INT ui_CommandRegister=0;
+ /*******************************/
+ /* Set the convert timing unit */
+ /*******************************/
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36);
+ /**************************/
+ /* Set the convert timing */
+ /**************************/
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32);
+ /******************************/
+ /*Configure the CJC Conversion*/
+ /******************************/
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ outl(0x00000400,devpriv->iobase+i_Offset + 4);
+/*******************************/
+/*Configure the Gain Conversion*/
+/*******************************/
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ outl(0x00040000,devpriv->iobase+i_Offset + 12);
+
+ /*******************************/
+ /*Initialise dw_CommandRegister*/
+ /*******************************/
+ ui_CommandRegister = 0;
+/*********************************/
+/*Test if the interrupt is enable*/
+/*********************************/
+ if (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);
+outl(ui_CommandRegister ,devpriv->iobase+i_Offset + 8);
+if (i_InterruptFlag == ADDIDATA_DISABLE)
+ {
+ do
+ {
+ /*******************/
+ /*Read the EOC flag*/
+ /*******************/
+ ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1;
+ } while (ui_EOC != 1);
+ /************************************************/
+ /*Read the digital value of the calibration Gain*/
+ /************************************************/
+ data[0] = inl (devpriv->iobase+i_Offset + 28);
+ }//if (i_InterruptFlag == ADDIDATA_DISABLE)
+return 0;
+}
+
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3200_InsnBits_AnalogInput_Test |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Tests the Selected Anlog Input Channel |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s : Subdevice Pointer |
+| comedi_insn *insn : Insn Structure Pointer |
+| lsampl_t *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(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+UINT ui_Configuration=0;
+INT i_Temp,i_TimeUnit;
+if(i_Initialised==0)
+ {
+ printk("\nThe channel is not initialised\n");
+ 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);
+ outl((0x00001000 |i_ChannelNo) , devpriv->iobase+i_Offset + 4);
+ /*************************/
+ /*Set the time unit to ns*/
+ /*************************/
+ /* i_TimeUnit= i_ADDIDATAConversionTimeUnit;
+ i_ADDIDATAConversionTimeUnit= 1;*/
+ i_Temp= i_InterruptFlag ;
+ i_InterruptFlag = ADDIDATA_DISABLE;
+ i_APCI3200_Read1AnalogInputChannel(dev,s,insn,data);
+ if(i_AutoCalibration == FALSE)
+ {
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ outl((0x00001000 |i_ChannelNo) , devpriv->iobase+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);
+ outl((0x00000800|i_ChannelNo) , devpriv->iobase+i_Offset + 4);
+ ui_Configuration = inl(devpriv->iobase+i_Offset + 0);
+ /*************************/
+ /*Set the time unit to ns*/
+ /*************************/
+ /* i_TimeUnit= i_ADDIDATAConversionTimeUnit;
+ i_ADDIDATAConversionTimeUnit= 1;*/
+ i_Temp= i_InterruptFlag ;
+ i_InterruptFlag = ADDIDATA_DISABLE;
+ i_APCI3200_Read1AnalogInputChannel(dev,s,insn,data);
+ if(i_AutoCalibration == FALSE)
+ {
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ outl((0x00000800|i_ChannelNo) , devpriv->iobase+i_Offset + 4);
+ data++;
+ i_APCI3200_ReadCalibrationOffsetValue(dev,data);
+ data++;
+ i_APCI3200_ReadCalibrationGainValue(dev,data);
+ }
+ }
+ i_InterruptFlag=i_Temp ;
+printk("\ni_InterruptFlag=%d\n",i_InterruptFlag);
+return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3200_InsnWriteReleaseAnalogInput |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Resets the channels |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s : Subdevice Pointer |
+| comedi_insn *insn : Insn Structure Pointer |
+| lsampl_t *data : Data Pointer
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
+
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI3200_InsnWriteReleaseAnalogInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ i_APCI3200_Reset(dev);
+ return insn->n;
+ }
+
+
+
+
+
+
+
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3200_CommandTestAnalogInput(comedi_device *dev|
+| ,comedi_subdevice *s,comedi_cmd *cmd) |
+| |
++----------------------------------------------------------------------------+
+| Task : Test validity for a command for cyclic anlog input |
+| acquisition |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev |
+| comedi_subdevice *s |
+| comedi_cmd *cmd |
+| |
+|
+| |
+| |
+| |
++----------------------------------------------------------------------------+
+| Return Value :0 |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3200_CommandTestAnalogInput(comedi_device *dev,comedi_subdevice *s,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)
+ {
+ 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];
+ 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;
+ }
+ d_SCANTimeNewUnit = (double)ui_DelayTime;
+ i_NbrOfChannel= i_LastChannel-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++;
+ }
+ }//else if(cmd->scan_begin_src==TRIG_FOLLOW)
+
+
+
+ if(err)
+ {
+ i_APCI3200_Reset(dev);
+ return 4;
+ }
+
+ return 0;
+ }
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3200_StopCyclicAcquisition(comedi_device *dev,|
+| comedi_subdevice *s)|
+| |
++----------------------------------------------------------------------------+
+| Task : Stop the acquisition |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev |
+| comedi_subdevice *s |
+| |
++----------------------------------------------------------------------------+
+| Return Value :0 |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3200_StopCyclicAcquisition(comedi_device *dev,comedi_subdevice *s)
+{
+UINT ui_Configuration=0;
+i_InterruptFlag=0;
+i_Initialised==0;
+i_Count=0;
+i_Sum=0;
+ /*******************/
+ /*Read the register*/
+ /*******************/
+ ui_Configuration = inl(devpriv->iobase+i_Offset + 8);
+/*****************************/
+/*Reset the START and IRQ bit*/
+/*****************************/
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ outl((ui_Configuration & 0xFFE7FFFF),devpriv->iobase+i_Offset + 8);
+return 0;
+}
+/*
++----------------------------------------------------------------------------+
+| Function name : int i_APCI3200_CommandAnalogInput(comedi_device *dev, |
+| comedi_subdevice *s) |
+| |
++----------------------------------------------------------------------------+
+| Task : Does asynchronous acquisition |
+| Determines the mode 1 or 2. |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev |
+| comedi_subdevice *s |
+| |
+| |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+ int i_APCI3200_CommandAnalogInput(comedi_device *dev,comedi_subdevice *s)
+{
+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];
+ 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;
+ }
+ printk("\nui_ConvertTime=%u\n",ui_ConvertTime);
+ printk("\nui_ConvertTimebase=%u\n",ui_ConvertTimeBase);
+ // if(i_ADDIDATAType ==1 || ((i_ADDIDATAType==2)))
+ // {
+ /**************************************************/
+ /*Read the old configuration of the current source*/
+ /**************************************************/
+ ui_Configuration = inl(devpriv->iobase+i_Offset + 12);
+ /***********************************************/
+ /*Write the configuration of the current source*/
+ /***********************************************/
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ outl((ui_Configuration & 0xFFC00000 ), devpriv->iobase+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_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);
+ outl( ui_Configuration, devpriv->iobase+i_Offset + 0x8);
+ /***********************/
+ /*Write the Delay Value*/
+ /***********************/
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ outl(ui_DelayTime,devpriv->iobase+i_Offset + 40);
+ /***************************/
+ /*Write the Delay time base*/
+ /***************************/
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ outl(ui_DelayTimeBase,devpriv->iobase+i_Offset + 44);
+ /*********************************/
+ /*Write the conversion time value*/
+ /*********************************/
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ outl(ui_ConvertTime,devpriv->iobase+i_Offset + 32);
+ /********************************/
+ /*Write the conversion time base*/
+ /********************************/
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ outl(ui_ConvertTimeBase,devpriv->iobase+i_Offset + 36);
+ /*******************/
+ /*Read the register*/
+ /*******************/
+ ui_Configuration = inl(devpriv->iobase+i_Offset + 4);
+ /******************/
+ /*Set the SCAN bit*/
+ /******************/
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+
+ outl(((ui_Configuration & 0x1E0FF) | 0x00002000),devpriv->iobase+i_Offset + 4);
+ /*******************/
+ /*Read the register*/
+ /*******************/
+ ui_Configuration=0;
+ ui_Configuration = inl(devpriv->iobase+i_Offset + 8);
+
+ /*******************/
+ /*Set the START bit*/
+ /*******************/
+ while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ outl((ui_Configuration | 0x00080000),devpriv->iobase+i_Offset + 8);
+ return 0;
+}
+
+
+
+
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3200_Reset(comedi_device *dev) |
+| |
++----------------------------------------------------------------------------+
+| Task :Resets the registers of the card |
++----------------------------------------------------------------------------+
+| Input Parameters : |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3200_Reset(comedi_device *dev)
+{
+INT i_Temp;
+DWORD dw_Dummy;
+i_InterruptFlag=0;
+i_Initialised==0;
+i_Count=0;
+i_Sum=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;
+ }//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, struct pt_regs *regs) |
++----------------------------------------------------------------------------+
+| Task : Interrupt processing Routine |
++----------------------------------------------------------------------------+
+| Input Parameters : int irq : irq number |
+| void *d : void pointer |
+| struct pt_regs *regs : structure pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+ void v_APCI3200_Interrupt(int irq, void *d, struct pt_regs *regs)
+{
+ 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;
+ int k;
+
+switch(i_ScanType)
+ {
+ case 0:
+ case 1:
+ switch(i_ADDIDATAType)
+ {
+ case 0:
+ case 1:
+
+ /************************************/
+ /*Read the interrupt status register*/
+ /************************************/
+ ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16);
+ if ((ui_StatusRegister & 0x2) == 0x2)
+ {
+ i_CalibrationFlag = ((inl(devpriv->iobase+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);
+ /***********************************************/
+ /* Test if the value read is the channel value */
+ /***********************************************/
+ if (i_CalibrationFlag == 0)
+ {
+ ui_InterruptChannelValue[i_Count + 0] = ui_DigitalInput;
+
+ /******************************************************/
+ /*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;
+
+ /******************************************************/
+ /* 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;
+ if(i_ScanType==1)
+ {
+
+ i_InterruptFlag=0;
+ i_Count=i_Count + 6;
+ }//if(i_ScanType==1)
+ else
+ {
+ i_Count=0;
+ }//elseif(i_ScanType==1)
+ if(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)
+ {
+
+ 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);
+ /*************************/
+ /*Test if interrupt occur*/
+ /*************************/
+
+
+ if ((ui_StatusRegister & 0x2) == 0x2)
+ {
+
+ i_CJCFlag = ((inl(devpriv->iobase+i_Offset + 4) & 0x00000400) >> 10);
+
+ i_CalibrationFlag = ((inl(devpriv->iobase+i_Offset + 12) & 0x00060000) >> 17);
+
+ /*************************/
+ /*Read the channel number*/
+ /*************************/
+
+ ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24);
+
+
+ /************************************/
+ /*Read the digital temperature value*/
+ /************************************/
+ ui_DigitalTemperature = inl(devpriv->iobase+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;
+
+ /*********************************/
+ /*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;
+
+
+ /******************************************************/
+ /*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;
+
+ /****************************************************/
+ /*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;
+
+ /**********************************************************/
+ /*Test if the Calibration channel must be read for the CJC*/
+ /**********************************************************/
+
+ /*Test if the polarity is the same*/
+ /**********************************/
+ if(i_CJCPolarity!=i_ADDIDATAPolarity)
+ {
+ i_ConvertCJCCalibration=1;
+ }//if(i_CJCPolarity!=i_ADDIDATAPolarity)
+ else
+ {
+ if(i_CJCGain==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;
+
+ }//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;
+
+ /****************************************************************/
+ /*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;
+
+ if(i_ScanType==1)
+ {
+
+ i_InterruptFlag=0;
+ i_Count=i_Count + 6;
+ }//if(i_ScanType==1)
+ else
+ {
+ i_Count=0;
+ }//elseif(i_ScanType==1)
+ if(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)
+ {
+ 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(comedi_device *dev) |
+| |
+| |
++----------------------------------------------------------------------------+
+| Task : . |
+| This function copies the acquired data(from FIFO) |
+| to Comedi buffer. |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev |
+| |
+| |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI3200_InterruptHandleEos(comedi_device *dev)
+{
+ UINT ui_StatusRegister=0;
+ UINT ui_ChannelNumber = 0;
+ UINT *data;
+ comedi_subdevice *s=dev->subdevices+0;
+ comedi_async *async = s->async;
+ data=async->data+async->buf_int_ptr;//new samples added from here onwards
+
+ /************************************/
+ /*Read the interrupt status register*/
+ /************************************/
+ ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16);
+ /*************************/
+ /*Test if interrupt occur*/
+ /*************************/
+
+ if ((ui_StatusRegister & 0x2) == 0x2)
+ {
+ /*************************/
+ /*Read the channel number*/
+ /*************************/
+ ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24);
+
+ /*************************************/
+ /*Read the digital Analog Input value*/
+ /*************************************/
+
+ data[i_Count] = inl(devpriv->iobase+i_Offset + 28);
+// printk("\ndata[%d]=%x\n",i_Count,data[i_Count]);
+ if((i_Count == (i_LastChannel-i_FirstChannel+3)))
+ {
+ i_Count=-1;
+ async->buf_int_count+=(i_LastChannel-i_FirstChannel+4)*sizeof(UINT);
+ async->buf_int_ptr+=(i_LastChannel-i_FirstChannel+4)*sizeof(UINT);
+ comedi_eos(dev,s);
+ 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);
+ }
+ }
+ i_Count++;
+ }
+ i_InterruptFlag=0;
+ return 0;
+}
+
+
+
--- /dev/null
+// Card Specific information\r
+#define APCI3200_BOARD_VENDOR_ID 0x15B8\r
+//#define APCI3200_ADDRESS_RANGE 264\r
+
+
+
+int MODULE_NO ;
+ struct
+{
+ INT i_Gain ;
+ INT i_Polarity;
+ INT i_OffsetRange;
+ INT i_Coupling;
+ INT i_SingleDiff;
+ INT i_AutoCalibration;
+ UINT ui_ReloadValue;
+ UINT ui_TimeUnitReloadVal;
+ INT i_Interrupt;
+ INT i_ModuleSelection;
+}Config_Parameters_Module1,Config_Parameters_Module2,Config_Parameters_Module3,Config_Parameters_Module4;
+
+
+
+//ANALOG INPUT RANGE
+comedi_lrange range_apci3200_ai={ 8, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2),
+ BIP_RANGE(1),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2),
+ UNI_RANGE(1)
+ }
+};
+
+//Analog Input related Defines\r
+#define APCI3200_AI_OFFSET_GAIN 0\r
+#define APCI3200_AI_SC_TEST 4\r
+#define APCI3200_AI_IRQ 8\r
+#define APCI3200_AI_AUTOCAL 12\r
+#define APCI3200_RELOAD_CONV_TIME_VAL 32\r
+#define APCI3200_CONV_TIME_TIME_BASE 36\r
+#define APCI3200_RELOAD_DELAY_TIME_VAL 40\r
+#define APCI3200_DELAY_TIME_TIME_BASE 44\r
+#define APCI3200_AI_MODULE1 0\r
+#define APCI3200_AI_MODULE2 64\r
+#define APCI3200_AI_MODULE3 128\r
+#define APCI3200_AI_MODULE4 192\r
+#define TRUE 1
+#define FALSE 0
+#define APCI3200_AI_EOSIRQ 16\r
+#define APCI3200_AI_EOS 20\r
+#define APCI3200_AI_CHAN_ID 24\r
+#define APCI3200_AI_CHAN_VAL 28\r
+#define ANALOG_INPUT 0\r
+#define TEMPERATURE 1\r
+#define RESISTANCE 2\r
+\r
+#define ENABLE_EXT_TRIG 1\r
+#define ENABLE_EXT_GATE 2\r
+#define ENABLE_EXT_TRIG_GATE 3\r
+\r
+\r
+#define APCI3200_MAXVOLT 2.5\r
+#define ADDIDATA_GREATER_THAN_TEST 0\r
+#define ADDIDATA_LESS_THAN_TEST 1\r
+\r
+#define ADDIDATA_UNIPOLAR 1\r
+#define ADDIDATA_BIPOLAR 2\r
+\r
+//ADDIDATA Enable Disable\r
+#define ADDIDATA_ENABLE 1\r
+#define ADDIDATA_DISABLE 0\r
+
+typedef struct
+ {
+ ULONG ul_NumberOfValue;
+ ULONG *pul_ResistanceValue;
+ ULONG *pul_TemperatureValue;
+ }str_ADDIDATA_RTDStruct,*pstr_ADDIDATA_RTDStruct;
+\r
+\r
+// Hardware Layer functions for Apci3200\r
+\r
+//AI\r
+
+INT i_APCI3200_ConfigAnalogInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);\r
+INT i_APCI3200_ReadAnalogInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);\r
+INT i_APCI3200_InsnWriteReleaseAnalogInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+INT i_APCI3200_InsnBits_AnalogInput_Test(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+INT i_APCI3200_StopCyclicAcquisition(comedi_device *dev,comedi_subdevice *s);
+INT i_APCI3200_InterruptHandleEos(comedi_device *dev);
+INT i_APCI3200_CommandTestAnalogInput(comedi_device *dev,comedi_subdevice *s,comedi_cmd *cmd) ;
+INT i_APCI3200_CommandAnalogInput(comedi_device *dev,comedi_subdevice *s);
+INT i_APCI3200_ReadDigitalInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+//Interrupt\r
+void v_APCI3200_Interrupt(int irq, void *d, struct pt_regs *regs) ;\r
+int i_APCI3200_InterruptHandleEos(comedi_device *dev);\r
+//Reset functions\r
+INT i_APCI3200_Reset(comedi_device *dev); \r
+
+
+int i_APCI3200_ReadCJCCalOffset(comedi_device *dev,lsampl_t *data);\r
+int i_APCI3200_ReadCJCValue(comedi_device *dev,lsampl_t *data);\r
+int i_APCI3200_ReadCalibrationGainValue(comedi_device *dev,UINT *data);\r
+int i_APCI3200_ReadCalibrationOffsetValue(comedi_device *dev,UINT *data);
+int i_APCI3200_Read1AnalogInputChannel(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+int i_APCI3200_ReadCJCCalGain(comedi_device *dev,lsampl_t *data);\r
--- /dev/null
+/*
+ +-----------------------------------------------------------------------+
+ | (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 : 13Card Linux Driver | Compiler : GCC |
+ | Module name : hwdrv_apci3501.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Author : Shitalkumar S Chavan | Date : 10.12.2001 |
+ +-------------------------------+---------------------------------------+
+ | Description : Hardware Layer Acces For APCI-3501 |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +----------+-----------+------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+#include "hwdrv_apci3501.h"
+
+
+
+
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3501_ReadDigitalInput |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Read value of the selected channel or port |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To read |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI3501_ReadDigitalInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ UINT ui_Temp;
+ UINT ui_NoOfChannel;
+ ui_NoOfChannel=CR_CHAN(insn->chanspec);
+ ui_Temp=data[0];
+ *data=inl(devpriv->iobase+APCI3501_DIGITAL_IP);
+ if (ui_Temp==0)
+ {
+ *data=(*data >> ui_NoOfChannel)&0x1;
+ } //if (ui_Temp==0)
+ else
+ {
+ if (ui_Temp==1)
+ {
+
+ *data=*data & 0x3;
+ }//if (ui_Temp==1)
+ else
+ {
+ printk("\nSpecified channel not supported \n");
+ }//elseif (ui_Temp==1)
+ }//elseif (ui_Temp==0)
+return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3501_ConfigDigitalOutput |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Configures The Digital Output Subdevice. |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[1] : 1 Enable VCC Interrupt |
+| 0 Disable VCC Interrupt |
+| data[2] : 1 Enable CC Interrupt |
+| 0 Disable CC Interrupt |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI3501_ConfigDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *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_APCI3501_WriteDigitalOutput |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : writes To the digital Output Subdevice |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s : Subdevice Pointer |
+| comedi_insn *insn : Insn Structure Pointer |
+| lsampl_t *data : Data Pointer contains |
+| configuration parameters as below |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI3501_WriteDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ UINT ui_Temp,ui_Temp1;
+UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
+ if(devpriv->b_OutputMemoryStatus )
+ {
+ ui_Temp=inl(devpriv->iobase+APCI3501_DIGITAL_OP);
+ }//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->iobase+APCI3501_DIGITAL_OP);
+ }//if(data[1]==0)
+ else
+ {
+ if(data[1]==1)
+ {
+ data[0]=(data[0] << (2*data[2]))|ui_Temp;
+ outl(data[0],devpriv->iobase+APCI3501_DIGITAL_OP);
+ }// 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)^0xffffffff;
+ data[0]=data[0]& ui_Temp;
+ outl(data[0],devpriv->iobase+APCI3501_DIGITAL_OP);
+ }//if(data[1]==0)
+ else
+ {
+ if(data[1]==1)
+ {
+ 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]))^0xffffffff)& ui_Temp;
+ outl(data[0],devpriv->iobase+APCI3501_DIGITAL_OP);
+ }// 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_APCI3501_ReadDigitalOutput |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Read value of the selected channel or port |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To read |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI3501_ReadDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ UINT ui_Temp;
+ UINT ui_NoOfChannel;
+
+ ui_NoOfChannel=CR_CHAN(insn->chanspec);
+ ui_Temp=data[0];
+ *data=inl(devpriv->iobase+APCI3501_DIGITAL_OP);
+ if (ui_Temp==0)
+ {
+ *data=(*data >> ui_NoOfChannel)&0x1;
+ } // if (ui_Temp==0)
+ else
+ {
+ if (ui_Temp==1)
+ {
+ *data=*data & 0x3;
+
+ } // 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_APCI3501_ConfigAnalogOutput |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Configures The Analog Output Subdevice |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s : Subdevice Pointer |
+| comedi_insn *insn : Insn Structure Pointer |
+| lsampl_t *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : Voltage Mode |
+| 0:Mode 0 |
+| 1:Mode 1 |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI3501_ConfigAnalogOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ outl(data[0],devpriv->iobase+APCI3501_ANALOG_OUTPUT+APCI3501_AO_VOLT_MODE);
+
+ if(data[0])
+ {
+ devpriv->b_InterruptMode=MODE1;
+ }
+ else
+ {
+ devpriv->b_InterruptMode=MODE0;
+ }
+return insn->n;
+}
+
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3501_WriteAnalogOutput |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Writes To the Selected Anlog Output Channel |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| comedi_subdevice *s : Subdevice Pointer |
+| comedi_insn *insn : Insn Structure Pointer |
+| lsampl_t *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI3501_WriteAnalogOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ULONG ul_Command1 = 0,ul_Channel_no,ul_Polarity,ul_DAC_Ready=0;;
+
+ul_Channel_no=CR_CHAN(insn->chanspec);
+
+if(devpriv->b_InterruptMode==MODE1)
+ {
+ ul_Polarity=0x80000000;
+ if((*data<0) || (*data>16384))
+ {
+ printk("\nIn WriteAnalogOutput :: Not Valid Data\n");
+ }
+
+ } // end if(devpriv->b_InterruptMode==MODE1)
+else {
+ ul_Polarity=0;
+ if((*data<0) || (*data>8192))
+ {
+ printk("\nIn WriteAnalogOutput :: Not Valid Data\n");
+ }
+
+ }// end else
+
+if((ul_Channel_no<0)||(ul_Channel_no>7))
+ {
+ printk("\nIn WriteAnalogOutput :: Not Valid Channel\n");
+ } // end if((ul_Channel_no<0)||(ul_Channel_no>7))
+
+ul_DAC_Ready=inl(devpriv->iobase+APCI3501_ANALOG_OUTPUT);
+
+while(ul_DAC_Ready==0)
+ {
+ ul_DAC_Ready=inl(devpriv->iobase+APCI3501_ANALOG_OUTPUT);
+ ul_DAC_Ready=(ul_DAC_Ready>>8)&1;
+ }
+
+if(ul_DAC_Ready)
+{
+// Output the Value on the output channels.
+ul_Command1=(ULONG)((ULONG)(ul_Channel_no & 0xFF)|(ULONG)((*data << 0x8)&0x7FFFFF00L)|(ULONG)(ul_Polarity));
+outl(ul_Command1,devpriv->iobase+APCI3501_ANALOG_OUTPUT+APCI3501_AO_PROG);
+}
+
+return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3501_ConfigTimerCounterWatchdog |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Configures The Timer , Counter or Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : 0 Configure As Timer |
+| 1 Configure As Counter |
+| 2 Configure As Watchdog |
+| data[1] : 1 Enable Interrupt |
+| 0 Disable Interrupt |
+| data[2] : Time Unit |
+| data[3] : Reload Value |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI3501_ConfigTimerCounterWatchdog (comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ ULONG ul_Command1 = 0;
+devpriv->tsk_Current=current;
+ if (data[0]==ADDIDATA_WATCHDOG)
+ {
+
+ devpriv->b_TimerSelectMode = ADDIDATA_WATCHDOG;
+ //Disable the watchdog
+ outl(0x0,devpriv->iobase+ APCI3501_WATCHDOG+ APCI3501_TCW_PROG); //disable Wa
+
+ if (data[1]==1)
+ {
+ //Enable TIMER int & DISABLE ALL THE OTHER int SOURCES
+ outl(0x02,devpriv->iobase+APCI3501_WATCHDOG+APCI3501_TCW_PROG);
+ }
+ else
+ {
+ outl(0x0,devpriv->iobase+APCI3501_WATCHDOG+APCI3501_TCW_PROG);//disable Timer interrupt
+ }
+
+
+ //Loading the Timebase value
+ outl(data[2],devpriv->iobase+APCI3501_WATCHDOG+APCI3501_TCW_TIMEBASE);
+
+
+ //Loading the Reload value
+ outl(data[3],devpriv->iobase+APCI3501_WATCHDOG+APCI3501_TCW_RELOAD_VALUE);
+ //Set the mode
+ ul_Command1 = inl(devpriv->iobase+APCI3501_WATCHDOG+APCI3501_TCW_PROG) | 0xFFF819E0UL;//e2->e0
+ outl(ul_Command1 , devpriv->iobase+APCI3501_WATCHDOG+APCI3501_TCW_PROG);
+ }//end if(data[0]==ADDIDATA_WATCHDOG)
+
+ else if (data[0]==ADDIDATA_TIMER)
+ {
+ //First Stop The Timer
+ ul_Command1 =inl(devpriv->iobase+ APCI3501_WATCHDOG+ APCI3501_TCW_PROG);
+ ul_Command1 =ul_Command1 & 0xFFFFF9FEUL;
+ outl(ul_Command1,devpriv->iobase+ APCI3501_WATCHDOG+ APCI3501_TCW_PROG);//Stop The Timer
+ devpriv->b_TimerSelectMode =ADDIDATA_TIMER;
+ if (data[1]==1)
+ {
+ //Enable TIMER int & DISABLE ALL THE OTHER int SOURCES
+ outl(0x02,devpriv->iobase+ APCI3501_WATCHDOG+ APCI3501_TCW_PROG);
+ }
+ else
+ {
+ outl(0x0,devpriv->iobase+ APCI3501_WATCHDOG+ APCI3501_TCW_PROG);//disable Timer interrupt
+ }
+
+ // Loading Timebase
+ outl(data[2],devpriv->iobase+APCI3501_WATCHDOG+APCI3501_TCW_TIMEBASE);
+
+ //Loading the Reload value
+ outl(data[3],devpriv->iobase+APCI3501_WATCHDOG+APCI3501_TCW_RELOAD_VALUE);
+
+ // printk ("\nTimer Address :: %x\n", (devpriv->iobase+APCI3501_WATCHDOG));
+ ul_Command1 =inl(devpriv->iobase+ APCI3501_WATCHDOG+ APCI3501_TCW_PROG);
+ ul_Command1 = (ul_Command1 & 0xFFF719E2UL) | 2UL << 13UL | 0x10UL;
+ outl(ul_Command1,devpriv->iobase+ APCI3501_WATCHDOG+ APCI3501_TCW_PROG);//mode 2
+
+ }//end if(data[0]==ADDIDATA_TIMER)
+
+return insn->n;
+}
+
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3501_StartStopWriteTimerCounterWatchdog |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Start / Stop The Selected Timer , Counter or Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : 0 Timer |
+| 1 Counter |
+| 2 Watchdog | | data[1] : 1 Start |
+| 0 Stop | 2 Trigger |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3501_StartStopWriteTimerCounterWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+ULONG ul_Command1 = 0;
+int i_Temp;
+if (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
+ {
+
+ if (data[1]==1)
+ {
+ ul_Command1=inl(devpriv->iobase+ APCI3501_WATCHDOG+ APCI3501_TCW_PROG);
+ ul_Command1=(ul_Command1& 0xFFFFF9FFUL) | 0x1UL;
+ //Enable the Watchdog
+ outl(ul_Command1,devpriv->iobase+ APCI3501_WATCHDOG+ APCI3501_TCW_PROG);
+ }
+
+ else if(data[1]==0)//Stop The Watchdog
+ {
+ //Stop The Watchdog
+ ul_Command1=inl(devpriv->iobase+ APCI3501_WATCHDOG+ APCI3501_TCW_PROG);
+ ul_Command1 =ul_Command1 & 0xFFFFF9FEUL;
+ outl(0x0,devpriv->iobase+ APCI3501_WATCHDOG+ APCI3501_TCW_PROG);
+ }
+ else if(data[1]==2)
+ {
+ ul_Command1=inl(devpriv->iobase+ APCI3501_WATCHDOG+ APCI3501_TCW_PROG);
+ ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x200UL;
+ outl(ul_Command1,devpriv->iobase+ APCI3501_WATCHDOG+ APCI3501_TCW_PROG);
+ }//if(data[1]==2)
+ } // end if (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
+
+if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
+ {
+ if (data[1]==1)
+ {
+
+ ul_Command1=inl(devpriv->iobase+ APCI3501_WATCHDOG+ APCI3501_TCW_PROG);
+ ul_Command1=(ul_Command1& 0xFFFFF9FFUL) | 0x1UL;
+ //Enable the Timer
+ outl(ul_Command1,devpriv->iobase+ APCI3501_WATCHDOG+ APCI3501_TCW_PROG);
+ }
+ else if(data[1]==0)
+ {
+ //Stop The Timer
+ ul_Command1=inl(devpriv->iobase+ APCI3501_WATCHDOG+ APCI3501_TCW_PROG);
+ ul_Command1 =ul_Command1 & 0xFFFFF9FEUL;
+ outl(ul_Command1,devpriv->iobase+ APCI3501_WATCHDOG+ APCI3501_TCW_PROG);
+ }
+
+ else if (data[1]==2)
+ {
+ //Trigger the Timer
+ ul_Command1=inl(devpriv->iobase+ APCI3501_WATCHDOG+ APCI3501_TCW_PROG);
+ ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x200UL;
+ outl(ul_Command1,devpriv->iobase+ APCI3501_WATCHDOG+ APCI3501_TCW_PROG);
+ }
+
+ } // end if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
+i_Temp= inl(devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_TRIG_STATUS)&0x1;
+return insn->n;
+}
+
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3501_ReadTimerCounterWatchdog |
+| (comedi_device *dev,comedi_subdevice *s, |
+| comedi_insn *insn,lsampl_t *data) |
++----------------------------------------------------------------------------+
+| Task : Read The Selected Timer , Counter or Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : 0 Timer |
+| 1 Counter |
+| 2 Watchdog | | data[1] : Timer Counter Watchdog Number |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3501_ReadTimerCounterWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
+{
+
+ if (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
+ {
+ data[0]= inl(devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_TRIG_STATUS)&0x1;
+ data[1]= inl(devpriv->iobase + APCI3501_WATCHDOG);
+ }// end if (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
+
+ else if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
+ {
+ data[0]= inl(devpriv->iobase+APCI3501_WATCHDOG+APCI3501_TCW_TRIG_STATUS)&0x1;
+ data[1]= inl(devpriv->iobase + APCI3501_WATCHDOG);
+ } // end if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
+
+ else if ((devpriv->b_TimerSelectMode!=ADDIDATA_TIMER) && (devpriv->b_TimerSelectMode!=ADDIDATA_WATCHDOG))
+ {
+ printk ("\nIn ReadTimerCounterWatchdog :: Invalid Subdevice \n");
+ }
+return insn->n;
+}
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3501_Reset(comedi_device *dev) |
+| |
++----------------------------------------------------------------------------+
+| Task :Resets the registers of the card |
++----------------------------------------------------------------------------+
+| Input Parameters : |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3501_Reset(comedi_device *dev)
+{
+int i_Count=0,i_temp=0;
+ULONG ul_Command1 = 0,ul_Polarity,ul_DAC_Ready=0;
+outl(0x0,devpriv->iobase+APCI3501_DIGITAL_OP);
+outl(1,devpriv->iobase+APCI3501_ANALOG_OUTPUT+APCI3501_AO_VOLT_MODE);
+
+ ul_Polarity=0x80000000;
+
+for(i_Count=0;i_Count<=7;i_Count++)
+ {
+ ul_DAC_Ready=inl(devpriv->iobase+APCI3501_ANALOG_OUTPUT);
+
+ while(ul_DAC_Ready==0)
+ {
+ ul_DAC_Ready=inl(devpriv->iobase+APCI3501_ANALOG_OUTPUT);
+ ul_DAC_Ready=(ul_DAC_Ready>>8)&1;
+ }
+
+ if(ul_DAC_Ready)
+ {
+ // Output the Value on the output channels.
+ ul_Command1=(ULONG)((ULONG)(i_Count & 0xFF)|(ULONG)((i_temp << 0x8)&0x7FFFFF00L)|(ULONG)(ul_Polarity));
+ outl(ul_Command1,devpriv->iobase+APCI3501_ANALOG_OUTPUT+APCI3501_AO_PROG);
+ }
+ }
+
+return 0;
+}
+
+
+
+
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : static void v_APCI3501_Interrupt |
+| (int irq , void *d, struct pt_regs *regs) |
++----------------------------------------------------------------------------+
+| Task : Interrupt processing Routine |
++----------------------------------------------------------------------------+
+| Input Parameters : int irq : irq number |
+| void *d : void pointer |
+| struct pt_regs *regs : structure pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+ void v_APCI3501_Interrupt(int irq, void *d, struct pt_regs *regs)
+{
+ int i_temp;
+ comedi_device *dev = d;
+ unsigned int ui_Timer_AOWatchdog ;
+ unsigned long ul_Command1;
+ // Disable Interrupt
+ ul_Command1=inl(devpriv->iobase+APCI3501_WATCHDOG +APCI3501_TCW_PROG);
+
+ ul_Command1 = (ul_Command1 & 0xFFFFF9FDul);
+ outl(ul_Command1 , devpriv->iobase+APCI3501_WATCHDOG +APCI3501_TCW_PROG);
+
+
+ ui_Timer_AOWatchdog=inl(devpriv->iobase+APCI3501_WATCHDOG +APCI3501_TCW_IRQ )& 0x1;
+
+ if ((!ui_Timer_AOWatchdog))
+ {
+ comedi_error(dev,"IRQ from unknow source");
+ return;
+ }
+
+
+ // Enable Interrupt
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO,devpriv->tsk_Current,0);
+ ul_Command1=inl(devpriv->iobase+APCI3501_WATCHDOG +APCI3501_TCW_PROG);
+ ul_Command1 = ((ul_Command1 & 0xFFFFF9FDul) | 1 << 1);
+ outl(ul_Command1 , devpriv->iobase+APCI3501_WATCHDOG +APCI3501_TCW_PROG);
+ i_temp= inl(devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_TRIG_STATUS)&0x1;
+return;
+}
+
+
+
--- /dev/null
+// Card Specific information
+#define APCI3501_BOARD_VENDOR_ID 0x15B8
+#define APCI3501_ADDRESS_RANGE 255
+
+#define APCI3501_DIGITAL_IP 0x50
+#define APCI3501_DIGITAL_OP 0x40
+#define APCI3501_ANALOG_OUTPUT 0x00
+
+//Analog Output related Defines
+#define APCI3501_AO_VOLT_MODE 0
+#define APCI3501_AO_PROG 4
+#define APCI3501_AO_TRIG_SCS 8
+#define UNIPOLAR 0
+#define BIPOLAR 1
+#define MODE0 0
+#define MODE1 1
+// ANALOG OUTPUT RANGE
+comedi_lrange range_apci3501_ao= { 2, {
+ BIP_RANGE(10),
+ UNI_RANGE(10)
+ }
+};
+
+//Watchdog Related Defines
+
+#define APCI3501_WATCHDOG 0x20
+#define APCI3501_TCW_SYNC_ENABLEDISABLE 0
+#define APCI3501_TCW_RELOAD_VALUE 4
+#define APCI3501_TCW_TIMEBASE 8
+#define APCI3501_TCW_PROG 12
+#define APCI3501_TCW_TRIG_STATUS 16
+#define APCI3501_TCW_IRQ 20
+#define APCI3501_TCW_WARN_TIMEVAL 24
+#define APCI3501_TCW_WARN_TIMEBASE 28
+#define ADDIDATA_TIMER 0
+#define ADDIDATA_WATCHDOG 2
+
+
+// Hardware Layer functions for Apci3501
+
+//AO
+INT i_APCI3501_ConfigAnalogOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+INT i_APCI3501_WriteAnalogOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+
+//DI
+// for di read
+//INT i_APCI3501_ReadDigitalInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+
+INT i_APCI3501_ReadDigitalInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+
+//DO
+int i_APCI3501_ConfigDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+INT i_APCI3501_WriteDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+INT i_APCI3501_ReadDigitalOutput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+
+// TIMER
+// timer value is passed as u seconds
+INT i_APCI3501_ConfigTimerCounterWatchdog (comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+int i_APCI3501_StartStopWriteTimerCounterWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+int i_APCI3501_ReadTimerCounterWatchdog(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+//Interrupt
+void v_APCI3501_Interrupt(int irq, void *d, struct pt_regs *regs) ;
+
+//Reset functions
+ int i_APCI3501_Reset(comedi_device *dev);
+
+
+
+
+
+