Commit 3b4cb671 authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman

staging: comedi: addi_apci_1710: delete driver

This driver is seriously broken and most of it does not "work" with
the comedi API. Just remove it.
Signed-off-by: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: default avatarIan Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c1f00be0
/*
* 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 |
*/
#define APCI1710_PCI_BUS_CLOCK 0
#define APCI1710_FRONT_CONNECTOR_INPUT 1
#define APCI1710_TIMER_READVALUE 0
#define APCI1710_TIMER_GETOUTPUTLEVEL 1
#define APCI1710_TIMER_GETPROGRESSSTATUS 2
#define APCI1710_TIMER_WRITEVALUE 3
#define APCI1710_TIMER_READINTERRUPT 1
#define APCI1710_TIMER_READALLTIMER 2
#ifndef APCI1710_10MHZ
#define APCI1710_10MHZ 10
#endif
/*
+----------------------------------------------------------------------------+
| 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 |
+----------------------------------------------------------------------------+
*/
static int i_APCI1710_InsnConfigInitTimer(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct addi_private *devpriv = dev->private;
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" |
+----------------------------------------------------------------------------+
*/
static int i_APCI1710_InsnWriteEnableDisableTimer(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct addi_private *devpriv = dev->private;
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" |
+----------------------------------------------------------------------------+
*/
static int i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct addi_private *devpriv = dev->private;
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_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" |
+----------------------------------------------------------------------------+
*/
static int i_APCI1710_ReadTimerValue(struct comedi_device *dev,
unsigned char b_ModulNbr,
unsigned char b_TimerNbr,
unsigned int *pul_TimerValue)
{
struct addi_private *devpriv = dev->private;
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" |
+----------------------------------------------------------------------------+
*/
static int i_APCI1710_GetTimerOutputLevel(struct comedi_device *dev,
unsigned char b_ModulNbr,
unsigned char b_TimerNbr,
unsigned char *pb_OutputLevel)
{
struct addi_private *devpriv = dev->private;
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" |
+----------------------------------------------------------------------------+
*/
static int i_APCI1710_GetTimerProgressStatus(struct comedi_device *dev,
unsigned char b_ModulNbr,
unsigned char b_TimerNbr,
unsigned char *pb_TimerStatus)
{
struct addi_private *devpriv = dev->private;
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" |
+----------------------------------------------------------------------------+
*/
static int i_APCI1710_WriteTimerValue(struct comedi_device *dev,
unsigned char b_ModulNbr,
unsigned char b_TimerNbr,
unsigned int ul_WriteValue)
{
struct addi_private *devpriv = dev->private;
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;
}
/*
+----------------------------------------------------------------------------+
| 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 :
+----------------------------------------------------------------------------+
*/
static 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;
}
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data.com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
@endverbatim
*/
/*
+-----------------------------------------------------------------------+
| (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+-----------------------------------------------------------------------+
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+-----------------------------------------------------------------------+
| Project : API APCI1710 | Compiler : gcc |
| Module name : CHRONO.C | Version : 2.96 |
+-------------------------------+---------------------------------------+
| Project manager: Eric Stolz | Date : 02/12/2002 |
+-----------------------------------------------------------------------+
| Description : APCI-1710 chronometer module |
| |
| |
+-----------------------------------------------------------------------+
| UPDATES |
+-----------------------------------------------------------------------+
| Date | Author | Description of updates |
+----------+-----------+------------------------------------------------+
| 29/06/98 | S. Weber | Digital input / output implementation |
|----------|-----------|------------------------------------------------|
| 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
| | | available |
+-----------------------------------------------------------------------+
| | | |
| | | |
+-----------------------------------------------------------------------+
*/
#define APCI1710_30MHZ 30
#define APCI1710_33MHZ 33
#define APCI1710_40MHZ 40
#define APCI1710_SINGLE 0
#define APCI1710_CONTINUOUS 1
#define APCI1710_CHRONO_PROGRESS_STATUS 0
#define APCI1710_CHRONO_READVALUE 1
#define APCI1710_CHRONO_CONVERTVALUE 2
#define APCI1710_CHRONO_READINTERRUPT 3
#define APCI1710_CHRONO_SET_CHANNELON 0
#define APCI1710_CHRONO_SET_CHANNELOFF 1
#define APCI1710_CHRONO_READ_CHANNEL 2
#define APCI1710_CHRONO_READ_PORT 3
/*
+----------------------------------------------------------------------------+
| Function Name : _INT_ i_APCI1710_InitChrono |
| (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
| unsigned char_ b_ChronoMode, |
| unsigned char_ b_PCIInputClock, |
| unsigned char_ b_TimingUnit, |
| ULONG_ ul_TimingInterval, |
| PULONG_ pul_RealTimingInterval)
+----------------------------------------------------------------------------+
| Task : Configure the chronometer operating mode (b_ChronoMode)|
| from selected module (b_ModulNbr). |
| The ul_TimingInterval and ul_TimingUnit determine the |
| timing base for the measurement. |
| The pul_RealTimingInterval return the real timing |
| value. You must calling this function be for you call |
| any other function witch access of the chronometer. |
| |
| Witch this functionality from the APCI-1710 you have |
| the possibility to measure the timing witch two event. |
| |
| The mode 0 and 1 is appropriate for period measurement.|
| The mode 2 and 3 is appropriate for frequent |
| measurement. |
| The mode 4 to 7 is appropriate for measuring the timing|
| between two event. |
+----------------------------------------------------------------------------+
| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
| unsigned char_ b_ModulNbr CR_AREF(insn->chanspec) : Module number to configure |
| (0 to 3) |
| unsigned char_ b_ChronoMode data[0] : Chronometer action mode |
| (0 to 7). |
| unsigned char_ b_PCIInputClock data[1] : Selection from PCI bus clock|
| - APCI1710_30MHZ : |
| The PC have a PCI bus |
| clock from 30 MHz |
| - APCI1710_33MHZ : |
| The PC have a PCI bus |
| clock from 33 MHz |
| - APCI1710_40MHZ |
| The APCI-1710 have a |
| integrated 40Mhz |
| quartz. |
| unsigned char_ b_TimingUnit data[2] : Base timing unity (0 to 4) |
| 0 : ns |
| 1 : µs |
| 2 : ms |
| 3 : s |
| 4 : mn |
| ULONG_ ul_TimingInterval : data[3] Base timing value. |
+----------------------------------------------------------------------------+
| Output Parameters : PULONG_ pul_RealTimingInterval : Real base timing |
| value.
| data[0]
+----------------------------------------------------------------------------+
| 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 mode selection is wrong |
| -5: The selected PCI input clock is wrong |
| -6: Timing unity selection is wrong |
| -7: Base timing selection is wrong |
| -8: You can not used the 40MHz clock selection with |
| this board |
| -9: You can not used the 40MHz clock selection with |
| this CHRONOS version |
+----------------------------------------------------------------------------+
*/
static int i_APCI1710_InsnConfigInitChrono(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int ul_TimerValue = 0;
unsigned int ul_TimingInterval = 0;
unsigned int ul_RealTimingInterval = 0;
double d_RealTimingInterval = 0;
unsigned int dw_ModeArray[8] =
{ 0x01, 0x05, 0x00, 0x04, 0x02, 0x0E, 0x0A, 0x06 };
unsigned char b_ModulNbr, b_ChronoMode, b_PCIInputClock, b_TimingUnit;
b_ModulNbr = CR_AREF(insn->chanspec);
b_ChronoMode = (unsigned char) data[0];
b_PCIInputClock = (unsigned char) data[1];
b_TimingUnit = (unsigned char) data[2];
ul_TimingInterval = (unsigned int) data[3];
i_ReturnValue = insn->n;
/**************************/
/* Test the module number */
/**************************/
if (b_ModulNbr < 4) {
/***********************/
/* Test if chronometer */
/***********************/
if ((devpriv->s_BoardInfos.
dw_MolduleConfiguration[b_ModulNbr] &
0xFFFF0000UL) == APCI1710_CHRONOMETER) {
/*****************************/
/* Test the chronometer mode */
/*****************************/
if (b_ChronoMode <= 7) {
/**************************/
/* Test the PCI bus clock */
/**************************/
if ((b_PCIInputClock == APCI1710_30MHZ) ||
(b_PCIInputClock == APCI1710_33MHZ) ||
(b_PCIInputClock == APCI1710_40MHZ)) {
/*************************/
/* Test the timing unity */
/*************************/
if (b_TimingUnit <= 4) {
/**********************************/
/* Test the base timing selection */
/**********************************/
if (((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 66) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 143165576UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 143165UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 143UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 2UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 60) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 130150240UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 130150UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 130UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 2UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 50) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 107374182UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 107374UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 107UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 1UL))) {
/**************************/
/* Test the board version */
/**************************/
if (((b_PCIInputClock == APCI1710_40MHZ) && (devpriv->s_BoardInfos.b_BoardVersion > 0)) || (b_PCIInputClock != APCI1710_40MHZ)) {
/************************/
/* Test the TOR version */
/************************/
if (((b_PCIInputClock == APCI1710_40MHZ) && ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) >= 0x3131)) || (b_PCIInputClock != APCI1710_40MHZ)) {
fpu_begin
();
/****************************************/
/* Calculate the timer 0 division fator */
/****************************************/
switch (b_TimingUnit) {
/******/
/* ns */
/******/
case 0:
/******************/
/* Timer 0 factor */
/******************/
ul_TimerValue
=
(unsigned int)
(ul_TimingInterval
*
(0.001 * b_PCIInputClock));
/*******************/
/* Round the value */
/*******************/
if ((double)((double)ul_TimingInterval * (0.001 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
ul_TimerValue
=
ul_TimerValue
+
1;
}
/*****************************/
/* Calculate the real timing */
/*****************************/
ul_RealTimingInterval
=
(unsigned int)
(ul_TimerValue
/
(0.001 * (double)b_PCIInputClock));
d_RealTimingInterval
=
(double)
ul_TimerValue
/
(0.001
*
(double)
b_PCIInputClock);
if ((double)((double)ul_TimerValue / (0.001 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
ul_RealTimingInterval
=
ul_RealTimingInterval
+
1;
}
ul_TimingInterval
=
ul_TimingInterval
-
1;
ul_TimerValue
=
ul_TimerValue
-
2;
if (b_PCIInputClock != APCI1710_40MHZ) {
ul_TimerValue
=
(unsigned int)
(
(double)
(ul_TimerValue)
*
0.99392);
}
break;
/******/
/* æs */
/******/
case 1:
/******************/
/* Timer 0 factor */
/******************/
ul_TimerValue
=
(unsigned int)
(ul_TimingInterval
*
(1.0 * b_PCIInputClock));
/*******************/
/* Round the value */
/*******************/
if ((double)((double)ul_TimingInterval * (1.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
ul_TimerValue
=
ul_TimerValue
+
1;
}
/*****************************/
/* Calculate the real timing */
/*****************************/
ul_RealTimingInterval
=
(unsigned int)
(ul_TimerValue
/
(1.0 * (double)b_PCIInputClock));
d_RealTimingInterval
=
(double)
ul_TimerValue
/
(
(double)
1.0
*
(double)
b_PCIInputClock);
if ((double)((double)ul_TimerValue / (1.0 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
ul_RealTimingInterval
=
ul_RealTimingInterval
+
1;
}
ul_TimingInterval
=
ul_TimingInterval
-
1;
ul_TimerValue
=
ul_TimerValue
-
2;
if (b_PCIInputClock != APCI1710_40MHZ) {
ul_TimerValue
=
(unsigned int)
(
(double)
(ul_TimerValue)
*
0.99392);
}
break;
/******/
/* ms */
/******/
case 2:
/******************/
/* Timer 0 factor */
/******************/
ul_TimerValue
=
ul_TimingInterval
*
(1000
*
b_PCIInputClock);
/*******************/
/* Round the value */
/*******************/
if ((double)((double)ul_TimingInterval * (1000.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
ul_TimerValue
=
ul_TimerValue
+
1;
}
/*****************************/
/* Calculate the real timing */
/*****************************/
ul_RealTimingInterval
=
(unsigned int)
(ul_TimerValue
/
(1000.0 * (double)b_PCIInputClock));
d_RealTimingInterval
=
(double)
ul_TimerValue
/
(1000.0
*
(double)
b_PCIInputClock);
if ((double)((double)ul_TimerValue / (1000.0 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
ul_RealTimingInterval
=
ul_RealTimingInterval
+
1;
}
ul_TimingInterval
=
ul_TimingInterval
-
1;
ul_TimerValue
=
ul_TimerValue
-
2;
if (b_PCIInputClock != APCI1710_40MHZ) {
ul_TimerValue
=
(unsigned int)
(
(double)
(ul_TimerValue)
*
0.99392);
}
break;
/*****/
/* s */
/*****/
case 3:
/******************/
/* Timer 0 factor */
/******************/
ul_TimerValue
=
(unsigned int)
(ul_TimingInterval
*
(1000000.0
*
b_PCIInputClock));
/*******************/
/* Round the value */
/*******************/
if ((double)((double)ul_TimingInterval * (1000000.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
ul_TimerValue
=
ul_TimerValue
+
1;
}
/*****************************/
/* Calculate the real timing */
/*****************************/
ul_RealTimingInterval
=
(unsigned int)
(ul_TimerValue
/
(1000000.0
*
(double)
b_PCIInputClock));
d_RealTimingInterval
=
(double)
ul_TimerValue
/
(1000000.0
*
(double)
b_PCIInputClock);
if ((double)((double)ul_TimerValue / (1000000.0 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
ul_RealTimingInterval
=
ul_RealTimingInterval
+
1;
}
ul_TimingInterval
=
ul_TimingInterval
-
1;
ul_TimerValue
=
ul_TimerValue
-
2;
if (b_PCIInputClock != APCI1710_40MHZ) {
ul_TimerValue
=
(unsigned int)
(
(double)
(ul_TimerValue)
*
0.99392);
}
break;
/******/
/* mn */
/******/
case 4:
/******************/
/* Timer 0 factor */
/******************/
ul_TimerValue
=
(unsigned int)
(
(ul_TimingInterval
*
60)
*
(1000000.0
*
b_PCIInputClock));
/*******************/
/* Round the value */
/*******************/
if ((double)((double)(ul_TimingInterval * 60.0) * (1000000.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
ul_TimerValue
=
ul_TimerValue
+
1;
}
/*****************************/
/* Calculate the real timing */
/*****************************/
ul_RealTimingInterval
=
(unsigned int)
(ul_TimerValue
/
(1000000.0
*
(double)
b_PCIInputClock))
/
60;
d_RealTimingInterval
=
(
(double)
ul_TimerValue
/
(0.001 * (double)b_PCIInputClock)) / 60.0;
if ((double)(((double)ul_TimerValue / (1000000.0 * (double)b_PCIInputClock)) / 60.0) >= (double)((double)ul_RealTimingInterval + 0.5)) {
ul_RealTimingInterval
=
ul_RealTimingInterval
+
1;
}
ul_TimingInterval
=
ul_TimingInterval
-
1;
ul_TimerValue
=
ul_TimerValue
-
2;
if (b_PCIInputClock != APCI1710_40MHZ) {
ul_TimerValue
=
(unsigned int)
(
(double)
(ul_TimerValue)
*
0.99392);
}
break;
}
fpu_end();
/****************************/
/* Save the PCI input clock */
/****************************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_ChronoModuleInfo.
b_PCIInputClock
=
b_PCIInputClock;
/*************************/
/* Save the timing unity */
/*************************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_ChronoModuleInfo.
b_TimingUnit
=
b_TimingUnit;
/************************/
/* Save the base timing */
/************************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_ChronoModuleInfo.
d_TimingInterval
=
d_RealTimingInterval;
/****************************/
/* Set the chronometer mode */
/****************************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_ChronoModuleInfo.
dw_ConfigReg
=
dw_ModeArray
[b_ChronoMode];
/***********************/
/* Test if 40 MHz used */
/***********************/
if (b_PCIInputClock == APCI1710_40MHZ) {
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_ChronoModuleInfo.
dw_ConfigReg
=
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_ChronoModuleInfo.
dw_ConfigReg
|
0x80;
}
outl(devpriv->s_ModuleInfo[b_ModulNbr].s_ChronoModuleInfo.dw_ConfigReg, devpriv->s_BoardInfos.ui_Address + 16 + (64 * b_ModulNbr));
/***********************/
/* Write timer 0 value */
/***********************/
outl(ul_TimerValue, devpriv->s_BoardInfos.ui_Address + (64 * b_ModulNbr));
/*********************/
/* Chronometer init. */
/*********************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_ChronoModuleInfo.
b_ChronoInit
=
1;
} else {
/***********************************************/
/* TOR version error for 40MHz clock selection */
/***********************************************/
DPRINTK("TOR version error for 40MHz clock selection\n");
i_ReturnValue
=
-9;
}
} else {
/**************************************************************/
/* You can not use the 40MHz clock selection with this board */
/**************************************************************/
DPRINTK("You can not used the 40MHz clock selection with this board\n");
i_ReturnValue =
-8;
}
} else {
/**********************************/
/* Base timing selection is wrong */
/**********************************/
DPRINTK("Base timing selection is wrong\n");
i_ReturnValue = -7;
}
} /* if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4)) */
else {
/***********************************/
/* Timing unity selection is wrong */
/***********************************/
DPRINTK("Timing unity selection is wrong\n");
i_ReturnValue = -6;
} /* if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4)) */
} /* if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ)) */
else {
/*****************************************/
/* The selected PCI input clock is wrong */
/*****************************************/
DPRINTK("The selected PCI input clock is wrong\n");
i_ReturnValue = -5;
} /* if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ)) */
} /* if (b_ChronoMode >= 0 && b_ChronoMode <= 7) */
else {
/***************************************/
/* Chronometer mode selection is wrong */
/***************************************/
DPRINTK("Chronometer mode selection is wrong\n");
i_ReturnValue = -4;
} /* if (b_ChronoMode >= 0 && b_ChronoMode <= 7) */
} 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;
}
data[0] = ul_RealTimingInterval;
return i_ReturnValue;
}
/*
+----------------------------------------------------------------------------+
| Function Name : _INT_ i_APCI1710_EnableChrono |
| (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
| unsigned char_ b_CycleMode, |
| unsigned char_ b_InterruptEnable)
int i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device *dev,
struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
+----------------------------------------------------------------------------+
| Task : Enable the chronometer from selected module |
| (b_ModulNbr). You must calling the |
| "i_APCI1710_InitChrono" function be for you call this |
| function. |
| If you enable the chronometer interrupt, the |
| chronometer generate a interrupt after the stop signal.|
| See function "i_APCI1710_SetBoardIntRoutineX" and the |
| Interrupt mask description chapter from this manual. |
| The b_CycleMode parameter determine if you will |
| measured a single or more cycle.
| Disable the chronometer from selected module |
| (b_ModulNbr). If you disable the chronometer after a |
| start signal occur and you restart the chronometer |
| witch the " i_APCI1710_EnableChrono" function, if no |
| stop signal occur this start signal is ignored.
+----------------------------------------------------------------------------+
| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
| unsigned char_ b_ModulNbr CR_AREF(chanspec) : Selected module number (0 to 3) |
data[0] ENABle/Disable chrono
| unsigned char_ b_CycleMode : Selected the chronometer |
| data[1] acquisition mode |
| unsigned char_ b_InterruptEnable : Enable or disable the |
| data[2] chronometer interrupt. |
| APCI1710_ENABLE: |
| Enable the chronometer |
| interrupt |
| APCI1710_DISABLE: |
| Disable the chronometer |
| 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 Chronometer module |
| -4: Chronometer not initialised see function |
| "i_APCI1710_InitChrono" |
| -5: Chronometer acquisition mode cycle is wrong |
| -6: Interrupt parameter is wrong |
| -7: Interrupt function not initialised. |
| See function "i_APCI1710_SetBoardIntRoutineX"
-8: data[0] wrong input |
+----------------------------------------------------------------------------+
*/
static int i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned char b_ModulNbr, b_CycleMode, b_InterruptEnable, b_Action;
b_ModulNbr = CR_AREF(insn->chanspec);
b_Action = (unsigned char) data[0];
b_CycleMode = (unsigned char) data[1];
b_InterruptEnable = (unsigned char) data[2];
i_ReturnValue = insn->n;
/**************************/
/* 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) {
switch (b_Action) {
case APCI1710_ENABLE:
/*********************************/
/* Test the cycle mode parameter */
/*********************************/
if ((b_CycleMode == APCI1710_SINGLE)
|| (b_CycleMode ==
APCI1710_CONTINUOUS)) {
/***************************/
/* Test the interrupt flag */
/***************************/
if ((b_InterruptEnable ==
APCI1710_ENABLE)
|| (b_InterruptEnable ==
APCI1710_DISABLE))
{
/***************************/
/* Save the interrupt flag */
/***************************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_ChronoModuleInfo.
b_InterruptMask
=
b_InterruptEnable;
/***********************/
/* Save the cycle mode */
/***********************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_ChronoModuleInfo.
b_CycleMode =
b_CycleMode;
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_ChronoModuleInfo.
dw_ConfigReg =
(devpriv->
s_ModuleInfo
[b_ModulNbr].
s_ChronoModuleInfo.
dw_ConfigReg &
0x8F) | ((1 &
b_InterruptEnable)
<< 5) | ((1 &
b_CycleMode)
<< 6) | 0x10;
/*****************************/
/* Test if interrupt enabled */
/*****************************/
if (b_InterruptEnable ==
APCI1710_ENABLE)
{
/****************************/
/* Clear the interrupt flag */
/****************************/
outl(devpriv->
s_ModuleInfo
[b_ModulNbr].
s_ChronoModuleInfo.
dw_ConfigReg,
devpriv->
s_BoardInfos.
ui_Address
+ 32 +
(64 * b_ModulNbr));
devpriv->tsk_Current = current; /* Save the current process task structure */
}
/***********************************/
/* Enable or disable the interrupt */
/* Enable the chronometer */
/***********************************/
outl(devpriv->
s_ModuleInfo
[b_ModulNbr].
s_ChronoModuleInfo.
dw_ConfigReg,
devpriv->
s_BoardInfos.
ui_Address +
16 +
(64 * b_ModulNbr));
/*************************/
/* Clear status register */
/*************************/
outl(0, devpriv->
s_BoardInfos.
ui_Address +
36 +
(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 = -6;
} /* if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE)) */
} /* if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS)) */
else {
/***********************************************/
/* Chronometer acquisition mode cycle is wrong */
/***********************************************/
DPRINTK("Chronometer acquisition mode cycle is wrong\n");
i_ReturnValue = -5;
} /* if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS)) */
break;
case APCI1710_DISABLE:
devpriv->s_ModuleInfo[b_ModulNbr].
s_ChronoModuleInfo.
b_InterruptMask = 0;
devpriv->s_ModuleInfo[b_ModulNbr].
s_ChronoModuleInfo.
dw_ConfigReg =
devpriv->
s_ModuleInfo[b_ModulNbr].
s_ChronoModuleInfo.
dw_ConfigReg & 0x2F;
/***************************/
/* Disable the interrupt */
/* Disable the chronometer */
/***************************/
outl(devpriv->s_ModuleInfo[b_ModulNbr].
s_ChronoModuleInfo.dw_ConfigReg,
devpriv->s_BoardInfos.
ui_Address + 16 +
(64 * b_ModulNbr));
/***************************/
/* 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;
default:
DPRINTK("Inputs wrong! Enable or Disable chrono\n");
i_ReturnValue = -8;
} /* switch ENABLE/DISABLE */
} 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_GetChronoProgressStatus |
| (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
| unsigned char *_ pb_ChronoStatus) |
+----------------------------------------------------------------------------+
| Task : Return the chronometer status (pb_ChronoStatus) from |
| selected chronometer 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_ 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" |
+----------------------------------------------------------------------------+
*/
static int i_APCI1710_GetChronoProgressStatus(struct comedi_device *dev,
unsigned char b_ModulNbr,
unsigned char *pb_ChronoStatus)
{
struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int 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 |
| (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
| unsigned int_ ui_TimeOut, |
| unsigned char *_ 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 : unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
| unsigned char_ 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" |
| unsigned int * 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. |
+----------------------------------------------------------------------------+
*/
static int i_APCI1710_ReadChronoValue(struct comedi_device *dev,
unsigned char b_ModulNbr,
unsigned int ui_TimeOut,
unsigned char *pb_ChronoStatus,
unsigned int *pul_ChronoValue)
{
struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_Status;
unsigned int 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 <= 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 |
| (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
| ULONG_ ul_ChronoValue, |
| PULONG_ pul_Hour, |
| unsigned char *_ pb_Minute, |
| unsigned char *_ pb_Second, |
| unsigned int *_ pui_MilliSecond, |
| unsigned int *_ pui_MicroSecond, |
| unsigned int *_ pui_NanoSecond) |
+----------------------------------------------------------------------------+
| Task : Convert the chronometer measured timing |
| (ul_ChronoValue) in to h, mn, s, ms, µs, ns. |
+----------------------------------------------------------------------------+
| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
| unsigned char_ 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 |
| unsigned char *_ pb_Minute : Chronometer timing minute |
| unsigned char *_ pb_Second : Chronometer timing second |
| unsigned int *_ pui_MilliSecond : Chronometer timing mini |
| second |
| unsigned int *_ pui_MicroSecond : Chronometer timing micro |
| second |
| unsigned int *_ 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" |
+----------------------------------------------------------------------------+
*/
static int i_APCI1710_ConvertChronoValue(struct comedi_device *dev,
unsigned char b_ModulNbr,
unsigned int ul_ChronoValue,
unsigned int *pul_Hour,
unsigned char *pb_Minute,
unsigned char *pb_Second,
unsigned int *pui_MilliSecond,
unsigned int *pui_MicroSecond,
unsigned int *pui_NanoSecond)
{
struct addi_private *devpriv = dev->private;
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) {
fpu_begin();
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 = (unsigned int) d_Hour;
/************************/
/* Calculate the minute */
/************************/
d_Minute = d_Hour - *pul_Hour;
d_Minute = d_Minute * 60;
*pb_Minute = (unsigned char) d_Minute;
/************************/
/* Calculate the second */
/************************/
d_Second = d_Minute - *pb_Minute;
d_Second = d_Second * 60;
*pb_Second = (unsigned char) d_Second;
/*****************************/
/* Calculate the mini second */
/*****************************/
d_MilliSecond = d_Second - *pb_Second;
d_MilliSecond = d_MilliSecond * 1000;
*pui_MilliSecond = (unsigned int) d_MilliSecond;
/******************************/
/* Calculate the micro second */
/******************************/
d_MicroSecond =
d_MilliSecond -
*pui_MilliSecond;
d_MicroSecond = d_MicroSecond * 1000;
*pui_MicroSecond = (unsigned int) d_MicroSecond;
/******************************/
/* Calculate the micro second */
/******************************/
d_NanoSecond =
d_MicroSecond -
*pui_MicroSecond;
d_NanoSecond = d_NanoSecond * 1000;
*pui_NanoSecond = (unsigned int) d_NanoSecond;
break;
}
fpu_end();
} 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_InsnReadChrono(struct comedi_device *dev,struct comedi_subdevice *s,
struct comedi_insn *insn,unsigned int *data) |
+----------------------------------------------------------------------------+
| Task : Read functions for Timer |
+----------------------------------------------------------------------------+
| Input Parameters :
+----------------------------------------------------------------------------+
| Output Parameters : - |
+----------------------------------------------------------------------------+
| Return Value :
+----------------------------------------------------------------------------+
*/
static int i_APCI1710_InsnReadChrono(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct addi_private *devpriv = dev->private;
unsigned char 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,
(unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]);
break;
case APCI1710_CHRONO_READVALUE:
i_ReturnValue = i_APCI1710_ReadChronoValue(dev,
(unsigned char) CR_AREF(insn->chanspec),
(unsigned int) insn->unused[0],
(unsigned char *) &data[0], (unsigned int *) &data[1]);
break;
case APCI1710_CHRONO_CONVERTVALUE:
i_ReturnValue = i_APCI1710_ConvertChronoValue(dev,
(unsigned char) CR_AREF(insn->chanspec),
(unsigned int) insn->unused[0],
(unsigned int *) &data[0],
(unsigned char *) &data[1],
(unsigned char *) &data[2],
(unsigned int *) &data[3],
(unsigned int *) &data[4], (unsigned int *) &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_InsnBitsChronoDigitalIO(struct comedi_device *dev,struct comedi_subdevice *s,
struct comedi_insn *insn,unsigned int *data) |
+----------------------------------------------------------------------------+
| Task : Sets the output witch has been passed with the |
| parameter b_Channel. Setting an output means setting an|
| output high. |
+----------------------------------------------------------------------------+
| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
| unsigned char_ b_ModulNbr : Selected module number (0 to 3)|
| unsigned char_ b_OutputChannel : Selection from digital output |
| CR_CHAN() channel (0 to 2) |
| 0 : Channel H |
| 1 : Channel A |
| 2 : Channel B |
+----------------------------------------------------------------------------+
| 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 Chronometer module |
| -4: The selected digital output is wrong |
| -5: Chronometer not initialised see function |
| "i_APCI1710_InitChrono" |
+----------------------------------------------------------------------------+
*/
/*
+----------------------------------------------------------------------------+
| Function Name : _INT_ i_APCI1710_SetChronoChlOff |
| (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
| unsigned char_ b_OutputChannel) |
+----------------------------------------------------------------------------+
| Task : Resets the output witch has been passed with the |
| parameter b_Channel. Resetting an output means setting |
| an output low. |
+----------------------------------------------------------------------------+
| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710
data[0] : Chl ON, Chl OFF , Chl Read , Port Read
| unsigned char_ b_ModulNbr CR_AREF : Selected module number (0 to 3)|
| unsigned char_ b_OutputChannel CR_CHAN : Selection from digital output |
| channel (0 to 2) |
| 0 : Channel H |
| 1 : Channel A |
| 2 : Channel B |
+----------------------------------------------------------------------------+
| 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 Chronometer module |
| -4: The selected digital output is wrong |
| -5: Chronometer not initialised see function |
| "i_APCI1710_InitChrono" |
+----------------------------------------------------------------------------+
*/
/*
+----------------------------------------------------------------------------+
| Function Name : _INT_ i_APCI1710_ReadChronoChlValue |
| (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
| unsigned char_ b_InputChannel, |
| unsigned char *_ pb_ChannelStatus) |
+----------------------------------------------------------------------------+
| Task : Return the status from selected digital input |
| (b_InputChannel) from selected chronometer |
| 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_InputChannel : Selection from digital input |
| channel (0 to 2) |
| CR_CHAN() 0 : Channel E |
| 1 : Channel F |
| 2 : Channel G |
+----------------------------------------------------------------------------+
| Output Parameters : unsigned char *_ pb_ChannelStatus : Digital input channel status.|
| data[0] 0 : Channel is not active |
| 1 : Channel is active |
+----------------------------------------------------------------------------+
| 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: The selected digital input is wrong |
| -5: Chronometer not initialised see function |
| "i_APCI1710_InitChrono" |
+----------------------------------------------------------------------------+
*/
/*
+----------------------------------------------------------------------------+
| Function Name : _INT_ i_APCI1710_ReadChronoPortValue |
| (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
| unsigned char *_ pb_PortValue) |
+----------------------------------------------------------------------------+
| Task : Return the status from digital inputs port from |
| selected (b_ModulNbr) chronometer module. |
+----------------------------------------------------------------------------+
| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
| unsigned char_ b_ModulNbr : Selected module number (0 to 3)|
+----------------------------------------------------------------------------+
| Output Parameters : unsigned char *_ pb_PortValue : Digital inputs port status.
| data[0]
+----------------------------------------------------------------------------+
| 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" |
+----------------------------------------------------------------------------+
*/
static int i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned char b_ModulNbr, b_OutputChannel, b_InputChannel, b_IOType;
unsigned int dw_Status;
unsigned char *pb_ChannelStatus;
unsigned char *pb_PortValue;
b_ModulNbr = CR_AREF(insn->chanspec);
i_ReturnValue = insn->n;
b_IOType = (unsigned char) data[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 digital output channel */
/***********************************/
switch (b_IOType) {
case APCI1710_CHRONO_SET_CHANNELOFF:
b_OutputChannel =
(unsigned char) CR_CHAN(insn->chanspec);
if (b_OutputChannel <= 2) {
outl(0, devpriv->s_BoardInfos.
ui_Address + 20 +
(b_OutputChannel * 4) +
(64 * b_ModulNbr));
} /* if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2)) */
else {
/****************************************/
/* The selected digital output is wrong */
/****************************************/
DPRINTK("The selected digital output is wrong\n");
i_ReturnValue = -4;
} /* if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2)) */
break;
case APCI1710_CHRONO_SET_CHANNELON:
b_OutputChannel =
(unsigned char) CR_CHAN(insn->chanspec);
if (b_OutputChannel <= 2) {
outl(1, devpriv->s_BoardInfos.
ui_Address + 20 +
(b_OutputChannel * 4) +
(64 * b_ModulNbr));
} /* if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2)) */
else {
/****************************************/
/* The selected digital output is wrong */
/****************************************/
DPRINTK("The selected digital output is wrong\n");
i_ReturnValue = -4;
} /* if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2)) */
break;
case APCI1710_CHRONO_READ_CHANNEL:
/**********************************/
/* Test the digital input channel */
/**********************************/
pb_ChannelStatus = (unsigned char *) &data[0];
b_InputChannel =
(unsigned char) CR_CHAN(insn->chanspec);
if (b_InputChannel <= 2) {
dw_Status =
inl(devpriv->
s_BoardInfos.
ui_Address + 12 +
(64 * b_ModulNbr));
*pb_ChannelStatus =
(unsigned char) (((dw_Status >>
b_InputChannel)
& 1) ^ 1);
} /* if ((b_InputChannel >= 0) && (b_InputChannel <= 2)) */
else {
/***************************************/
/* The selected digital input is wrong */
/***************************************/
DPRINTK("The selected digital input is wrong\n");
i_ReturnValue = -4;
} /* if ((b_InputChannel >= 0) && (b_InputChannel <= 2)) */
break;
case APCI1710_CHRONO_READ_PORT:
pb_PortValue = (unsigned char *) &data[0];
dw_Status =
inl(devpriv->s_BoardInfos.
ui_Address + 12 +
(64 * b_ModulNbr));
*pb_PortValue =
(unsigned char) ((dw_Status & 0x7) ^ 7);
break;
}
} else {
/*******************************/
/* Chronometer not initialised */
/*******************************/
DPRINTK("Chronometer not initialised\n");
i_ReturnValue = -5;
}
} 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;
}
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data.com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
@endverbatim
*/
/*
+-----------------------------------------------------------------------+
| (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+-----------------------------------------------------------------------+
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+-----------------------------------------------------------------------+
| Project : API APCI1710 | Compiler : gcc |
| Module name : DIG_IO.C | Version : 2.96 |
+-------------------------------+---------------------------------------+
| Project manager: Eric Stolz | Date : 02/12/2002 |
+-----------------------------------------------------------------------+
| Description : APCI-1710 digital I/O module |
| |
| |
+-----------------------------------------------------------------------+
| UPDATES |
+-----------------------------------------------------------------------+
| Date | Author | Description of updates |
+----------+-----------+------------------------------------------------+
| 16/06/98 | S. Weber | Digital input / output implementation |
|----------|-----------|------------------------------------------------|
| 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
| | | available |
+-----------------------------------------------------------------------+
| | | |
| | | |
+-----------------------------------------------------------------------+
*/
/* Digital Output ON or OFF */
#define APCI1710_ON 1
#define APCI1710_OFF 0
/* Digital I/O */
#define APCI1710_INPUT 0
#define APCI1710_OUTPUT 1
#define APCI1710_DIGIO_MEMORYONOFF 0x10
#define APCI1710_DIGIO_INIT 0x11
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev, |
| struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)|
+----------------------------------------------------------------------------+
| Task : Configure the digital I/O operating mode from selected |
| module (b_ModulNbr). You must calling this function be|
| for you call any other function witch access of digital|
| I/O. |
+----------------------------------------------------------------------------+
| Input Parameters : |
| unsigned char_ b_ModulNbr data[0]: Module number to |
| configure (0 to 3) |
| unsigned char_ b_ChannelAMode data[1] : Channel A mode selection |
| 0 : Channel used for digital |
| input |
| 1 : Channel used for digital |
| output |
| unsigned char_ b_ChannelBMode data[2] : Channel B mode selection |
| 0 : Channel used for digital |
| input |
| 1 : Channel used for digital |
| output |
data[0] memory on/off
Activates and deactivates the digital output memory.
After having |
| called up this function with memory on,the output you have previously|
| activated with the function are not reset
+----------------------------------------------------------------------------+
| Output Parameters : - |
+----------------------------------------------------------------------------+
| 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 digital I/O module |
| -4: Bi-directional channel A configuration error |
| -5: Bi-directional channel B configuration error |
+----------------------------------------------------------------------------+
*/
static int i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct addi_private *devpriv = dev->private;
unsigned char b_ModulNbr, b_ChannelAMode, b_ChannelBMode;
unsigned char b_MemoryOnOff, b_ConfigType;
int i_ReturnValue = 0;
unsigned int dw_WriteConfig = 0;
b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
b_ConfigType = (unsigned char) data[0]; /* Memory or Init */
b_ChannelAMode = (unsigned char) data[1];
b_ChannelBMode = (unsigned char) data[2];
b_MemoryOnOff = (unsigned char) data[1]; /* if memory operation */
i_ReturnValue = insn->n;
/**************************/
/* Test the module number */
/**************************/
if (b_ModulNbr >= 4) {
DPRINTK("Module Number invalid\n");
i_ReturnValue = -2;
return i_ReturnValue;
}
switch (b_ConfigType) {
case APCI1710_DIGIO_MEMORYONOFF:
if (b_MemoryOnOff) /* If Memory ON */
{
/****************************/
/* Set the output memory on */
/****************************/
devpriv->s_ModuleInfo[b_ModulNbr].
s_DigitalIOInfo.b_OutputMemoryEnabled = 1;
/***************************/
/* Clear the output memory */
/***************************/
devpriv->s_ModuleInfo[b_ModulNbr].
s_DigitalIOInfo.dw_OutputMemory = 0;
} else /* If memory off */
{
/*****************************/
/* Set the output memory off */
/*****************************/
devpriv->s_ModuleInfo[b_ModulNbr].
s_DigitalIOInfo.b_OutputMemoryEnabled = 0;
}
break;
case APCI1710_DIGIO_INIT:
/*******************************/
/* Test if digital I/O counter */
/*******************************/
if ((devpriv->s_BoardInfos.
dw_MolduleConfiguration[b_ModulNbr] &
0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
/***************************************************/
/* Test the bi-directional channel A configuration */
/***************************************************/
if ((b_ChannelAMode == 0) || (b_ChannelAMode == 1)) {
/***************************************************/
/* Test the bi-directional channel B configuration */
/***************************************************/
if ((b_ChannelBMode == 0)
|| (b_ChannelBMode == 1)) {
devpriv->s_ModuleInfo[b_ModulNbr].
s_DigitalIOInfo.b_DigitalInit =
1;
/********************************/
/* Save channel A configuration */
/********************************/
devpriv->s_ModuleInfo[b_ModulNbr].
s_DigitalIOInfo.
b_ChannelAMode = b_ChannelAMode;
/********************************/
/* Save channel B configuration */
/********************************/
devpriv->s_ModuleInfo[b_ModulNbr].
s_DigitalIOInfo.
b_ChannelBMode = b_ChannelBMode;
/*****************************************/
/* Set the channel A and B configuration */
/*****************************************/
dw_WriteConfig =
(unsigned int) (b_ChannelAMode |
(b_ChannelBMode * 2));
/***************************/
/* Write the configuration */
/***************************/
outl(dw_WriteConfig,
devpriv->s_BoardInfos.
ui_Address + 4 +
(64 * b_ModulNbr));
} else {
/************************************************/
/* Bi-directional channel B configuration error */
/************************************************/
DPRINTK("Bi-directional channel B configuration error\n");
i_ReturnValue = -5;
}
} else {
/************************************************/
/* Bi-directional channel A configuration error */
/************************************************/
DPRINTK("Bi-directional channel A configuration error\n");
i_ReturnValue = -4;
}
} else {
/******************************************/
/* The module is not a digital I/O module */
/******************************************/
DPRINTK("The module is not a digital I/O module\n");
i_ReturnValue = -3;
}
} /* end of Switch */
printk("Return Value %d\n", i_ReturnValue);
return i_ReturnValue;
}
/*
+----------------------------------------------------------------------------+
| INPUT FUNCTIONS |
+----------------------------------------------------------------------------+
*/
/*
+----------------------------------------------------------------------------+
|INT i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev,comedi_subdevice
*s, struct comedi_insn *insn,unsigned int *data)
+----------------------------------------------------------------------------+
| Task : Read the status from selected digital I/O digital input|
| (b_InputChannel) |
+----------------------------------------------------------------------------|
|
| unsigned char_ b_ModulNbr CR_AREF(chanspec) : Selected module number |
| (0 to 3) |
| unsigned char_ b_InputChannel CR_CHAN(chanspec) : Selection from digital |
| input ( 0 to 6) |
| 0 : Channel C |
| 1 : Channel D |
| 2 : Channel E |
| 3 : Channel F |
| 4 : Channel G |
| 5 : Channel A |
| 6 : Channel B
|
+----------------------------------------------------------------------------+
| Output Parameters : data[0] : Digital input channel |
| status |
| 0 : Channle is not active|
| 1 : Channle is active |
+----------------------------------------------------------------------------+
| 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 digital I/O module |
| -4: The selected digital I/O digital input is wrong |
| -5: Digital I/O not initialised |
| -6: The digital channel A is used for output |
| -7: The digital channel B is used for output |
+----------------------------------------------------------------------------+
*/
/* _INT_ i_APCI1710_ReadDigitalIOChlValue (unsigned char_ b_BoardHandle, */
/*
* unsigned char_ b_ModulNbr, unsigned char_ b_InputChannel,
* unsigned char *_ pb_ChannelStatus)
*/
static int i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_StatusReg;
unsigned char b_ModulNbr, b_InputChannel;
unsigned char *pb_ChannelStatus;
b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
b_InputChannel = (unsigned char) CR_CHAN(insn->chanspec);
data[0] = 0;
pb_ChannelStatus = (unsigned char *) &data[0];
i_ReturnValue = insn->n;
/**************************/
/* Test the module number */
/**************************/
if (b_ModulNbr < 4) {
/*******************************/
/* Test if digital I/O counter */
/*******************************/
if ((devpriv->s_BoardInfos.
dw_MolduleConfiguration[b_ModulNbr] &
0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
/******************************************/
/* Test the digital imnput channel number */
/******************************************/
if (b_InputChannel <= 6) {
/**********************************************/
/* Test if the digital I/O module initialised */
/**********************************************/
if (devpriv->s_ModuleInfo[b_ModulNbr].
s_DigitalIOInfo.b_DigitalInit == 1) {
/**********************************/
/* Test if channel A or channel B */
/**********************************/
if (b_InputChannel > 4) {
/*********************/
/* Test if channel A */
/*********************/
if (b_InputChannel == 5) {
/***************************/
/* Test the channel A mode */
/***************************/
if (devpriv->
s_ModuleInfo
[b_ModulNbr].
s_DigitalIOInfo.
b_ChannelAMode
!= 0) {
/********************************************/
/* The digital channel A is used for output */
/********************************************/
i_ReturnValue =
-6;
}
} /* if (b_InputChannel == 5) */
else {
/***************************/
/* Test the channel B mode */
/***************************/
if (devpriv->
s_ModuleInfo
[b_ModulNbr].
s_DigitalIOInfo.
b_ChannelBMode
!= 0) {
/********************************************/
/* The digital channel B is used for output */
/********************************************/
i_ReturnValue =
-7;
}
} /* if (b_InputChannel == 5) */
} /* if (b_InputChannel > 4) */
/***********************/
/* Test if error occur */
/***********************/
if (i_ReturnValue >= 0) {
/**************************/
/* Read all digital input */
/**************************/
/*
* INPDW (ps_APCI1710Variable-> s_Board [b_BoardHandle].
* s_BoardInfos. ui_Address + (64 * b_ModulNbr), &dw_StatusReg);
*/
dw_StatusReg =
inl(devpriv->
s_BoardInfos.
ui_Address +
(64 * b_ModulNbr));
*pb_ChannelStatus =
(unsigned char) ((dw_StatusReg ^
0x1C) >>
b_InputChannel) & 1;
} /* if (i_ReturnValue == 0) */
} else {
/*******************************/
/* Digital I/O not initialised */
/*******************************/
DPRINTK("Digital I/O not initialised\n");
i_ReturnValue = -5;
}
} else {
/********************************/
/* Selected digital input error */
/********************************/
DPRINTK("Selected digital input error\n");
i_ReturnValue = -4;
}
} else {
/******************************************/
/* The module is not a digital I/O module */
/******************************************/
DPRINTK("The module is not a digital I/O module\n");
i_ReturnValue = -3;
}
} else {
/***********************/
/* Module number error */
/***********************/
DPRINTK("Module number error\n");
i_ReturnValue = -2;
}
return i_ReturnValue;
}
/*
+----------------------------------------------------------------------------+
| OUTPUT FUNCTIONS |
+----------------------------------------------------------------------------+
*/
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI1710_InsnWriteDigitalIOChlOnOff(comedi_device
|*dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)
+----------------------------------------------------------------------------+
| Task : Sets or resets the output witch has been passed with the |
| parameter b_Channel. Setting an output means setting |
| an ouput high. |
+----------------------------------------------------------------------------+
| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
| unsigned char_ b_ModulNbr (aref ) : Selected module number (0 to 3)|
| unsigned char_ b_OutputChannel (CR_CHAN) : Selection from digital output |
| channel (0 to 2) |
| 0 : Channel H |
| 1 : Channel A |
| 2 : Channel B |
+----------------------------------------------------------------------------+
| Output Parameters : - |
+----------------------------------------------------------------------------+
| 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 digital I/O module |
| -4: The selected digital output is wrong |
| -5: digital I/O not initialised see function |
| " i_APCI1710_InitDigitalIO" |
| -6: The digital channel A is used for input |
| -7: The digital channel B is used for input
-8: Digital Output Memory OFF. |
| Use previously the function |
| "i_APCI1710_SetDigitalIOMemoryOn". |
+----------------------------------------------------------------------------+
*/
/*
* _INT_ i_APCI1710_SetDigitalIOChlOn (unsigned char_ b_BoardHandle,
* unsigned char_ b_ModulNbr, unsigned char_ b_OutputChannel)
*/
static int i_APCI1710_InsnWriteDigitalIOChlOnOff(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_WriteValue = 0;
unsigned char b_ModulNbr, b_OutputChannel;
i_ReturnValue = insn->n;
b_ModulNbr = CR_AREF(insn->chanspec);
b_OutputChannel = CR_CHAN(insn->chanspec);
/**************************/
/* Test the module number */
/**************************/
if (b_ModulNbr < 4) {
/*******************************/
/* Test if digital I/O counter */
/*******************************/
if ((devpriv->s_BoardInfos.
dw_MolduleConfiguration[b_ModulNbr] &
0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
/**********************************************/
/* Test if the digital I/O module initialised */
/**********************************************/
if (devpriv->s_ModuleInfo[b_ModulNbr].
s_DigitalIOInfo.b_DigitalInit == 1) {
/******************************************/
/* Test the digital output channel number */
/******************************************/
switch (b_OutputChannel) {
/*************/
/* Channel H */
/*************/
case 0:
break;
/*************/
/* Channel A */
/*************/
case 1:
if (devpriv->s_ModuleInfo[b_ModulNbr].
s_DigitalIOInfo.
b_ChannelAMode != 1) {
/*******************************************/
/* The digital channel A is used for input */
/*******************************************/
i_ReturnValue = -6;
}
break;
/*************/
/* Channel B */
/*************/
case 2:
if (devpriv->s_ModuleInfo[b_ModulNbr].
s_DigitalIOInfo.
b_ChannelBMode != 1) {
/*******************************************/
/* The digital channel B is used for input */
/*******************************************/
i_ReturnValue = -7;
}
break;
default:
/****************************************/
/* The selected digital output is wrong */
/****************************************/
i_ReturnValue = -4;
break;
}
/***********************/
/* Test if error occur */
/***********************/
if (i_ReturnValue >= 0) {
/*********************************/
/* Test if set channel ON */
/*********************************/
if (data[0]) {
/*********************************/
/* Test if output memory enabled */
/*********************************/
if (devpriv->
s_ModuleInfo
[b_ModulNbr].
s_DigitalIOInfo.
b_OutputMemoryEnabled ==
1) {
dw_WriteValue =
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_DigitalIOInfo.
dw_OutputMemory
| (1 <<
b_OutputChannel);
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_DigitalIOInfo.
dw_OutputMemory
= dw_WriteValue;
} else {
dw_WriteValue =
1 <<
b_OutputChannel;
}
} /* set channel off */
else {
if (devpriv->
s_ModuleInfo
[b_ModulNbr].
s_DigitalIOInfo.
b_OutputMemoryEnabled ==
1) {
dw_WriteValue =
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_DigitalIOInfo.
dw_OutputMemory
& (0xFFFFFFFFUL
-
(1 << b_OutputChannel));
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_DigitalIOInfo.
dw_OutputMemory
= dw_WriteValue;
} else {
/*****************************/
/* Digital Output Memory OFF */
/*****************************/
/* +Use previously the function "i_APCI1710_SetDigitalIOMemoryOn" */
i_ReturnValue = -8;
}
}
/*******************/
/* Write the value */
/*******************/
/* OUTPDW (ps_APCI1710Variable->
* s_Board [b_BoardHandle].
* s_BoardInfos. ui_Address + (64 * b_ModulNbr),
* dw_WriteValue);
*/
outl(dw_WriteValue,
devpriv->s_BoardInfos.
ui_Address + (64 * b_ModulNbr));
}
} else {
/*******************************/
/* Digital I/O not initialised */
/*******************************/
i_ReturnValue = -5;
}
} else {
/******************************************/
/* The module is not a digital I/O module */
/******************************************/
i_ReturnValue = -3;
}
} else {
/***********************/
/* Module number error */
/***********************/
i_ReturnValue = -2;
}
return i_ReturnValue;
}
/*
+----------------------------------------------------------------------------+
|INT i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device *dev,comedi_subdevice
*s, struct comedi_insn *insn,unsigned int *data)
+----------------------------------------------------------------------------+
| Task : write:
Sets or resets one or several outputs from port. |
| Setting an output means setting an output high. |
| If you have switched OFF the digital output memory |
| (OFF), all the other output are set to "0".
| read:
Read the status from digital input port |
| from selected digital I/O module (b_ModulNbr)
+----------------------------------------------------------------------------+
| Input Parameters :
unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
| unsigned char_ b_ModulNbr CR_AREF(aref) : Selected module number (0 to 3)|
| unsigned char_ b_PortValue CR_CHAN(chanspec) : Output Value ( 0 To 7 )
| data[0] read or write port
| data[1] if write then indicate ON or OFF
| if read : data[1] will return port status.
+----------------------------------------------------------------------------+
| Output Parameters : - |
+----------------------------------------------------------------------------+
| Return Value :
| INPUT :
0: No error |
| -1: The handle parameter of the board is wrong |
| -2: The module parameter is wrong |
| -3: The module is not a digital I/O module |
| -4: Digital I/O not initialised
OUTPUT: 0: No error |
| -1: The handle parameter of the board is wrong |
| -2: The module parameter is wrong |
| -3: The module is not a digital I/O module |
| -4: Output value wrong |
| -5: digital I/O not initialised see function |
| " i_APCI1710_InitDigitalIO" |
| -6: The digital channel A is used for input |
| -7: The digital channel B is used for input
-8: Digital Output Memory OFF. |
| Use previously the function |
| "i_APCI1710_SetDigitalIOMemoryOn". |
+----------------------------------------------------------------------------+
*/
/*
* _INT_ i_APCI1710_SetDigitalIOPortOn (unsigned char_
* b_BoardHandle, unsigned char_ b_ModulNbr, unsigned char_
* b_PortValue)
*/
static int i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_WriteValue = 0;
unsigned int dw_StatusReg;
unsigned char b_ModulNbr, b_PortValue;
unsigned char b_PortOperation, b_PortOnOFF;
unsigned char *pb_PortValue;
b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
b_PortOperation = (unsigned char) data[0]; /* Input or output */
b_PortOnOFF = (unsigned char) data[1]; /* if output then On or Off */
b_PortValue = (unsigned char) data[2]; /* if out put then Value */
i_ReturnValue = insn->n;
pb_PortValue = (unsigned char *) &data[0];
/* if input then read value */
switch (b_PortOperation) {
case APCI1710_INPUT:
/**************************/
/* Test the module number */
/**************************/
if (b_ModulNbr < 4) {
/*******************************/
/* Test if digital I/O counter */
/*******************************/
if ((devpriv->s_BoardInfos.
dw_MolduleConfiguration[b_ModulNbr] &
0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
/**********************************************/
/* Test if the digital I/O module initialised */
/**********************************************/
if (devpriv->s_ModuleInfo[b_ModulNbr].
s_DigitalIOInfo.b_DigitalInit == 1) {
/**************************/
/* Read all digital input */
/**************************/
/* INPDW (ps_APCI1710Variable->
* s_Board [b_BoardHandle].
* s_BoardInfos.
* ui_Address + (64 * b_ModulNbr),
* &dw_StatusReg);
*/
dw_StatusReg =
inl(devpriv->s_BoardInfos.
ui_Address + (64 * b_ModulNbr));
*pb_PortValue =
(unsigned char) (dw_StatusReg ^ 0x1C);
} else {
/*******************************/
/* Digital I/O not initialised */
/*******************************/
i_ReturnValue = -4;
}
} else {
/******************************************/
/* The module is not a digital I/O module */
/******************************************/
i_ReturnValue = -3;
}
} else {
/***********************/
/* Module number error */
/***********************/
i_ReturnValue = -2;
}
break;
case APCI1710_OUTPUT:
/**************************/
/* Test the module number */
/**************************/
if (b_ModulNbr < 4) {
/*******************************/
/* Test if digital I/O counter */
/*******************************/
if ((devpriv->s_BoardInfos.
dw_MolduleConfiguration[b_ModulNbr] &
0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
/**********************************************/
/* Test if the digital I/O module initialised */
/**********************************************/
if (devpriv->s_ModuleInfo[b_ModulNbr].
s_DigitalIOInfo.b_DigitalInit == 1) {
/***********************/
/* Test the port value */
/***********************/
if (b_PortValue <= 7) {
/***********************************/
/* Test the digital output channel */
/***********************************/
/**************************/
/* Test if channel A used */
/**************************/
if ((b_PortValue & 2) == 2) {
if (devpriv->
s_ModuleInfo
[b_ModulNbr].
s_DigitalIOInfo.
b_ChannelAMode
!= 1) {
/*******************************************/
/* The digital channel A is used for input */
/*******************************************/
i_ReturnValue =
-6;
}
} /* if ((b_PortValue & 2) == 2) */
/**************************/
/* Test if channel B used */
/**************************/
if ((b_PortValue & 4) == 4) {
if (devpriv->
s_ModuleInfo
[b_ModulNbr].
s_DigitalIOInfo.
b_ChannelBMode
!= 1) {
/*******************************************/
/* The digital channel B is used for input */
/*******************************************/
i_ReturnValue =
-7;
}
} /* if ((b_PortValue & 4) == 4) */
/***********************/
/* Test if error occur */
/***********************/
if (i_ReturnValue >= 0) {
/* if(data[1]) { */
switch (b_PortOnOFF) {
/*********************************/
/* Test if set Port ON */
/*********************************/
case APCI1710_ON:
/*********************************/
/* Test if output memory enabled */
/*********************************/
if (devpriv->
s_ModuleInfo
[b_ModulNbr].
s_DigitalIOInfo.
b_OutputMemoryEnabled
== 1) {
dw_WriteValue
=
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_DigitalIOInfo.
dw_OutputMemory
|
b_PortValue;
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_DigitalIOInfo.
dw_OutputMemory
=
dw_WriteValue;
} else {
dw_WriteValue
=
b_PortValue;
}
break;
/* If Set PORT OFF */
case APCI1710_OFF:
/*********************************/
/* Test if output memory enabled */
/*********************************/
if (devpriv->
s_ModuleInfo
[b_ModulNbr].
s_DigitalIOInfo.
b_OutputMemoryEnabled
== 1) {
dw_WriteValue
=
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_DigitalIOInfo.
dw_OutputMemory
&
(0xFFFFFFFFUL
-
b_PortValue);
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_DigitalIOInfo.
dw_OutputMemory
=
dw_WriteValue;
} else {
/*****************************/
/* Digital Output Memory OFF */
/*****************************/
i_ReturnValue
=
-8;
}
} /* switch */
/*******************/
/* Write the value */
/*******************/
/* OUTPDW (ps_APCI1710Variable->
* s_Board [b_BoardHandle].
* s_BoardInfos.
* ui_Address + (64 * b_ModulNbr),
* dw_WriteValue); */
outl(dw_WriteValue,
devpriv->
s_BoardInfos.
ui_Address +
(64 * b_ModulNbr));
}
} else {
/**********************/
/* Output value wrong */
/**********************/
i_ReturnValue = -4;
}
} else {
/*******************************/
/* Digital I/O not initialised */
/*******************************/
i_ReturnValue = -5;
}
} else {
/******************************************/
/* The module is not a digital I/O module */
/******************************************/
i_ReturnValue = -3;
}
} else {
/***********************/
/* Module number error */
/***********************/
i_ReturnValue = -2;
}
break;
default:
i_ReturnValue = -9;
DPRINTK("NO INPUT/OUTPUT specified\n");
} /* switch INPUT / OUTPUT */
return i_ReturnValue;
}
This source diff could not be displayed because it is too large. You can view the blob instead.
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data.com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
@endverbatim
*/
/*
+-----------------------------------------------------------------------+
| (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+-----------------------------------------------------------------------+
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+-----------------------------------------------------------------------+
| Project : API APCI1710 | Compiler : gcc |
| Module name : Inp_CPT.C | Version : 2.96 |
+-------------------------------+---------------------------------------+
| Project manager: Eric Stolz | Date : 02/12/2002 |
+-----------------------------------------------------------------------+
| Description : APCI-1710 pulse encoder module |
| |
| |
+-----------------------------------------------------------------------+
| UPDATES |
+-----------------------------------------------------------------------+
| Date | Author | Description of updates |
+----------+-----------+------------------------------------------------+
| | | |
|----------|-----------|------------------------------------------------|
| 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
| | | available |
+-----------------------------------------------------------------------+
*/
#define APCI1710_SINGLE 0
#define APCI1710_CONTINUOUS 1
#define APCI1710_PULSEENCODER_READ 0
#define APCI1710_PULSEENCODER_WRITE 1
/*
+----------------------------------------------------------------------------+
| Function Name : _INT_ i_APCI1710_InitPulseEncoder |
| (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
| unsigned char_ b_PulseEncoderNbr, |
| unsigned char_ b_InputLevelSelection, |
| unsigned char_ b_TriggerOutputAction, |
| ULONG_ ul_StartValue) |
+----------------------------------------------------------------------------+
| Task : Configure the pulse encoder operating mode selected via|
| b_ModulNbr and b_PulseEncoderNbr. The pulse encoder |
| after each pulse decrement the counter value from 1. |
| |
| You must calling this function be for you call any |
| other function witch access of pulse encoders. |
+----------------------------------------------------------------------------+
| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710|
| unsigned char_ b_ModulNbr : Module number to |
| configure (0 to 3) |
| unsigned char_ b_PulseEncoderNbr : Pulse encoder selection |
| (0 to 3) |
| unsigned char_ b_InputLevelSelection : Input level selection |
| (0 or 1) |
| 0 : Set pulse encoder|
| count the the low|
| level pulse. |
| 1 : Set pulse encoder|
| count the the |
| high level pulse.|
| unsigned char_ b_TriggerOutputAction : Digital TRIGGER output |
| action |
| 0 : No action |
| 1 : Set the trigger |
| output to "1" |
| (high) after the |
| passage from 1 to|
| 0 from pulse |
| encoder. |
| 2 : Set the trigger |
| output to "0" |
| (low) after the |
| passage from 1 to|
| 0 from pulse |
| encoder |
| ULONG_ ul_StartValue : Pulse encoder start value|
| (1 to 4294967295)
b_ModulNbr =(unsigned char) CR_AREF(insn->chanspec);
b_PulseEncoderNbr =(unsigned char) data[0];
b_InputLevelSelection =(unsigned char) data[1];
b_TriggerOutputAction =(unsigned char) data[2];
ul_StartValue =(unsigned int) data[3];
|
+----------------------------------------------------------------------------+
| Output Parameters : - |
+----------------------------------------------------------------------------+
| Return Value : 0: No error |
| -1: The handle parameter of the board is wrong |
| -2: The module is not a pulse encoder module |
| -3: Pulse encoder selection is wrong |
| -4: Input level selection is wrong |
| -5: Digital TRIGGER output action selection is wrong |
| -6: Pulse encoder start value is wrong |
+----------------------------------------------------------------------------+
*/
static int i_APCI1710_InsnConfigInitPulseEncoder(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_IntRegister;
unsigned char b_ModulNbr;
unsigned char b_PulseEncoderNbr;
unsigned char b_InputLevelSelection;
unsigned char b_TriggerOutputAction;
unsigned int ul_StartValue;
b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
b_PulseEncoderNbr = (unsigned char) data[0];
b_InputLevelSelection = (unsigned char) data[1];
b_TriggerOutputAction = (unsigned char) data[2];
ul_StartValue = (unsigned int) data[3];
i_ReturnValue = insn->n;
/***********************************/
/* Test the selected module number */
/***********************************/
if (b_ModulNbr <= 3) {
/*************************/
/* Test if pulse encoder */
/*************************/
if ((devpriv->s_BoardInfos.
dw_MolduleConfiguration[b_ModulNbr] &
APCI1710_PULSE_ENCODER) ==
APCI1710_PULSE_ENCODER) {
/******************************************/
/* Test the selected pulse encoder number */
/******************************************/
if (b_PulseEncoderNbr <= 3) {
/************************/
/* Test the input level */
/************************/
if ((b_InputLevelSelection == 0)
|| (b_InputLevelSelection == 1)) {
/*******************************************/
/* Test the ouput TRIGGER action selection */
/*******************************************/
if ((b_TriggerOutputAction <= 2)
|| (b_PulseEncoderNbr > 0)) {
if (ul_StartValue > 1) {
dw_IntRegister =
inl(devpriv->
s_BoardInfos.
ui_Address +
20 +
(64 * b_ModulNbr));
/***********************/
/* Set the start value */
/***********************/
outl(ul_StartValue,
devpriv->
s_BoardInfos.
ui_Address +
(b_PulseEncoderNbr
* 4) +
(64 * b_ModulNbr));
/***********************/
/* Set the input level */
/***********************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PulseEncoderModuleInfo.
dw_SetRegister =
(devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PulseEncoderModuleInfo.
dw_SetRegister &
(0xFFFFFFFFUL -
(1UL << (8 + b_PulseEncoderNbr)))) | ((1UL & (~b_InputLevelSelection)) << (8 + b_PulseEncoderNbr));
/*******************************/
/* Test if output trigger used */
/*******************************/
if ((b_TriggerOutputAction > 0) && (b_PulseEncoderNbr > 1)) {
/****************************/
/* Enable the output action */
/****************************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PulseEncoderModuleInfo.
dw_SetRegister
=
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PulseEncoderModuleInfo.
dw_SetRegister
| (1UL
<< (4 + b_PulseEncoderNbr));
/*********************************/
/* Set the output TRIGGER action */
/*********************************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PulseEncoderModuleInfo.
dw_SetRegister
=
(devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PulseEncoderModuleInfo.
dw_SetRegister
&
(0xFFFFFFFFUL
-
(1UL << (12 + b_PulseEncoderNbr)))) | ((1UL & (b_TriggerOutputAction - 1)) << (12 + b_PulseEncoderNbr));
} else {
/*****************************/
/* Disable the output action */
/*****************************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PulseEncoderModuleInfo.
dw_SetRegister
=
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PulseEncoderModuleInfo.
dw_SetRegister
&
(0xFFFFFFFFUL
-
(1UL << (4 + b_PulseEncoderNbr)));
}
/*************************/
/* Set the configuration */
/*************************/
outl(devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PulseEncoderModuleInfo.
dw_SetRegister,
devpriv->
s_BoardInfos.
ui_Address +
20 +
(64 * b_ModulNbr));
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PulseEncoderModuleInfo.
s_PulseEncoderInfo
[b_PulseEncoderNbr].
b_PulseEncoderInit
= 1;
} else {
/**************************************/
/* Pulse encoder start value is wrong */
/**************************************/
DPRINTK("Pulse encoder start value is wrong\n");
i_ReturnValue = -6;
}
} else {
/****************************************************/
/* Digital TRIGGER output action selection is wrong */
/****************************************************/
DPRINTK("Digital TRIGGER output action selection is wrong\n");
i_ReturnValue = -5;
}
} else {
/**********************************/
/* Input level selection is wrong */
/**********************************/
DPRINTK("Input level selection is wrong\n");
i_ReturnValue = -4;
}
} else {
/************************************/
/* Pulse encoder selection is wrong */
/************************************/
DPRINTK("Pulse encoder selection is wrong\n");
i_ReturnValue = -3;
}
} else {
/********************************************/
/* The module is not a pulse encoder module */
/********************************************/
DPRINTK("The module is not a pulse encoder module\n");
i_ReturnValue = -2;
}
} else {
/********************************************/
/* The module is not a pulse encoder module */
/********************************************/
DPRINTK("The module is not a pulse encoder module\n");
i_ReturnValue = -2;
}
return i_ReturnValue;
}
/*
+----------------------------------------------------------------------------+
| Function Name : _INT_ i_APCI1710_EnablePulseEncoder |
| (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
| unsigned char_ b_PulseEncoderNbr, |
| unsigned char_ b_CycleSelection, |
| unsigned char_ b_InterruptHandling) |
+----------------------------------------------------------------------------+
| Task : Enableor disable the selected pulse encoder (b_PulseEncoderNbr) |
| from selected module (b_ModulNbr). Each input pulse |
| decrement the pulse encoder counter value from 1. |
| If you enabled the interrupt (b_InterruptHandling), a |
| interrupt is generated when the pulse encoder has run |
| down. |
+----------------------------------------------------------------------------+
| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710|
| unsigned char_ b_ModulNbr : Module number to |
| configure (0 to 3) |
| unsigned char_ b_PulseEncoderNbr : Pulse encoder selection |
| (0 to 3) |
| unsigned char_ b_CycleSelection : APCI1710_CONTINUOUS: |
| Each time the |
| counting value is set|
| on "0", the pulse |
| encoder load the |
| start value after |
| the next pulse. |
| APCI1710_SINGLE: |
| If the counter is set|
| on "0", the pulse |
| encoder is stopped. |
| unsigned char_ b_InterruptHandling : Interrupts can be |
| generated, when the pulse|
| encoder has run down. |
| With this parameter the |
| user decides if |
| interrupts are used or |
| not. |
| APCI1710_ENABLE: |
| Interrupts are enabled |
| APCI1710_DISABLE: |
| Interrupts are disabled
b_ModulNbr =(unsigned char) CR_AREF(insn->chanspec);
b_Action =(unsigned char) data[0];
b_PulseEncoderNbr =(unsigned char) data[1];
b_CycleSelection =(unsigned char) data[2];
b_InterruptHandling =(unsigned char) data[3];|
+----------------------------------------------------------------------------+
| Output Parameters : - |
+----------------------------------------------------------------------------+
| Return Value : 0: No error |
| -1: The handle parameter of the board is wrong |
| -2: Module selection is wrong |
| -3: Pulse encoder selection is wrong |
| -4: Pulse encoder not initialised. |
| See function "i_APCI1710_InitPulseEncoder" |
| -5: Cycle selection mode is wrong |
| -6: Interrupt handling mode is wrong |
| -7: Interrupt routine not installed. |
| See function "i_APCI1710_SetBoardIntRoutineX" |
+----------------------------------------------------------------------------+
*/
static int i_APCI1710_InsnWriteEnableDisablePulseEncoder(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned char b_ModulNbr;
unsigned char b_PulseEncoderNbr;
unsigned char b_CycleSelection;
unsigned char b_InterruptHandling;
unsigned char b_Action;
i_ReturnValue = insn->n;
b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
b_Action = (unsigned char) data[0];
b_PulseEncoderNbr = (unsigned char) data[1];
b_CycleSelection = (unsigned char) data[2];
b_InterruptHandling = (unsigned char) data[3];
/***********************************/
/* Test the selected module number */
/***********************************/
if (b_ModulNbr <= 3) {
/******************************************/
/* Test the selected pulse encoder number */
/******************************************/
if (b_PulseEncoderNbr <= 3) {
/*************************************/
/* Test if pulse encoder initialised */
/*************************************/
if (devpriv->s_ModuleInfo[b_ModulNbr].
s_PulseEncoderModuleInfo.
s_PulseEncoderInfo[b_PulseEncoderNbr].
b_PulseEncoderInit == 1) {
switch (b_Action) {
case APCI1710_ENABLE:
/****************************/
/* Test the cycle selection */
/****************************/
if (b_CycleSelection ==
APCI1710_CONTINUOUS
|| b_CycleSelection ==
APCI1710_SINGLE) {
/*******************************/
/* Test the interrupt handling */
/*******************************/
if (b_InterruptHandling ==
APCI1710_ENABLE
|| b_InterruptHandling
== APCI1710_DISABLE) {
/******************************/
/* Test if interrupt not used */
/******************************/
if (b_InterruptHandling
==
APCI1710_DISABLE)
{
/*************************/
/* Disable the interrupt */
/*************************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PulseEncoderModuleInfo.
dw_SetRegister
=
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PulseEncoderModuleInfo.
dw_SetRegister
&
(0xFFFFFFFFUL
-
(1UL << b_PulseEncoderNbr));
} else {
/************************/
/* Enable the interrupt */
/************************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PulseEncoderModuleInfo.
dw_SetRegister
=
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PulseEncoderModuleInfo.
dw_SetRegister
| (1UL
<<
b_PulseEncoderNbr);
devpriv->tsk_Current = current; /* Save the current process task structure */
}
if (i_ReturnValue >= 0) {
/***********************************/
/* Enable or disable the interrupt */
/***********************************/
outl(devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PulseEncoderModuleInfo.
dw_SetRegister,
devpriv->
s_BoardInfos.
ui_Address
+ 20 +
(64 * b_ModulNbr));
/****************************/
/* Enable the pulse encoder */
/****************************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PulseEncoderModuleInfo.
dw_ControlRegister
=
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PulseEncoderModuleInfo.
dw_ControlRegister
| (1UL
<<
b_PulseEncoderNbr);
/**********************/
/* Set the cycle mode */
/**********************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PulseEncoderModuleInfo.
dw_ControlRegister
=
(devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PulseEncoderModuleInfo.
dw_ControlRegister
&
(0xFFFFFFFFUL
-
(1 << (b_PulseEncoderNbr + 4)))) | ((b_CycleSelection & 1UL) << (4 + b_PulseEncoderNbr));
/****************************/
/* Enable the pulse encoder */
/****************************/
outl(devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PulseEncoderModuleInfo.
dw_ControlRegister,
devpriv->
s_BoardInfos.
ui_Address
+ 16 +
(64 * b_ModulNbr));
}
} else {
/************************************/
/* Interrupt handling mode is wrong */
/************************************/
DPRINTK("Interrupt handling mode is wrong\n");
i_ReturnValue = -6;
}
} else {
/*********************************/
/* Cycle selection mode is wrong */
/*********************************/
DPRINTK("Cycle selection mode is wrong\n");
i_ReturnValue = -5;
}
break;
case APCI1710_DISABLE:
devpriv->s_ModuleInfo[b_ModulNbr].
s_PulseEncoderModuleInfo.
dw_ControlRegister =
devpriv->
s_ModuleInfo[b_ModulNbr].
s_PulseEncoderModuleInfo.
dw_ControlRegister &
(0xFFFFFFFFUL -
(1UL << b_PulseEncoderNbr));
/*****************************/
/* Disable the pulse encoder */
/*****************************/
outl(devpriv->s_ModuleInfo[b_ModulNbr].
s_PulseEncoderModuleInfo.
dw_ControlRegister,
devpriv->s_BoardInfos.
ui_Address + 16 +
(64 * b_ModulNbr));
break;
} /* switch End */
} else {
/*********************************/
/* Pulse encoder not initialised */
/*********************************/
DPRINTK("Pulse encoder not initialised\n");
i_ReturnValue = -4;
}
} else {
/************************************/
/* Pulse encoder selection is wrong */
/************************************/
DPRINTK("Pulse encoder selection is wrong\n");
i_ReturnValue = -3;
}
} else {
/*****************************/
/* Module selection is wrong */
/*****************************/
DPRINTK("Module selection is wrong\n");
i_ReturnValue = -2;
}
return i_ReturnValue;
}
/*
+----------------------------------------------------------------------------+
| Function Name : _INT_ i_APCI1710_ReadPulseEncoderStatus |
| (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
| unsigned char_ b_PulseEncoderNbr, |
| unsigned char *_ pb_Status) |
+----------------------------------------------------------------------------+
| Task APCI1710_PULSEENCODER_READ : Reads the pulse encoder status
and valuefrom selected pulse |
| encoder (b_PulseEncoderNbr) from selected module |
| (b_ModulNbr). |
+----------------------------------------------------------------------------+
unsigned char b_Type; data[0]
APCI1710_PULSEENCODER_WRITE
Writes a 32-bit value (ul_WriteValue) into the selected|
| pulse encoder (b_PulseEncoderNbr) from selected module |
| (b_ModulNbr). This operation set the new start pulse |
| encoder value.
APCI1710_PULSEENCODER_READ
| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710|
| CRAREF() unsigned char_ b_ModulNbr : Module number to |
| configure (0 to 3) |
| data[1] unsigned char_ b_PulseEncoderNbr : Pulse encoder selection |
| (0 to 3)
APCI1710_PULSEENCODER_WRITE
data[2] ULONG_ ul_WriteValue : 32-bit value to be |
| written |
+----------------------------------------------------------------------------+
| Output Parameters : unsigned char *_ pb_Status : Pulse encoder status. |
| 0 : No overflow occur|
| 1 : Overflow occur
PULONG_ pul_ReadValue : Pulse encoder value | |
+----------------------------------------------------------------------------+
| Return Value : 0: No error |
| -1: The handle parameter of the board is wrong |
| -2: Module selection is wrong |
| -3: Pulse encoder selection is wrong |
| -4: Pulse encoder not initialised. |
| See function "i_APCI1710_InitPulseEncoder" |
+----------------------------------------------------------------------------+
*/
/*_INT_ i_APCI1710_ReadPulseEncoderStatus (unsigned char_ b_BoardHandle,
unsigned char_ b_ModulNbr,
unsigned char_ b_PulseEncoderNbr,
unsigned char *_ pb_Status)
*/
static int i_APCI1710_InsnBitsReadWritePulseEncoder(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_StatusRegister;
unsigned char b_ModulNbr;
unsigned char b_PulseEncoderNbr;
unsigned char *pb_Status;
unsigned char b_Type;
unsigned int *pul_ReadValue;
unsigned int ul_WriteValue;
i_ReturnValue = insn->n;
b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
b_Type = (unsigned char) data[0];
b_PulseEncoderNbr = (unsigned char) data[1];
pb_Status = (unsigned char *) &data[0];
pul_ReadValue = (unsigned int *) &data[1];
/***********************************/
/* Test the selected module number */
/***********************************/
if (b_ModulNbr <= 3) {
/******************************************/
/* Test the selected pulse encoder number */
/******************************************/
if (b_PulseEncoderNbr <= 3) {
/*************************************/
/* Test if pulse encoder initialised */
/*************************************/
if (devpriv->s_ModuleInfo[b_ModulNbr].
s_PulseEncoderModuleInfo.
s_PulseEncoderInfo[b_PulseEncoderNbr].
b_PulseEncoderInit == 1) {
switch (b_Type) {
case APCI1710_PULSEENCODER_READ:
/****************************/
/* Read the status register */
/****************************/
dw_StatusRegister =
inl(devpriv->s_BoardInfos.
ui_Address + 16 +
(64 * b_ModulNbr));
devpriv->s_ModuleInfo[b_ModulNbr].
s_PulseEncoderModuleInfo.
dw_StatusRegister = devpriv->
s_ModuleInfo[b_ModulNbr].
s_PulseEncoderModuleInfo.
dw_StatusRegister |
dw_StatusRegister;
*pb_Status =
(unsigned char) (devpriv->
s_ModuleInfo[b_ModulNbr].
s_PulseEncoderModuleInfo.
dw_StatusRegister >> (1 +
b_PulseEncoderNbr)) & 1;
devpriv->s_ModuleInfo[b_ModulNbr].
s_PulseEncoderModuleInfo.
dw_StatusRegister =
devpriv->
s_ModuleInfo[b_ModulNbr].
s_PulseEncoderModuleInfo.
dw_StatusRegister &
(0xFFFFFFFFUL - (1 << (1 +
b_PulseEncoderNbr)));
/******************/
/* Read the value */
/******************/
*pul_ReadValue =
inl(devpriv->s_BoardInfos.
ui_Address +
(4 * b_PulseEncoderNbr) +
(64 * b_ModulNbr));
break;
case APCI1710_PULSEENCODER_WRITE:
ul_WriteValue = (unsigned int) data[2];
/*******************/
/* Write the value */
/*******************/
outl(ul_WriteValue,
devpriv->s_BoardInfos.
ui_Address +
(4 * b_PulseEncoderNbr) +
(64 * b_ModulNbr));
} /* end of switch */
} else {
/*********************************/
/* Pulse encoder not initialised */
/*********************************/
DPRINTK("Pulse encoder not initialised\n");
i_ReturnValue = -4;
}
} else {
/************************************/
/* Pulse encoder selection is wrong */
/************************************/
DPRINTK("Pulse encoder selection is wrong\n");
i_ReturnValue = -3;
}
} else {
/*****************************/
/* Module selection is wrong */
/*****************************/
DPRINTK("Module selection is wrong\n");
i_ReturnValue = -2;
}
return i_ReturnValue;
}
static int i_APCI1710_InsnReadInterruptPulseEncoder(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct addi_private *devpriv = dev->private;
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;
}
This source diff could not be displayed because it is too large. You can view the blob instead.
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data.com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
@endverbatim
*/
/*
+-----------------------------------------------------------------------+
| (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+-----------------------------------------------------------------------+
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+-----------------------------------------------------------------------+
| Project : API APCI1710 | Compiler : gcc |
| Module name : SSI.C | Version : 2.96 |
+-------------------------------+---------------------------------------+
| Project manager: Eric Stolz | Date : 02/12/2002 |
+-----------------------------------------------------------------------+
| Description : APCI-1710 SSI counter module |
+-----------------------------------------------------------------------+
| several changes done by S. Weber in 1998 and C. Guinot in 2000 |
+-----------------------------------------------------------------------+
*/
#define APCI1710_30MHZ 30
#define APCI1710_33MHZ 33
#define APCI1710_40MHZ 40
#define APCI1710_BINARY_MODE 0x1
#define APCI1710_GRAY_MODE 0x0
#define APCI1710_SSI_READ1VALUE 1
#define APCI1710_SSI_READALLVALUE 2
#define APCI1710_SSI_SET_CHANNELON 0
#define APCI1710_SSI_SET_CHANNELOFF 1
#define APCI1710_SSI_READ_1CHANNEL 2
#define APCI1710_SSI_READ_ALLCHANNEL 3
/*
+----------------------------------------------------------------------------+
| Function Name : _INT_ i_APCI1710_InitSSI |
| (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
| unsigned char_ b_SSIProfile, |
| unsigned char_ b_PositionTurnLength, |
| unsigned char_ b_TurnCptLength, |
| unsigned char_ b_PCIInputClock, |
| ULONG_ ul_SSIOutputClock, |
| unsigned char_ b_SSICountingMode) |
+----------------------------------------------------------------------------+
| Task : Configure the SSI operating mode from selected module |
| (b_ModulNbr). You must calling this function be for you|
| call any other function witch access of SSI. |
+----------------------------------------------------------------------------+
| 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_SSIProfile : Selection from SSI |
| profile length (2 to 32).|
| unsigned char_ b_PositionTurnLength : Selection from SSI |
| position data length |
| (1 to 31). |
| unsigned char_ b_TurnCptLength : Selection from SSI turn |
| counter data length |
| (1 to 31). |
| unsigned char b_PCIInputClock : Selection from PCI bus |
| clock |
| - APCI1710_30MHZ : |
| The PC have a PCI bus |
| clock from 30 MHz |
| - APCI1710_33MHZ : |
| The PC have a PCI bus |
| clock from 33 MHz |
| ULONG_ ul_SSIOutputClock : Selection from SSI output|
| clock. |
| From 229 to 5 000 000 Hz|
| for 30 MHz selection. |
| From 252 to 5 000 000 Hz|
| for 33 MHz selection. |
| unsigned char b_SSICountingMode : SSI counting mode |
| selection |
| - APCI1710_BINARY_MODE : |
| Binary counting mode. |
| - APCI1710_GRAY_MODE : |
| Gray counting mode.
b_ModulNbr = CR_AREF(insn->chanspec);
b_SSIProfile = (unsigned char) data[0];
b_PositionTurnLength= (unsigned char) data[1];
b_TurnCptLength = (unsigned char) data[2];
b_PCIInputClock = (unsigned char) data[3];
ul_SSIOutputClock = (unsigned int) data[4];
b_SSICountingMode = (unsigned char) data[5]; |
+----------------------------------------------------------------------------+
| Output Parameters : - |
+----------------------------------------------------------------------------+
| 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 SSI module |
| -4: The selected SSI profile length is wrong |
| -5: The selected SSI position data length is wrong |
| -6: The selected SSI turn counter data length is wrong |
| -7: The selected PCI input clock is wrong |
| -8: The selected SSI output clock is wrong |
| -9: The selected SSI counting mode parameter is wrong |
+----------------------------------------------------------------------------+
*/
static int i_APCI1710_InsnConfigInitSSI(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int ui_TimerValue;
unsigned char b_ModulNbr, b_SSIProfile, b_PositionTurnLength, b_TurnCptLength,
b_PCIInputClock, b_SSICountingMode;
unsigned int ul_SSIOutputClock;
b_ModulNbr = CR_AREF(insn->chanspec);
b_SSIProfile = (unsigned char) data[0];
b_PositionTurnLength = (unsigned char) data[1];
b_TurnCptLength = (unsigned char) data[2];
b_PCIInputClock = (unsigned char) data[3];
ul_SSIOutputClock = (unsigned int) data[4];
b_SSICountingMode = (unsigned char) data[5];
i_ReturnValue = insn->n;
/**************************/
/* Test the module number */
/**************************/
if (b_ModulNbr < 4) {
/***********************/
/* Test if SSI counter */
/***********************/
if ((devpriv->s_BoardInfos.
dw_MolduleConfiguration[b_ModulNbr] &
0xFFFF0000UL) == APCI1710_SSI_COUNTER) {
/*******************************/
/* Test the SSI profile length */
/*******************************/
/* CG 22/03/00 b_SSIProfile >= 2 anstatt b_SSIProfile > 2 */
if (b_SSIProfile >= 2 && b_SSIProfile < 33) {
/*************************************/
/* Test the SSI position data length */
/*************************************/
if (b_PositionTurnLength > 0
&& b_PositionTurnLength < 32) {
/*****************************************/
/* Test the SSI turn counter data length */
/*****************************************/
if (b_TurnCptLength > 0
&& b_TurnCptLength < 32) {
/***************************/
/* Test the profile length */
/***************************/
if ((b_TurnCptLength +
b_PositionTurnLength)
<= b_SSIProfile) {
/****************************/
/* Test the PCI input clock */
/****************************/
if (b_PCIInputClock ==
APCI1710_30MHZ
||
b_PCIInputClock
==
APCI1710_33MHZ)
{
/*************************/
/* Test the output clock */
/*************************/
if ((b_PCIInputClock == APCI1710_30MHZ && (ul_SSIOutputClock > 228 && ul_SSIOutputClock <= 5000000UL)) || (b_PCIInputClock == APCI1710_33MHZ && (ul_SSIOutputClock > 251 && ul_SSIOutputClock <= 5000000UL))) {
if (b_SSICountingMode == APCI1710_BINARY_MODE || b_SSICountingMode == APCI1710_GRAY_MODE) {
/**********************/
/* Save configuration */
/**********************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_SSICounterInfo.
b_SSIProfile
=
b_SSIProfile;
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_SSICounterInfo.
b_PositionTurnLength
=
b_PositionTurnLength;
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_SSICounterInfo.
b_TurnCptLength
=
b_TurnCptLength;
/*********************************/
/* Initialise the profile length */
/*********************************/
if (b_SSICountingMode == APCI1710_BINARY_MODE) {
outl(b_SSIProfile + 1, devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr));
} else {
outl(b_SSIProfile, devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr));
}
/******************************/
/* Calculate the output clock */
/******************************/
ui_TimerValue
=
(unsigned int)
(
((unsigned int) (b_PCIInputClock) * 500000UL) / ul_SSIOutputClock);
/************************/
/* Initialise the timer */
/************************/
outl(ui_TimerValue, devpriv->s_BoardInfos.ui_Address + (64 * b_ModulNbr));
/********************************/
/* Initialise the counting mode */
/********************************/
outl(7 * b_SSICountingMode, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr));
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_SSICounterInfo.
b_SSIInit
=
1;
} else {
/*****************************************************/
/* The selected SSI counting mode parameter is wrong */
/*****************************************************/
DPRINTK("The selected SSI counting mode parameter is wrong\n");
i_ReturnValue
=
-9;
}
} else {
/******************************************/
/* The selected SSI output clock is wrong */
/******************************************/
DPRINTK("The selected SSI output clock is wrong\n");
i_ReturnValue
=
-8;
}
} else {
/*****************************************/
/* The selected PCI input clock is wrong */
/*****************************************/
DPRINTK("The selected PCI input clock is wrong\n");
i_ReturnValue =
-7;
}
} else {
/********************************************/
/* The selected SSI profile length is wrong */
/********************************************/
DPRINTK("The selected SSI profile length is wrong\n");
i_ReturnValue = -4;
}
} else {
/******************************************************/
/* The selected SSI turn counter data length is wrong */
/******************************************************/
DPRINTK("The selected SSI turn counter data length is wrong\n");
i_ReturnValue = -6;
}
} else {
/**************************************************/
/* The selected SSI position data length is wrong */
/**************************************************/
DPRINTK("The selected SSI position data length is wrong\n");
i_ReturnValue = -5;
}
} else {
/********************************************/
/* The selected SSI profile length is wrong */
/********************************************/
DPRINTK("The selected SSI profile length is wrong\n");
i_ReturnValue = -4;
}
} else {
/**********************************/
/* The module is not a SSI module */
/**********************************/
DPRINTK("The module is not a SSI 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_Read1SSIValue |
| (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
| unsigned char_ b_SelectedSSI, |
| PULONG_ pul_Position, |
| PULONG_ pul_TurnCpt)
int i_APCI1710_ReadSSIValue(struct comedi_device *dev,struct comedi_subdevice *s,
struct comedi_insn *insn,unsigned int *data) |
+----------------------------------------------------------------------------+
| Task :
Read the selected SSI counter (b_SelectedSSI) from |
| selected module (b_ModulNbr).
or Read all SSI counter (b_SelectedSSI) from |
| selected module (b_ModulNbr). |
+----------------------------------------------------------------------------+
| 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_SelectedSSI : Selection from SSI |
| counter (0 to 2)
b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
b_SelectedSSI = (unsigned char) CR_CHAN(insn->chanspec); (in case of single ssi)
b_ReadType = (unsigned char) CR_RANGE(insn->chanspec);
|
+----------------------------------------------------------------------------+
| Output Parameters : PULONG_ pul_Position : SSI position in the turn |
| PULONG_ pul_TurnCpt : Number of turns
pul_Position = (unsigned int *) &data[0];
pul_TurnCpt = (unsigned int *) &data[1]; |
+----------------------------------------------------------------------------+
| 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 SSI module |
| -4: SSI not initialised see function |
| "i_APCI1710_InitSSI" |
| -5: The selected SSI is wrong |
+----------------------------------------------------------------------------+
*/
static int i_APCI1710_InsnReadSSIValue(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned char b_Cpt;
unsigned char b_Length;
unsigned char b_Schift;
unsigned char b_SSICpt;
unsigned int dw_And;
unsigned int dw_And1;
unsigned int dw_And2;
unsigned int dw_StatusReg;
unsigned int dw_CounterValue;
unsigned char b_ModulNbr;
unsigned char b_SelectedSSI;
unsigned char b_ReadType;
unsigned int *pul_Position;
unsigned int *pul_TurnCpt;
unsigned int *pul_Position1;
unsigned int *pul_TurnCpt1;
i_ReturnValue = insn->n;
pul_Position1 = (unsigned int *) &data[0];
/* For Read1 */
pul_TurnCpt1 = (unsigned int *) &data[1];
/* For Read all */
pul_Position = (unsigned int *) &data[0]; /* 0-2 */
pul_TurnCpt = (unsigned int *) &data[3]; /* 3-5 */
b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
b_SelectedSSI = (unsigned char) CR_CHAN(insn->chanspec);
b_ReadType = (unsigned char) CR_RANGE(insn->chanspec);
/**************************/
/* Test the module number */
/**************************/
if (b_ModulNbr < 4) {
/***********************/
/* Test if SSI counter */
/***********************/
if ((devpriv->s_BoardInfos.
dw_MolduleConfiguration[b_ModulNbr] &
0xFFFF0000UL) == APCI1710_SSI_COUNTER) {
/***************************/
/* Test if SSI initialised */
/***************************/
if (devpriv->s_ModuleInfo[b_ModulNbr].
s_SSICounterInfo.b_SSIInit == 1) {
switch (b_ReadType) {
case APCI1710_SSI_READ1VALUE:
/****************************************/
/* Test the selected SSI counter number */
/****************************************/
if (b_SelectedSSI < 3) {
/************************/
/* Start the conversion */
/************************/
outl(0, devpriv->s_BoardInfos.
ui_Address + 8 +
(64 * b_ModulNbr));
do {
/*******************/
/* Read the status */
/*******************/
dw_StatusReg =
inl(devpriv->
s_BoardInfos.
ui_Address +
(64 * b_ModulNbr));
} while ((dw_StatusReg & 0x1)
!= 0);
/******************************/
/* Read the SSI counter value */
/******************************/
dw_CounterValue =
inl(devpriv->
s_BoardInfos.
ui_Address + 4 +
(b_SelectedSSI * 4) +
(64 * b_ModulNbr));
b_Length =
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_SSICounterInfo.
b_SSIProfile / 2;
if ((b_Length * 2) !=
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_SSICounterInfo.
b_SSIProfile) {
b_Length++;
}
b_Schift =
b_Length -
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_SSICounterInfo.
b_PositionTurnLength;
*pul_Position1 =
dw_CounterValue >>
b_Schift;
dw_And = 1;
for (b_Cpt = 0;
b_Cpt <
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_SSICounterInfo.
b_PositionTurnLength;
b_Cpt++) {
dw_And = dw_And * 2;
}
*pul_Position1 =
*pul_Position1 &
((dw_And) - 1);
*pul_TurnCpt1 =
dw_CounterValue >>
b_Length;
dw_And = 1;
for (b_Cpt = 0;
b_Cpt <
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_SSICounterInfo.
b_TurnCptLength;
b_Cpt++) {
dw_And = dw_And * 2;
}
*pul_TurnCpt1 =
*pul_TurnCpt1 &
((dw_And) - 1);
} else {
/*****************************/
/* The selected SSI is wrong */
/*****************************/
DPRINTK("The selected SSI is wrong\n");
i_ReturnValue = -5;
}
break;
case APCI1710_SSI_READALLVALUE:
dw_And1 = 1;
for (b_Cpt = 0;
b_Cpt <
devpriv->
s_ModuleInfo[b_ModulNbr].
s_SSICounterInfo.
b_PositionTurnLength; b_Cpt++) {
dw_And1 = dw_And1 * 2;
}
dw_And2 = 1;
for (b_Cpt = 0;
b_Cpt <
devpriv->
s_ModuleInfo[b_ModulNbr].
s_SSICounterInfo.
b_TurnCptLength; b_Cpt++) {
dw_And2 = dw_And2 * 2;
}
/************************/
/* Start the conversion */
/************************/
outl(0, devpriv->s_BoardInfos.
ui_Address + 8 +
(64 * b_ModulNbr));
do {
/*******************/
/* Read the status */
/*******************/
dw_StatusReg =
inl(devpriv->
s_BoardInfos.
ui_Address +
(64 * b_ModulNbr));
} while ((dw_StatusReg & 0x1) != 0);
for (b_SSICpt = 0; b_SSICpt < 3;
b_SSICpt++) {
/******************************/
/* Read the SSI counter value */
/******************************/
dw_CounterValue =
inl(devpriv->
s_BoardInfos.
ui_Address + 4 +
(b_SSICpt * 4) +
(64 * b_ModulNbr));
b_Length =
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_SSICounterInfo.
b_SSIProfile / 2;
if ((b_Length * 2) !=
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_SSICounterInfo.
b_SSIProfile) {
b_Length++;
}
b_Schift =
b_Length -
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_SSICounterInfo.
b_PositionTurnLength;
pul_Position[b_SSICpt] =
dw_CounterValue >>
b_Schift;
pul_Position[b_SSICpt] =
pul_Position[b_SSICpt] &
((dw_And1) - 1);
pul_TurnCpt[b_SSICpt] =
dw_CounterValue >>
b_Length;
pul_TurnCpt[b_SSICpt] =
pul_TurnCpt[b_SSICpt] &
((dw_And2) - 1);
}
break;
default:
printk("Read Type Inputs Wrong\n");
} /* switch ending */
} else {
/***********************/
/* SSI not initialised */
/***********************/
DPRINTK("SSI not initialised\n");
i_ReturnValue = -4;
}
} else {
/**********************************/
/* The module is not a SSI module */
/**********************************/
DPRINTK("The module is not a SSI 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_ReadSSI1DigitalInput |
| (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
| unsigned char_ b_InputChannel, |
| unsigned char *_ pb_ChannelStatus) |
+----------------------------------------------------------------------------+
| Task :
(0) Set the digital output from selected SSI module |
| (b_ModuleNbr) ON
(1) Set the digital output from selected SSI module |
| (b_ModuleNbr) OFF
(2)Read the status from selected SSI digital input |
| (b_InputChannel)
(3)Read the status from all SSI digital inputs from |
| selected SSI module (b_ModulNbr) |
+----------------------------------------------------------------------------+
| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710|
| unsigned char_ b_ModulNbr CR_AREF : Module number to |
| configure (0 to 3) |
| unsigned char_ b_InputChannel CR_CHAN : Selection from digital |
| data[0] which IOTYPE input ( 0 to 2) |
+----------------------------------------------------------------------------+
| Output Parameters : unsigned char *_ pb_ChannelStatus : Digital input channel |
| data[0] status |
| 0 : Channle is not active|
| 1 : Channle is active |
+----------------------------------------------------------------------------+
| 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 SSI module |
| -4: The selected SSI digital input is wrong |
+----------------------------------------------------------------------------+
*/
static int i_APCI1710_InsnBitsSSIDigitalIO(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_StatusReg;
unsigned char b_ModulNbr;
unsigned char b_InputChannel;
unsigned char *pb_ChannelStatus;
unsigned char *pb_InputStatus;
unsigned char b_IOType;
i_ReturnValue = insn->n;
b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
b_IOType = (unsigned char) data[0];
/**************************/
/* Test the module number */
/**************************/
if (b_ModulNbr < 4) {
/***********************/
/* Test if SSI counter */
/***********************/
if ((devpriv->s_BoardInfos.
dw_MolduleConfiguration[b_ModulNbr] &
0xFFFF0000UL) == APCI1710_SSI_COUNTER) {
switch (b_IOType) {
case APCI1710_SSI_SET_CHANNELON:
/*****************************/
/* Set the digital output ON */
/*****************************/
outl(1, devpriv->s_BoardInfos.ui_Address + 16 +
(64 * b_ModulNbr));
break;
case APCI1710_SSI_SET_CHANNELOFF:
/******************************/
/* Set the digital output OFF */
/******************************/
outl(0, devpriv->s_BoardInfos.ui_Address + 16 +
(64 * b_ModulNbr));
break;
case APCI1710_SSI_READ_1CHANNEL:
/******************************************/
/* Test the digital imnput channel number */
/******************************************/
b_InputChannel = (unsigned char) CR_CHAN(insn->chanspec);
pb_ChannelStatus = (unsigned char *) &data[0];
if (b_InputChannel <= 2) {
/**************************/
/* Read all digital input */
/**************************/
dw_StatusReg =
inl(devpriv->s_BoardInfos.
ui_Address + (64 * b_ModulNbr));
*pb_ChannelStatus =
(unsigned char) (((~dw_StatusReg) >> (4 +
b_InputChannel))
& 1);
} else {
/********************************/
/* Selected digital input error */
/********************************/
DPRINTK("Selected digital input error\n");
i_ReturnValue = -4;
}
break;
case APCI1710_SSI_READ_ALLCHANNEL:
/**************************/
/* Read all digital input */
/**************************/
pb_InputStatus = (unsigned char *) &data[0];
dw_StatusReg =
inl(devpriv->s_BoardInfos.ui_Address +
(64 * b_ModulNbr));
*pb_InputStatus =
(unsigned char) (((~dw_StatusReg) >> 4) & 7);
break;
default:
printk("IO type wrong\n");
} /* switch end */
} else {
/**********************************/
/* The module is not a SSI module */
/**********************************/
DPRINTK("The module is not a SSI module\n");
i_ReturnValue = -3;
}
} else {
/***********************/
/* Module number error */
/***********************/
DPRINTK("Module number error\n");
i_ReturnValue = -2;
}
return i_ReturnValue;
}
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data.com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
@endverbatim
*/
/*
+-----------------------------------------------------------------------+
| (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+-----------------------------------------------------------------------+
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+-----------------------------------------------------------------------+
| Project : API APCI1710 | Compiler : gcc |
| Module name : TOR.C | Version : 2.96 |
+-------------------------------+---------------------------------------+
| Project manager: Eric Stolz | Date : 02/12/2002 |
+-----------------------------------------------------------------------+
| Description : APCI-1710 tor counter module |
| |
| |
+-----------------------------------------------------------------------+
| UPDATES |
+-----------------------------------------------------------------------+
| Date | Author | Description of updates |
+----------+-----------+------------------------------------------------+
| 27/01/99 | S. Weber | 40 MHz implementation |
+-----------------------------------------------------------------------+
| 28/04/00 | S. Weber | Simple,double and quadruple mode implementation|
| | | Extern clock implementation |
+-----------------------------------------------------------------------+
| 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
| | | available |
+-----------------------------------------------------------------------+
*/
#define APCI1710_30MHZ 30
#define APCI1710_33MHZ 33
#define APCI1710_40MHZ 40
#define APCI1710_GATE_INPUT 10
#define APCI1710_TOR_SIMPLE_MODE 2
#define APCI1710_TOR_DOUBLE_MODE 3
#define APCI1710_TOR_QUADRUPLE_MODE 4
#define APCI1710_SINGLE 0
#define APCI1710_CONTINUOUS 1
#define APCI1710_TOR_GETPROGRESSSTATUS 0
#define APCI1710_TOR_GETCOUNTERVALUE 1
#define APCI1710_TOR_READINTERRUPT 2
/*
+----------------------------------------------------------------------------+
| Function Name : _INT_ i_APCI1710_InitTorCounter |
| (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
| unsigned char_ b_TorCounter, |
| unsigned char_ b_PCIInputClock, |
| unsigned char_ b_TimingUnit, |
| ULONG_ ul_TimingInterval, |
| PULONG_ pul_RealTimingInterval) |
+----------------------------------------------------------------------------+
| Task : Configure the selected tor counter (b_TorCounter) |
| from selected module (b_ModulNbr). |
| The ul_TimingInterval and ul_TimingUnit determine the |
| timing base for the measurement. |
| The pul_RealTimingInterval return the real timing |
| value. You must calling this function be for you call |
| any other function witch access of the tor counter. |
| |
+----------------------------------------------------------------------------+
| Input Parameters : |
|
CR_AREF unsigned char_ b_ModulNbr : Module number to configure |
| (0 to 3) |
| data[0] unsigned char_ b_TorCounter : Tor counter selection |
| (0 or 1). |
| data[1] unsigned char_ b_PCIInputClock : Selection from PCI bus clock|
| - APCI1710_30MHZ : |
| The PC have a PCI bus |
| clock from 30 MHz |
| - APCI1710_33MHZ : |
| The PC have a PCI bus |
| clock from 33 MHz |
| - APCI1710_40MHZ |
| The APCI-1710 have a |
| integrated 40Mhz |
| quartz. |
| - APCI1710_GATE_INPUT |
| Used the gate input for |
| the base clock. If you |
| have selected this option,|
| than it is not possibl to |
| used the gate input for |
| enabled the acquisition |
| data[2] unsigned char_ b_TimingUnit : Base timing unit (0 to 4) |
| 0 : ns |
| 1 : µs |
| 2 : ms |
| 3 : s |
| 4 : mn |
| data[3] ULONG_ ul_TimingInterval : Base timing value. |
+----------------------------------------------------------------------------+
| Output Parameters : PULONG_ pul_RealTimingInterval : Real base timing |
| data[0] 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 tor counter module |
| -4: Tor counter selection is wrong |
| -5: The selected PCI input clock is wrong |
| -6: Timing unit selection is wrong |
| -7: Base timing selection is wrong |
| -8: You can not used the 40MHz clock selection wich |
| this board |
| -9: You can not used the 40MHz clock selection wich |
| this TOR version |
+----------------------------------------------------------------------------+
*/
static int i_APCI1710_InsnConfigInitTorCounter(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int ul_TimerValue = 0;
unsigned int dw_Command;
double d_RealTimingInterval = 0;
unsigned char b_ModulNbr;
unsigned char b_TorCounter;
unsigned char b_PCIInputClock;
unsigned char b_TimingUnit;
unsigned int ul_TimingInterval;
unsigned int ul_RealTimingInterval = 0;
i_ReturnValue = insn->n;
b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
b_TorCounter = (unsigned char) data[0];
b_PCIInputClock = (unsigned char) data[1];
b_TimingUnit = (unsigned char) data[2];
ul_TimingInterval = (unsigned int) data[3];
printk("INPUT clock %d\n", b_PCIInputClock);
/**************************/
/* Test the module number */
/**************************/
if (b_ModulNbr < 4) {
/***********************/
/* Test if tor counter */
/***********************/
if ((devpriv->s_BoardInfos.
dw_MolduleConfiguration[b_ModulNbr] &
0xFFFF0000UL) == APCI1710_TOR_COUNTER) {
/**********************************/
/* Test the tor counter selection */
/**********************************/
if (b_TorCounter <= 1) {
/**************************/
/* Test the PCI bus clock */
/**************************/
if ((b_PCIInputClock == APCI1710_30MHZ) ||
(b_PCIInputClock == APCI1710_33MHZ) ||
(b_PCIInputClock == APCI1710_40MHZ) ||
(b_PCIInputClock ==
APCI1710_GATE_INPUT)) {
/************************/
/* Test the timing unit */
/************************/
if ((b_TimingUnit <= 4)
|| (b_PCIInputClock ==
APCI1710_GATE_INPUT)) {
/**********************************/
/* Test the base timing selection */
/**********************************/
if (((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 133) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 571230650UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 571230UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 571UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 9UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 121) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 519691043UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 519691UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 520UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 8UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 100) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 429496729UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 429496UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 429UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 7UL)) || ((b_PCIInputClock == APCI1710_GATE_INPUT) && (ul_TimingInterval >= 2))) {
/**************************/
/* Test the board version */
/**************************/
if (((b_PCIInputClock == APCI1710_40MHZ) && (devpriv->s_BoardInfos.b_BoardVersion > 0)) || (b_PCIInputClock != APCI1710_40MHZ)) {
/************************/
/* Test the TOR version */
/************************/
if (((b_PCIInputClock == APCI1710_40MHZ) && ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) >= 0x3131)) || ((b_PCIInputClock == APCI1710_GATE_INPUT) && ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) >= 0x3132)) || (b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ)) {
/*********************************/
/* Test if not extern clock used */
/*********************************/
if (b_PCIInputClock != APCI1710_GATE_INPUT) {
fpu_begin
();
/****************************************/
/* Calculate the timer 0 division fator */
/****************************************/
switch (b_TimingUnit) {
/******/
/* ns */
/******/
case 0:
/******************/
/* Timer 0 factor */
/******************/
ul_TimerValue
=
(unsigned int)
(ul_TimingInterval
*
(0.00025 * b_PCIInputClock));
/*******************/
/* Round the value */
/*******************/
if ((double)((double)ul_TimingInterval * (0.00025 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
ul_TimerValue
=
ul_TimerValue
+
1;
}
/*****************************/
/* Calculate the real timing */
/*****************************/
ul_RealTimingInterval
=
(unsigned int)
(ul_TimerValue
/
(0.00025 * (double)b_PCIInputClock));
d_RealTimingInterval
=
(double)
ul_TimerValue
/
(0.00025
*
(double)
b_PCIInputClock);
if ((double)((double)ul_TimerValue / (0.00025 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
ul_RealTimingInterval
=
ul_RealTimingInterval
+
1;
}
ul_TimingInterval
=
ul_TimingInterval
-
1;
ul_TimerValue
=
ul_TimerValue
-
2;
if (b_PCIInputClock != APCI1710_40MHZ) {
ul_TimerValue
=
(unsigned int)
(
(double)
(ul_TimerValue)
*
1.007752288);
}
break;
/******/
/* æs */
/******/
case 1:
/******************/
/* Timer 0 factor */
/******************/
ul_TimerValue
=
(unsigned int)
(ul_TimingInterval
*
(0.25 * b_PCIInputClock));
/*******************/
/* Round the value */
/*******************/
if ((double)((double)ul_TimingInterval * (0.25 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
ul_TimerValue
=
ul_TimerValue
+
1;
}
/*****************************/
/* Calculate the real timing */
/*****************************/
ul_RealTimingInterval
=
(unsigned int)
(ul_TimerValue
/
(0.25 * (double)b_PCIInputClock));
d_RealTimingInterval
=
(double)
ul_TimerValue
/
(
(double)
0.25
*
(double)
b_PCIInputClock);
if ((double)((double)ul_TimerValue / (0.25 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
ul_RealTimingInterval
=
ul_RealTimingInterval
+
1;
}
ul_TimingInterval
=
ul_TimingInterval
-
1;
ul_TimerValue
=
ul_TimerValue
-
2;
if (b_PCIInputClock != APCI1710_40MHZ) {
ul_TimerValue
=
(unsigned int)
(
(double)
(ul_TimerValue)
*
1.007752288);
}
break;
/******/
/* ms */
/******/
case 2:
/******************/
/* Timer 0 factor */
/******************/
ul_TimerValue
=
ul_TimingInterval
*
(250.0
*
b_PCIInputClock);
/*******************/
/* Round the value */
/*******************/
if ((double)((double)ul_TimingInterval * (250.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
ul_TimerValue
=
ul_TimerValue
+
1;
}
/*****************************/
/* Calculate the real timing */
/*****************************/
ul_RealTimingInterval
=
(unsigned int)
(ul_TimerValue
/
(250.0 * (double)b_PCIInputClock));
d_RealTimingInterval
=
(double)
ul_TimerValue
/
(250.0
*
(double)
b_PCIInputClock);
if ((double)((double)ul_TimerValue / (250.0 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
ul_RealTimingInterval
=
ul_RealTimingInterval
+
1;
}
ul_TimingInterval
=
ul_TimingInterval
-
1;
ul_TimerValue
=
ul_TimerValue
-
2;
if (b_PCIInputClock != APCI1710_40MHZ) {
ul_TimerValue
=
(unsigned int)
(
(double)
(ul_TimerValue)
*
1.007752288);
}
break;
/*****/
/* s */
/*****/
case 3:
/******************/
/* Timer 0 factor */
/******************/
ul_TimerValue
=
(unsigned int)
(ul_TimingInterval
*
(250000.0
*
b_PCIInputClock));
/*******************/
/* Round the value */
/*******************/
if ((double)((double)ul_TimingInterval * (250000.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
ul_TimerValue
=
ul_TimerValue
+
1;
}
/*****************************/
/* Calculate the real timing */
/*****************************/
ul_RealTimingInterval
=
(unsigned int)
(ul_TimerValue
/
(250000.0
*
(double)
b_PCIInputClock));
d_RealTimingInterval
=
(double)
ul_TimerValue
/
(250000.0
*
(double)
b_PCIInputClock);
if ((double)((double)ul_TimerValue / (250000.0 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
ul_RealTimingInterval
=
ul_RealTimingInterval
+
1;
}
ul_TimingInterval
=
ul_TimingInterval
-
1;
ul_TimerValue
=
ul_TimerValue
-
2;
if (b_PCIInputClock != APCI1710_40MHZ) {
ul_TimerValue
=
(unsigned int)
(
(double)
(ul_TimerValue)
*
1.007752288);
}
break;
/******/
/* mn */
/******/
case 4:
/******************/
/* Timer 0 factor */
/******************/
ul_TimerValue
=
(unsigned int)
(
(ul_TimingInterval
*
60)
*
(250000.0
*
b_PCIInputClock));
/*******************/
/* Round the value */
/*******************/
if ((double)((double)(ul_TimingInterval * 60.0) * (250000.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
ul_TimerValue
=
ul_TimerValue
+
1;
}
/*****************************/
/* Calculate the real timing */
/*****************************/
ul_RealTimingInterval
=
(unsigned int)
(ul_TimerValue
/
(250000.0
*
(double)
b_PCIInputClock))
/
60;
d_RealTimingInterval
=
(
(double)
ul_TimerValue
/
(250000.0
*
(double)
b_PCIInputClock))
/
60.0;
if ((double)(((double)ul_TimerValue / (250000.0 * (double)b_PCIInputClock)) / 60.0) >= (double)((double)ul_RealTimingInterval + 0.5)) {
ul_RealTimingInterval
=
ul_RealTimingInterval
+
1;
}
ul_TimingInterval
=
ul_TimingInterval
-
1;
ul_TimerValue
=
ul_TimerValue
-
2;
if (b_PCIInputClock != APCI1710_40MHZ) {
ul_TimerValue
=
(unsigned int)
(
(double)
(ul_TimerValue)
*
1.007752288);
}
break;
}
fpu_end();
} /* if (b_PCIInputClock != APCI1710_GATE_INPUT) */
else {
/*************************************************************/
/* 2 Clock used for the overflow and the reload from counter */
/*************************************************************/
ul_TimerValue
=
ul_TimingInterval
-
2;
} /* if (b_PCIInputClock != APCI1710_GATE_INPUT) */
/****************************/
/* Save the PCI input clock */
/****************************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_TorCounterModuleInfo.
b_PCIInputClock
=
b_PCIInputClock;
/************************/
/* Save the timing unit */
/************************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_TorCounterModuleInfo.
s_TorCounterInfo
[b_TorCounter].
b_TimingUnit
=
b_TimingUnit;
/************************/
/* Save the base timing */
/************************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_TorCounterModuleInfo.
s_TorCounterInfo
[b_TorCounter].
d_TimingInterval
=
d_RealTimingInterval;
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_TorCounterModuleInfo.
s_TorCounterInfo
[b_TorCounter].
ul_RealTimingInterval
=
ul_RealTimingInterval;
/*******************/
/* Get the command */
/*******************/
dw_Command
=
inl
(devpriv->
s_BoardInfos.
ui_Address
+
4
+
(16 * b_TorCounter) + (64 * b_ModulNbr));
dw_Command
=
(dw_Command
>>
4)
&
0xF;
/******************/
/* Test if 40 MHz */
/******************/
if (b_PCIInputClock == APCI1710_40MHZ) {
/****************************/
/* Set the 40 MHz selection */
/****************************/
dw_Command
=
dw_Command
|
0x10;
}
/*****************************/
/* Test if extern clock used */
/*****************************/
if (b_PCIInputClock == APCI1710_GATE_INPUT) {
/****************************/
/* Set the 40 MHz selection */
/****************************/
dw_Command
=
dw_Command
|
0x20;
}
/*************************/
/* Write the new command */
/*************************/
outl(dw_Command, devpriv->s_BoardInfos.ui_Address + 4 + (16 * b_TorCounter) + (64 * b_ModulNbr));
/*******************/
/* Disable the tor */
/*******************/
outl(0, devpriv->s_BoardInfos.ui_Address + 8 + (16 * b_TorCounter) + (64 * b_ModulNbr));
/*************************/
/* Set the timer 1 value */
/*************************/
outl(ul_TimerValue, devpriv->s_BoardInfos.ui_Address + 0 + (16 * b_TorCounter) + (64 * b_ModulNbr));
/*********************/
/* Tor counter init. */
/*********************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_TorCounterModuleInfo.
s_TorCounterInfo
[b_TorCounter].
b_TorCounterInit
=
1;
} else {
/***********************************************/
/* TOR version error for 40MHz clock selection */
/***********************************************/
DPRINTK("TOR version error for 40MHz clock selection\n");
i_ReturnValue
=
-9;
}
} else {
/**************************************************************/
/* You can not used the 40MHz clock selection wich this board */
/**************************************************************/
DPRINTK("You can not used the 40MHz clock selection wich this board\n");
i_ReturnValue =
-8;
}
} else {
/**********************************/
/* Base timing selection is wrong */
/**********************************/
DPRINTK("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_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ)) */
else {
/*****************************************/
/* The selected PCI input clock is wrong */
/*****************************************/
DPRINTK("The selected PCI input clock is wrong\n");
i_ReturnValue = -5;
} /* if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ)) */
} /* if (b_TorCounterMode >= 0 && b_TorCounterMode <= 7) */
else {
/**********************************/
/* Tor Counter selection is wrong */
/**********************************/
DPRINTK("Tor Counter selection is wrong\n");
i_ReturnValue = -4;
} /* if (b_TorCounterMode >= 0 && b_TorCounterMode <= 7) */
} else {
/******************************************/
/* The module is not a tor counter module */
/******************************************/
DPRINTK("The module is not a tor counter module\n");
i_ReturnValue = -3;
}
} else {
/***********************/
/* Module number error */
/***********************/
DPRINTK("Module number error\n");
i_ReturnValue = -2;
}
data[0] = (unsigned int) ul_RealTimingInterval;
return i_ReturnValue;
}
/*
+----------------------------------------------------------------------------+
| Function Name : _INT_ i_APCI1710_EnableTorCounter |
| (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
| unsigned char_ b_TorCounter, |
| unsigned char_ b_InputMode, |
| unsigned char_ b_ExternGate, |
| unsigned char_ b_CycleMode, |
| unsigned char_ b_InterruptEnable) |
+----------------------------------------------------------------------------+
| Task : Enable the tor counter (b_TorCounter) from selected |
| module (b_ModulNbr). You must calling the |
| "i_APCI1710_InitTorCounter" function be for you call |
| this function. |
| If you enable the tor counter interrupt, the |
| tor counter generate a interrupt after the timing cycle|
| See function "i_APCI1710_SetBoardIntRoutineX" and the |
| Interrupt mask description chapter from this manual. |
| The b_CycleMode parameter determine if you will |
| measured a single or more cycle. |
+----------------------------------------------------------------------------+
| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
| unsigned char_ b_ModulNbr : Selected module number (0 to 3) |
| unsigned char_ b_TorCounter : Tor counter selection (0 or 1). |
| unsigned char_ b_InputMode : Input signal level selection |
| 0 : Tor count each low level |
| 1 : Tor count each high level|
| unsigned char_ b_ExternGate : Extern gate action selection |
| 0 : Extern gate signal not |
| used |
| 1 : Extern gate signal used. |
| If you selected the |
| single mode, each high |
| level signal start the |
| counter. |
| If you selected the |
| continuous mode, the |
| first high level signal |
| start the tor counter |
| |
| APCI1710_TOR_QUADRUPLE _MODE : |
| In the quadruple mode, the edge|
| analysis circuit generates a |
| counting pulse from each edge |
| of 2 signals which are phase |
| shifted in relation to each |
| other. |
| The gate input is used for the |
| signal B |
| |
| APCI1710_TOR_DOUBLE_MODE: |
| Functions in the same way as |
| the quadruple mode, except that|
| only two of the four edges are |
| analysed per period. |
| The gate input is used for the |
| signal B |
| |
| APCI1710_TOR_SIMPLE_MODE: |
| Functions in the same way as |
| the quadruple mode, except that|
| only one of the four edges is |
| analysed per period. |
| The gate input is used for the |
| signal B |
| |
| unsigned char_ b_CycleMode : Selected the tor counter |
| acquisition mode |
| unsigned char_ b_InterruptEnable : Enable or disable the |
| tor counter interrupt. |
| APCI1710_ENABLE: |
| Enable the tor counter |
| interrupt |
| APCI1710_DISABLE: |
| Disable the tor counter |
| 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 tor counter module |
| -4: Tor counter selection is wrong |
| -5: Tor counter not initialised see function |
| "i_APCI1710_InitTorCounter" |
| -6: Tor input signal selection is wrong |
| -7: Extern gate signal mode is wrong |
| -8: Tor counter acquisition mode cycle is wrong |
| -9: Interrupt parameter is wrong |
| -10:Interrupt function not initialised. |
| See function "i_APCI1710_SetBoardIntRoutineX" |
+----------------------------------------------------------------------------+
*/
/*
+----------------------------------------------------------------------------+
| Function Name : _INT_ i_APCI1710_DisableTorCounter |
| (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
| unsigned char_ b_TorCounter) |
+----------------------------------------------------------------------------+
| Task : Disable the tor counter (b_TorCounter) from selected |
| module (b_ModulNbr). If you disable the tor counter |
| after a start cycle occur and you restart the tor |
| counter witch the " i_APCI1710_EnableTorCounter" |
| function, the status register is cleared |
+----------------------------------------------------------------------------+
| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
| unsigned char_ b_ModulNbr : Selected module number (0 to 3) |
| unsigned char_ b_TorCounter : Tor counter selection (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 tor counter module |
| -4: Tor counter selection is wrong |
| -5: Tor counter not initialised see function |
| "i_APCI1710_InitTorCounter" |
| -6: Tor counter not enabled see function |
| "i_APCI1710_EnableTorCounter" |
+----------------------------------------------------------------------------+
*/
static int i_APCI1710_InsnWriteEnableDisableTorCounter(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_Status;
unsigned int dw_DummyRead;
unsigned int dw_ConfigReg;
unsigned char b_ModulNbr, b_Action;
unsigned char b_TorCounter;
unsigned char b_InputMode;
unsigned char b_ExternGate;
unsigned char b_CycleMode;
unsigned char b_InterruptEnable;
b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
b_Action = (unsigned char) data[0]; /* enable or disable */
b_TorCounter = (unsigned char) data[1];
b_InputMode = (unsigned char) data[2];
b_ExternGate = (unsigned char) data[3];
b_CycleMode = (unsigned char) data[4];
b_InterruptEnable = (unsigned char) data[5];
i_ReturnValue = insn->n;
devpriv->tsk_Current = current; /* Save the current process task structure */
/**************************/
/* Test the module number */
/**************************/
if (b_ModulNbr < 4) {
/***********************/
/* Test if tor counter */
/***********************/
if ((devpriv->s_BoardInfos.
dw_MolduleConfiguration[b_ModulNbr] &
0xFFFF0000UL) == APCI1710_TOR_COUNTER) {
/**********************************/
/* Test the tor counter selection */
/**********************************/
if (b_TorCounter <= 1) {
switch (b_Action) /* Enable or Disable */
{
case APCI1710_ENABLE:
/***********************************/
/* Test if tor counter initialised */
/***********************************/
dw_Status =
inl(devpriv->s_BoardInfos.
ui_Address + 8 +
(16 * b_TorCounter) +
(64 * b_ModulNbr));
if (dw_Status & 0x10) {
/******************************/
/* Test the input signal mode */
/******************************/
if (b_InputMode == 0 ||
b_InputMode == 1 ||
b_InputMode ==
APCI1710_TOR_SIMPLE_MODE
|| b_InputMode ==
APCI1710_TOR_DOUBLE_MODE
|| b_InputMode ==
APCI1710_TOR_QUADRUPLE_MODE)
{
/************************************/
/* Test the extern gate signal mode */
/************************************/
if (b_ExternGate == 0
|| b_ExternGate
== 1
|| b_InputMode >
1) {
/*********************************/
/* Test the cycle mode parameter */
/*********************************/
if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS)) {
/***************************/
/* Test the interrupt flag */
/***************************/
if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE)) {
/***************************/
/* Save the interrupt mode */
/***************************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_TorCounterModuleInfo.
s_TorCounterInfo
[b_TorCounter].
b_InterruptEnable
=
b_InterruptEnable;
/*******************/
/* Get the command */
/*******************/
dw_ConfigReg
=
inl
(devpriv->
s_BoardInfos.
ui_Address
+
4
+
(16 * b_TorCounter) + (64 * b_ModulNbr));
dw_ConfigReg
=
(dw_ConfigReg
>>
4)
&
0x30;
/********************************/
/* Test if not direct mode used */
/********************************/
if (b_InputMode > 1) {
/*******************************/
/* Extern gate can not be used */
/*******************************/
b_ExternGate
=
0;
/*******************************************/
/* Enable the extern gate for the Signal B */
/*******************************************/
dw_ConfigReg
=
dw_ConfigReg
|
0x40;
/***********************/
/* Test if simple mode */
/***********************/
if (b_InputMode == APCI1710_TOR_SIMPLE_MODE) {
/**************************/
/* Enable the sinple mode */
/**************************/
dw_ConfigReg
=
dw_ConfigReg
|
0x780;
} /* if (b_InputMode == APCI1710_TOR_SIMPLE_MODE) */
/***********************/
/* Test if double mode */
/***********************/
if (b_InputMode == APCI1710_TOR_DOUBLE_MODE) {
/**************************/
/* Enable the double mode */
/**************************/
dw_ConfigReg
=
dw_ConfigReg
|
0x180;
} /* if (b_InputMode == APCI1710_TOR_DOUBLE_MODE) */
b_InputMode
=
0;
} /* if (b_InputMode > 1) */
/*******************/
/* Set the command */
/*******************/
dw_ConfigReg
=
dw_ConfigReg
|
b_CycleMode
|
(b_InterruptEnable
*
2)
|
(b_InputMode
*
4)
|
(b_ExternGate
*
8);
/*****************************/
/* Clear the status register */
/*****************************/
dw_DummyRead
=
inl
(devpriv->
s_BoardInfos.
ui_Address
+
0
+
(16 * b_TorCounter) + (64 * b_ModulNbr));
/***************************************/
/* Clear the interrupt status register */
/***************************************/
dw_DummyRead
=
inl
(devpriv->
s_BoardInfos.
ui_Address
+
12
+
(16 * b_TorCounter) + (64 * b_ModulNbr));
/********************/
/* Set the commando */
/********************/
outl(dw_ConfigReg, devpriv->s_BoardInfos.ui_Address + 4 + (16 * b_TorCounter) + (64 * b_ModulNbr));
/****************/
/* Set the gate */
/****************/
outl(1, devpriv->s_BoardInfos.ui_Address + 8 + (16 * b_TorCounter) + (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
=
-9;
} /* if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE)) */
} /* if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS)) */
else {
/***********************************************/
/* Tor counter acquisition mode cycle is wrong */
/***********************************************/
DPRINTK("Tor counter acquisition mode cycle is wrong\n");
i_ReturnValue
=
-8;
} /* if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS)) */
} /* if (b_ExternGate >= 0 && b_ExternGate <= 1) */
else {
/***********************************/
/* Extern gate input mode is wrong */
/***********************************/
DPRINTK("Extern gate input mode is wrong\n");
i_ReturnValue =
-7;
} /* if (b_ExternGate >= 0 && b_ExternGate <= 1) */
} /* if (b_InputMode >= 0 && b_InputMode <= 1) */
else {
/***************************************/
/* Tor input signal selection is wrong */
/***************************************/
DPRINTK("Tor input signal selection is wrong\n");
i_ReturnValue = -6;
}
} else {
/*******************************/
/* Tor counter not initialised */
/*******************************/
DPRINTK("Tor counter not initialised\n");
i_ReturnValue = -5;
}
break;
case APCI1710_DISABLE:
/***********************************/
/* Test if tor counter initialised */
/***********************************/
dw_Status = inl(devpriv->s_BoardInfos.
ui_Address + 8 +
(16 * b_TorCounter) +
(64 * b_ModulNbr));
/*******************************/
/* Test if counter initialised */
/*******************************/
if (dw_Status & 0x10) {
/***************************/
/* Test if counter enabled */
/***************************/
if (dw_Status & 0x1) {
/****************************/
/* Clear the interrupt mode */
/****************************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_TorCounterModuleInfo.
s_TorCounterInfo
[b_TorCounter].
b_InterruptEnable
=
APCI1710_DISABLE;
/******************/
/* Clear the gate */
/******************/
outl(0, devpriv->
s_BoardInfos.
ui_Address + 8 +
(16 * b_TorCounter) + (64 * b_ModulNbr));
} /* if (dw_Status & 0x1) */
else {
/***************************/
/* Tor counter not enabled */
/***************************/
DPRINTK("Tor counter not enabled \n");
i_ReturnValue = -6;
} /* if (dw_Status & 0x1) */
} /* if (dw_Status & 0x10) */
else {
/*******************************/
/* Tor counter not initialised */
/*******************************/
DPRINTK("Tor counter not initialised\n");
i_ReturnValue = -5;
} /* // if (dw_Status & 0x10) */
} /* switch */
} /* if (b_TorCounter <= 1) */
else {
/**********************************/
/* Tor counter selection is wrong */
/**********************************/
DPRINTK("Tor counter selection is wrong\n");
i_ReturnValue = -4;
} /* if (b_TorCounter <= 1) */
} else {
/******************************************/
/* The module is not a tor counter module */
/******************************************/
DPRINTK("The module is not a tor counter 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_GetTorCounterInitialisation |
| (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
| unsigned char_ b_TorCounter, |
| unsigned char *_ pb_TimingUnit, |
| PULONG_ pul_TimingInterval, |
| unsigned char *_ pb_InputMode, |
| unsigned char *_ pb_ExternGate, |
| unsigned char *_ pb_CycleMode, |
| unsigned char *_ pb_Enable, |
| unsigned char *_ pb_InterruptEnable)|
+----------------------------------------------------------------------------+
| Task : Enable the tor counter (b_TorCounter) from selected |
| module (b_ModulNbr). You must calling the |
| "i_APCI1710_InitTorCounter" function be for you call |
| this function. |
| If you enable the tor counter interrupt, the |
| tor counter generate a interrupt after the timing cycle|
| See function "i_APCI1710_SetBoardIntRoutineX" and the |
| Interrupt mask description chapter from this manual. |
| The b_CycleMode parameter determine if you will |
| measured a single or more cycle. |
+----------------------------------------------------------------------------+
| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
| unsigned char_ b_ModulNbr : Selected module number (0 to 3) |
| unsigned char_ b_TorCounter : Tor counter selection (0 or 1)
b_ModulNbr = CR_AREF(insn->chanspec);
b_TorCounter = CR_CHAN(insn->chanspec);
. |
+----------------------------------------------------------------------------+
| Output Parameters : unsigned char *_ pb_TimingUnit : Base timing unit (0 to 4) |
| 0 : ns |
| 1 : µs |
| 2 : ms |
| 3 : s |
| 4 : mn |
| PULONG_ pul_TimingInterval : Base timing value. |
| unsigned char *_ pb_InputMode : Input signal level |
| selection |
| 0 : Tor count each low level |
| 1 : Tor count each high level|
| unsigned char *_ pb_ExternGate : Extern gate action |
| selection |
| 0 : Extern gate signal not |
| used |
| 1 : Extern gate signal used|
| unsigned char *_ pb_CycleMode : Tor counter acquisition |
| mode |
| unsigned char *_ pb_Enable : Indicate if the tor counter|
| is enabled or no |
| 0 : Tor counter disabled |
| 1 : Tor counter enabled |
| unsigned char *_ pb_InterruptEnable : Enable or disable the |
| tor counter interrupt. |
| APCI1710_ENABLE: |
| Enable the tor counter |
| interrupt |
| APCI1710_DISABLE: |
| Disable the tor counter |
| interrupt
pb_TimingUnit = (unsigned char *) &data[0];
pul_TimingInterval = (unsigned int *) &data[1];
pb_InputMode = (unsigned char *) &data[2];
pb_ExternGate = (unsigned char *) &data[3];
pb_CycleMode = (unsigned char *) &data[4];
pb_Enable = (unsigned char *) &data[5];
pb_InterruptEnable = (unsigned char *) &data[6];
|
+----------------------------------------------------------------------------+
| Return Value : 0: No error |
| -1: The handle parameter of the board is wrong |
| -2: Module selection wrong |
| -3: The module is not a tor counter module |
| -4: Tor counter selection is wrong |
| -5: Tor counter not initialised see function |
| "i_APCI1710_InitTorCounter" |
+----------------------------------------------------------------------------+
*/
static int i_APCI1710_InsnReadGetTorCounterInitialisation(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_Status;
unsigned char b_ModulNbr;
unsigned char b_TorCounter;
unsigned char *pb_TimingUnit;
unsigned int *pul_TimingInterval;
unsigned char *pb_InputMode;
unsigned char *pb_ExternGate;
unsigned char *pb_CycleMode;
unsigned char *pb_Enable;
unsigned char *pb_InterruptEnable;
i_ReturnValue = insn->n;
b_ModulNbr = CR_AREF(insn->chanspec);
b_TorCounter = CR_CHAN(insn->chanspec);
pb_TimingUnit = (unsigned char *) &data[0];
pul_TimingInterval = (unsigned int *) &data[1];
pb_InputMode = (unsigned char *) &data[2];
pb_ExternGate = (unsigned char *) &data[3];
pb_CycleMode = (unsigned char *) &data[4];
pb_Enable = (unsigned char *) &data[5];
pb_InterruptEnable = (unsigned char *) &data[6];
/**************************/
/* Test the module number */
/**************************/
if (b_ModulNbr < 4) {
/***********************/
/* Test if tor counter */
/***********************/
if ((devpriv->s_BoardInfos.
dw_MolduleConfiguration[b_ModulNbr] &
0xFFFF0000UL) == APCI1710_TOR_COUNTER) {
/**********************************/
/* Test the tor counter selection */
/**********************************/
if (b_TorCounter <= 1) {
/***********************************/
/* Test if tor counter initialised */
/***********************************/
dw_Status = inl(devpriv->s_BoardInfos.
ui_Address + 8 + (16 * b_TorCounter) +
(64 * b_ModulNbr));
if (dw_Status & 0x10) {
*pb_Enable = dw_Status & 1;
/********************/
/* Get the commando */
/********************/
dw_Status = inl(devpriv->s_BoardInfos.
ui_Address + 4 +
(16 * b_TorCounter) +
(64 * b_ModulNbr));
*pb_CycleMode =
(unsigned char) ((dw_Status >> 4) & 1);
*pb_InterruptEnable =
(unsigned char) ((dw_Status >> 5) & 1);
/******************************************************/
/* Test if extern gate used for clock or for signal B */
/******************************************************/
if (dw_Status & 0x600) {
/*****************************************/
/* Test if extern gate used for signal B */
/*****************************************/
if (dw_Status & 0x400) {
/***********************/
/* Test if simple mode */
/***********************/
if ((dw_Status & 0x7800)
== 0x7800) {
*pb_InputMode =
APCI1710_TOR_SIMPLE_MODE;
}
/***********************/
/* Test if double mode */
/***********************/
if ((dw_Status & 0x7800)
== 0x1800) {
*pb_InputMode =
APCI1710_TOR_DOUBLE_MODE;
}
/**************************/
/* Test if quadruple mode */
/**************************/
if ((dw_Status & 0x7800)
== 0x0000) {
*pb_InputMode =
APCI1710_TOR_QUADRUPLE_MODE;
}
} /* if (dw_Status & 0x400) */
else {
*pb_InputMode = 1;
} /* // if (dw_Status & 0x400) */
/************************/
/* Extern gate not used */
/************************/
*pb_ExternGate = 0;
} /* if (dw_Status & 0x600) */
else {
*pb_InputMode =
(unsigned char) ((dw_Status >> 6)
& 1);
*pb_ExternGate =
(unsigned char) ((dw_Status >> 7)
& 1);
} /* if (dw_Status & 0x600) */
*pb_TimingUnit =
devpriv->
s_ModuleInfo[b_ModulNbr].
s_TorCounterModuleInfo.
s_TorCounterInfo[b_TorCounter].
b_TimingUnit;
*pul_TimingInterval =
devpriv->
s_ModuleInfo[b_ModulNbr].
s_TorCounterModuleInfo.
s_TorCounterInfo[b_TorCounter].
ul_RealTimingInterval;
} else {
/*******************************/
/* Tor counter not initialised */
/*******************************/
DPRINTK("Tor counter not initialised\n");
i_ReturnValue = -5;
}
} /* if (b_TorCounter <= 1) */
else {
/**********************************/
/* Tor counter selection is wrong */
/**********************************/
DPRINTK("Tor counter selection is wrong \n");
i_ReturnValue = -4;
} /* if (b_TorCounter <= 1) */
} else {
/******************************************/
/* The module is not a tor counter module */
/******************************************/
DPRINTK("The module is not a tor counter 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_ReadTorCounterValue |
| (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
| unsigned char_ b_TorCounter, |
| unsigned int_ ui_TimeOut, |
| unsigned char *_ pb_TorCounterStatus, |
| PULONG_ pul_TorCounterValue) |
+----------------------------------------------------------------------------+
| Task case APCI1710_TOR_GETPROGRESSSTATUS: Return the tor counter
(b_TorCounter) status (pb_TorCounterStatus) from selected tor counter |
| module (b_ModulNbr).
case APCI1710_TOR_GETCOUNTERVALUE :
Return the tor counter (b_TorCounter) status |
| (pb_TorCounterStatus) and the timing value |
| (pul_TorCounterValue) after a conting cycle stop |
| from selected tor counter 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_TorCounter : Tor counter selection (0 or 1).
b_ModulNbr = CR_AREF(insn->chanspec);
b_ReadType = (unsigned char) data[0];
b_TorCounter = (unsigned char) data[1];
ui_TimeOut = (unsigned int) data[2]; |
+----------------------------------------------------------------------------+
| Output Parameters : unsigned char *_ pb_TorCounterStatus : Return the tor counter |
| status. |
| 0 : Conting cycle not started|
| Software gate not set. |
| 1 : Conting cycle started. |
| Software gate set. |
| 2 : Conting cycle stopped. |
| The conting cycle is |
| terminate. |
| 3 : A overflow occur. You |
| must change the base |
| timing witch the |
| function |
| "i_APCI1710_InitTorCounter"|
| 4 : Timeeout occur |
| unsigned int * pul_TorCounterValue : Tor counter value.
pb_TorCounterStatus=(unsigned char *) &data[0];
pul_TorCounterValue=(unsigned int *) &data[1]; |
+----------------------------------------------------------------------------+
| Return Value : 0: No error |
| -1: The handle parameter of the board is wrong |
| -2: Module selection wrong |
| -3: The module is not a tor counter module |
| -4: Tor counter selection is wrong |
| -5: Tor counter not initialised see function |
| "i_APCI1710_InitTorCounter" |
| -6: Tor counter not enabled see function |
| "i_APCI1710_EnableTorCounter" |
| -7: Timeout parameter is wrong (0 to 65535) |
+----------------------------------------------------------------------------+
*/
static int i_APCI1710_InsnBitsGetTorCounterProgressStatusAndValue(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_Status;
unsigned int dw_TimeOut = 0;
unsigned char b_ModulNbr;
unsigned char b_TorCounter;
unsigned char b_ReadType;
unsigned int ui_TimeOut;
unsigned char *pb_TorCounterStatus;
unsigned int *pul_TorCounterValue;
i_ReturnValue = insn->n;
b_ModulNbr = CR_AREF(insn->chanspec);
b_ReadType = (unsigned char) data[0];
b_TorCounter = (unsigned char) data[1];
ui_TimeOut = (unsigned int) data[2];
pb_TorCounterStatus = (unsigned char *) &data[0];
pul_TorCounterValue = (unsigned int *) &data[1];
/**************************/
/* Test the module number */
/**************************/
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;
}
if (b_ModulNbr < 4) {
/***********************/
/* Test if tor counter */
/***********************/
if ((devpriv->s_BoardInfos.
dw_MolduleConfiguration[b_ModulNbr] &
0xFFFF0000UL) == APCI1710_TOR_COUNTER) {
/**********************************/
/* Test the tor counter selection */
/**********************************/
if (b_TorCounter <= 1) {
/***********************************/
/* Test if tor counter initialised */
/***********************************/
dw_Status = inl(devpriv->s_BoardInfos.
ui_Address + 8 + (16 * b_TorCounter) +
(64 * b_ModulNbr));
/*******************************/
/* Test if counter initialised */
/*******************************/
if (dw_Status & 0x10) {
/***************************/
/* Test if counter enabled */
/***************************/
if (dw_Status & 0x1) {
switch (b_ReadType) {
case APCI1710_TOR_GETPROGRESSSTATUS:
/*******************/
/* Read the status */
/*******************/
dw_Status =
inl(devpriv->
s_BoardInfos.
ui_Address + 4 +
(16 * b_TorCounter) + (64 * b_ModulNbr));
dw_Status =
dw_Status & 0xF;
/*****************/
/* Test if start */
/*****************/
if (dw_Status & 1) {
if (dw_Status &
2) {
if (dw_Status & 4) {
/************************/
/* Tor counter overflow */
/************************/
*pb_TorCounterStatus
=
3;
} else {
/***********************/
/* Tor counter started */
/***********************/
*pb_TorCounterStatus
=
2;
}
} else {
/***********************/
/* Tor counter started */
/***********************/
*pb_TorCounterStatus
=
1;
}
} else {
/***************************/
/* Tor counter not started */
/***************************/
*pb_TorCounterStatus
= 0;
}
break;
case APCI1710_TOR_GETCOUNTERVALUE:
/*****************************/
/* Test the timout parameter */
/*****************************/
if ((ui_TimeOut >= 0)
&& (ui_TimeOut
<=
65535UL))
{
for (;;) {
/*******************/
/* Read the status */
/*******************/
dw_Status
=
inl
(devpriv->
s_BoardInfos.
ui_Address
+
4
+
(16 * b_TorCounter) + (64 * b_ModulNbr));
/********************/
/* Test if overflow */
/********************/
if ((dw_Status & 4) == 4) {
/******************/
/* Overflow occur */
/******************/
*pb_TorCounterStatus
=
3;
/******************/
/* Read the value */
/******************/
*pul_TorCounterValue
=
inl
(devpriv->
s_BoardInfos.
ui_Address
+
0
+
(16 * b_TorCounter) + (64 * b_ModulNbr));
break;
} /* if ((dw_Status & 4) == 4) */
else {
/*******************************/
/* Test if measurement stopped */
/*******************************/
if ((dw_Status & 2) == 2) {
/***********************/
/* A stop signal occur */
/***********************/
*pb_TorCounterStatus
=
2;
/******************/
/* Read the value */
/******************/
*pul_TorCounterValue
=
inl
(devpriv->
s_BoardInfos.
ui_Address
+
0
+
(16 * b_TorCounter) + (64 * b_ModulNbr));
break;
} /* if ((dw_Status & 2) == 2) */
else {
/*******************************/
/* Test if measurement started */
/*******************************/
if ((dw_Status & 1) == 1) {
/************************/
/* A start signal occur */
/************************/
*pb_TorCounterStatus
=
1;
} /* if ((dw_Status & 1) == 1) */
else {
/***************************/
/* Measurement not started */
/***************************/
*pb_TorCounterStatus
=
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 timeout occur */
/*************************/
if ((*pb_TorCounterStatus != 3) && (dw_TimeOut == ui_TimeOut) && (ui_TimeOut != 0)) {
/*****************/
/* Timeout occur */
/*****************/
*pb_TorCounterStatus
=
4;
}
} else {
/******************************/
/* Timeout parameter is wrong */
/******************************/
DPRINTK("Timeout parameter is wrong\n");
i_ReturnValue =
-7;
}
break;
default:
printk("Inputs wrong\n");
} /* switch end */
} /* if (dw_Status & 0x1) */
else {
/***************************/
/* Tor counter not enabled */
/***************************/
DPRINTK("Tor counter not enabled\n");
i_ReturnValue = -6;
} /* if (dw_Status & 0x1) */
} else {
/*******************************/
/* Tor counter not initialised */
/*******************************/
DPRINTK("Tor counter not initialised\n");
i_ReturnValue = -5;
}
} /* if (b_TorCounter <= 1) */
else {
/**********************************/
/* Tor counter selection is wrong */
/**********************************/
DPRINTK("Tor counter selection is wrong\n");
i_ReturnValue = -4;
} /* if (b_TorCounter <= 1) */
} else {
/******************************************/
/* The module is not a tor counter module */
/******************************************/
DPRINTK("The module is not a tor counter module\n");
i_ReturnValue = -3;
}
} else {
/***********************/
/* Module number error */
/***********************/
DPRINTK("Module number error\n");
i_ReturnValue = -2;
}
return i_ReturnValue;
}
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data.com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
@endverbatim
*/
/*
+-----------------------------------------------------------------------+
| (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+-----------------------------------------------------------------------+
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+-----------------------------------------------------------------------+
| Project : API APCI1710 | Compiler : gcc |
| Module name : TTL.C | Version : 2.96 |
+-------------------------------+---------------------------------------+
| Project manager: Eric Stolz | Date : 02/12/2002 |
+-----------------------------------------------------------------------+
| Description : APCI-1710 TTL I/O module |
| |
| |
+-----------------------------------------------------------------------+
| UPDATES |
+-----------------------------------------------------------------------+
| Date | Author | Description of updates |
+----------+-----------+------------------------------------------------+
| 13/05/98 | S. Weber | TTL digital input / output implementation |
|----------|-----------|------------------------------------------------|
| 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
| | | available |
+-----------------------------------------------------------------------+
| | | |
| | | |
+-----------------------------------------------------------------------+
*/
#define APCI1710_TTL_INIT 0
#define APCI1710_TTL_INITDIRECTION 1
#define APCI1710_TTL_READCHANNEL 0
#define APCI1710_TTL_READPORT 1
/*
+----------------------------------------------------------------------------+
| Function Name : _INT_ i_APCI1710_InitTTLIODirection |
| (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
| unsigned char_ b_PortAMode, |
| unsigned char_ b_PortBMode, |
| unsigned char_ b_PortCMode, |
| unsigned char_ b_PortDMode) |
+----------------------------------------------------------------------------+
| Task APCI1710_TTL_INIT (using defaults) : Configure the TTL I/O operating mode from selected |
| module (b_ModulNbr). You must calling this function be|
| for you call any other function witch access of TTL. |
APCI1710_TTL_INITDIRECTION(user inputs for direction)
+----------------------------------------------------------------------------+
| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710|
| unsigned char_ b_ModulNbr : Module number to |
| configure (0 to 3)
b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
b_InitType = (unsigned char) data[0];
b_PortAMode = (unsigned char) data[1];
b_PortBMode = (unsigned char) data[2];
b_PortCMode = (unsigned char) data[3];
b_PortDMode = (unsigned char) data[4];|
+----------------------------------------------------------------------------+
| Output Parameters : - |
+----------------------------------------------------------------------------+
| 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: Function not available for this version |
| -5: Port A mode selection is wrong |
| -6: Port B mode selection is wrong |
| -7: Port C mode selection is wrong |
| -8: Port D mode selection is wrong |
+----------------------------------------------------------------------------+
*/
static int i_APCI1710_InsnConfigInitTTLIO(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned char b_ModulNbr;
unsigned char b_InitType;
unsigned char b_PortAMode;
unsigned char b_PortBMode;
unsigned char b_PortCMode;
unsigned char b_PortDMode;
b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
b_InitType = (unsigned char) data[0];
i_ReturnValue = insn->n;
/**************************/
/* 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) {
switch (b_InitType) {
case APCI1710_TTL_INIT:
devpriv->s_ModuleInfo[b_ModulNbr].
s_TTLIOInfo.b_TTLInit = 1;
/***************************/
/* Set TTL port A to input */
/***************************/
devpriv->s_ModuleInfo[b_ModulNbr].
s_TTLIOInfo.b_PortConfiguration[0] = 0;
/***************************/
/* Set TTL port B to input */
/***************************/
devpriv->s_ModuleInfo[b_ModulNbr].
s_TTLIOInfo.b_PortConfiguration[1] = 0;
/***************************/
/* Set TTL port C to input */
/***************************/
devpriv->s_ModuleInfo[b_ModulNbr].
s_TTLIOInfo.b_PortConfiguration[2] = 0;
/****************************/
/* Set TTL port D to output */
/****************************/
devpriv->s_ModuleInfo[b_ModulNbr].
s_TTLIOInfo.b_PortConfiguration[3] = 1;
/*************************/
/* Set the configuration */
/*************************/
outl(0x8,
devpriv->s_BoardInfos.ui_Address + 20 +
(64 * b_ModulNbr));
break;
case APCI1710_TTL_INITDIRECTION:
b_PortAMode = (unsigned char) data[1];
b_PortBMode = (unsigned char) data[2];
b_PortCMode = (unsigned char) data[3];
b_PortDMode = (unsigned char) data[4];
/********************/
/* Test the version */
/********************/
if ((devpriv->s_BoardInfos.
dw_MolduleConfiguration
[b_ModulNbr] & 0xFFFF) >=
0x3230) {
/************************/
/* Test the port A mode */
/************************/
if ((b_PortAMode == 0)
|| (b_PortAMode == 1)) {
/************************/
/* Test the port B mode */
/************************/
if ((b_PortBMode == 0)
|| (b_PortBMode == 1)) {
/************************/
/* Test the port C mode */
/************************/
if ((b_PortCMode == 0)
|| (b_PortCMode
== 1)) {
/************************/
/* Test the port D mode */
/************************/
if ((b_PortDMode == 0) || (b_PortDMode == 1)) {
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_TTLIOInfo.
b_TTLInit
=
1;
/***********************/
/* Set TTL port A mode */
/***********************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_TTLIOInfo.
b_PortConfiguration
[0]
=
b_PortAMode;
/***********************/
/* Set TTL port B mode */
/***********************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_TTLIOInfo.
b_PortConfiguration
[1]
=
b_PortBMode;
/***********************/
/* Set TTL port C mode */
/***********************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_TTLIOInfo.
b_PortConfiguration
[2]
=
b_PortCMode;
/***********************/
/* Set TTL port D mode */
/***********************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_TTLIOInfo.
b_PortConfiguration
[3]
=
b_PortDMode;
/*************************/
/* Set the configuration */
/*************************/
outl((b_PortAMode << 0) | (b_PortBMode << 1) | (b_PortCMode << 2) | (b_PortDMode << 3), devpriv->s_BoardInfos.ui_Address + 20 + (64 * b_ModulNbr));
} else {
/**********************************/
/* Port D mode selection is wrong */
/**********************************/
DPRINTK("Port D mode selection is wrong\n");
i_ReturnValue
=
-8;
}
} else {
/**********************************/
/* Port C mode selection is wrong */
/**********************************/
DPRINTK("Port C mode selection is wrong\n");
i_ReturnValue =
-7;
}
} else {
/**********************************/
/* Port B mode selection is wrong */
/**********************************/
DPRINTK("Port B mode selection is wrong\n");
i_ReturnValue = -6;
}
} else {
/**********************************/
/* Port A mode selection is wrong */
/**********************************/
DPRINTK("Port A mode selection is wrong\n");
i_ReturnValue = -5;
}
} else {
/*******************************************/
/* Function not available for this version */
/*******************************************/
DPRINTK("Function not available for this version\n");
i_ReturnValue = -4;
}
break;
DPRINTK("\n");
default:
printk("Bad Config Type\n");
} /* switch end */
} 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;
}
/*
+----------------------------------------------------------------------------+
| INPUT FUNCTIONS |
+----------------------------------------------------------------------------+
*/
/*
+----------------------------------------------------------------------------+
| Function Name : _INT_ i_APCI1710_ReadTTLIOChannelValue |
| (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
| unsigned char_ b_SelectedPort, |
| unsigned char_ b_InputChannel, |
| unsigned char *_ pb_ChannelStatus) |
+----------------------------------------------------------------------------+
| Task : Read the status from selected TTL digital input |
| (b_InputChannel)
+----------------------------------------------------------------------------+
| Task : Read the status from digital input port |
| (b_SelectedPort) from selected TTL module (b_ModulNbr) |
+----------------------------------------------------------------------------+
+----------------------------------------------------------------------------+
| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710|
| unsigned char_ b_ModulNbr : Module number to |
| configure (0 to 7) |
| unsigned char_ b_SelectedPort, : Selection from TTL I/O |
| port (0 to 2) |
| 0 : Port A selection |
| 1 : Port B selection |
| 2 : Port C selection |
| 3 : Port D selection |
| unsigned char_ b_InputChannel : Selection from digital |
| input ( 0 to 2)
APCI1710_TTL_READCHANNEL
b_ModulNbr = CR_AREF(insn->chanspec);
b_SelectedPort= CR_RANGE(insn->chanspec);
b_InputChannel= CR_CHAN(insn->chanspec);
b_ReadType = (unsigned char) data[0];
APCI1710_TTL_READPORT|
b_ModulNbr = CR_AREF(insn->chanspec);
b_SelectedPort= CR_RANGE(insn->chanspec);
b_ReadType = (unsigned char) data[0];
+----------------------------------------------------------------------------+
| Output Parameters : data[0]
unsigned char *_ pb_ChannelStatus : Digital input channel |
| status |
| 0 : Channle is not active|
| 1 : Channle is active |
+----------------------------------------------------------------------------+
| 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: The selected TTL input port is wrong |
| -5: The selected TTL digital input is wrong |
| -6: TTL I/O not initialised |
+----------------------------------------------------------------------------+
*/
static int i_APCI1710_InsnBitsReadTTLIO(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_StatusReg;
unsigned char b_ModulNbr;
unsigned char b_SelectedPort;
unsigned char b_InputChannel;
unsigned char b_ReadType;
unsigned char *pb_ChannelStatus;
unsigned char *pb_PortValue;
i_ReturnValue = insn->n;
b_ReadType = (unsigned char) data[0];
b_ModulNbr = CR_AREF(insn->chanspec);
b_SelectedPort = CR_RANGE(insn->chanspec);
b_InputChannel = CR_CHAN(insn->chanspec);
/**************************/
/* 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) {
switch (b_ReadType) {
case APCI1710_TTL_READCHANNEL:
pb_ChannelStatus = (unsigned char *) &data[0];
/********************************/
/* Test the TTL I/O port number */
/********************************/
if (((b_SelectedPort <= 2)
&& ((devpriv->s_BoardInfos.
dw_MolduleConfiguration
[b_ModulNbr] &
0xFFFF) ==
0x3130))
|| ((b_SelectedPort <= 3)
&& ((devpriv->s_BoardInfos.
dw_MolduleConfiguration
[b_ModulNbr] &
0xFFFF) >=
0x3230))) {
/******************************************/
/* Test the digital imnput channel number */
/******************************************/
if (((b_InputChannel <= 7)
&& (b_SelectedPort < 3))
|| ((b_InputChannel <= 1)
&& (b_SelectedPort ==
3))) {
/******************************************/
/* Test if the TTL I/O module initialised */
/******************************************/
if (devpriv->
s_ModuleInfo
[b_ModulNbr].
s_TTLIOInfo.b_TTLInit ==
1) {
/***********************************/
/* Test if TTL port used for input */
/***********************************/
if (((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) == 0x3130) || (((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) >= 0x3230) && (devpriv->s_ModuleInfo[b_ModulNbr].s_TTLIOInfo.b_PortConfiguration[b_SelectedPort] == 0))) {
/**************************/
/* Read all digital input */
/**************************/
dw_StatusReg =
inl
(devpriv->
s_BoardInfos.
ui_Address
+
(64 * b_ModulNbr));
*pb_ChannelStatus
=
(unsigned char) (
(dw_StatusReg
>>
(8 * b_SelectedPort)) >> b_InputChannel) & 1;
} else {
/*******************************/
/* Selected TTL I/O port error */
/*******************************/
DPRINTK("Selected TTL I/O port error\n");
i_ReturnValue =
-4;
}
} else {
/***************************/
/* TTL I/O not initialised */
/***************************/
DPRINTK("TTL I/O not initialised\n");
i_ReturnValue = -6;
}
} else {
/********************************/
/* Selected digital input error */
/********************************/
DPRINTK("Selected digital input error\n");
i_ReturnValue = -5;
}
} else {
/*******************************/
/* Selected TTL I/O port error */
/*******************************/
DPRINTK("Selected TTL I/O port error\n");
i_ReturnValue = -4;
}
break;
case APCI1710_TTL_READPORT:
pb_PortValue = (unsigned char *) &data[0];
/********************************/
/* Test the TTL I/O port number */
/********************************/
if (((b_SelectedPort <= 2)
&& ((devpriv->s_BoardInfos.
dw_MolduleConfiguration
[b_ModulNbr] &
0xFFFF) ==
0x3130))
|| ((b_SelectedPort <= 3)
&& ((devpriv->s_BoardInfos.
dw_MolduleConfiguration
[b_ModulNbr] &
0xFFFF) >=
0x3230))) {
/******************************************/
/* Test if the TTL I/O module initialised */
/******************************************/
if (devpriv->s_ModuleInfo[b_ModulNbr].
s_TTLIOInfo.b_TTLInit == 1) {
/***********************************/
/* Test if TTL port used for input */
/***********************************/
if (((devpriv->s_BoardInfos.
dw_MolduleConfiguration
[b_ModulNbr]
&
0xFFFF)
== 0x3130)
|| (((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) >= 0x3230) && (devpriv->s_ModuleInfo[b_ModulNbr].s_TTLIOInfo.b_PortConfiguration[b_SelectedPort] == 0))) {
/**************************/
/* Read all digital input */
/**************************/
dw_StatusReg =
inl(devpriv->
s_BoardInfos.
ui_Address +
(64 * b_ModulNbr));
*pb_PortValue =
(unsigned char) (
(dw_StatusReg >>
(8 * b_SelectedPort)) & 0xFF);
} else {
/*******************************/
/* Selected TTL I/O port error */
/*******************************/
DPRINTK("Selected TTL I/O port error\n");
i_ReturnValue = -4;
}
} else {
/***************************/
/* TTL I/O not initialised */
/***************************/
DPRINTK("TTL I/O not initialised\n");
i_ReturnValue = -5;
}
} else {
/*******************************/
/* Selected TTL I/O port error */
/*******************************/
DPRINTK("Selected TTL I/O port error\n");
i_ReturnValue = -4;
}
break;
default:
printk("Bad ReadType\n");
} /* End Switch */
} 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;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI1710_InsnReadTTLIOAllPortValue(comedi_device
*dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *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 : unsigned char_ b_BoardHandle : Handle of board APCI-1710|
| unsigned char_ 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 |
+----------------------------------------------------------------------------+
*/
static int i_APCI1710_InsnReadTTLIOAllPortValue(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_StatusReg;
unsigned char b_ModulNbr;
unsigned int *pul_PortValue;
b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
i_ReturnValue = insn->n;
pul_PortValue = (unsigned int *) &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;
}
/*
+----------------------------------------------------------------------------+
| OUTPUT FUNCTIONS |
+----------------------------------------------------------------------------+
*/
/*
+----------------------------------------------------------------------------+
| Function Name : _INT_ i_APCI1710_SetTTLIOChlOn |
| (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
| unsigned char_ b_OutputChannel)
int i_APCI1710_InsnWriteSetTTLIOChlOnOff(struct comedi_device *dev,struct comedi_subdevice *s,
struct comedi_insn *insn,unsigned int *data) |
+----------------------------------------------------------------------------+
| Task : Sets or resets the output witch has been passed with the |
| parameter b_Channel. Setting an output means setting |
| an ouput high. |
+----------------------------------------------------------------------------+
| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
| unsigned char_ b_ModulNbr : Selected module number (0 to 3)|
| unsigned char_ b_OutputChannel : Selection from digital output |
| channel (0 or 1) |
| 0 : PD0 |
| 1 : PD1 |
| 2 to 9 : PA |
| 10 to 17: PB |
| 18 to 25: PC |
b_ModulNbr = CR_AREF(insn->chanspec);
b_OutputChannel= CR_CHAN(insn->chanspec);
ui_State = data[0]; ON or OFF
+----------------------------------------------------------------------------+
| Output Parameters : - |
+----------------------------------------------------------------------------+
| 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 I/O module |
| -4: The selected digital output is wrong |
| -5: TTL I/O not initialised see function |
| " i_APCI1710_InitTTLIO"
+----------------------------------------------------------------------------+
*/
static int i_APCI1710_InsnWriteSetTTLIOChlOnOff(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct addi_private *devpriv = dev->private;
int i_ReturnValue = 0;
unsigned int dw_StatusReg = 0;
unsigned char b_ModulNbr;
unsigned char b_OutputChannel;
unsigned int ui_State;
i_ReturnValue = insn->n;
b_ModulNbr = CR_AREF(insn->chanspec);
b_OutputChannel = CR_CHAN(insn->chanspec);
ui_State = data[0]; /* ON or OFF */
/**************************/
/* 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) {
/***********************************/
/* Test the TTL I/O channel number */
/***********************************/
if (((b_OutputChannel <= 1)
&& ((devpriv->s_BoardInfos.
dw_MolduleConfiguration
[b_ModulNbr] &
0xFFFF) ==
0x3130))
|| ((b_OutputChannel <= 25)
&& ((devpriv->s_BoardInfos.
dw_MolduleConfiguration
[b_ModulNbr] &
0xFFFF) >=
0x3230))) {
/****************************************************/
/* Test if the selected channel is a output channel */
/****************************************************/
if (((b_OutputChannel <= 1)
&& (devpriv->
s_ModuleInfo
[b_ModulNbr].
s_TTLIOInfo.
b_PortConfiguration
[3] == 1))
|| ((b_OutputChannel >= 2)
&& (b_OutputChannel <=
9)
&& (devpriv->
s_ModuleInfo
[b_ModulNbr].
s_TTLIOInfo.
b_PortConfiguration
[0] == 1))
|| ((b_OutputChannel >= 10)
&& (b_OutputChannel <=
17)
&& (devpriv->
s_ModuleInfo
[b_ModulNbr].
s_TTLIOInfo.
b_PortConfiguration
[1] == 1))
|| ((b_OutputChannel >= 18)
&& (b_OutputChannel <=
25)
&& (devpriv->
s_ModuleInfo
[b_ModulNbr].
s_TTLIOInfo.
b_PortConfiguration
[2] == 1))) {
/************************/
/* Test if PD0 selected */
/************************/
if (b_OutputChannel == 0) {
outl(ui_State,
devpriv->
s_BoardInfos.
ui_Address +
(64 * b_ModulNbr));
} else {
/************************/
/* Test if PD1 selected */
/************************/
if (b_OutputChannel ==
1) {
outl(ui_State,
devpriv->
s_BoardInfos.
ui_Address
+ 4 +
(64 * b_ModulNbr));
} else {
b_OutputChannel
=
b_OutputChannel
- 2;
/********************/
/* Read all channel */
/********************/
dw_StatusReg =
inl
(devpriv->
s_BoardInfos.
ui_Address
+
(64 * b_ModulNbr));
if (ui_State) /* ON */
{
dw_StatusReg
=
(dw_StatusReg
>>
((b_OutputChannel / 8) * 8)) & 0xFF;
dw_StatusReg
=
dw_StatusReg
|
(1
<<
(b_OutputChannel
%
8));
} else /* Off */
{
dw_StatusReg
=
(dw_StatusReg
>>
((b_OutputChannel / 8) * 8)) & 0xFF;
dw_StatusReg
=
dw_StatusReg
&
(0xFF
-
(1 << (b_OutputChannel % 8)));
}
/****************************/
/* Set the new output value */
/****************************/
outl(dw_StatusReg, devpriv->s_BoardInfos.ui_Address + 8 + ((b_OutputChannel / 8) * 4) + (64 * b_ModulNbr));
}
}
} else {
/************************************/
/* The selected TTL output is wrong */
/************************************/
DPRINTK(" The selected TTL output is wrong\n");
i_ReturnValue = -4;
}
} else {
/************************************/
/* The selected TTL output is wrong */
/************************************/
DPRINTK("The selected TTL output is wrong\n");
i_ReturnValue = -4;
}
} else {
/***************************/
/* TTL I/O not initialised */
/***************************/
DPRINTK("TTL I/O not initialised\n");
i_ReturnValue = -5;
}
} else {
/**************************************/
/* The module is not a TTL I/O module */
/**************************************/
DPRINTK("The module is not a TTL I/O module\n");
i_ReturnValue = -3;
}
} else {
/***********************/
/* Module number error */
/***********************/
DPRINTK("Module number error\n");
i_ReturnValue = -2;
}
return i_ReturnValue;
}
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data.com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
@endverbatim
*/
/*
+-----------------------------------------------------------------------+
| (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+-----------------------------------------------------------------------+
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+-------------------------------+---------------------------------------+
| Project : APCI-1710 | Compiler : GCC |
| Module name : hwdrv_apci1710.c| Version : 2.96 |
+-------------------------------+---------------------------------------+
| Project manager: Eric Stolz | Date : 02/12/2002 |
+-------------------------------+---------------------------------------+
| Description : Hardware Layer Access For APCI-1710 |
+-----------------------------------------------------------------------+
| UPDATES |
+----------+-----------+------------------------------------------------+
| Date | Author | Description of updates |
+----------+-----------+------------------------------------------------+
| | | |
| | | |
| | | |
+----------+-----------+------------------------------------------------+
*/
#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 */
#define APCI1710_BOARD_NAME "apci1710"
#define APCI1710_BOARD_DEVICE_ID 0x818F
#define APCI1710_ADDRESS_RANGE 256
#define APCI1710_CONFIG_ADDRESS_RANGE 8
#define APCI1710_INCREMENTAL_COUNTER 0x53430000UL
#define APCI1710_SSI_COUNTER 0x53490000UL
#define APCI1710_TTL_IO 0x544C0000UL
#define APCI1710_DIGITAL_IO 0x44490000UL
#define APCI1710_82X54_TIMER 0x49430000UL
#define APCI1710_CHRONOMETER 0x43480000UL
#define APCI1710_PULSE_ENCODER 0x495A0000UL
#define APCI1710_TOR_COUNTER 0x544F0000UL
#define APCI1710_PWM 0x50570000UL
#define APCI1710_ETM 0x45540000UL
#define APCI1710_CDA 0x43440000UL
#define APCI1710_DISABLE 0
#define APCI1710_ENABLE 1
#define APCI1710_SYNCHRONOUS_MODE 1
#define APCI1710_ASYNCHRONOUS_MODE 0
#include "APCI1710_Inp_cpt.c"
#include "APCI1710_Ssi.c"
#include "APCI1710_Tor.c"
#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"
static const struct comedi_lrange range_apci1710_ttl = {
4, {
BIP_RANGE(10),
BIP_RANGE(5),
BIP_RANGE(2),
BIP_RANGE(1)
}
};
static const struct comedi_lrange range_apci1710_ssi = {
4, {
BIP_RANGE(10),
BIP_RANGE(5),
BIP_RANGE(2),
BIP_RANGE(1)
}
};
static const struct comedi_lrange range_apci1710_inccpt = {
4, {
BIP_RANGE(10),
BIP_RANGE(5),
BIP_RANGE(2),
BIP_RANGE(1)
}
};
static void i_ADDI_AttachPCI1710(struct comedi_device *dev)
{
struct comedi_subdevice *s;
int ret = 0;
int n_subdevices = 9;
ret = comedi_alloc_subdevices(dev, n_subdevices);
if (ret)
return;
/* Allocate and Initialise Timer Subdevice Structures */
s = &dev->subdevices[0];
s->type = COMEDI_SUBD_TIMER;
s->subdev_flags = SDF_WRITEABLE | 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_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_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_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_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_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_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_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_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;
}
static int i_APCI1710_Reset(struct comedi_device *dev)
{
struct addi_private *devpriv = dev->private;
int ret;
unsigned int 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);
devpriv->s_BoardInfos.b_BoardVersion = 1;
/* Enable the interrupt for the controller */
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 |
| (unsigned char b_Interrupt, __CPPARGS) |
+----------------------------------------------------------------------------+
| Task : APCI-1710 interrupt function |
+----------------------------------------------------------------------------+
| Input Parameters : unsigned char b_Interrupt : Interrupt number |
+----------------------------------------------------------------------------+
| Output Parameters : - |
+----------------------------------------------------------------------------+
| Return Value : 0 : OK |
| -1 : Error |
+----------------------------------------------------------------------------+
*/
static void v_APCI1710_Interrupt(int irq, void *d)
{
struct comedi_device *dev = d;
struct addi_private *devpriv = dev->private;
unsigned char b_ModuleCpt = 0;
unsigned char b_InterruptFlag = 0;
unsigned char b_PWMCpt = 0;
unsigned char b_TorCounterCpt = 0;
unsigned char b_PulseIncoderCpt = 0;
unsigned int ui_16BitValue;
unsigned int ul_InterruptLatchReg = 0;
unsigned int ul_LatchRegisterValue = 0;
unsigned int ul_82X54InterruptStatus;
unsigned int ul_StatusRegister;
union 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 =
(unsigned int)
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 =
(unsigned int) (
(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 =
(unsigned int) (
(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 =
(unsigned int)
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;
}
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <asm/i387.h>
#include "../comedidev.h"
#include "comedi_fc.h"
#include "amcc_s5933.h"
#define APCI1710_SAVE_INTERRUPT 1
union str_ModuleInfo {
/* Incremental counter infos */
struct {
union {
struct {
unsigned char b_ModeRegister1;
unsigned char b_ModeRegister2;
unsigned char b_ModeRegister3;
unsigned char b_ModeRegister4;
} s_ByteModeRegister;
unsigned int 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 {
unsigned char b_SSIProfile;
unsigned char b_PositionTurnLength;
unsigned char b_TurnCptLength;
unsigned char b_SSIInit;
} s_SSICounterInfo;
/* TTL I/O infos */
struct {
unsigned char b_TTLInit;
unsigned char b_PortConfiguration[4];
} s_TTLIOInfo;
/* Digital I/O infos */
struct {
unsigned char b_DigitalInit;
unsigned char b_ChannelAMode;
unsigned char b_ChannelBMode;
unsigned char b_OutputMemoryEnabled;
unsigned int dw_OutputMemory;
} s_DigitalIOInfo;
/* 82X54 timer infos */
struct {
struct {
unsigned char b_82X54Init;
unsigned char b_InputClockSelection;
unsigned char b_InputClockLevel;
unsigned char b_OutputLevel;
unsigned char b_HardwareGateLevel;
unsigned int dw_ConfigurationWord;
} s_82X54TimerInfo[3];
unsigned char b_InterruptMask;
} s_82X54ModuleInfo;
/* Chronometer infos */
struct {
unsigned char b_ChronoInit;
unsigned char b_InterruptMask;
unsigned char b_PCIInputClock;
unsigned char b_TimingUnit;
unsigned char b_CycleMode;
double d_TimingInterval;
unsigned int dw_ConfigReg;
} s_ChronoModuleInfo;
/* Pulse encoder infos */
struct {
struct {
unsigned char b_PulseEncoderInit;
} s_PulseEncoderInfo[4];
unsigned int dw_SetRegister;
unsigned int dw_ControlRegister;
unsigned int dw_StatusRegister;
} s_PulseEncoderModuleInfo;
/* Tor conter infos */
struct {
struct {
unsigned char b_TorCounterInit;
unsigned char b_TimingUnit;
unsigned char b_InterruptEnable;
double d_TimingInterval;
unsigned int ul_RealTimingInterval;
} s_TorCounterInfo[2];
unsigned char b_PCIInputClock;
} s_TorCounterModuleInfo;
/* PWM infos */
struct {
struct {
unsigned char b_PWMInit;
unsigned char b_TimingUnit;
unsigned char b_InterruptEnable;
double d_LowTiming;
double d_HighTiming;
unsigned int ul_RealLowTiming;
unsigned int ul_RealHighTiming;
} s_PWMInfo[2];
unsigned char b_ClockSelection;
} s_PWMModuleInfo;
/* CDA infos */
struct {
unsigned char b_CDAEnable;
unsigned char b_FctSelection;
} s_CDAModuleInfo;
};
struct addi_private {
/* Pointer to the current process */
struct task_struct *tsk_Current;
struct {
unsigned int ui_Address;
unsigned char b_BoardVersion;
unsigned int dw_MolduleConfiguration[4];
} s_BoardInfos;
struct {
unsigned int ul_InterruptOccur;
unsigned int ui_Read;
unsigned int ui_Write;
struct {
unsigned char b_OldModuleMask;
unsigned int ul_OldInterruptMask;
unsigned int ul_OldCounterLatchValue;
} s_FIFOInterruptParameters[APCI1710_SAVE_INTERRUPT];
} s_InterruptParameters;
union str_ModuleInfo s_ModuleInfo[4];
};
static void fpu_begin(void)
{
kernel_fpu_begin();
}
static void fpu_end(void)
{
kernel_fpu_end();
}
#include "addi-data/hwdrv_APCI1710.c"
static irqreturn_t v_ADDI_Interrupt(int irq, void *d)
{
v_APCI1710_Interrupt(irq, d);
return IRQ_RETVAL(1);
}
static int apci1710_auto_attach(struct comedi_device *dev,
unsigned long context_unused)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
struct addi_private *devpriv;
int ret;
devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
if (!devpriv)
return -ENOMEM;
ret = comedi_pci_enable(dev);
if (ret)
return ret;
devpriv->s_BoardInfos.ui_Address = pci_resource_start(pcidev, 2);
if (pcidev->irq > 0) {
ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED,
dev->board_name, dev);
if (ret == 0)
dev->irq = pcidev->irq;
}
i_ADDI_AttachPCI1710(dev);
i_APCI1710_Reset(dev);
return 0;
}
static void apci1710_detach(struct comedi_device *dev)
{
if (dev->iobase)
i_APCI1710_Reset(dev);
if (dev->irq)
free_irq(dev->irq, dev);
comedi_pci_disable(dev);
}
static struct comedi_driver apci1710_driver = {
.driver_name = "addi_apci_1710",
.module = THIS_MODULE,
.auto_attach = apci1710_auto_attach,
.detach = apci1710_detach,
};
static int apci1710_pci_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
return comedi_pci_auto_config(dev, &apci1710_driver, id->driver_data);
}
static DEFINE_PCI_DEVICE_TABLE(apci1710_pci_table) = {
{ PCI_DEVICE(PCI_VENDOR_ID_AMCC, APCI1710_BOARD_DEVICE_ID) },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, apci1710_pci_table);
static struct pci_driver apci1710_pci_driver = {
.name = "addi_apci_1710",
.id_table = apci1710_pci_table,
.probe = apci1710_pci_probe,
.remove = comedi_pci_auto_unconfig,
};
module_comedi_pci_driver(apci1710_driver, apci1710_pci_driver);
MODULE_AUTHOR("Comedi http://www.comedi.org");
MODULE_DESCRIPTION("Comedi low-level driver");
MODULE_LICENSE("GPL");
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment