| /* |
| * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. |
| * |
| * ADDI-DATA GmbH |
| * Dieselstrasse 3 |
| * D-77833 Ottersweier |
| * Tel: +19(0)7223/9493-0 |
| * Fax: +49(0)7223/9493-92 |
| * http://www.addi-data-com |
| * info@addi-data.com |
| * |
| * This program is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License as published by the Free |
| * Software Foundation; either version 2 of the License, or (at your option) |
| * any later version. |
| */ |
| /* |
| | Description : APCI-1710 82X54 timer module | |
| */ |
| |
| #include "APCI1710_82x54.h" |
| |
| /* |
| +----------------------------------------------------------------------------+ |
| | Function Name : _INT_ i_APCI1710_InitTimer | |
| | (unsigned char_ b_BoardHandle, | |
| | unsigned char_ b_ModulNbr, | |
| | unsigned char_ b_TimerNbr, | |
| | unsigned char_ b_TimerMode, | |
| | ULONG_ ul_ReloadValue, | |
| | unsigned char_ b_InputClockSelection, | |
| | unsigned char_ b_InputClockLevel, | |
| | unsigned char_ b_OutputLevel, | |
| | unsigned char_ b_HardwareGateLevel) |
| int i_InsnConfig_InitTimer(struct comedi_device *dev,struct comedi_subdevice *s, |
| struct comedi_insn *insn,unsigned int *data) |
| | |
| +----------------------------------------------------------------------------+ |
| | Task : Configure the Timer (b_TimerNbr) operating mode | |
| | (b_TimerMode) from selected module (b_ModulNbr). | |
| | You must calling this function be for you call any | |
| | other function witch access of the timer. | |
| | | |
| | | |
| | Timer mode description table | |
| | | |
| |+--------+-----------------------------+--------------+--------------------+| |
| ||Selected+ Mode description +u_ReloadValue | Hardware gate input|| |
| || mode | | description | action || |
| |+--------+-----------------------------+--------------+--------------------+| |
| || |Mode 0 is typically used | | || |
| || |for event counting. After | | || |
| || |the initialisation, OUT | | || |
| || |is initially low, and | | || |
| || 0 |will remain low until the |Start counting| Hardware gate || |
| || |counter reaches zero. | value | || |
| || |OUT then goes high and | | || |
| || |remains high until a new | | || |
| || |count is written. See | | || |
| || |"i_APCI1710_WriteTimerValue" | | || |
| || |function. | | || |
| |+--------+-----------------------------+--------------+--------------------+| |
| || |Mode 1 is similar to mode 0 | | || |
| || |except for the gate input | | || |
| || 1 |action. The gate input is not|Start counting| Hardware trigger || |
| || |used for enabled or disabled | value | || |
| || |the timer. | | || |
| || |The gate input is used for | | || |
| || |triggered the timer. | | || |
| |+--------+-----------------------------+--------------+--------------------+| |
| || |This mode functions like a | | || |
| || |divide-by-ul_ReloadValue | | || |
| || |counter. It is typically used| | || |
| || |to generate a real time clock| | || |
| || |interrupt. OUT will initially| | || |
| || 2 |be high after the | Division | Hardware gate || |
| || |initialisation. When the | factor | || |
| || |initial count has decremented| | || |
| || |to 1, OUT goes low for one | | || |
| || |CLK pule. OUT then goes high | | || |
| || |again, the counter reloads | | || |
| || |the initial count | | || |
| || |(ul_ReloadValue) and the | | || |
| || |process is repeated. | | || |
| || |This action can generated a | | || |
| || |interrupt. See function | | || |
| || |"i_APCI1710_SetBoardInt- | | || |
| || |RoutineX" | | || |
| || |and "i_APCI1710_EnableTimer" | | || |
| |+--------+-----------------------------+--------------+--------------------+| |
| || |Mode 3 is typically used for | | || |
| || |baud rate generation. This | | || |
| || |mode is similar to mode 2 | | || |
| || |except for the duty cycle of | | || |
| || 3 |OUT. OUT will initially be | Division | Hardware gate || |
| || |high after the initialisation| factor | || |
| || |When half the initial count | | || |
| || |(ul_ReloadValue) has expired,| | || |
| || |OUT goes low for the | | || |
| || |remainder of the count. The | | || |
| || |mode is periodic; the | | || |
| || |sequence above is repeated | | || |
| || |indefinitely. | | || |
| |+--------+-----------------------------+--------------+--------------------+| |
| || |OUT will be initially high | | || |
| || |after the initialisation. | | || |
| || |When the initial count | | || |
| || 4 |expires OUT will go low for |Start counting| Hardware gate || |
| || |one CLK pulse and then go | value | || |
| || |high again. | | || |
| || |The counting sequences is | | || |
| || |triggered by writing a new | | || |
| || |value. See | | || |
| || |"i_APCI1710_WriteTimerValue" | | || |
| || |function. If a new count is | | || |
| || |written during counting, | | || |
| || |it will be loaded on the | | || |
| || |next CLK pulse | | || |
| |+--------+-----------------------------+--------------+--------------------+| |
| || |Mode 5 is similar to mode 4 | | || |
| || |except for the gate input | | || |
| || |action. The gate input is not| | || |
| || 5 |used for enabled or disabled |Start counting| Hardware trigger || |
| || |the timer. The gate input is | value | || |
| || |used for triggered the timer.| | || |
| |+--------+-----------------------------+--------------+--------------------+| |
| | | |
| | | |
| | | |
| | Input clock selection table | |
| | | |
| | +--------------------------------+------------------------------------+ | |
| | | b_InputClockSelection | Description | | |
| | | parameter | | | |
| | +--------------------------------+------------------------------------+ | |
| | | APCI1710_PCI_BUS_CLOCK | For the timer input clock, the PCI | | |
| | | | bus clock / 4 is used. This PCI bus| | |
| | | | clock can be 30MHz or 33MHz. For | | |
| | | | Timer 0 only this selection are | | |
| | | | available. | | |
| | +--------------------------------+------------------------------------+ | |
| | | APCI1710_ FRONT_CONNECTOR_INPUT| Of the front connector you have the| | |
| | | | possibility to inject a input clock| | |
| | | | for Timer 1 or Timer 2. The source | | |
| | | | from this clock can eat the output | | |
| | | | clock from Timer 0 or any other | | |
| | | | clock source. | | |
| | +--------------------------------+------------------------------------+ | |
| | | |
| +----------------------------------------------------------------------------+ |
| | Input Parameters : unsigned char_ b_BoardHandle : Handle of board | |
| | APCI-1710 | |
| | unsigned char_ b_ModulNbr : Module number to | |
| | configure (0 to 3) | |
| | unsigned char_ b_TimerNbr : Timer number to | |
| | configure (0 to 2) | |
| | unsigned char_ b_TimerMode : Timer mode selection | |
| | (0 to 5) | |
| | 0: Interrupt on terminal| |
| | count | |
| | 1: Hardware | |
| | retriggerable one- | |
| | shot | |
| | 2: Rate generator | |
| | 3: Square wave mode | |
| | 4: Software triggered | |
| | strobe | |
| | 5: Hardware triggered | |
| | strobe | |
| | See timer mode | |
| | description table. | |
| | ULONG_ ul_ReloadValue : Start counting value | |
| | or division factor | |
| | See timer mode | |
| | description table. | |
| | unsigned char_ b_InputClockSelection : Selection from input | |
| | timer clock. | |
| | See input clock | |
| | selection table. | |
| | unsigned char_ b_InputClockLevel : Selection from input | |
| | clock level. | |
| | 0 : Low active | |
| | (Input inverted) | |
| | 1 : High active | |
| | unsigned char_ b_OutputLevel, : Selection from output | |
| | clock level. | |
| | 0 : Low active | |
| | 1 : High active | |
| | (Output inverted) | |
| | unsigned char_ b_HardwareGateLevel : Selection from | |
| | hardware gate level. | |
| | 0 : Low active | |
| | (Input inverted) | |
| | 1 : High active | |
| | If you will not used | |
| | the hardware gate set | |
| | this value to 0. |
| |b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec); |
| b_TimerNbr = (unsigned char) CR_CHAN(insn->chanspec); |
| b_TimerMode = (unsigned char) data[0]; |
| ul_ReloadValue = (unsigned int) data[1]; |
| b_InputClockSelection =(unsigned char) data[2]; |
| b_InputClockLevel =(unsigned char) data[3]; |
| b_OutputLevel =(unsigned char) data[4]; |
| b_HardwareGateLevel =(unsigned char) data[5]; |
| +----------------------------------------------------------------------------+ |
| | 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 mode selection is wrong | |
| | -6: Input timer clock selection is wrong | |
| | -7: Selection from input clock level is wrong | |
| | -8: Selection from output clock level is wrong | |
| | -9: Selection from hardware gate level is wrong | |
| +----------------------------------------------------------------------------+ |
| */ |
| |
| int i_APCI1710_InsnConfigInitTimer(struct comedi_device *dev, struct comedi_subdevice *s, |
| struct comedi_insn *insn, unsigned int *data) |
| { |
| |
| int i_ReturnValue = 0; |
| unsigned char b_ModulNbr; |
| unsigned char b_TimerNbr; |
| unsigned char b_TimerMode; |
| unsigned int ul_ReloadValue; |
| unsigned char b_InputClockSelection; |
| unsigned char b_InputClockLevel; |
| unsigned char b_OutputLevel; |
| unsigned char b_HardwareGateLevel; |
| |
| /* BEGIN JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz */ |
| unsigned int dw_Test = 0; |
| /* END JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz */ |
| |
| i_ReturnValue = insn->n; |
| b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec); |
| b_TimerNbr = (unsigned char) CR_CHAN(insn->chanspec); |
| b_TimerMode = (unsigned char) data[0]; |
| ul_ReloadValue = (unsigned int) data[1]; |
| b_InputClockSelection = (unsigned char) data[2]; |
| b_InputClockLevel = (unsigned char) data[3]; |
| b_OutputLevel = (unsigned char) data[4]; |
| b_HardwareGateLevel = (unsigned char) data[5]; |
| |
| /* 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 <= 2) { |
| /* Test the timer mode */ |
| if (b_TimerMode <= 5) { |
| /* BEGIN JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz */ |
| /* Test te imput clock selection */ |
| /* |
| if (((b_TimerNbr == 0) && (b_InputClockSelection == 0)) || |
| ((b_TimerNbr != 0) && ((b_InputClockSelection == 0) || (b_InputClockSelection == 1)))) |
| */ |
| |
| if (((b_TimerNbr == 0) && |
| (b_InputClockSelection == APCI1710_PCI_BUS_CLOCK)) || |
| ((b_TimerNbr == 0) && |
| (b_InputClockSelection == APCI1710_10MHZ)) || |
| ((b_TimerNbr != 0) && |
| ((b_InputClockSelection == APCI1710_PCI_BUS_CLOCK) || |
| (b_InputClockSelection == APCI1710_FRONT_CONNECTOR_INPUT) || |
| (b_InputClockSelection == APCI1710_10MHZ)))) { |
| /* BEGIN JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz */ |
| if (((b_InputClockSelection == APCI1710_10MHZ) && |
| ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0x0000FFFFUL) >= 0x3131)) || |
| (b_InputClockSelection != APCI1710_10MHZ)) { |
| /* END JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz */ |
| /* Test the input clock level selection */ |
| |
| if ((b_InputClockLevel == 0) || |
| (b_InputClockLevel == 1)) { |
| /* Test the output clock level selection */ |
| if ((b_OutputLevel == 0) || (b_OutputLevel == 1)) { |
| /* Test the hardware gate level selection */ |
| if ((b_HardwareGateLevel == 0) || (b_HardwareGateLevel == 1)) { |
| /* BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz */ |
| /* Test if version > 1.1 and clock selection = 10MHz */ |
| if ((b_InputClockSelection == APCI1710_10MHZ) && ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0x0000FFFFUL) > 0x3131)) { |
| /* Test if 40MHz quartz on board */ |
| dw_Test = inl(devpriv->s_BoardInfos.ui_Address + (16 + (b_TimerNbr * 4) + (64 * b_ModulNbr))); |
| |
| dw_Test = (dw_Test >> 16) & 1; |
| } else { |
| dw_Test = 1; |
| } |
| |
| /* Test if detection OK */ |
| if (dw_Test == 1) { |
| /* END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz */ |
| /* Initialisation OK */ |
| devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init = 1; |
| |
| /* Save the input clock selection */ |
| devpriv-> s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_InputClockSelection = b_InputClockSelection; |
| |
| /* Save the input clock level */ |
| devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_InputClockLevel = ~b_InputClockLevel & 1; |
| |
| /* Save the output level */ |
| devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_OutputLevel = ~b_OutputLevel & 1; |
| |
| /* Save the gate level */ |
| devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_HardwareGateLevel = b_HardwareGateLevel; |
| |
| /* Set the configuration word and disable the timer */ |
| /* BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz */ |
| /* |
| devpriv->s_ModuleInfo [b_ModulNbr]. |
| s_82X54ModuleInfo. |
| s_82X54TimerInfo [b_TimerNbr]. |
| dw_ConfigurationWord = (unsigned int) (((b_HardwareGateLevel << 0) & 0x1) | |
| ((b_InputClockLevel << 1) & 0x2) | |
| (((~b_OutputLevel & 1) << 2) & 0x4) | |
| ((b_InputClockSelection << 4) & 0x10)); |
| */ |
| /* Test if 10MHz selected */ |
| if (b_InputClockSelection == APCI1710_10MHZ) { |
| b_InputClockSelection = 2; |
| } |
| |
| devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord = (unsigned int)(((b_HardwareGateLevel << 0) & 0x1) | ((b_InputClockLevel << 1) & 0x2) | (((~b_OutputLevel & 1) << 2) & 0x4) | ((b_InputClockSelection << 4) & 0x30)); |
| /* END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz */ |
| outl(devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord, devpriv->s_BoardInfos.ui_Address + 32 + (b_TimerNbr * 4) + (64 * b_ModulNbr)); |
| |
| /* Initialise the 82X54 Timer */ |
| outl((unsigned int) b_TimerMode, devpriv->s_BoardInfos.ui_Address + 16 + (b_TimerNbr * 4) + (64 * b_ModulNbr)); |
| |
| /* Write the reload value */ |
| outl(ul_ReloadValue, devpriv->s_BoardInfos.ui_Address + 0 + (b_TimerNbr * 4) + (64 * b_ModulNbr)); |
| /* BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz */ |
| } /* if (dw_Test == 1) */ |
| else { |
| /* Input timer clock selection is wrong */ |
| i_ReturnValue = -6; |
| } /* if (dw_Test == 1) */ |
| /* END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz */ |
| } /* if ((b_HardwareGateLevel == 0) || (b_HardwareGateLevel == 1)) */ |
| else { |
| /* Selection from hardware gate level is wrong */ |
| DPRINTK("Selection from hardware gate level is wrong\n"); |
| i_ReturnValue = -9; |
| } /* if ((b_HardwareGateLevel == 0) || (b_HardwareGateLevel == 1)) */ |
| } /* if ((b_OutputLevel == 0) || (b_OutputLevel == 1)) */ |
| else { |
| /* Selection from output clock level is wrong */ |
| DPRINTK("Selection from output clock level is wrong\n"); |
| i_ReturnValue = -8; |
| } /* if ((b_OutputLevel == 0) || (b_OutputLevel == 1)) */ |
| } /* if ((b_InputClockLevel == 0) || (b_InputClockLevel == 1)) */ |
| else { |
| /* Selection from input clock level is wrong */ |
| DPRINTK("Selection from input clock level is wrong\n"); |
| i_ReturnValue = -7; |
| } /* if ((b_InputClockLevel == 0) || (b_InputClockLevel == 1)) */ |
| } else { |
| /* Input timer clock selection is wrong */ |
| DPRINTK("Input timer clock selection is wrong\n"); |
| i_ReturnValue = -6; |
| } |
| } else { |
| /* Input timer clock selection is wrong */ |
| DPRINTK("Input timer clock selection is wrong\n"); |
| i_ReturnValue = -6; |
| } |
| } /* if ((b_TimerMode >= 0) && (b_TimerMode <= 5)) */ |
| else { |
| /* Timer mode selection is wrong */ |
| DPRINTK("Timer mode selection is wrong\n"); |
| i_ReturnValue = -5; |
| } /* if ((b_TimerMode >= 0) && (b_TimerMode <= 5)) */ |
| } /* if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2)) */ |
| 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_EnableTimer | |
| | (unsigned char_ b_BoardHandle, | |
| | unsigned char_ b_ModulNbr, | |
| | unsigned char_ b_TimerNbr, | |
| | unsigned char_ b_InterruptEnable) |
| int i_APCI1710_InsnWriteEnableDisableTimer(struct comedi_device *dev,struct comedi_subdevice *s, |
| struct comedi_insn *insn,unsigned int *data) | |
| +----------------------------------------------------------------------------+ |
| | Task : Enable OR Disable the Timer (b_TimerNbr) from selected module | |
| | (b_ModulNbr). You must calling the | |
| | "i_APCI1710_InitTimer" function be for you call this | |
| | function. If you enable the timer interrupt, the timer | |
| | generate a interrupt after the timer value reach | |
| | the zero. See function "i_APCI1710_SetBoardIntRoutineX"| |
| +----------------------------------------------------------------------------+ |
| | Input Parameters : unsigned char_ b_BoardHandle : Handle of board | |
| | APCI-1710 | |
| | unsigned char_ b_ModulNbr : Selected module number | |
| | (0 to 3) | |
| | unsigned char_ b_TimerNbr : Timer number to enable | |
| | (0 to 2) | |
| | unsigned char_ b_InterruptEnable : Enable or disable the | |
| | timer interrupt. | |
| | APCI1710_ENABLE : | |
| | Enable the timer interrupt | |
| | APCI1710_DISABLE : | |
| | Disable the timer interrupt| |
| i_ReturnValue=insn->n; |
| b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec); |
| b_TimerNbr = (unsigned char) CR_CHAN(insn->chanspec); |
| b_ActionType = (unsigned char) data[0]; /* enable disable */ |
| +----------------------------------------------------------------------------+ |
| | 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" | |
| | -6: Interrupt parameter is wrong | |
| | -7: Interrupt function not initialised. | |
| | See function "i_APCI1710_SetBoardIntRoutineX" | |
| +----------------------------------------------------------------------------+ |
| */ |
| |
| int i_APCI1710_InsnWriteEnableDisableTimer(struct comedi_device *dev, |
| struct comedi_subdevice *s, |
| struct comedi_insn *insn, unsigned int *data) |
| { |
| int i_ReturnValue = 0; |
| unsigned int dw_DummyRead; |
| unsigned char b_ModulNbr; |
| unsigned char b_TimerNbr; |
| unsigned char b_ActionType; |
| unsigned char b_InterruptEnable; |
| |
| i_ReturnValue = insn->n; |
| b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec); |
| b_TimerNbr = (unsigned char) CR_CHAN(insn->chanspec); |
| b_ActionType = (unsigned char) data[0]; /* enable disable */ |
| |
| /* 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 <= 2) { |
| /* Test if timer initialised */ |
| if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init == 1) { |
| |
| switch (b_ActionType) { |
| case APCI1710_ENABLE: |
| b_InterruptEnable = (unsigned char) data[1]; |
| /* Test the interrupt selection */ |
| if ((b_InterruptEnable == APCI1710_ENABLE) || |
| (b_InterruptEnable == APCI1710_DISABLE)) { |
| if (b_InterruptEnable == APCI1710_ENABLE) { |
| |
| dw_DummyRead = inl(devpriv->s_BoardInfos.ui_Address + 12 + (b_TimerNbr * 4) + (64 * b_ModulNbr)); |
| |
| /* Enable the interrupt */ |
| devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord | 0x8; |
| |
| outl(devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord, devpriv->s_BoardInfos.ui_Address + 32 + (b_TimerNbr * 4) + (64 * b_ModulNbr)); |
| devpriv->tsk_Current = current; /* Save the current process task structure */ |
| |
| } /* if (b_InterruptEnable == APCI1710_ENABLE) */ |
| else { |
| /* Disable the interrupt */ |
| devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord & 0xF7; |
| |
| outl(devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord, devpriv->s_BoardInfos.ui_Address + 32 + (b_TimerNbr * 4) + (64 * b_ModulNbr)); |
| |
| /* Save the interrupt flag */ |
| devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask & (0xFF - (1 << b_TimerNbr)); |
| } /* if (b_InterruptEnable == APCI1710_ENABLE) */ |
| |
| /* Test if error occur */ |
| if (i_ReturnValue >= 0) { |
| /* Save the interrupt flag */ |
| devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask | ((1 & b_InterruptEnable) << b_TimerNbr); |
| |
| /* Enable the timer */ |
| outl(1, devpriv->s_BoardInfos.ui_Address + 44 + (b_TimerNbr * 4) + (64 * b_ModulNbr)); |
| } |
| } else { |
| /* Interrupt parameter is wrong */ |
| DPRINTK("\n"); |
| i_ReturnValue = -6; |
| } |
| break; |
| case APCI1710_DISABLE: |
| /* Test the interrupt flag */ |
| if (((devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask >> b_TimerNbr) & 1) == 1) { |
| /* Disable the interrupt */ |
| |
| devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr]. dw_ConfigurationWord = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord & 0xF7; |
| |
| outl(devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord, devpriv->s_BoardInfos.ui_Address + 32 + (b_TimerNbr * 4) + (64 * b_ModulNbr)); |
| |
| /* Save the interrupt flag */ |
| devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask & (0xFF - (1 << b_TimerNbr)); |
| } |
| |
| /* Disable the timer */ |
| outl(0, devpriv->s_BoardInfos.ui_Address + 44 + (b_TimerNbr * 4) + (64 * b_ModulNbr)); |
| break; |
| } /* Switch end */ |
| } 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_ReadAllTimerValue | |
| | (unsigned char_ b_BoardHandle, | |
| | unsigned char_ b_ModulNbr, | |
| | PULONG_ pul_TimerValueArray) |
| int i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev,struct comedi_subdevice *s, |
| struct comedi_insn *insn,unsigned int *data) | |
| +----------------------------------------------------------------------------+ |
| | Task : Return the all timer values from selected timer | |
| | module (b_ModulNbr). | |
| +----------------------------------------------------------------------------+ |
| | Input Parameters : unsigned char_ b_BoardHandle : Handle of board | |
| | APCI-1710 | |
| | unsigned char_ b_ModulNbr : Selected module number | |
| | (0 to 3) | |
| +----------------------------------------------------------------------------+ |
| | Output Parameters : PULONG_ pul_TimerValueArray : Timer value array. | |
| | Element 0 contain the timer 0 value. | |
| | Element 1 contain the timer 1 value. | |
| | Element 2 contain the timer 2 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 TIMER module | |
| | -4: Timer 0 not initialised see function | |
| | "i_APCI1710_InitTimer" | |
| | -5: Timer 1 not initialised see function | |
| | "i_APCI1710_InitTimer" | |
| | -6: Timer 2 not initialised see function | |
| | "i_APCI1710_InitTimer" | |
| +----------------------------------------------------------------------------+ |
| */ |
| |
| int i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev, struct comedi_subdevice *s, |
| struct comedi_insn *insn, unsigned int *data) |
| { |
| int i_ReturnValue = 0; |
| unsigned char b_ModulNbr, b_ReadType; |
| unsigned int *pul_TimerValueArray; |
| |
| b_ModulNbr = CR_AREF(insn->chanspec); |
| b_ReadType = CR_CHAN(insn->chanspec); |
| pul_TimerValueArray = (unsigned int *) data; |
| i_ReturnValue = insn->n; |
| |
| 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; |
| |
| case APCI1710_TIMER_READALLTIMER: |
| /* 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 if timer 0 iniutialised */ |
| if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[0].b_82X54Init == 1) { |
| /* Test if timer 1 iniutialised */ |
| if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[1].b_82X54Init == 1) { |
| /* Test if timer 2 iniutialised */ |
| if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[2].b_82X54Init == 1) { |
| /* Latch all counter */ |
| outl(0x17, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr)); |
| |
| /* Read the timer 0 value */ |
| pul_TimerValueArray[0] = inl(devpriv->s_BoardInfos.ui_Address + 0 + (64 * b_ModulNbr)); |
| |
| /* Read the timer 1 value */ |
| pul_TimerValueArray[1] = inl(devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr)); |
| |
| /* Read the timer 2 value */ |
| pul_TimerValueArray[2] = inl(devpriv->s_BoardInfos.ui_Address + 8 + (64 * b_ModulNbr)); |
| } else { |
| /* Timer 2 not initialised see function */ |
| DPRINTK("Timer 2 not initialised see function\n"); |
| i_ReturnValue = -6; |
| } |
| } else { |
| /* Timer 1 not initialised see function */ |
| DPRINTK("Timer 1 not initialised see function\n"); |
| i_ReturnValue = -5; |
| } |
| } else { |
| /* Timer 0 not initialised see function */ |
| DPRINTK("Timer 0 not initialised see function\n"); |
| i_ReturnValue = -4; |
| } |
| } else { |
| /* The module is not a TIMER module */ |
| DPRINTK("The module is not a TIMER module\n"); |
| i_ReturnValue = -3; |
| } |
| } else { |
| /* Module number error */ |
| DPRINTK("Module number error\n"); |
| i_ReturnValue = -2; |
| } |
| |
| } /* End of Switch */ |
| return i_ReturnValue; |
| } |
| |
| /* |
| +----------------------------------------------------------------------------+ |
| | Function Name :INT i_APCI1710_InsnBitsTimer(struct comedi_device *dev, |
| struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) | |
| +----------------------------------------------------------------------------+ |
| | Task : Read write functions for Timer | |
| +----------------------------------------------------------------------------+ |
| | Input Parameters : |
| +----------------------------------------------------------------------------+ |
| | Output Parameters : - | |
| +----------------------------------------------------------------------------+ |
| | Return Value : |
| +----------------------------------------------------------------------------+ |
| */ |
| |
| int i_APCI1710_InsnBitsTimer(struct comedi_device *dev, struct comedi_subdevice *s, |
| struct comedi_insn *insn, unsigned int *data) |
| { |
| unsigned char b_BitsType; |
| int i_ReturnValue = 0; |
| b_BitsType = data[0]; |
| |
| printk("\n82X54"); |
| |
| switch (b_BitsType) { |
| case APCI1710_TIMER_READVALUE: |
| i_ReturnValue = i_APCI1710_ReadTimerValue(dev, |
| (unsigned char)CR_AREF(insn->chanspec), |
| (unsigned char)CR_CHAN(insn->chanspec), |
| (unsigned int *) &data[0]); |
| break; |
| |
| case APCI1710_TIMER_GETOUTPUTLEVEL: |
| i_ReturnValue = i_APCI1710_GetTimerOutputLevel(dev, |
| (unsigned char)CR_AREF(insn->chanspec), |
| (unsigned char)CR_CHAN(insn->chanspec), |
| (unsigned char *) &data[0]); |
| break; |
| |
| case APCI1710_TIMER_GETPROGRESSSTATUS: |
| i_ReturnValue = i_APCI1710_GetTimerProgressStatus(dev, |
| (unsigned char)CR_AREF(insn->chanspec), |
| (unsigned char)CR_CHAN(insn->chanspec), |
| (unsigned char *)&data[0]); |
| break; |
| |
| case APCI1710_TIMER_WRITEVALUE: |
| i_ReturnValue = i_APCI1710_WriteTimerValue(dev, |
| (unsigned char)CR_AREF(insn->chanspec), |
| (unsigned char)CR_CHAN(insn->chanspec), |
| (unsigned int)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 | |
| | (unsigned char_ b_BoardHandle, | |
| | unsigned char_ b_ModulNbr, | |
| | unsigned char_ b_TimerNbr, | |
| | PULONG_ pul_TimerValue) | |
| +----------------------------------------------------------------------------+ |
| | Task : Return the timer value from selected digital timer | |
| | (b_TimerNbr) from selected timer module (b_ModulNbr). | |
| +----------------------------------------------------------------------------+ |
| | Input Parameters : unsigned char_ b_BoardHandle : Handle of board | |
| | APCI-1710 | |
| | unsigned char_ b_ModulNbr : Selected module number | |
| | (0 to 3) | |
| | unsigned char_ 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(struct comedi_device *dev, |
| unsigned char b_ModulNbr, unsigned char b_TimerNbr, |
| unsigned int *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 <= 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 | |
| | (unsigned char_ b_BoardHandle, | |
| | unsigned char_ b_ModulNbr, | |
| | unsigned char_ b_TimerNbr, | |
| | unsigned char *_ pb_OutputLevel) | |
| +----------------------------------------------------------------------------+ |
| | Task : Return the output signal level (pb_OutputLevel) from | |
| | selected digital timer (b_TimerNbr) from selected timer| |
| | module (b_ModulNbr). | |
| +----------------------------------------------------------------------------+ |
| | Input Parameters : unsigned char_ b_BoardHandle : Handle of board | |
| | APCI-1710 | |
| | unsigned char_ b_ModulNbr : Selected module number | |
| | (0 to 3) | |
| | unsigned char_ b_TimerNbr : Timer number to test | |
| | (0 to 2) | |
| +----------------------------------------------------------------------------+ |
| | Output Parameters : unsigned char *_ 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(struct comedi_device *dev, |
| unsigned char b_ModulNbr, unsigned char b_TimerNbr, |
| unsigned char *pb_OutputLevel) |
| { |
| int i_ReturnValue = 0; |
| unsigned int 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 <= 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 = (unsigned char) (((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 | |
| | (unsigned char_ b_BoardHandle, | |
| | unsigned char_ b_ModulNbr, | |
| | unsigned char_ b_TimerNbr, | |
| | unsigned char *_ pb_TimerStatus) | |
| +----------------------------------------------------------------------------+ |
| | Task : Return the progress status (pb_TimerStatus) from | |
| | selected digital timer (b_TimerNbr) from selected timer| |
| | module (b_ModulNbr). | |
| +----------------------------------------------------------------------------+ |
| | Input Parameters : unsigned char_ b_BoardHandle : Handle of board | |
| | APCI-1710 | |
| | unsigned char_ b_ModulNbr : Selected module number | |
| | (0 to 3) | |
| | unsigned char_ b_TimerNbr : Timer number to test | |
| | (0 to 2) | |
| +----------------------------------------------------------------------------+ |
| | Output Parameters : unsigned char *_ 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(struct comedi_device *dev, |
| unsigned char b_ModulNbr, unsigned char b_TimerNbr, |
| unsigned char *pb_TimerStatus) |
| { |
| int i_ReturnValue = 0; |
| unsigned int 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 <= 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 = (unsigned char) ((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 | |
| | (unsigned char_ b_BoardHandle, | |
| | unsigned char_ b_ModulNbr, | |
| | unsigned char_ 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 : unsigned char_ b_BoardHandle : Handle of board | |
| | APCI-1710 | |
| | unsigned char_ b_ModulNbr : Selected module number | |
| | (0 to 3) | |
| | unsigned char_ 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(struct comedi_device *dev, |
| unsigned char b_ModulNbr, unsigned char b_TimerNbr, |
| unsigned int 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 <= 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; |
| } |