2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2025-01-08 13:44:01 +08:00

Staging: comedi: add addi-data drivers

This adds the addi-data family of comedi drivers to the staging tree

From: ADDI-DATA GmbH <info@addi-data.com>
Cc: David Schleef <ds@schleef.org>
Cc: Frank Mori Hess <fmhess@users.sourceforge.net>
Cc: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
ADDI-DATA GmbH 2009-02-12 15:14:18 -08:00 committed by Greg Kroah-Hartman
parent 98ccdc56a0
commit c995fe9475
70 changed files with 44828 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,84 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
#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
// BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
#ifndef APCI1710_10MHZ
#define APCI1710_10MHZ 10
#endif
// END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
/*
+----------------------------------------------------------------------------+
| 82X54 TIMER INISIALISATION FUNCTION |
+----------------------------------------------------------------------------+
*/
INT i_APCI1710_InsnConfigInitTimer(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI1710_InsnWriteEnableDisableTimer(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
/*
+----------------------------------------------------------------------------+
| 82X54 READ FUNCTION |
+----------------------------------------------------------------------------+
*/
INT i_APCI1710_InsnReadAllTimerValue(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI1710_InsnBitsTimer(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
/*
+----------------------------------------------------------------------------+
| 82X54 READ & WRITE FUNCTION |
+----------------------------------------------------------------------------+
*/
INT i_APCI1710_ReadTimerValue(comedi_device * dev,
BYTE b_ModulNbr, BYTE b_TimerNbr, PULONG pul_TimerValue);
INT i_APCI1710_GetTimerOutputLevel(comedi_device * dev,
BYTE b_ModulNbr, BYTE b_TimerNbr, PBYTE pb_OutputLevel);
INT i_APCI1710_GetTimerProgressStatus(comedi_device * dev,
BYTE b_ModulNbr, BYTE b_TimerNbr, PBYTE pb_TimerStatus);
/*
+----------------------------------------------------------------------------+
| 82X54 WRITE FUNCTION |
+----------------------------------------------------------------------------+
*/
INT i_APCI1710_WriteTimerValue(comedi_device * dev,
BYTE b_ModulNbr, BYTE b_TimerNbr, ULONG ul_WriteValue);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,85 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
#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
/*
+----------------------------------------------------------------------------+
| CHRONOMETER INISIALISATION FUNCTION |
+----------------------------------------------------------------------------+
*/
INT i_APCI1710_InsnConfigInitChrono(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI1710_InsnWriteEnableDisableChrono(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
/*
+----------------------------------------------------------------------------+
| CHRONOMETER READ FUNCTION |
+----------------------------------------------------------------------------+
*/
INT i_APCI1710_InsnReadChrono(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI1710_GetChronoProgressStatus(comedi_device * dev,
BYTE b_ModulNbr, PBYTE pb_ChronoStatus);
INT i_APCI1710_ReadChronoValue(comedi_device * dev,
BYTE b_ModulNbr,
UINT ui_TimeOut, PBYTE pb_ChronoStatus, PULONG pul_ChronoValue);
INT i_APCI1710_ConvertChronoValue(comedi_device * dev,
BYTE b_ModulNbr,
ULONG ul_ChronoValue,
PULONG pul_Hour,
PBYTE pb_Minute,
PBYTE pb_Second,
PUINT pui_MilliSecond, PUINT pui_MicroSecond, PUINT pui_NanoSecond);
/*
+----------------------------------------------------------------------------+
| CHRONOMETER DIGITAL INPUT OUTPUT FUNCTION |
+----------------------------------------------------------------------------+
*/
INT i_APCI1710_InsnBitsChronoDigitalIO(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,55 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
#define APCI1710_ON 1 // Digital Output ON or OFF
#define APCI1710_OFF 0
#define APCI1710_INPUT 0 // Digital I/O
#define APCI1710_OUTPUT 1
#define APCI1710_DIGIO_MEMORYONOFF 0x10 //
#define APCI1710_DIGIO_INIT 0x11
/*
+----------------------------------------------------------------------------+
| DIGITAL I/O INISIALISATION FUNCTION |
+----------------------------------------------------------------------------+
*/
INT i_APCI1710_InsnConfigDigitalIO(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
/*
+----------------------------------------------------------------------------+
| INPUT OUTPUT FUNCTIONS |
+----------------------------------------------------------------------------+
*/
INT i_APCI1710_InsnReadDigitalIOChlValue(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
INT i_APCI1710_InsnWriteDigitalIOChlOnOff(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
INT i_APCI1710_InsnBitsDigitalIOPortOnOff(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,269 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
#define APCI1710_16BIT_COUNTER 0x10
#define APCI1710_32BIT_COUNTER 0x0
#define APCI1710_QUADRUPLE_MODE 0x0
#define APCI1710_DOUBLE_MODE 0x3
#define APCI1710_SIMPLE_MODE 0xF
#define APCI1710_DIRECT_MODE 0x80
#define APCI1710_HYSTERESIS_ON 0x60
#define APCI1710_HYSTERESIS_OFF 0x0
#define APCI1710_INCREMENT 0x60
#define APCI1710_DECREMENT 0x0
#define APCI1710_LATCH_COUNTER 0x1
#define APCI1710_CLEAR_COUNTER 0x0
#define APCI1710_LOW 0x0
#define APCI1710_HIGH 0x1
/*********************/
/* Version 0600-0229 */
/*********************/
#define APCI1710_HIGH_EDGE_CLEAR_COUNTER 0x0
#define APCI1710_HIGH_EDGE_LATCH_COUNTER 0x1
#define APCI1710_LOW_EDGE_CLEAR_COUNTER 0x2
#define APCI1710_LOW_EDGE_LATCH_COUNTER 0x3
#define APCI1710_HIGH_EDGE_LATCH_AND_CLEAR_COUNTER 0x4
#define APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER 0x5
#define APCI1710_SOURCE_0 0x0
#define APCI1710_SOURCE_1 0x1
#define APCI1710_30MHZ 30
#define APCI1710_33MHZ 33
#define APCI1710_40MHZ 40
#define APCI1710_ENABLE_LATCH_INT 0x80
#define APCI1710_DISABLE_LATCH_INT (~APCI1710_ENABLE_LATCH_INT)
#define APCI1710_INDEX_LATCH_COUNTER 0x10
#define APCI1710_INDEX_AUTO_MODE 0x8
#define APCI1710_ENABLE_INDEX 0x4
#define APCI1710_DISABLE_INDEX (~APCI1710_ENABLE_INDEX)
#define APCI1710_ENABLE_LATCH_AND_CLEAR 0x8
#define APCI1710_DISABLE_LATCH_AND_CLEAR (~APCI1710_ENABLE_LATCH_AND_CLEAR)
#define APCI1710_SET_LOW_INDEX_LEVEL 0x4
#define APCI1710_SET_HIGH_INDEX_LEVEL (~APCI1710_SET_LOW_INDEX_LEVEL)
#define APCI1710_INVERT_INDEX_RFERENCE 0x2
#define APCI1710_DEFAULT_INDEX_RFERENCE (~APCI1710_INVERT_INDEX_RFERENCE)
#define APCI1710_ENABLE_INDEX_INT 0x1
#define APCI1710_DISABLE_INDEX_INT (~APCI1710_ENABLE_INDEX_INT)
#define APCI1710_ENABLE_FREQUENCY 0x4
#define APCI1710_DISABLE_FREQUENCY (~APCI1710_ENABLE_FREQUENCY)
#define APCI1710_ENABLE_FREQUENCY_INT 0x8
#define APCI1710_DISABLE_FREQUENCY_INT (~APCI1710_ENABLE_FREQUENCY_INT)
#define APCI1710_ENABLE_40MHZ_FREQUENCY 0x40
#define APCI1710_DISABLE_40MHZ_FREQUENCY (~APCI1710_ENABLE_40MHZ_FREQUENCY)
#define APCI1710_ENABLE_40MHZ_FILTER 0x80
#define APCI1710_DISABLE_40MHZ_FILTER (~APCI1710_ENABLE_40MHZ_FILTER)
#define APCI1710_ENABLE_COMPARE_INT 0x2
#define APCI1710_DISABLE_COMPARE_INT (~APCI1710_ENABLE_COMPARE_INT)
#define APCI1710_ENABLE_INDEX_ACTION 0x20
#define APCI1710_DISABLE_INDEX_ACTION (~APCI1710_ENABLE_INDEX_ACTION)
#define APCI1710_REFERENCE_HIGH 0x40
#define APCI1710_REFERENCE_LOW (~APCI1710_REFERENCE_HIGH)
#define APCI1710_TOR_GATE_LOW 0x40
#define APCI1710_TOR_GATE_HIGH (~APCI1710_TOR_GATE_LOW)
// INSN CONFIG
#define APCI1710_INCCPT_INITCOUNTER 100
#define APCI1710_INCCPT_COUNTERAUTOTEST 101
#define APCI1710_INCCPT_INITINDEX 102
#define APCI1710_INCCPT_INITREFERENCE 103
#define APCI1710_INCCPT_INITEXTERNALSTROBE 104
#define APCI1710_INCCPT_INITCOMPARELOGIC 105
#define APCI1710_INCCPT_INITFREQUENCYMEASUREMENT 106
// INSN READ
#define APCI1710_INCCPT_READLATCHREGISTERSTATUS 200
#define APCI1710_INCCPT_READLATCHREGISTERVALUE 201
#define APCI1710_INCCPT_READ16BITCOUNTERVALUE 202
#define APCI1710_INCCPT_READ32BITCOUNTERVALUE 203
#define APCI1710_INCCPT_GETINDEXSTATUS 204
#define APCI1710_INCCPT_GETREFERENCESTATUS 205
#define APCI1710_INCCPT_GETUASSTATUS 206
#define APCI1710_INCCPT_GETCBSTATUS 207
#define APCI1710_INCCPT_GET16BITCBSTATUS 208
#define APCI1710_INCCPT_GETUDSTATUS 209
#define APCI1710_INCCPT_GETINTERRUPTUDLATCHEDSTATUS 210
#define APCI1710_INCCPT_READFREQUENCYMEASUREMENT 211
#define APCI1710_INCCPT_READINTERRUPT 212
//INSN BITS
#define APCI1710_INCCPT_CLEARCOUNTERVALUE 300
#define APCI1710_INCCPT_CLEARALLCOUNTERVALUE 301
#define APCI1710_INCCPT_SETINPUTFILTER 302
#define APCI1710_INCCPT_LATCHCOUNTER 303
#define APCI1710_INCCPT_SETINDEXANDREFERENCESOURCE 304
#define APCI1710_INCCPT_SETDIGITALCHLON 305
#define APCI1710_INCCPT_SETDIGITALCHLOFF 306
// INSN WRITE
#define APCI1710_INCCPT_ENABLELATCHINTERRUPT 400
#define APCI1710_INCCPT_DISABLELATCHINTERRUPT 401
#define APCI1710_INCCPT_WRITE16BITCOUNTERVALUE 402
#define APCI1710_INCCPT_WRITE32BITCOUNTERVALUE 403
#define APCI1710_INCCPT_ENABLEINDEX 404
#define APCI1710_INCCPT_DISABLEINDEX 405
#define APCI1710_INCCPT_ENABLECOMPARELOGIC 406
#define APCI1710_INCCPT_DISABLECOMPARELOGIC 407
#define APCI1710_INCCPT_ENABLEFREQUENCYMEASUREMENT 408
#define APCI1710_INCCPT_DISABLEFREQUENCYMEASUREMENT 409
/************ Main Functions *************/
INT i_APCI1710_InsnConfigINCCPT(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI1710_InsnBitsINCCPT(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI1710_InsnWriteINCCPT(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI1710_InsnReadINCCPT(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
/*********** Supplementary Functions********/
// INSN CONFIG
INT i_APCI1710_InitCounter(comedi_device * dev,
BYTE b_ModulNbr,
BYTE b_CounterRange,
BYTE b_FirstCounterModus,
BYTE b_FirstCounterOption,
BYTE b_SecondCounterModus, BYTE b_SecondCounterOption);
INT i_APCI1710_CounterAutoTest(comedi_device * dev, PBYTE pb_TestStatus);
INT i_APCI1710_InitIndex(comedi_device * dev,
BYTE b_ModulNbr,
BYTE b_ReferenceAction,
BYTE b_IndexOperation, BYTE b_AutoMode, BYTE b_InterruptEnable);
INT i_APCI1710_InitReference(comedi_device * dev,
BYTE b_ModulNbr, BYTE b_ReferenceLevel);
INT i_APCI1710_InitExternalStrobe(comedi_device * dev,
BYTE b_ModulNbr, BYTE b_ExternalStrobe, BYTE b_ExternalStrobeLevel);
INT i_APCI1710_InitCompareLogic(comedi_device * dev,
BYTE b_ModulNbr, UINT ui_CompareValue);
INT i_APCI1710_InitFrequencyMeasurement(comedi_device * dev,
BYTE b_ModulNbr,
BYTE b_PCIInputClock,
BYTE b_TimingUnity,
ULONG ul_TimingInterval, PULONG pul_RealTimingInterval);
//INSN BITS
INT i_APCI1710_ClearCounterValue(comedi_device * dev, BYTE b_ModulNbr);
INT i_APCI1710_ClearAllCounterValue(comedi_device * dev);
INT i_APCI1710_SetInputFilter(comedi_device * dev,
BYTE b_ModulNbr, BYTE b_PCIInputClock, BYTE b_Filter);
INT i_APCI1710_LatchCounter(comedi_device * dev,
BYTE b_ModulNbr, BYTE b_LatchReg);
INT i_APCI1710_SetIndexAndReferenceSource(comedi_device * dev,
BYTE b_ModulNbr, BYTE b_SourceSelection);
INT i_APCI1710_SetDigitalChlOn(comedi_device * dev, BYTE b_ModulNbr);
INT i_APCI1710_SetDigitalChlOff(comedi_device * dev, BYTE b_ModulNbr);
// INSN WRITE
INT i_APCI1710_EnableLatchInterrupt(comedi_device * dev, BYTE b_ModulNbr);
INT i_APCI1710_DisableLatchInterrupt(comedi_device * dev, BYTE b_ModulNbr);
INT i_APCI1710_Write16BitCounterValue(comedi_device * dev,
BYTE b_ModulNbr, BYTE b_SelectedCounter, UINT ui_WriteValue);
INT i_APCI1710_Write32BitCounterValue(comedi_device * dev,
BYTE b_ModulNbr, ULONG ul_WriteValue);
INT i_APCI1710_EnableIndex(comedi_device * dev, BYTE b_ModulNbr);
INT i_APCI1710_DisableIndex(comedi_device * dev, BYTE b_ModulNbr);
INT i_APCI1710_EnableCompareLogic(comedi_device * dev, BYTE b_ModulNbr);
INT i_APCI1710_DisableCompareLogic(comedi_device * dev, BYTE b_ModulNbr);
INT i_APCI1710_EnableFrequencyMeasurement(comedi_device * dev,
BYTE b_ModulNbr, BYTE b_InterruptEnable);
INT i_APCI1710_DisableFrequencyMeasurement(comedi_device * dev,
BYTE b_ModulNbr);
// INSN READ
INT i_APCI1710_ReadLatchRegisterStatus(comedi_device * dev,
BYTE b_ModulNbr, BYTE b_LatchReg, PBYTE pb_LatchStatus);
INT i_APCI1710_ReadLatchRegisterValue(comedi_device * dev,
BYTE b_ModulNbr, BYTE b_LatchReg, PULONG pul_LatchValue);
INT i_APCI1710_Read16BitCounterValue(comedi_device * dev,
BYTE b_ModulNbr, BYTE b_SelectedCounter, PUINT pui_CounterValue);
INT i_APCI1710_Read32BitCounterValue(comedi_device * dev,
BYTE b_ModulNbr, PULONG pul_CounterValue);
INT i_APCI1710_GetIndexStatus(comedi_device * dev,
BYTE b_ModulNbr, PBYTE pb_IndexStatus);
INT i_APCI1710_GetReferenceStatus(comedi_device * dev,
BYTE b_ModulNbr, PBYTE pb_ReferenceStatus);
INT i_APCI1710_GetUASStatus(comedi_device * dev,
BYTE b_ModulNbr, PBYTE pb_UASStatus);
INT i_APCI1710_GetCBStatus(comedi_device * dev,
BYTE b_ModulNbr, PBYTE pb_CBStatus);
INT i_APCI1710_Get16BitCBStatus(comedi_device * dev,
BYTE b_ModulNbr, PBYTE pb_CBStatusCounter0, PBYTE pb_CBStatusCounter1);
INT i_APCI1710_GetUDStatus(comedi_device * dev,
BYTE b_ModulNbr, PBYTE pb_UDStatus);
INT i_APCI1710_GetInterruptUDLatchedStatus(comedi_device * dev,
BYTE b_ModulNbr, PBYTE pb_UDStatus);
INT i_APCI1710_ReadFrequencyMeasurement(comedi_device * dev,
BYTE b_ModulNbr,
PBYTE pb_Status, PBYTE pb_UDStatus, PULONG pul_ReadValue);

View File

@ -0,0 +1,861 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
/*
+-----------------------------------------------------------------------+
| (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+-----------------------------------------------------------------------+
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+-----------------------------------------------------------------------+
| Project : API APCI1710 | Compiler : gcc |
| Module name : Inp_CPT.C | Version : 2.96 |
+-------------------------------+---------------------------------------+
| Project manager: Eric Stolz | Date : 02/12/2002 |
+-----------------------------------------------------------------------+
| Description : APCI-1710 pulse encoder module |
| |
| |
+-----------------------------------------------------------------------+
| UPDATES |
+-----------------------------------------------------------------------+
| Date | Author | Description of updates |
+----------+-----------+------------------------------------------------+
| | | |
|----------|-----------|------------------------------------------------|
| 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
| | | available |
+-----------------------------------------------------------------------+
*/
/*
+----------------------------------------------------------------------------+
| Included files |
+----------------------------------------------------------------------------+
*/
#include "APCI1710_Inp_cpt.h"
/*
+----------------------------------------------------------------------------+
| Function Name : _INT_ i_APCI1710_InitPulseEncoder |
| (BYTE_ b_BoardHandle, |
| BYTE_ b_ModulNbr, |
| BYTE_ b_PulseEncoderNbr, |
| BYTE_ b_InputLevelSelection, |
| BYTE_ 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 : BYTE_ b_BoardHandle : Handle of board APCI-1710|
| BYTE_ b_ModulNbr : Module number to |
| configure (0 to 3) |
| BYTE_ b_PulseEncoderNbr : Pulse encoder selection |
| (0 to 3) |
| BYTE_ 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.|
| BYTE_ 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 =(BYTE) CR_AREF(insn->chanspec);
b_PulseEncoderNbr =(BYTE) data[0];
b_InputLevelSelection =(BYTE) data[1];
b_TriggerOutputAction =(BYTE) data[2];
ul_StartValue =(ULONG) data[3];
|
+----------------------------------------------------------------------------+
| Output Parameters : - |
+----------------------------------------------------------------------------+
| Return Value : 0: No error |
| -1: The handle parameter of the board is wrong |
| -2: The module is not a pulse encoder module |
| -3: Pulse encoder selection is wrong |
| -4: Input level selection is wrong |
| -5: Digital TRIGGER output action selection is wrong |
| -6: Pulse encoder start value is wrong |
+----------------------------------------------------------------------------+
*/
INT i_APCI1710_InsnConfigInitPulseEncoder(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
{
INT i_ReturnValue = 0;
DWORD dw_IntRegister;
BYTE b_ModulNbr;
BYTE b_PulseEncoderNbr;
BYTE b_InputLevelSelection;
BYTE b_TriggerOutputAction;
ULONG ul_StartValue;
b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
b_PulseEncoderNbr = (BYTE) data[0];
b_InputLevelSelection = (BYTE) data[1];
b_TriggerOutputAction = (BYTE) data[2];
ul_StartValue = (ULONG) 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 |
| (BYTE_ b_BoardHandle, |
| BYTE_ b_ModulNbr, |
| BYTE_ b_PulseEncoderNbr, |
| BYTE_ b_CycleSelection, |
| BYTE_ 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 : BYTE_ b_BoardHandle : Handle of board APCI-1710|
| BYTE_ b_ModulNbr : Module number to |
| configure (0 to 3) |
| BYTE_ b_PulseEncoderNbr : Pulse encoder selection |
| (0 to 3) |
| BYTE_ 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. |
| BYTE_ 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 =(BYTE) CR_AREF(insn->chanspec);
b_Action =(BYTE) data[0];
b_PulseEncoderNbr =(BYTE) data[1];
b_CycleSelection =(BYTE) data[2];
b_InterruptHandling =(BYTE) data[3];|
+----------------------------------------------------------------------------+
| Output Parameters : - |
+----------------------------------------------------------------------------+
| Return Value : 0: No error |
| -1: The handle parameter of the board is wrong |
| -2: Module selection is wrong |
| -3: Pulse encoder selection is wrong |
| -4: Pulse encoder not initialised. |
| See function "i_APCI1710_InitPulseEncoder" |
| -5: Cycle selection mode is wrong |
| -6: Interrupt handling mode is wrong |
| -7: Interrupt routine not installed. |
| See function "i_APCI1710_SetBoardIntRoutineX" |
+----------------------------------------------------------------------------+
*/
INT i_APCI1710_InsnWriteEnableDisablePulseEncoder(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
{
INT i_ReturnValue = 0;
BYTE b_ModulNbr;
BYTE b_PulseEncoderNbr;
BYTE b_CycleSelection;
BYTE b_InterruptHandling;
BYTE b_Action;
i_ReturnValue = insn->n;
b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
b_Action = (BYTE) data[0];
b_PulseEncoderNbr = (BYTE) data[1];
b_CycleSelection = (BYTE) data[2];
b_InterruptHandling = (BYTE) 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 |
| (BYTE_ b_BoardHandle, |
| BYTE_ b_ModulNbr, |
| BYTE_ b_PulseEncoderNbr, |
| PBYTE_ pb_Status) |
+----------------------------------------------------------------------------+
| Task APCI1710_PULSEENCODER_READ : Reads the pulse encoder status
and valuefrom selected pulse |
| encoder (b_PulseEncoderNbr) from selected module |
| (b_ModulNbr). |
+----------------------------------------------------------------------------+
BYTE 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 : BYTE_ b_BoardHandle : Handle of board APCI-1710|
| CRAREF() BYTE_ b_ModulNbr : Module number to |
| configure (0 to 3) |
| data[1] BYTE_ b_PulseEncoderNbr : Pulse encoder selection |
| (0 to 3)
APCI1710_PULSEENCODER_WRITE
data[2] ULONG_ ul_WriteValue : 32-bit value to be |
| written |
+----------------------------------------------------------------------------+
| Output Parameters : PBYTE_ 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 (BYTE_ b_BoardHandle,
BYTE_ b_ModulNbr,
BYTE_ b_PulseEncoderNbr,
PBYTE_ pb_Status)
*/
INT i_APCI1710_InsnBitsReadWritePulseEncoder(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
{
INT i_ReturnValue = 0;
DWORD dw_StatusRegister;
BYTE b_ModulNbr;
BYTE b_PulseEncoderNbr;
PBYTE pb_Status;
BYTE b_Type;
PULONG pul_ReadValue;
ULONG ul_WriteValue;
i_ReturnValue = insn->n;
b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
b_Type = (BYTE) data[0];
b_PulseEncoderNbr = (BYTE) data[1];
pb_Status = (PBYTE) & data[0];
pul_ReadValue = (PULONG) & 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 =
(BYTE) (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 = (ULONG) data[2];
/*******************/
/* Write the value */
/*******************/
outl(ul_WriteValue,
devpriv->s_BoardInfos.
ui_Address +
(4 * b_PulseEncoderNbr) +
(64 * b_ModulNbr));
} //end of switch
} else {
/*********************************/
/* Pulse encoder not initialised */
/*********************************/
DPRINTK("Pulse encoder not initialised\n");
i_ReturnValue = -4;
}
} else {
/************************************/
/* Pulse encoder selection is wrong */
/************************************/
DPRINTK("Pulse encoder selection is wrong\n");
i_ReturnValue = -3;
}
} else {
/*****************************/
/* Module selection is wrong */
/*****************************/
DPRINTK("Module selection is wrong\n");
i_ReturnValue = -2;
}
return (i_ReturnValue);
}
INT i_APCI1710_InsnReadInterruptPulseEncoder(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
{
data[0] = devpriv->s_InterruptParameters.
s_FIFOInterruptParameters[devpriv->
s_InterruptParameters.ui_Read].b_OldModuleMask;
data[1] = devpriv->s_InterruptParameters.
s_FIFOInterruptParameters[devpriv->
s_InterruptParameters.ui_Read].ul_OldInterruptMask;
data[2] = devpriv->s_InterruptParameters.
s_FIFOInterruptParameters[devpriv->
s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
/***************************/
/* Increment the read FIFO */
/***************************/
devpriv->s_InterruptParameters.
ui_Read = (devpriv->
s_InterruptParameters.ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
return insn->n;
}

View File

@ -0,0 +1,52 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
#define APCI1710_SINGLE 0
#define APCI1710_CONTINUOUS 1
#define APCI1710_PULSEENCODER_READ 0
#define APCI1710_PULSEENCODER_WRITE 1
INT i_APCI1710_InsnConfigInitPulseEncoder(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
INT i_APCI1710_InsnWriteEnableDisablePulseEncoder(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
/*
+----------------------------------------------------------------------------+
| READ PULSE ENCODER FUNCTIONS |
+----------------------------------------------------------------------------+
*/
INT i_APCI1710_InsnReadInterruptPulseEncoder(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
/*
+----------------------------------------------------------------------------+
| WRITE PULSE ENCODER FUNCTIONS |
+----------------------------------------------------------------------------+
*/
INT i_APCI1710_InsnBitsReadWritePulseEncoder(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,79 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
#define APCI1710_30MHZ 30
#define APCI1710_33MHZ 33
#define APCI1710_40MHZ 40
#define APCI1710_PWM_INIT 0
#define APCI1710_PWM_GETINITDATA 1
#define APCI1710_PWM_DISABLE 0
#define APCI1710_PWM_ENABLE 1
#define APCI1710_PWM_NEWTIMING 2
INT i_APCI1710_InsnConfigPWM(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI1710_InitPWM(comedi_device * dev,
BYTE b_ModulNbr,
BYTE b_PWM,
BYTE b_ClockSelection,
BYTE b_TimingUnit,
ULONG ul_LowTiming,
ULONG ul_HighTiming,
PULONG pul_RealLowTiming, PULONG pul_RealHighTiming);
INT i_APCI1710_GetPWMInitialisation(comedi_device * dev,
BYTE b_ModulNbr,
BYTE b_PWM,
PBYTE pb_TimingUnit,
PULONG pul_LowTiming,
PULONG pul_HighTiming,
PBYTE pb_StartLevel,
PBYTE pb_StopMode,
PBYTE pb_StopLevel,
PBYTE pb_ExternGate, PBYTE pb_InterruptEnable, PBYTE pb_Enable);
INT i_APCI1710_InsnWritePWM(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI1710_EnablePWM(comedi_device * dev,
BYTE b_ModulNbr,
BYTE b_PWM,
BYTE b_StartLevel,
BYTE b_StopMode,
BYTE b_StopLevel, BYTE b_ExternGate, BYTE b_InterruptEnable);
INT i_APCI1710_SetNewPWMTiming(comedi_device * dev,
BYTE b_ModulNbr,
BYTE b_PWM, BYTE b_TimingUnit, ULONG ul_LowTiming, ULONG ul_HighTiming);
INT i_APCI1710_DisablePWM(comedi_device * dev, BYTE b_ModulNbr, BYTE b_PWM);
INT i_APCI1710_InsnReadGetPWMStatus(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI1710_InsnBitsReadPWMInterrupt(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);

View File

@ -0,0 +1,848 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
/*
+-----------------------------------------------------------------------+
| (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+-----------------------------------------------------------------------+
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+-----------------------------------------------------------------------+
| Project : 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 |
| |
| |
+-----------------------------------------------------------------------+
| UPDATES |
+-----------------------------------------------------------------------+
| Date | Author | Description of updates |
+----------+-----------+------------------------------------------------+
| 13/05/98 | S. Weber | SSI digital input / output implementation |
|----------|-----------|------------------------------------------------|
| 22/03/00 | C.Guinot | 0100/0226 -> 0200/0227 |
| | | Änderung in InitSSI Funktion |
| | | b_SSIProfile >= 2 anstatt b_SSIProfile > 2 |
| | | |
+-----------------------------------------------------------------------+
| 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
| | | available |
+-----------------------------------------------------------------------+
*/
/*
+----------------------------------------------------------------------------+
| Included files |
+----------------------------------------------------------------------------+
*/
#include "APCI1710_Ssi.h"
/*
+----------------------------------------------------------------------------+
| Function Name : _INT_ i_APCI1710_InitSSI |
| (BYTE_ b_BoardHandle, |
| BYTE_ b_ModulNbr, |
| BYTE_ b_SSIProfile, |
| BYTE_ b_PositionTurnLength, |
| BYTE_ b_TurnCptLength, |
| BYTE_ b_PCIInputClock, |
| ULONG_ ul_SSIOutputClock, |
| BYTE_ 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 : BYTE_ b_BoardHandle : Handle of board APCI-1710|
| BYTE_ b_ModulNbr : Module number to |
| configure (0 to 3) |
| BYTE_ b_SSIProfile : Selection from SSI |
| profile length (2 to 32).|
| BYTE_ b_PositionTurnLength : Selection from SSI |
| position data length |
| (1 to 31). |
| BYTE_ b_TurnCptLength : Selection from SSI turn |
| counter data length |
| (1 to 31). |
| BYTE 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. |
| BYTE 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 = (BYTE) data[0];
b_PositionTurnLength= (BYTE) data[1];
b_TurnCptLength = (BYTE) data[2];
b_PCIInputClock = (BYTE) data[3];
ul_SSIOutputClock = (ULONG) data[4];
b_SSICountingMode = (BYTE) 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 |
+----------------------------------------------------------------------------+
*/
INT i_APCI1710_InsnConfigInitSSI(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
INT i_ReturnValue = 0;
UINT ui_TimerValue;
BYTE b_ModulNbr, b_SSIProfile, b_PositionTurnLength, b_TurnCptLength,
b_PCIInputClock, b_SSICountingMode;
ULONG ul_SSIOutputClock;
b_ModulNbr = CR_AREF(insn->chanspec);
b_SSIProfile = (BYTE) data[0];
b_PositionTurnLength = (BYTE) data[1];
b_TurnCptLength = (BYTE) data[2];
b_PCIInputClock = (BYTE) data[3];
ul_SSIOutputClock = (ULONG) data[4];
b_SSICountingMode = (BYTE) 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
=
(UINT)
(
((ULONG) (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 |
| (BYTE_ b_BoardHandle, |
| BYTE_ b_ModulNbr, |
| BYTE_ b_SelectedSSI, |
| PULONG_ pul_Position, |
| PULONG_ pul_TurnCpt)
INT i_APCI1710_ReadSSIValue(comedi_device *dev,comedi_subdevice *s,
comedi_insn *insn,lsampl_t *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 : BYTE_ b_BoardHandle : Handle of board APCI-1710|
| BYTE_ b_ModulNbr : Module number to |
| configure (0 to 3) |
| BYTE_ b_SelectedSSI : Selection from SSI |
| counter (0 to 2)
b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
b_SelectedSSI = (BYTE) CR_CHAN(insn->chanspec); (in case of single ssi)
b_ReadType = (BYTE) CR_RANGE(insn->chanspec);
|
+----------------------------------------------------------------------------+
| Output Parameters : PULONG_ pul_Position : SSI position in the turn |
| PULONG_ pul_TurnCpt : Number of turns
pul_Position = (PULONG) &data[0];
pul_TurnCpt = (PULONG) &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 |
+----------------------------------------------------------------------------+
*/
INT i_APCI1710_InsnReadSSIValue(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
INT i_ReturnValue = 0;
BYTE b_Cpt;
BYTE b_Length;
BYTE b_Schift;
BYTE b_SSICpt;
DWORD dw_And;
DWORD dw_And1;
DWORD dw_And2;
DWORD dw_StatusReg;
DWORD dw_CounterValue;
BYTE b_ModulNbr;
BYTE b_SelectedSSI;
BYTE b_ReadType;
PULONG pul_Position;
PULONG pul_TurnCpt;
PULONG pul_Position1;
PULONG pul_TurnCpt1;
i_ReturnValue = insn->n;
pul_Position1 = (PULONG) & data[0];
// For Read1
pul_TurnCpt1 = (PULONG) & data[1];
// For Read all
pul_Position = (PULONG) & data[0]; //0-2
pul_TurnCpt = (PULONG) & data[3]; //3-5
b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
b_SelectedSSI = (BYTE) CR_CHAN(insn->chanspec);
b_ReadType = (BYTE) 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 |
| (BYTE_ b_BoardHandle, |
| BYTE_ b_ModulNbr, |
| BYTE_ b_InputChannel, |
| PBYTE_ pb_ChannelStatus) |
+----------------------------------------------------------------------------+
| Task :
(0) Set the digital output from selected SSI moule |
| (b_ModuleNbr) ON
(1) Set the digital output from selected SSI moule |
| (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 : BYTE_ b_BoardHandle : Handle of board APCI-1710|
| BYTE_ b_ModulNbr CR_AREF : Module number to |
| configure (0 to 3) |
| BYTE_ b_InputChannel CR_CHAN : Selection from digital |
| data[0] which IOTYPE input ( 0 to 2) |
+----------------------------------------------------------------------------+
| Output Parameters : PBYTE_ 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 |
+----------------------------------------------------------------------------+
*/
INT i_APCI1710_InsnBitsSSIDigitalIO(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
INT i_ReturnValue = 0;
DWORD dw_StatusReg;
BYTE b_ModulNbr;
BYTE b_InputChannel;
PBYTE pb_ChannelStatus;
PBYTE pb_InputStatus;
BYTE b_IOType;
i_ReturnValue = insn->n;
b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
b_IOType = (BYTE) 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 = (BYTE) CR_CHAN(insn->chanspec);
pb_ChannelStatus = (PBYTE) & data[0];
if (b_InputChannel <= 2) {
/**************************/
/* Read all digital input */
/**************************/
dw_StatusReg =
inl(devpriv->s_BoardInfos.
ui_Address + (64 * b_ModulNbr));
*pb_ChannelStatus =
(BYTE) (((~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 = (PBYTE) & data[0];
dw_StatusReg =
inl(devpriv->s_BoardInfos.ui_Address +
(64 * b_ModulNbr));
*pb_InputStatus =
(BYTE) (((~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);
}

View File

@ -0,0 +1,52 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
#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
/*
+----------------------------------------------------------------------------+
| SSI INISIALISATION FUNCTION |
+----------------------------------------------------------------------------+
*/
INT i_APCI1710_InsnConfigInitSSI(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI1710_InsnReadSSIValue(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI1710_InsnBitsSSIDigitalIO(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,63 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
#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
/*
+----------------------------------------------------------------------------+
| TOR_COUNTER INISIALISATION FUNCTION |
+----------------------------------------------------------------------------+
*/
INT i_APCI1710_InsnConfigInitTorCounter(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
INT i_APCI1710_InsnWriteEnableDisableTorCounter(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
INT i_APCI1710_InsnReadGetTorCounterInitialisation(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
/*
+----------------------------------------------------------------------------+
| TOR_COUNTER READ FUNCTION |
+----------------------------------------------------------------------------+
*/
INT i_APCI1710_InsnBitsGetTorCounterProgressStatusAndValue(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,56 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
#define APCI1710_TTL_INIT 0
#define APCI1710_TTL_INITDIRECTION 1
#define APCI1710_TTL_READCHANNEL 0
#define APCI1710_TTL_READPORT 1
/*
+----------------------------------------------------------------------------+
| TTL INISIALISATION FUNCTION |
+----------------------------------------------------------------------------+
*/
INT i_APCI1710_InsnConfigInitTTLIO(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
/*
+----------------------------------------------------------------------------+
| TTL INPUT FUNCTION |
+----------------------------------------------------------------------------+
*/
INT i_APCI1710_InsnBitsReadTTLIO(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI1710_InsnReadTTLIOAllPortValue(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
/*
+----------------------------------------------------------------------------+
| TTL OUTPUT FUNCTIONS |
+----------------------------------------------------------------------------+
*/
INT i_APCI1710_InsnWriteSetTTLIOChlOnOff(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);

View File

@ -0,0 +1,203 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
/*
+-----------------------------------------------------------------------+
| (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+-----------------------------------------------------------------------+
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+-------------------------------+---------------------------------------+
| Project : ADDI HEADER READ WRITER | Compiler : Visual C++ |
| Module name : S5920.cpp | Version : 6.0 |
+-------------------------------+---------------------------------------+
| Author : E. LIBS Date : 02/05/2002 |
+-----------------------------------------------------------------------+
| Description : DLL with the S5920 PCI Controller functions |
+-----------------------------------------------------------------------+
| UPDATE'S |
+-----------------------------------------------------------------------+
| Date | Author | Description of updates |
+----------+-----------+------------------------------------------------+
| 28/08/02 | LIBS Eric | Add return codes each time a function of the |
| | | Addi Library is called |
+-----------------------------------------------------------------------+
| 31/07/03 | KRAUTH J. | Changes for the MSX-Box |
+-----------------------------------------------------------------------+
*/
#include "addi_amcc_S5920.h"
/*+----------------------------------------------------------------------------+*/
/*| Function Name : INT i_AddiHeaderRW_ReadEeprom |*/
/*| (INT i_NbOfWordsToRead, |*/
/*| DWORD dw_PCIBoardEepromAddress, |*/
/*| WORD w_EepromStartAddress, |*/
/*| PWORD pw_DataRead) |*/
/*+----------------------------------------------------------------------------+*/
/*| Task : Read word from the 5920 eeprom. |*/
/*+----------------------------------------------------------------------------+*/
/*| Input Parameters : INT i_NbOfWordsToRead : Nbr. of word to read |*/
/*| DWORD dw_PCIBoardEepromAddress : Address of the eeprom |*/
/*| WORD w_EepromStartAddress : Eeprom strat address |*/
/*+----------------------------------------------------------------------------+*/
/*| Output Parameters : PWORD pw_DataRead : Read data |*/
/*+----------------------------------------------------------------------------+*/
/*| Return Value : - |*/
/*+----------------------------------------------------------------------------+*/
INT i_AddiHeaderRW_ReadEeprom(INT i_NbOfWordsToRead,
DWORD dw_PCIBoardEepromAddress,
WORD w_EepromStartAddress, PWORD pw_DataRead)
{
DWORD dw_eeprom_busy = 0;
INT i_Counter = 0;
INT i_WordCounter;
INT i;
BYTE pb_ReadByte[1];
BYTE b_ReadLowByte = 0;
BYTE b_ReadHighByte = 0;
BYTE b_SelectedAddressLow = 0;
BYTE b_SelectedAddressHigh = 0;
WORD w_ReadWord = 0;
for (i_WordCounter = 0; i_WordCounter < i_NbOfWordsToRead;
i_WordCounter++) {
do {
dw_eeprom_busy =
inl(dw_PCIBoardEepromAddress +
AMCC_OP_REG_MCSR);
dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
}
while (dw_eeprom_busy == EEPROM_BUSY);
for (i_Counter = 0; i_Counter < 2; i_Counter++) {
b_SelectedAddressLow = (w_EepromStartAddress + i_Counter) % 256; //Read the low 8 bit part
b_SelectedAddressHigh = (w_EepromStartAddress + i_Counter) / 256; //Read the high 8 bit part
//Select the load low address mode
outb(NVCMD_LOAD_LOW,
dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
3);
//Wait on busy
do {
dw_eeprom_busy =
inl(dw_PCIBoardEepromAddress +
AMCC_OP_REG_MCSR);
dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
}
while (dw_eeprom_busy == EEPROM_BUSY);
//Load the low address
outb(b_SelectedAddressLow,
dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
2);
//Wait on busy
do {
dw_eeprom_busy =
inl(dw_PCIBoardEepromAddress +
AMCC_OP_REG_MCSR);
dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
}
while (dw_eeprom_busy == EEPROM_BUSY);
//Select the load high address mode
outb(NVCMD_LOAD_HIGH,
dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
3);
//Wait on busy
do {
dw_eeprom_busy =
inl(dw_PCIBoardEepromAddress +
AMCC_OP_REG_MCSR);
dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
}
while (dw_eeprom_busy == EEPROM_BUSY);
//Load the high address
outb(b_SelectedAddressHigh,
dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
2);
//Wait on busy
do {
dw_eeprom_busy =
inl(dw_PCIBoardEepromAddress +
AMCC_OP_REG_MCSR);
dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
}
while (dw_eeprom_busy == EEPROM_BUSY);
//Select the READ mode
outb(NVCMD_BEGIN_READ,
dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
3);
//Wait on busy
do {
dw_eeprom_busy =
inl(dw_PCIBoardEepromAddress +
AMCC_OP_REG_MCSR);
dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
}
while (dw_eeprom_busy == EEPROM_BUSY);
//Read data into the EEPROM
*pb_ReadByte =
inb(dw_PCIBoardEepromAddress +
AMCC_OP_REG_MCSR + 2);
//Wait on busy
do {
dw_eeprom_busy =
inl(dw_PCIBoardEepromAddress +
AMCC_OP_REG_MCSR);
dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
}
while (dw_eeprom_busy == EEPROM_BUSY);
//Select the upper address part
if (i_Counter == 0) {
b_ReadLowByte = pb_ReadByte[0];
} else {
b_ReadHighByte = pb_ReadByte[0];
}
//Sleep
for (i = 0; i < 10000; i++) ;
}
w_ReadWord =
(b_ReadLowByte | (((unsigned short)b_ReadHighByte) *
256));
pw_DataRead[i_WordCounter] = w_ReadWord;
w_EepromStartAddress += 2; // to read the next word
} // for (...) i_NbOfWordsToRead
return (0);
}

View File

@ -0,0 +1,59 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
/*
#define VOID void
#define INT int
#define UINT unsigned int
#define SHORT short
#define USHORT unsigned short
#define CHAR char
#define BYTE unsigned char
#define WORD unsigned int
#define LONG long
#define ULONG unsigned long
#define DWORD unsigned long
#define DOUBLE double
#define PINT int *
#define PUINT unsigned int *
#define PSHORT short *
#define PUSHORT unsigned short *
#define PCHAR char *
#define PBYTE unsigned char *
#define PWORD unsigned int *
#define PLONG long *
#define PULONG unsigned long *
#define PDWORD unsigned long *
#define PDOUBLE double *
*/
#define AMCC_OP_REG_MCSR 0x3c
#define EEPROM_BUSY 0x80000000
#define NVCMD_LOAD_LOW (0x4 << 5 ) // nvRam load low command
#define NVCMD_LOAD_HIGH (0x5 << 5 ) // nvRam load high command
#define NVCMD_BEGIN_READ (0x7 << 5 ) // nvRam begin read command
#define NVCMD_BEGIN_WRITE (0x6 << 5) //EEPROM begin write command
INT i_AddiHeaderRW_ReadEeprom(INT i_NbOfWordsToRead,
DWORD dw_PCIBoardEepromAddress,
WORD w_EepromStartAddress, PWORD pw_DataRead);

View File

@ -0,0 +1,490 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
/*
+-----------------------------------------------------------------------+
| (C) ADDI-DATA GmbH Dieselstrasse 3 D-77833 Ottersweier |
+-----------------------------------------------------------------------+
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+-----------------------------------------------------------------------+
| Project : ADDI DATA | Compiler : GCC |
| Modulname : addi_amcc_s5933.h | Version : 2.96 Redhat Linux |
| | kernel-2.4.2 |
+-------------------------------+---------------------------------------+
| Author : | Date : |
+-----------------------------------------------------------------------+
| Description :|Header file for AMCC s 5933 |
+-----------------------------------------------------------------------+
| UPDATE'S |
+-----------------------------------------------------------------------+
| Date | Author | Description of updates |
+----------+-----------+------------------------------------------------+
| | | |
| | | |
| | | |
| | | |
| | | |
+----------+-----------+------------------------------------------------+
| | | |
| | | |
| | | |
+----------+-----------+------------------------------------------------+
*/
#ifndef _AMCC_S5933_H_
#define _AMCC_S5933_H_
#include "../../comedidev.h"
#include "../comedi_pci.h"
#ifdef PCI_SUPPORT_VER1
#error No support for 2.1.55 and older
#endif
#define FIFO_ADVANCE_ON_BYTE_2 0x20000000 // written on base0
#define AMWEN_ENABLE 0x02 // added for step 6 dma written on base2
#define A2P_FIFO_WRITE_ENABLE 0x01
#define AGCSTS_TC_ENABLE 0x10000000 // for transfer count enable bit
// ADDON RELATED ADDITIONS
// Constant
#define APCI3120_ENABLE_TRANSFER_ADD_ON_LOW 0x00
#define APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH 0x1200
#define APCI3120_A2P_FIFO_MANAGEMENT 0x04000400L
#define APCI3120_AMWEN_ENABLE 0x02
#define APCI3120_A2P_FIFO_WRITE_ENABLE 0x01
#define APCI3120_FIFO_ADVANCE_ON_BYTE_2 0x20000000L
#define APCI3120_ENABLE_WRITE_TC_INT 0x00004000L
#define APCI3120_CLEAR_WRITE_TC_INT 0x00040000L
#define APCI3120_DISABLE_AMWEN_AND_A2P_FIFO_WRITE 0x0
#define APCI3120_DISABLE_BUS_MASTER_ADD_ON 0x0
#define APCI3120_DISABLE_BUS_MASTER_PCI 0x0
// ADD_ON ::: this needed since apci supports 16 bit interface to add on
#define APCI3120_ADD_ON_AGCSTS_LOW 0x3C
#define APCI3120_ADD_ON_AGCSTS_HIGH APCI3120_ADD_ON_AGCSTS_LOW + 2
#define APCI3120_ADD_ON_MWAR_LOW 0x24
#define APCI3120_ADD_ON_MWAR_HIGH APCI3120_ADD_ON_MWAR_LOW + 2
#define APCI3120_ADD_ON_MWTC_LOW 0x058
#define APCI3120_ADD_ON_MWTC_HIGH APCI3120_ADD_ON_MWTC_LOW + 2
// AMCC
#define APCI3120_AMCC_OP_MCSR 0x3C
#define APCI3120_AMCC_OP_REG_INTCSR 0x38
/****************************************************************************/
/* AMCC Operation Register Offsets - PCI */
/****************************************************************************/
#define AMCC_OP_REG_OMB1 0x00
#define AMCC_OP_REG_OMB2 0x04
#define AMCC_OP_REG_OMB3 0x08
#define AMCC_OP_REG_OMB4 0x0c
#define AMCC_OP_REG_IMB1 0x10
#define AMCC_OP_REG_IMB2 0x14
#define AMCC_OP_REG_IMB3 0x18
#define AMCC_OP_REG_IMB4 0x1c
#define AMCC_OP_REG_FIFO 0x20
#define AMCC_OP_REG_MWAR 0x24
#define AMCC_OP_REG_MWTC 0x28
#define AMCC_OP_REG_MRAR 0x2c
#define AMCC_OP_REG_MRTC 0x30
#define AMCC_OP_REG_MBEF 0x34
#define AMCC_OP_REG_INTCSR 0x38
#define AMCC_OP_REG_INTCSR_SRC (AMCC_OP_REG_INTCSR + 2) /* INT source */
#define AMCC_OP_REG_INTCSR_FEC (AMCC_OP_REG_INTCSR + 3) /* FIFO ctrl */
#define AMCC_OP_REG_MCSR 0x3c
#define AMCC_OP_REG_MCSR_NVDATA (AMCC_OP_REG_MCSR + 2) /* Data in byte 2 */
#define AMCC_OP_REG_MCSR_NVCMD (AMCC_OP_REG_MCSR + 3) /* Command in byte 3 */
#define AMCC_FIFO_DEPTH_DWORD 8
#define AMCC_FIFO_DEPTH_BYTES (8 * sizeof (u32))
/****************************************************************************/
/* AMCC Operation Registers Size - PCI */
/****************************************************************************/
#define AMCC_OP_REG_SIZE 64 /* in bytes */
/****************************************************************************/
/* AMCC Operation Register Offsets - Add-on */
/****************************************************************************/
#define AMCC_OP_REG_AIMB1 0x00
#define AMCC_OP_REG_AIMB2 0x04
#define AMCC_OP_REG_AIMB3 0x08
#define AMCC_OP_REG_AIMB4 0x0c
#define AMCC_OP_REG_AOMB1 0x10
#define AMCC_OP_REG_AOMB2 0x14
#define AMCC_OP_REG_AOMB3 0x18
#define AMCC_OP_REG_AOMB4 0x1c
#define AMCC_OP_REG_AFIFO 0x20
#define AMCC_OP_REG_AMWAR 0x24
#define AMCC_OP_REG_APTA 0x28
#define AMCC_OP_REG_APTD 0x2c
#define AMCC_OP_REG_AMRAR 0x30
#define AMCC_OP_REG_AMBEF 0x34
#define AMCC_OP_REG_AINT 0x38
#define AMCC_OP_REG_AGCSTS 0x3c
#define AMCC_OP_REG_AMWTC 0x58
#define AMCC_OP_REG_AMRTC 0x5c
/****************************************************************************/
/* AMCC - Add-on General Control/Status Register */
/****************************************************************************/
#define AGCSTS_CONTROL_MASK 0xfffff000
#define AGCSTS_NV_ACC_MASK 0xe0000000
#define AGCSTS_RESET_MASK 0x0e000000
#define AGCSTS_NV_DA_MASK 0x00ff0000
#define AGCSTS_BIST_MASK 0x0000f000
#define AGCSTS_STATUS_MASK 0x000000ff
#define AGCSTS_TCZERO_MASK 0x000000c0
#define AGCSTS_FIFO_ST_MASK 0x0000003f
#define AGCSTS_RESET_MBFLAGS 0x08000000
#define AGCSTS_RESET_P2A_FIFO 0x04000000
#define AGCSTS_RESET_A2P_FIFO 0x02000000
#define AGCSTS_RESET_FIFOS (AGCSTS_RESET_A2P_FIFO | AGCSTS_RESET_P2A_FIFO)
#define AGCSTS_A2P_TCOUNT 0x00000080
#define AGCSTS_P2A_TCOUNT 0x00000040
#define AGCSTS_FS_P2A_EMPTY 0x00000020
#define AGCSTS_FS_P2A_HALF 0x00000010
#define AGCSTS_FS_P2A_FULL 0x00000008
#define AGCSTS_FS_A2P_EMPTY 0x00000004
#define AGCSTS_FS_A2P_HALF 0x00000002
#define AGCSTS_FS_A2P_FULL 0x00000001
/****************************************************************************/
/* AMCC - Add-on Interrupt Control/Status Register */
/****************************************************************************/
#define AINT_INT_MASK 0x00ff0000
#define AINT_SEL_MASK 0x0000ffff
#define AINT_IS_ENSEL_MASK 0x00001f1f
#define AINT_INT_ASSERTED 0x00800000
#define AINT_BM_ERROR 0x00200000
#define AINT_BIST_INT 0x00100000
#define AINT_RT_COMPLETE 0x00080000
#define AINT_WT_COMPLETE 0x00040000
#define AINT_OUT_MB_INT 0x00020000
#define AINT_IN_MB_INT 0x00010000
#define AINT_READ_COMPL 0x00008000
#define AINT_WRITE_COMPL 0x00004000
#define AINT_OMB_ENABLE 0x00001000
#define AINT_OMB_SELECT 0x00000c00
#define AINT_OMB_BYTE 0x00000300
#define AINT_IMB_ENABLE 0x00000010
#define AINT_IMB_SELECT 0x0000000c
#define AINT_IMB_BYTE 0x00000003
/* Enable Bus Mastering */
#define EN_A2P_TRANSFERS 0x00000400
/* FIFO Flag Reset */
#define RESET_A2P_FLAGS 0x04000000L
/* FIFO Relative Priority */
#define A2P_HI_PRIORITY 0x00000100L
/* Identify Interrupt Sources */
#define ANY_S593X_INT 0x00800000L
#define READ_TC_INT 0x00080000L
#define WRITE_TC_INT 0x00040000L
#define IN_MB_INT 0x00020000L
#define MASTER_ABORT_INT 0x00100000L
#define TARGET_ABORT_INT 0x00200000L
#define BUS_MASTER_INT 0x00200000L
/****************************************************************************/
struct pcilst_struct {
struct pcilst_struct *next;
int used;
struct pci_dev *pcidev;
unsigned short vendor;
unsigned short device;
unsigned char pci_bus;
unsigned char pci_slot;
unsigned char pci_func;
resource_size_t io_addr[5];
unsigned int irq;
};
struct pcilst_struct *amcc_devices; // ptr to root list of all amcc devices
static const int i_ADDIDATADeviceID[] = { 0x15B8, 0x10E8 };
/****************************************************************************/
void v_pci_card_list_init(unsigned short pci_vendor, char display);
void v_pci_card_list_cleanup(unsigned short pci_vendor);
struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id,
unsigned short device_id);
int i_find_free_pci_card_by_position(unsigned short vendor_id,
unsigned short device_id, unsigned short pci_bus,
unsigned short pci_slot, struct pcilst_struct **card);
struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
unsigned short device_id, unsigned short pci_bus,
unsigned short pci_slot, int i_Master);
int pci_card_alloc(struct pcilst_struct *amcc, int master);
int i_pci_card_free(struct pcilst_struct *amcc);
void v_pci_card_list_display(void);
int i_pci_card_data(struct pcilst_struct *amcc,
unsigned char *pci_bus, unsigned char *pci_slot,
unsigned char *pci_func, resource_size_t * io_addr, unsigned int *irq);
/****************************************************************************/
/* build list of amcc cards in this system */
void v_pci_card_list_init(unsigned short pci_vendor, char display)
{
struct pci_dev *pcidev;
struct pcilst_struct *amcc, *last;
int i;
int i_Count = 0;
amcc_devices = NULL;
last = NULL;
for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
pcidev != NULL;
pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
for (i_Count = 0; i_Count < 2; i_Count++) {
pci_vendor = i_ADDIDATADeviceID[i_Count];
if (pcidev->vendor == pci_vendor) {
amcc = kmalloc(sizeof(*amcc), GFP_KERNEL);
memset(amcc, 0, sizeof(*amcc));
amcc->pcidev = pcidev;
if (last) {
last->next = amcc;
} else {
amcc_devices = amcc;
}
last = amcc;
amcc->vendor = pcidev->vendor;
amcc->device = pcidev->device;
amcc->pci_bus = pcidev->bus->number;
amcc->pci_slot = PCI_SLOT(pcidev->devfn);
amcc->pci_func = PCI_FUNC(pcidev->devfn);
/* Note: resources may be invalid if PCI device
* not enabled, but they are corrected in
* pci_card_alloc. */
for (i = 0; i < 5; i++)
amcc->io_addr[i] =
pci_resource_start(pcidev, i);
amcc->irq = pcidev->irq;
}
}
}
if (display)
v_pci_card_list_display();
}
/****************************************************************************/
/* free up list of amcc cards in this system */
void v_pci_card_list_cleanup(unsigned short pci_vendor)
{
struct pcilst_struct *amcc, *next;
for (amcc = amcc_devices; amcc; amcc = next) {
next = amcc->next;
kfree(amcc);
}
amcc_devices = NULL;
}
/****************************************************************************/
/* find first unused card with this device_id */
struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id,
unsigned short device_id)
{
struct pcilst_struct *amcc, *next;
for (amcc = amcc_devices; amcc; amcc = next) {
next = amcc->next;
if ((!amcc->used) && (amcc->device == device_id)
&& (amcc->vendor == vendor_id))
return amcc;
}
return NULL;
}
/****************************************************************************/
/* find card on requested position */
int i_find_free_pci_card_by_position(unsigned short vendor_id,
unsigned short device_id, unsigned short pci_bus,
unsigned short pci_slot, struct pcilst_struct **card)
{
struct pcilst_struct *amcc, *next;
*card = NULL;
for (amcc = amcc_devices; amcc; amcc = next) {
next = amcc->next;
if ((amcc->vendor == vendor_id) && (amcc->device == device_id)
&& (amcc->pci_bus == pci_bus)
&& (amcc->pci_slot == pci_slot)) {
if (!(amcc->used)) {
*card = amcc;
return 0; // ok, card is found
} else {
rt_printk
(" - \nCard on requested position is used b:s %d:%d!\n",
pci_bus, pci_slot);
return 2; // card exist but is used
}
}
}
return 1; // no card found
}
/****************************************************************************/
/* mark card as used */
int pci_card_alloc(struct pcilst_struct *amcc, int master)
{
int i;
if (!amcc)
return -1;
if (amcc->used)
return 1;
if (comedi_pci_enable(amcc->pcidev, "addi_amcc_s5933"))
return -1;
/* Resources will be accurate now. */
for (i = 0; i < 5; i++)
amcc->io_addr[i] = pci_resource_start(amcc->pcidev, i);
if (master)
pci_set_master(amcc->pcidev);
amcc->used = 1;
return 0;
}
/****************************************************************************/
/* mark card as free */
int i_pci_card_free(struct pcilst_struct *amcc)
{
if (!amcc)
return -1;
if (!amcc->used)
return 1;
amcc->used = 0;
comedi_pci_disable(amcc->pcidev);
return 0;
}
/****************************************************************************/
/* display list of found cards */
void v_pci_card_list_display(void)
{
struct pcilst_struct *amcc, *next;
printk("List of pci cards\n");
printk("bus:slot:func vendor device io_amcc io_daq irq used\n");
for (amcc = amcc_devices; amcc; amcc = next) {
next = amcc->next;
printk("%2d %2d %2d 0x%4x 0x%4x 0x%8llx 0x%8llx %2u %2d\n", amcc->pci_bus, amcc->pci_slot, amcc->pci_func, amcc->vendor, amcc->device, (unsigned long long)amcc->io_addr[0], (unsigned long long)amcc->io_addr[2], amcc->irq, amcc->used);
}
}
/****************************************************************************/
/* return all card information for driver */
int i_pci_card_data(struct pcilst_struct *amcc,
unsigned char *pci_bus, unsigned char *pci_slot,
unsigned char *pci_func, resource_size_t * io_addr, unsigned int *irq)
{
int i;
if (!amcc)
return -1;
*pci_bus = amcc->pci_bus;
*pci_slot = amcc->pci_slot;
*pci_func = amcc->pci_func;
for (i = 0; i < 5; i++)
io_addr[i] = amcc->io_addr[i];
*irq = amcc->irq;
return 0;
}
/****************************************************************************/
/* select and alloc card */
struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
unsigned short device_id, unsigned short pci_bus,
unsigned short pci_slot, int i_Master)
{
struct pcilst_struct *card;
if ((pci_bus < 1) & (pci_slot < 1)) { // use autodetection
if ((card = ptr_find_free_pci_card_by_device(vendor_id,
device_id)) == NULL) {
rt_printk(" - Unused card not found in system!\n");
return NULL;
}
} else {
switch (i_find_free_pci_card_by_position(vendor_id, device_id,
pci_bus, pci_slot, &card)) {
case 1:
rt_printk
(" - Card not found on requested position b:s %d:%d!\n",
pci_bus, pci_slot);
return NULL;
case 2:
rt_printk
(" - Card on requested position is used b:s %d:%d!\n",
pci_bus, pci_slot);
return NULL;
}
}
if (pci_card_alloc(card, i_Master) != 0) {
rt_printk(" - Can't allocate card!\n");
return NULL;
}
return card;
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,482 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
/*
+-----------------------------------------------------------------------+
| (C) ADDI-DATA GmbH Dieselstrasse 3 D-77833 Ottersweier |
+-----------------------------------------------------------------------+
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+-----------------------------------------------------------------------+
| Project : ADDI-DATA | Compiler : GCC |
| Modulname : addi_common.h | Version : 2.96 |
+-------------------------------+---------------------------------------+
| Project manager: Eric Stolz | Date : 02/12/2002 |
+-----------------------------------------------------------------------+
| Description : ADDI COMMON Header File |
+-----------------------------------------------------------------------+
*/
//including header files
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/mm.h>
//#include <linux/malloc.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/timex.h>
#include <linux/timer.h>
#include <linux/pci.h>
#include <asm/io.h>
#include "../../comedidev.h"
#include "addi_amcc_s5933.h"
#include <linux/kmod.h>
#include <asm/uaccess.h>
#define ERROR -1
#define SUCCESS 1
// variable type definition
typedef void VOID, *PVOID;
typedef char CHAR, *PCHAR;
typedef const CHAR *PCSTR;
typedef unsigned char BYTE, *PBYTE;
typedef short SHORT, *PSHORT;
typedef unsigned short USHORT, *PUSHORT;
typedef unsigned short WORD, *PWORD;
typedef int INT, *PINT;;
typedef unsigned int UINT, *PUINT;
typedef int LONG, *PLONG; /* 32-bit */
typedef unsigned int ULONG, *PULONG; /* 32-bit */
typedef unsigned int DWORD, *PDWORD; /* 32-bit */
typedef unsigned long ULONG_PTR;
typedef const comedi_lrange *PCRANGE;
#define LOBYTE(W) (BYTE )((W)&0xFF)
#define HIBYTE(W) (BYTE )(((W)>>8)&0xFF)
#define MAKEWORD(H,L) (USHORT )((L)|( (H)<<8) )
#define LOWORD(W) (USHORT )((W)&0xFFFF)
#define HIWORD(W) (USHORT )(((W)>>16)&0xFFFF)
#define MAKEDWORD(H,L) (UINT )((L)|( (H)<<16) )
#define ADDI_ENABLE 1
#define ADDI_DISABLE 0
#define APCI1710_SAVE_INTERRUPT 1
#define ADDIDATA_EEPROM 1
#define ADDIDATA_NO_EEPROM 0
#define ADDIDATA_93C76 "93C76"
#define ADDIDATA_S5920 "S5920"
#define ADDIDATA_S5933 "S5933"
#define ADDIDATA_9054 "9054"
//ADDIDATA Enable Disable
#define ADDIDATA_ENABLE 1
#define ADDIDATA_DISABLE 0
// Structures
// structure for the boardtype
typedef struct {
PCSTR pc_DriverName; // driver name
INT i_VendorId; //PCI vendor a device ID of card
INT i_DeviceId;
INT i_IorangeBase0;
INT i_IorangeBase1;
INT i_IorangeBase2; // base 2 range
INT i_IorangeBase3; // base 3 range
INT i_PCIEeprom; // eeprom present or not
PCHAR pc_EepromChip; // type of chip
INT i_NbrAiChannel; // num of A/D chans
INT i_NbrAiChannelDiff; // num of A/D chans in diff mode
INT i_AiChannelList; // len of chanlist
INT i_NbrAoChannel; // num of D/A chans
INT i_AiMaxdata; // resolution of A/D
INT i_AoMaxdata; // resolution of D/A
PCRANGE pr_AiRangelist; // rangelist for A/D
PCRANGE pr_AoRangelist; // rangelist for D/A
INT i_NbrDiChannel; // Number of DI channels
INT i_NbrDoChannel; // Number of DO channels
INT i_DoMaxdata; // data to set all chanels high
INT i_NbrTTLChannel; // Number of TTL channels
PCRANGE pr_TTLRangelist; // rangelist for TTL
INT i_Dma; // dma present or not
INT i_Timer; // timer subdevice present or not
BYTE b_AvailableConvertUnit;
UINT ui_MinAcquisitiontimeNs; // Minimum Acquisition in Nano secs
UINT ui_MinDelaytimeNs; // Minimum Delay in Nano secs
// interrupt and reset
void (*v_hwdrv_Interrupt) (int irq, void *d);
int (*i_hwdrv_Reset) (comedi_device * dev);
//Subdevice functions
//ANALOG INPUT
int (*i_hwdrv_InsnConfigAnalogInput) (comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
int (*i_hwdrv_InsnReadAnalogInput) (comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
int (*i_hwdrv_InsnWriteAnalogInput) (comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
int (*i_hwdrv_InsnBitsAnalogInput) (comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
int (*i_hwdrv_CommandTestAnalogInput) (comedi_device * dev,
comedi_subdevice * s, comedi_cmd * cmd);
int (*i_hwdrv_CommandAnalogInput) (comedi_device * dev,
comedi_subdevice * s);
int (*i_hwdrv_CancelAnalogInput) (comedi_device * dev,
comedi_subdevice * s);
//Analog Output
int (*i_hwdrv_InsnConfigAnalogOutput) (comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
int (*i_hwdrv_InsnWriteAnalogOutput) (comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
int (*i_hwdrv_InsnBitsAnalogOutput) (comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
//Digital Input
int (*i_hwdrv_InsnConfigDigitalInput) (comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
int (*i_hwdrv_InsnReadDigitalInput) (comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
int (*i_hwdrv_InsnWriteDigitalInput) (comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
int (*i_hwdrv_InsnBitsDigitalInput) (comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
//Digital Output
int (*i_hwdrv_InsnConfigDigitalOutput) (comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
int (*i_hwdrv_InsnWriteDigitalOutput) (comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
int (*i_hwdrv_InsnBitsDigitalOutput) (comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
int (*i_hwdrv_InsnReadDigitalOutput) (comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
//TIMER
int (*i_hwdrv_InsnConfigTimer) (comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
int (*i_hwdrv_InsnWriteTimer) (comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
int (*i_hwdrv_InsnReadTimer) (comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
int (*i_hwdrv_InsnBitsTimer) (comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
//TTL IO
int (*i_hwdr_ConfigInitTTLIO) (comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
int (*i_hwdr_ReadTTLIOBits) (comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
int (*i_hwdr_ReadTTLIOAllPortValue) (comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
int (*i_hwdr_WriteTTLIOChlOnOff) (comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
} boardtype;
//MODULE INFO STRUCTURE
typedef union {
/*****************************/
/* Incremental counter infos */
/*****************************/
struct {
union {
struct {
BYTE b_ModeRegister1;
BYTE b_ModeRegister2;
BYTE b_ModeRegister3;
BYTE b_ModeRegister4;
} s_ByteModeRegister;
DWORD dw_ModeRegister1_2_3_4;
} s_ModeRegister;
struct {
unsigned int b_IndexInit:1;
unsigned int b_CounterInit:1;
unsigned int b_ReferenceInit:1;
unsigned int b_IndexInterruptOccur:1;
unsigned int b_CompareLogicInit:1;
unsigned int b_FrequencyMeasurementInit:1;
unsigned int b_FrequencyMeasurementEnable:1;
} s_InitFlag;
} s_SiemensCounterInfo;
/*************/
/* SSI infos */
/*************/
struct {
BYTE b_SSIProfile;
BYTE b_PositionTurnLength;
BYTE b_TurnCptLength;
BYTE b_SSIInit;
} s_SSICounterInfo;
/*****************/
/* TTL I/O infos */
/*****************/
struct {
BYTE b_TTLInit;
BYTE b_PortConfiguration[4];
} s_TTLIOInfo;
/*********************/
/* Digital I/O infos */
/*********************/
struct {
BYTE b_DigitalInit;
BYTE b_ChannelAMode;
BYTE b_ChannelBMode;
BYTE b_OutputMemoryEnabled;
DWORD dw_OutputMemory;
} s_DigitalIOInfo;
/*********************/
/* 82X54 timer infos */
/*********************/
struct {
struct {
BYTE b_82X54Init;
BYTE b_InputClockSelection;
BYTE b_InputClockLevel;
BYTE b_OutputLevel;
BYTE b_HardwareGateLevel;
DWORD dw_ConfigurationWord;
} s_82X54TimerInfo[3];
BYTE b_InterruptMask;
} s_82X54ModuleInfo;
/*********************/
/* Chronometer infos */
/*********************/
struct {
BYTE b_ChronoInit;
BYTE b_InterruptMask;
BYTE b_PCIInputClock;
BYTE b_TimingUnit;
BYTE b_CycleMode;
double d_TimingInterval;
DWORD dw_ConfigReg;
} s_ChronoModuleInfo;
/***********************/
/* Pulse encoder infos */
/***********************/
struct {
struct {
BYTE b_PulseEncoderInit;
} s_PulseEncoderInfo[4];
DWORD dw_SetRegister;
DWORD dw_ControlRegister;
DWORD dw_StatusRegister;
} s_PulseEncoderModuleInfo;
/********************/
/* Tor conter infos */
/********************/
struct {
struct {
BYTE b_TorCounterInit;
BYTE b_TimingUnit;
BYTE b_InterruptEnable;
double d_TimingInterval;
ULONG ul_RealTimingInterval;
} s_TorCounterInfo[2];
BYTE b_PCIInputClock;
} s_TorCounterModuleInfo;
/*************/
/* PWM infos */
/*************/
struct {
struct {
BYTE b_PWMInit;
BYTE b_TimingUnit;
BYTE b_InterruptEnable;
double d_LowTiming;
double d_HighTiming;
ULONG ul_RealLowTiming;
ULONG ul_RealHighTiming;
} s_PWMInfo[2];
BYTE b_ClockSelection;
} s_PWMModuleInfo;
/*************/
/* ETM infos */
/*************/
struct {
struct {
BYTE b_ETMEnable;
BYTE b_ETMInterrupt;
} s_ETMInfo[2];
BYTE b_ETMInit;
BYTE b_TimingUnit;
BYTE b_ClockSelection;
double d_TimingInterval;
ULONG ul_Timing;
} s_ETMModuleInfo;
/*************/
/* CDA infos */
/*************/
struct {
BYTE b_CDAEnable;
BYTE b_CDAInterrupt;
BYTE b_CDAInit;
BYTE b_FctSelection;
BYTE b_CDAReadFIFOOverflow;
} s_CDAModuleInfo;
} str_ModuleInfo;
// Private structure for the addi_apci3120 driver
typedef struct {
INT iobase;
INT i_IobaseAmcc; // base+size for AMCC chip
INT i_IobaseAddon; //addon base address
INT i_IobaseReserved;
ULONG_PTR dw_AiBase;
struct pcilst_struct *amcc; // ptr too AMCC data
BYTE allocated; // we have blocked card
BYTE b_ValidDriver; // driver is ok
BYTE b_AiContinuous; // we do unlimited AI
BYTE b_AiInitialisation;
UINT ui_AiActualScan; //how many scans we finished
UINT ui_AiBufferPtr; // data buffer ptr in samples
UINT ui_AiNbrofChannels; // how many channels is measured
UINT ui_AiScanLength; // Length of actual scanlist
UINT ui_AiActualScanPosition; // position in actual scan
PUINT pui_AiChannelList; // actual chanlist
UINT ui_AiChannelList[32]; // actual chanlist
BYTE b_AiChannelConfiguration[32]; // actual chanlist
UINT ui_AiReadData[32];
DWORD dw_AiInitialised;
UINT ui_AiTimer0; //Timer Constant for Timer0
UINT ui_AiTimer1; //Timer constant for Timer1
UINT ui_AiFlags;
UINT ui_AiDataLength;
sampl_t *AiData; // Pointer to sample data
UINT ui_AiNbrofScans; // number of scans to do
USHORT us_UseDma; // To use Dma or not
BYTE b_DmaDoubleBuffer; // we can use double buffering
UINT ui_DmaActualBuffer; // which buffer is used now
//*UPDATE-0.7.57->0.7.68
//ULONG ul_DmaBufferVirtual[2];// pointers to begin of DMA buffer
sampl_t *ul_DmaBufferVirtual[2]; // pointers to begin of DMA buffer
ULONG ul_DmaBufferHw[2]; // hw address of DMA buff
UINT ui_DmaBufferSize[2]; // size of dma buffer in bytes
UINT ui_DmaBufferUsesize[2]; // which size we may now used for transfer
UINT ui_DmaBufferSamples[2]; // size in samples
UINT ui_DmaBufferPages[2]; // number of pages in buffer
BYTE b_DigitalOutputRegister; // Digital Output Register
BYTE b_OutputMemoryStatus;
BYTE b_AnalogInputChannelNbr; // Analog input channel Nbr
BYTE b_AnalogOutputChannelNbr; // Analog input Output Nbr
BYTE b_TimerSelectMode; // Contain data written at iobase + 0C
BYTE b_ModeSelectRegister; // Contain data written at iobase + 0E
USHORT us_OutputRegister; // Contain data written at iobase + 0
BYTE b_InterruptState;
BYTE b_TimerInit; // Specify if InitTimerWatchdog was load
BYTE b_TimerStarted; // Specify if timer 2 is running or not
BYTE b_Timer2Mode; // Specify the timer 2 mode
BYTE b_Timer2Interrupt; //Timer2 interrupt enable or disable
BYTE b_AiCyclicAcquisition; // indicate cyclic acquisition
BYTE b_InterruptMode; // eoc eos or dma
BYTE b_EocEosInterrupt; // Enable disable eoc eos interrupt
UINT ui_EocEosConversionTime;
BYTE b_EocEosConversionTimeBase;
BYTE b_SingelDiff;
BYTE b_ExttrigEnable; // To enable or disable external trigger
struct task_struct *tsk_Current; // Pointer to the current process
boardtype *ps_BoardInfo;
// Hardware board infos for 1710
struct {
UINT ui_Address; // Board address
UINT ui_FlashAddress;
BYTE b_InterruptNbr; // Board interrupt number
BYTE b_SlotNumber; // PCI slot number
BYTE b_BoardVersion;
DWORD dw_MolduleConfiguration[4]; // Module configuration
} s_BoardInfos;
/*******************/
/* Interrupt infos */
/*******************/
struct {
ULONG ul_InterruptOccur; /* 0 : No interrupt occur */
/* > 0 : Interrupt occur */
UINT ui_Read; /* Read FIFO */
UINT ui_Write; /* Write FIFO */
struct {
BYTE b_OldModuleMask;
ULONG ul_OldInterruptMask; /* Interrupt mask */
ULONG ul_OldCounterLatchValue; /* Interrupt counter value */
} s_FIFOInterruptParameters[APCI1710_SAVE_INTERRUPT];
} s_InterruptParameters;
str_ModuleInfo s_ModuleInfo[4];
ULONG ul_TTLPortConfiguration[10];
} addi_private;
static unsigned short pci_list_builded = 0; /* set to 1 when list of card is known */
//Function declarations
static int i_ADDI_Attach(comedi_device * dev, comedi_devconfig * it);
static int i_ADDI_Detach(comedi_device * dev);
static int i_ADDI_Reset(comedi_device * dev);
static irqreturn_t v_ADDI_Interrupt(int irq, void *d PT_REGS_ARG);
static int i_ADDIDATA_InsnReadEeprom(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,462 @@
/*
Modified by umesh on 16th may 2001
Modified by sarath on 22nd may 2001
*/
/*
comedi/drivers/amcc_s5933_v_58.h
Stuff for AMCC S5933 PCI Controller
Author: Michal Dobes <majkl@tesnet.cz>
Inspirated from general-purpose AMCC S5933 PCI Matchmaker driver
made by Andrea Cisternino <acister@pcape1.pi.infn.it>
and as result of espionage from MITE code made by David A. Schleef.
Thanks to AMCC for their on-line documentation and bus master DMA
example.
*/
#ifndef _AMCC_S5933_H_
#define _AMCC_S5933_H_
#include <linux/pci.h>
#include "../../comedidev.h"
#ifdef PCI_SUPPORT_VER1
#error Sorry, no support for 2.1.55 and older! :-((((
#endif
/***********Added by sarath for compatibility with APCI3120
*************************/
#define FIFO_ADVANCE_ON_BYTE_2 0x20000000 // written on base0
#define AMWEN_ENABLE 0x02 // added for step 6 dma written on base2
#define A2P_FIFO_WRITE_ENABLE 0x01
#define AGCSTS_TC_ENABLE 0x10000000 // Added for transfer count enable bit
// ADDON RELATED ADDITIONS
// Constant
#define APCI3120_ENABLE_TRANSFER_ADD_ON_LOW 0x00
#define APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH 0x1200
#define APCI3120_A2P_FIFO_MANAGEMENT 0x04000400L
#define APCI3120_AMWEN_ENABLE 0x02
#define APCI3120_A2P_FIFO_WRITE_ENABLE 0x01
#define APCI3120_FIFO_ADVANCE_ON_BYTE_2 0x20000000L
#define APCI3120_ENABLE_WRITE_TC_INT 0x00004000L
#define APCI3120_CLEAR_WRITE_TC_INT 0x00040000L
#define APCI3120_DISABLE_AMWEN_AND_A2P_FIFO_WRITE 0x0
#define APCI3120_DISABLE_BUS_MASTER_ADD_ON 0x0
#define APCI3120_DISABLE_BUS_MASTER_PCI 0x0
// ADD_ON ::: this needed since apci supports 16 bit interface to add on
#define APCI3120_ADD_ON_AGCSTS_LOW 0x3C
#define APCI3120_ADD_ON_AGCSTS_HIGH APCI3120_ADD_ON_AGCSTS_LOW + 2
#define APCI3120_ADD_ON_MWAR_LOW 0x24
#define APCI3120_ADD_ON_MWAR_HIGH APCI3120_ADD_ON_MWAR_LOW + 2
#define APCI3120_ADD_ON_MWTC_LOW 0x058
#define APCI3120_ADD_ON_MWTC_HIGH APCI3120_ADD_ON_MWTC_LOW + 2
// AMCC
#define APCI3120_AMCC_OP_MCSR 0x3C
#define APCI3120_AMCC_OP_REG_INTCSR 0x38
/*******from here all upward definitions are added by sarath */
/****************************************************************************/
/* AMCC Operation Register Offsets - PCI */
/****************************************************************************/
#define AMCC_OP_REG_OMB1 0x00
#define AMCC_OP_REG_OMB2 0x04
#define AMCC_OP_REG_OMB3 0x08
#define AMCC_OP_REG_OMB4 0x0c
#define AMCC_OP_REG_IMB1 0x10
#define AMCC_OP_REG_IMB2 0x14
#define AMCC_OP_REG_IMB3 0x18
#define AMCC_OP_REG_IMB4 0x1c
#define AMCC_OP_REG_FIFO 0x20
#define AMCC_OP_REG_MWAR 0x24
#define AMCC_OP_REG_MWTC 0x28
#define AMCC_OP_REG_MRAR 0x2c
#define AMCC_OP_REG_MRTC 0x30
#define AMCC_OP_REG_MBEF 0x34
#define AMCC_OP_REG_INTCSR 0x38
#define AMCC_OP_REG_INTCSR_SRC (AMCC_OP_REG_INTCSR + 2) /* INT source */
#define AMCC_OP_REG_INTCSR_FEC (AMCC_OP_REG_INTCSR + 3) /* FIFO ctrl */
#define AMCC_OP_REG_MCSR 0x3c
#define AMCC_OP_REG_MCSR_NVDATA (AMCC_OP_REG_MCSR + 2) /* Data in byte 2 */
#define AMCC_OP_REG_MCSR_NVCMD (AMCC_OP_REG_MCSR + 3) /* Command in byte 3 */
#define AMCC_FIFO_DEPTH_DWORD 8
#define AMCC_FIFO_DEPTH_BYTES (8 * sizeof (u32))
/****************************************************************************/
/* AMCC Operation Registers Size - PCI */
/****************************************************************************/
#define AMCC_OP_REG_SIZE 64 /* in bytes */
/****************************************************************************/
/* AMCC Operation Register Offsets - Add-on */
/****************************************************************************/
#define AMCC_OP_REG_AIMB1 0x00
#define AMCC_OP_REG_AIMB2 0x04
#define AMCC_OP_REG_AIMB3 0x08
#define AMCC_OP_REG_AIMB4 0x0c
#define AMCC_OP_REG_AOMB1 0x10
#define AMCC_OP_REG_AOMB2 0x14
#define AMCC_OP_REG_AOMB3 0x18
#define AMCC_OP_REG_AOMB4 0x1c
#define AMCC_OP_REG_AFIFO 0x20
#define AMCC_OP_REG_AMWAR 0x24
#define AMCC_OP_REG_APTA 0x28
#define AMCC_OP_REG_APTD 0x2c
#define AMCC_OP_REG_AMRAR 0x30
#define AMCC_OP_REG_AMBEF 0x34
#define AMCC_OP_REG_AINT 0x38
#define AMCC_OP_REG_AGCSTS 0x3c
#define AMCC_OP_REG_AMWTC 0x58
#define AMCC_OP_REG_AMRTC 0x5c
/****************************************************************************/
/* AMCC - Add-on General Control/Status Register */
/****************************************************************************/
#define AGCSTS_CONTROL_MASK 0xfffff000
#define AGCSTS_NV_ACC_MASK 0xe0000000
#define AGCSTS_RESET_MASK 0x0e000000
#define AGCSTS_NV_DA_MASK 0x00ff0000
#define AGCSTS_BIST_MASK 0x0000f000
#define AGCSTS_STATUS_MASK 0x000000ff
#define AGCSTS_TCZERO_MASK 0x000000c0
#define AGCSTS_FIFO_ST_MASK 0x0000003f
#define AGCSTS_RESET_MBFLAGS 0x08000000
#define AGCSTS_RESET_P2A_FIFO 0x04000000
#define AGCSTS_RESET_A2P_FIFO 0x02000000
#define AGCSTS_RESET_FIFOS (AGCSTS_RESET_A2P_FIFO | AGCSTS_RESET_P2A_FIFO)
#define AGCSTS_A2P_TCOUNT 0x00000080
#define AGCSTS_P2A_TCOUNT 0x00000040
#define AGCSTS_FS_P2A_EMPTY 0x00000020
#define AGCSTS_FS_P2A_HALF 0x00000010
#define AGCSTS_FS_P2A_FULL 0x00000008
#define AGCSTS_FS_A2P_EMPTY 0x00000004
#define AGCSTS_FS_A2P_HALF 0x00000002
#define AGCSTS_FS_A2P_FULL 0x00000001
/****************************************************************************/
/* AMCC - Add-on Interrupt Control/Status Register */
/****************************************************************************/
#define AINT_INT_MASK 0x00ff0000
#define AINT_SEL_MASK 0x0000ffff
#define AINT_IS_ENSEL_MASK 0x00001f1f
#define AINT_INT_ASSERTED 0x00800000
#define AINT_BM_ERROR 0x00200000
#define AINT_BIST_INT 0x00100000
#define AINT_RT_COMPLETE 0x00080000
#define AINT_WT_COMPLETE 0x00040000
#define AINT_OUT_MB_INT 0x00020000
#define AINT_IN_MB_INT 0x00010000
#define AINT_READ_COMPL 0x00008000
#define AINT_WRITE_COMPL 0x00004000
#define AINT_OMB_ENABLE 0x00001000
#define AINT_OMB_SELECT 0x00000c00
#define AINT_OMB_BYTE 0x00000300
#define AINT_IMB_ENABLE 0x00000010
#define AINT_IMB_SELECT 0x0000000c
#define AINT_IMB_BYTE 0x00000003
/* Enable Bus Mastering */
#define EN_A2P_TRANSFERS 0x00000400
/* FIFO Flag Reset */
#define RESET_A2P_FLAGS 0x04000000L
/* FIFO Relative Priority */
#define A2P_HI_PRIORITY 0x00000100L
/* Identify Interrupt Sources */
#define ANY_S593X_INT 0x00800000L
#define READ_TC_INT 0x00080000L
#define WRITE_TC_INT 0x00040000L
#define IN_MB_INT 0x00020000L
#define MASTER_ABORT_INT 0x00100000L
#define TARGET_ABORT_INT 0x00200000L
#define BUS_MASTER_INT 0x00200000L
/****************************************************************************/
struct pcilst_struct {
struct pcilst_struct *next;
int used;
struct pci_dev *pcidev;
unsigned short vendor;
unsigned short device;
unsigned int master;
unsigned char pci_bus;
unsigned char pci_slot;
unsigned char pci_func;
unsigned int io_addr[5];
unsigned int irq;
};
struct pcilst_struct *amcc_devices; // ptr to root list of all amcc devices
/****************************************************************************/
void v_pci_card_list_init(unsigned short pci_vendor, char display);
void v_pci_card_list_cleanup(unsigned short pci_vendor);
struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id,
unsigned short device_id);
int i_find_free_pci_card_by_position(unsigned short vendor_id,
unsigned short device_id, unsigned short pci_bus,
unsigned short pci_slot, struct pcilst_struct **card);
struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
unsigned short device_id, unsigned short pci_bus,
unsigned short pci_slot);
int i_pci_card_alloc(struct pcilst_struct *amcc);
int i_pci_card_free(struct pcilst_struct *amcc);
void v_pci_card_list_display(void);
int i_pci_card_data(struct pcilst_struct *amcc,
unsigned char *pci_bus, unsigned char *pci_slot,
unsigned char *pci_func, unsigned short *io_addr, unsigned short *irq,
unsigned short *master);
/****************************************************************************/
/* build list of amcc cards in this system */
void v_pci_card_list_init(unsigned short pci_vendor, char display)
{
struct pci_dev *pcidev;
struct pcilst_struct *amcc, *last;
int i;
amcc_devices = NULL;
last = NULL;
#if LINUX_VERSION_CODE < 0x020300
for (pcidev = pci_devices; pcidev; pcidev = pcidev->next) {
#else
pci_for_each_dev(pcidev) {
#endif
if (pcidev->vendor == pci_vendor) {
amcc = kmalloc(sizeof(*amcc), GFP_KERNEL);
memset(amcc, 0, sizeof(*amcc));
amcc->pcidev = pcidev;
if (last) {
last->next = amcc;
} else {
amcc_devices = amcc;
}
last = amcc;
#if LINUX_VERSION_CODE < 0x020300
amcc->vendor = pcidev->vendor;
amcc->device = pcidev->device;
amcc->master = pcidev->master;
amcc->pci_bus = pcidev->bus->number;
amcc->pci_slot = PCI_SLOT(pcidev->devfn);
amcc->pci_func = PCI_FUNC(pcidev->devfn);
for (i = 0; i < 5; i++)
amcc->io_addr[i] =
pcidev->base_address[i] & ~3UL;
amcc->irq = pcidev->irq;
#else
amcc->vendor = pcidev->vendor;
amcc->device = pcidev->device;
#if 0
amcc->master = pcidev->master; // how get this information under 2.4 kernels?
#endif
amcc->pci_bus = pcidev->bus->number;
amcc->pci_slot = PCI_SLOT(pcidev->devfn);
amcc->pci_func = PCI_FUNC(pcidev->devfn);
for (i = 0; i < 5; i++)
amcc->io_addr[i] =
pcidev->resource[i].start & ~3UL;
amcc->irq = pcidev->irq;
#endif
}
}
if (display)
v_pci_card_list_display();
}
/****************************************************************************/
/* free up list of amcc cards in this system */
void v_pci_card_list_cleanup(unsigned short pci_vendor)
{
struct pcilst_struct *amcc, *next;
for (amcc = amcc_devices; amcc; amcc = next) {
next = amcc->next;
kfree(amcc);
}
amcc_devices = NULL;
}
/****************************************************************************/
/* find first unused card with this device_id */
struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id,
unsigned short device_id)
{
struct pcilst_struct *amcc, *next;
for (amcc = amcc_devices; amcc; amcc = next) {
next = amcc->next;
if ((!amcc->used) && (amcc->device == device_id)
&& (amcc->vendor == vendor_id))
return amcc;
}
return NULL;
}
/****************************************************************************/
/* find card on requested position */
int i_find_free_pci_card_by_position(unsigned short vendor_id,
unsigned short device_id, unsigned short pci_bus,
unsigned short pci_slot, struct pcilst_struct **card)
{
struct pcilst_struct *amcc, *next;
*card = NULL;
for (amcc = amcc_devices; amcc; amcc = next) {
next = amcc->next;
if ((amcc->vendor == vendor_id) && (amcc->device == device_id)
&& (amcc->pci_bus == pci_bus)
&& (amcc->pci_slot == pci_slot)) {
if (!(amcc->used)) {
*card = amcc;
return 0; // ok, card is found
} else {
rt_printk
(" - \nCard on requested position is used b:s %d:%d!\n",
pci_bus, pci_slot);
return 2; // card exist but is used
}
}
}
return 1; // no card found
}
/****************************************************************************/
/* mark card as used */
int i_pci_card_alloc(struct pcilst_struct *amcc)
{
if (!amcc)
return -1;
if (amcc->used)
return 1;
amcc->used = 1;
return 0;
}
/****************************************************************************/
/* mark card as free */
int i_pci_card_free(struct pcilst_struct *amcc)
{
if (!amcc)
return -1;
if (!amcc->used)
return 1;
amcc->used = 0;
return 0;
}
/****************************************************************************/
/* display list of found cards */
void v_pci_card_list_display(void)
{
struct pcilst_struct *amcc, *next;
printk("List of pci cards\n");
printk("bus:slot:func vendor device master io_amcc io_daq irq used\n");
for (amcc = amcc_devices; amcc; amcc = next) {
next = amcc->next;
printk("%2d %2d %2d 0x%4x 0x%4x %3s 0x%4x 0x%4x %2d %2d\n", amcc->pci_bus, amcc->pci_slot, amcc->pci_func, amcc->vendor, amcc->device, amcc->master ? "yes" : "no", amcc->io_addr[0], amcc->io_addr[2], amcc->irq, amcc->used);
}
}
/****************************************************************************/
/* return all card information for driver */
int i_pci_card_data(struct pcilst_struct *amcc,
unsigned char *pci_bus, unsigned char *pci_slot,
unsigned char *pci_func, unsigned short *io_addr, unsigned short *irq,
unsigned short *master)
{
int i;
if (!amcc)
return -1;
*pci_bus = amcc->pci_bus;
*pci_slot = amcc->pci_slot;
*pci_func = amcc->pci_func;
for (i = 0; i < 5; i++)
io_addr[i] = amcc->io_addr[i];
*irq = amcc->irq;
*master = amcc->master;
return 0;
}
/****************************************************************************/
/* select and alloc card */
struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
unsigned short device_id, unsigned short pci_bus,
unsigned short pci_slot)
{
struct pcilst_struct *card;
if ((pci_bus < 1) & (pci_slot < 1)) { // use autodetection
if ((card = ptr_find_free_pci_card_by_device(vendor_id,
device_id)) == NULL) {
rt_printk(" - Unused card not found in system!\n");
return NULL;
}
} else {
switch (i_find_free_pci_card_by_position(vendor_id, device_id,
pci_bus, pci_slot, &card)) {
case 1:
rt_printk
(" - Card not found on requested position b:s %d:%d!\n",
pci_bus, pci_slot);
return NULL;
case 2:
rt_printk
(" - Card on requested position is used b:s %d:%d!\n",
pci_bus, pci_slot);
return NULL;
}
}
if (i_pci_card_alloc(card) != 0) {
rt_printk(" - Can't allocate card!\n");
return NULL;
}
return card;
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,78 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
#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_VENDOR_ID 0x10E8
#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
//MODULE INFO STRUCTURE
static const comedi_lrange range_apci1710_ttl = { 4, {
BIP_RANGE(10),
BIP_RANGE(5),
BIP_RANGE(2),
BIP_RANGE(1)
}
};
static const comedi_lrange range_apci1710_ssi = { 4, {
BIP_RANGE(10),
BIP_RANGE(5),
BIP_RANGE(2),
BIP_RANGE(1)
}
};
static const comedi_lrange range_apci1710_inccpt = { 4, {
BIP_RANGE(10),
BIP_RANGE(5),
BIP_RANGE(2),
BIP_RANGE(1)
}
};

View File

@ -0,0 +1,600 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
/*
+-----------------------------------------------------------------------+
| (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+-----------------------------------------------------------------------+
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+-------------------------------+---------------------------------------+
| Project : APCI-035 | Compiler : GCC |
| Module name : hwdrv_apci035.c | Version : 2.96 |
+-------------------------------+---------------------------------------+
| Project manager: Eric Stolz | Date : 02/12/2002 |
+-------------------------------+---------------------------------------+
| Description : Hardware Layer Acces For APCI-035 |
+-----------------------------------------------------------------------+
| UPDATES |
+----------+-----------+------------------------------------------------+
| Date | Author | Description of updates |
+----------+-----------+------------------------------------------------+
| | | |
| | | |
| | | |
+----------+-----------+------------------------------------------------+
*/
/*
+----------------------------------------------------------------------------+
| Included files |
+----------------------------------------------------------------------------+
*/
#include "hwdrv_apci035.h"
INT i_WatchdogNbr = 0;
INT i_Temp = 0;
INT i_Flag = 1;
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI035_ConfigTimerWatchdog |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Configures The Timer , Counter or Watchdog |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| UINT *data : Data Pointer contains |
| configuration parameters as below |
| |
| data[0] : 0 Configure As Timer |
| 1 Configure As Watchdog |
data[1] : Watchdog number
| data[2] : Time base Unit |
| data[3] : Reload Value |
data[4] : External Trigger |
1:Enable
0:Disable
data[5] :External Trigger Level
00 Trigger Disabled
01 Trigger Enabled (Low level)
10 Trigger Enabled (High Level)
11 Trigger Enabled (High/Low level)
data[6] : External Gate |
1:Enable
0:Disable
data[7] : External Gate level
00 Gate Disabled
01 Gate Enabled (Low level)
10 Gate Enabled (High Level)
data[8] :Warning Relay
1: ENABLE
0: DISABLE
data[9] :Warning Delay available
data[10] :Warning Relay Time unit
data[11] :Warning Relay Time Reload value
data[12] :Reset Relay
1 : ENABLE
0 : DISABLE
data[13] :Interrupt
1 : ENABLE
0 : DISABLE
|
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
INT i_APCI035_ConfigTimerWatchdog(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
UINT ui_Status = 0;
UINT ui_Command = 0;
UINT ui_Mode = 0;
i_Temp = 0;
devpriv->tsk_Current = current;
devpriv->b_TimerSelectMode = data[0];
i_WatchdogNbr = data[1];
if (data[0] == 0) {
ui_Mode = 2;
} else {
ui_Mode = 0;
}
//ui_Command = inl(devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
ui_Command = 0;
//ui_Command = ui_Command & 0xFFFFF9FEUL;
outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
ui_Command = 0;
ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
/************************/
/* Set the reload value */
/************************/
outl(data[3], devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 4);
/*********************/
/* Set the time unit */
/*********************/
outl(data[2], devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 8);
if (data[0] == ADDIDATA_TIMER) {
/******************************/
/* Set the mode : */
/* - Disable the hardware */
/* - Disable the counter mode */
/* - Disable the warning */
/* - Disable the reset */
/* - Enable the timer mode */
/* - Set the timer mode */
/******************************/
ui_Command =
(ui_Command & 0xFFF719E2UL) | ui_Mode << 13UL | 0x10UL;
} //if (data[0] == ADDIDATA_TIMER)
else {
if (data[0] == ADDIDATA_WATCHDOG) {
/******************************/
/* Set the mode : */
/* - Disable the hardware */
/* - Disable the counter mode */
/* - Disable the warning */
/* - Disable the reset */
/* - Disable the timer mode */
/******************************/
ui_Command = ui_Command & 0xFFF819E2UL;
} else {
printk("\n The parameter for Timer/watchdog selection is in error\n");
return -EINVAL;
}
}
outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
ui_Command = 0;
ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
/********************************/
/* Disable the hardware trigger */
/********************************/
ui_Command = ui_Command & 0xFFFFF89FUL;
if (data[4] == ADDIDATA_ENABLE) {
/**********************************/
/* Set the hardware trigger level */
/**********************************/
ui_Command = ui_Command | (data[5] << 5);
}
outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
ui_Command = 0;
ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
/*****************************/
/* Disable the hardware gate */
/*****************************/
ui_Command = ui_Command & 0xFFFFF87FUL;
if (data[6] == ADDIDATA_ENABLE) {
/*******************************/
/* Set the hardware gate level */
/*******************************/
ui_Command = ui_Command | (data[7] << 7);
}
outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
ui_Command = 0;
ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
/*******************************/
/* Disable the hardware output */
/*******************************/
ui_Command = ui_Command & 0xFFFFF9FBUL;
/*********************************/
/* Set the hardware output level */
/*********************************/
ui_Command = ui_Command | (data[8] << 2);
outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
if (data[9] == ADDIDATA_ENABLE) {
/************************/
/* Set the reload value */
/************************/
outl(data[11],
devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 24);
/**********************/
/* Set the time unite */
/**********************/
outl(data[10],
devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 28);
}
ui_Command = 0;
ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
/*******************************/
/* Disable the hardware output */
/*******************************/
ui_Command = ui_Command & 0xFFFFF9F7UL;
/*********************************/
/* Set the hardware output level */
/*********************************/
ui_Command = ui_Command | (data[12] << 3);
outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
/*************************************/
/** Enable the watchdog interrupt **/
/*************************************/
ui_Command = 0;
ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
/*******************************/
/* Set the interrupt selection */
/*******************************/
ui_Status = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 16);
ui_Command = (ui_Command & 0xFFFFF9FDUL) | (data[13] << 1);
outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI035_StartStopWriteTimerWatchdog |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Start / Stop The Selected Timer , or Watchdog |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| UINT *data : Data Pointer contains |
| configuration parameters as below |
| |
| data[0] : 0 - Stop Selected Timer/Watchdog |
| 1 - Start Selected Timer/Watchdog |
| 2 - Trigger Selected Timer/Watchdog |
| 3 - Stop All Timer/Watchdog |
| 4 - Start All Timer/Watchdog |
| 5 - Trigger All Timer/Watchdog |
| |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
INT i_APCI035_StartStopWriteTimerWatchdog(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
{
UINT ui_Command = 0;
INT i_Count = 0;
if (data[0] == 1) {
ui_Command =
inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
/**********************/
/* Start the hardware */
/**********************/
ui_Command = (ui_Command & 0xFFFFF9FFUL) | 0x1UL;
outl(ui_Command,
devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
} // if (data[0]==1)
if (data[0] == 2) {
ui_Command =
inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
/***************************/
/* Set the trigger command */
/***************************/
ui_Command = (ui_Command & 0xFFFFF9FFUL) | 0x200UL;
outl(ui_Command,
devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
}
if (data[0] == 0) //Stop The Watchdog
{
//Stop The Watchdog
ui_Command = 0;
//ui_Command = inl(devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
//ui_Command = ui_Command & 0xFFFFF9FEUL;
outl(ui_Command,
devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
} // if (data[1]==0)
if (data[0] == 3) //stop all Watchdogs
{
ui_Command = 0;
for (i_Count = 1; i_Count <= 4; i_Count++) {
if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
ui_Command = 0x2UL;
} else {
ui_Command = 0x10UL;
}
i_WatchdogNbr = i_Count;
outl(ui_Command,
devpriv->iobase + ((i_WatchdogNbr - 1) * 32) +
0);
}
}
if (data[0] == 4) //start all Watchdogs
{
ui_Command = 0;
for (i_Count = 1; i_Count <= 4; i_Count++) {
if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
ui_Command = 0x1UL;
} else {
ui_Command = 0x8UL;
}
i_WatchdogNbr = i_Count;
outl(ui_Command,
devpriv->iobase + ((i_WatchdogNbr - 1) * 32) +
0);
}
}
if (data[0] == 5) //trigger all Watchdogs
{
ui_Command = 0;
for (i_Count = 1; i_Count <= 4; i_Count++) {
if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
ui_Command = 0x4UL;
} else {
ui_Command = 0x20UL;
}
i_WatchdogNbr = i_Count;
outl(ui_Command,
devpriv->iobase + ((i_WatchdogNbr - 1) * 32) +
0);
}
i_Temp = 1;
}
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI035_ReadTimerWatchdog |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Read The Selected Timer , Counter or Watchdog |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| UINT *data : Data Pointer contains |
| configuration parameters as below |
| |
| |
+----------------------------------------------------------------------------+
| Output Parameters : data[0] : software trigger status
data[1] : hardware trigger status
| data[2] : Software clear status
data[3] : Overflow status
data[4] : Timer actual value
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
INT i_APCI035_ReadTimerWatchdog(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
UINT ui_Status = 0; // Status register
i_WatchdogNbr = insn->unused[0];
/******************/
/* Get the status */
/******************/
ui_Status = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 16);
/***********************************/
/* Get the software trigger status */
/***********************************/
data[0] = ((ui_Status >> 1) & 1);
/***********************************/
/* Get the hardware trigger status */
/***********************************/
data[1] = ((ui_Status >> 2) & 1);
/*********************************/
/* Get the software clear status */
/*********************************/
data[2] = ((ui_Status >> 3) & 1);
/***************************/
/* Get the overflow status */
/***************************/
data[3] = ((ui_Status >> 0) & 1);
if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
data[4] = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 0);
} // if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : INT i_APCI035_ConfigAnalogInput |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Configures The Analog Input Subdevice |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| comedi_subdevice *s : Subdevice Pointer |
| comedi_insn *insn : Insn Structure Pointer |
| lsampl_t *data : Data Pointer contains |
| configuration parameters as below |
| data[0] : Warning delay value
| |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
INT i_APCI035_ConfigAnalogInput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
devpriv->tsk_Current = current;
outl(0x200 | 0, devpriv->iobase + 128 + 0x4);
outl(0, devpriv->iobase + 128 + 0);
/********************************/
/* Initialise the warning value */
/********************************/
outl(0x300 | 0, devpriv->iobase + 128 + 0x4);
outl((data[0] << 8), devpriv->iobase + 128 + 0);
outl(0x200000UL, devpriv->iobase + 128 + 12);
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI035_ReadAnalogInput |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Read value of the selected channel |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| UINT ui_NoOfChannels : No Of Channels To read |
| UINT *data : Data Pointer to read status |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
| data[0] : Digital Value Of Input |
| |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
INT i_APCI035_ReadAnalogInput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
UINT ui_CommandRegister = 0;
/******************/
/* Set the start */
/******************/
ui_CommandRegister = 0x80000;
/******************************/
/* Write the command register */
/******************************/
outl(ui_CommandRegister, devpriv->iobase + 128 + 8);
/***************************************/
/* Read the digital value of the input */
/***************************************/
data[0] = inl(devpriv->iobase + 128 + 28);
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI035_Reset(comedi_device *dev) |
| |
+----------------------------------------------------------------------------+
| Task :Resets the registers of the card |
+----------------------------------------------------------------------------+
| Input Parameters : |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : |
| |
+----------------------------------------------------------------------------+
*/
INT i_APCI035_Reset(comedi_device * dev)
{
INT i_Count = 0;
for (i_Count = 1; i_Count <= 4; i_Count++) {
i_WatchdogNbr = i_Count;
outl(0x0, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 0); //stop all timers
}
outl(0x0, devpriv->iobase + 128 + 12); //Disable the warning delay
return 0;
}
/*
+----------------------------------------------------------------------------+
| Function Name : static void v_APCI035_Interrupt |
| (int irq , void *d) |
+----------------------------------------------------------------------------+
| Task : Interrupt processing Routine |
+----------------------------------------------------------------------------+
| Input Parameters : int irq : irq number |
| void *d : void pointer |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
static void v_APCI035_Interrupt(int irq, void *d)
{
comedi_device *dev = d;
UINT ui_StatusRegister1 = 0;
UINT ui_StatusRegister2 = 0;
UINT ui_ReadCommand = 0;
UINT ui_ChannelNumber = 0;
UINT ui_DigitalTemperature = 0;
if (i_Temp == 1) {
i_WatchdogNbr = i_Flag;
i_Flag = i_Flag + 1;
}
/**************************************/
/* Read the interrupt status register of temperature Warning */
/**************************************/
ui_StatusRegister1 = inl(devpriv->iobase + 128 + 16);
/**************************************/
/* Read the interrupt status register for Watchdog/timer */
/**************************************/
ui_StatusRegister2 =
inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 20);
if ((((ui_StatusRegister1) & 0x8) == 0x8)) //Test if warning relay interrupt
{
/**********************************/
/* Disable the temperature warning */
/**********************************/
ui_ReadCommand = inl(devpriv->iobase + 128 + 12);
ui_ReadCommand = ui_ReadCommand & 0xFFDF0000UL;
outl(ui_ReadCommand, devpriv->iobase + 128 + 12);
/***************************/
/* Read the channel number */
/***************************/
ui_ChannelNumber = inl(devpriv->iobase + 128 + 60);
/**************************************/
/* Read the digital temperature value */
/**************************************/
ui_DigitalTemperature = inl(devpriv->iobase + 128 + 60);
send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
} //if (((ui_StatusRegister1 & 0x8) == 0x8))
else {
if ((ui_StatusRegister2 & 0x1) == 0x1) {
send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
}
} //else if (((ui_StatusRegister1 & 0x8) == 0x8))
return;
}

View File

@ -0,0 +1,129 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
// Card Specific information
#define APCI035_BOARD_VENDOR_ID 0x15B8
#define APCI035_ADDRESS_RANGE 255
INT i_TW_Number;
struct {
INT i_Gain;
INT i_Polarity;
INT i_OffsetRange;
INT i_Coupling;
INT i_SingleDiff;
INT i_AutoCalibration;
UINT ui_ReloadValue;
UINT ui_TimeUnitReloadVal;
INT i_Interrupt;
INT i_ModuleSelection;
} Config_Parameters_Main;
//ANALOG INPUT RANGE
comedi_lrange range_apci035_ai = { 8, {
BIP_RANGE(10),
BIP_RANGE(5),
BIP_RANGE(2),
BIP_RANGE(1),
UNI_RANGE(10),
UNI_RANGE(5),
UNI_RANGE(2),
UNI_RANGE(1)
}
};
// Timer / Watchdog Related Defines
#define APCI035_TCW_SYNC_ENABLEDISABLE 0
#define APCI035_TCW_RELOAD_VALUE 4
#define APCI035_TCW_TIMEBASE 8
#define APCI035_TCW_PROG 12
#define APCI035_TCW_TRIG_STATUS 16
#define APCI035_TCW_IRQ 20
#define APCI035_TCW_WARN_TIMEVAL 24
#define APCI035_TCW_WARN_TIMEBASE 28
#define ADDIDATA_TIMER 0
//#define ADDIDATA_WATCHDOG 1
#define APCI035_TW1 0
#define APCI035_TW2 32
#define APCI035_TW3 64
#define APCI035_TW4 96
#define APCI035_AI_OFFSET 0
#define APCI035_TEMP 128
#define APCI035_ALR_SEQ 4
#define APCI035_START_STOP_INDEX 8
#define APCI035_ALR_START_STOP 12
#define APCI035_ALR_IRQ 16
#define APCI035_EOS 20
#define APCI035_CHAN_NO 24
#define APCI035_CHAN_VAL 28
#define APCI035_CONV_TIME_TIME_BASE 36
#define APCI035_RELOAD_CONV_TIME_VAL 32
#define APCI035_DELAY_TIME_TIME_BASE 44
#define APCI035_RELOAD_DELAY_TIME_VAL 40
#define ENABLE_EXT_TRIG 1
#define ENABLE_EXT_GATE 2
#define ENABLE_EXT_TRIG_GATE 3
#define ANALOG_INPUT 0
#define TEMPERATURE 1
#define RESISTANCE 2
#define ADDIDATA_GREATER_THAN_TEST 0
#define ADDIDATA_LESS_THAN_TEST 1
#define APCI035_MAXVOLT 2.5
#define ADDIDATA_UNIPOLAR 1
#define ADDIDATA_BIPOLAR 2
//ADDIDATA Enable Disable
#define ADDIDATA_ENABLE 1
#define ADDIDATA_DISABLE 0
// Hardware Layer functions for Apci035
// TIMER
// timer value is passed as u seconds
INT i_APCI035_ConfigTimerWatchdog(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI035_StartStopWriteTimerWatchdog(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
INT i_APCI035_ReadTimerWatchdog(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
//Temperature Related Defines (Analog Input Subdevice)
INT i_APCI035_ConfigAnalogInput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI035_ReadAnalogInput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
//Interrupt
static void v_APCI035_Interrupt(int irq, void *d);
//Reset functions
INT i_APCI035_Reset(comedi_device * dev);

View File

@ -0,0 +1,285 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
/*
+-----------------------------------------------------------------------+
| (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+-----------------------------------------------------------------------+
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+-------------------------------+---------------------------------------+
| Project : APCI-1032 | Compiler : GCC |
| Module name : hwdrv_apci1032.c| Version : 2.96 |
+-------------------------------+---------------------------------------+
| Project manager: Eric Stolz | Date : 02/12/2002 |
+-------------------------------+---------------------------------------+
| Description : Hardware Layer Acces For APCI-1032 |
+-----------------------------------------------------------------------+
| UPDATES |
+----------+-----------+------------------------------------------------+
| Date | Author | Description of updates |
+----------+-----------+------------------------------------------------+
| | | |
| | | |
| | | |
+----------+-----------+------------------------------------------------+
*/
/*
+----------------------------------------------------------------------------+
| Included files |
+----------------------------------------------------------------------------+
*/
#include "hwdrv_apci1032.h"
#include <linux/delay.h>
//Global variables
UINT ui_InterruptStatus = 0;
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI1032_ConfigDigitalInput |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Configures the digital input Subdevice |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| lsampl_t *data : Data Pointer contains |
| configuration parameters as below |
| |
| data[0] : 1 Enable Digital Input Interrupt |
| 0 Disable Digital Input Interrupt |
| data[1] : 0 ADDIDATA Interrupt OR LOGIC |
| : 1 ADDIDATA Interrupt AND LOGIC |
| data[2] : Interrupt mask for the mode 1 |
| data[3] : Interrupt mask for the mode 2 |
| |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
INT i_APCI1032_ConfigDigitalInput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
UINT ui_TmpValue;
ULONG ul_Command1 = 0;
ULONG ul_Command2 = 0;
devpriv->tsk_Current = current;
/*******************************/
/* Set the digital input logic */
/*******************************/
if (data[0] == ADDIDATA_ENABLE) {
ul_Command1 = ul_Command1 | data[2];
ul_Command2 = ul_Command2 | data[3];
outl(ul_Command1,
devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1);
outl(ul_Command2,
devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2);
if (data[1] == ADDIDATA_OR) {
outl(0x4, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
ui_TmpValue =
inl(devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
} //if (data[1] == ADDIDATA_OR)
else {
outl(0x6, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
} //else if(data[1] == ADDIDATA_OR)
} // if( data[0] == ADDIDATA_ENABLE)
else {
ul_Command1 = ul_Command1 & 0xFFFF0000;
ul_Command2 = ul_Command2 & 0xFFFF0000;
outl(ul_Command1,
devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1);
outl(ul_Command2,
devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2);
outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
} //else if ( data[0] == ADDIDATA_ENABLE)
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI1032_Read1DigitalInput |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Return the status of the digital input |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| UINT ui_Channel : Channel number to read |
| lsampl_t *data : Data Pointer to read status |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
INT i_APCI1032_Read1DigitalInput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
UINT ui_TmpValue = 0;
UINT ui_Channel;
ui_Channel = CR_CHAN(insn->chanspec);
if (ui_Channel >= 0 && ui_Channel <= 31) {
ui_TmpValue = (UINT) inl(devpriv->iobase + APCI1032_DIGITAL_IP);
// since only 1 channel reqd to bring it to last bit it is rotated
// 8 +(chan - 1) times then ANDed with 1 for last bit.
*data = (ui_TmpValue >> ui_Channel) & 0x1;
} //if(ui_Channel >= 0 && ui_Channel <=31)
else {
//comedi_error(dev," \n chan spec wrong\n");
return -EINVAL; // "sorry channel spec wrong "
} //else if(ui_Channel >= 0 && ui_Channel <=31)
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI1032_ReadMoreDigitalInput |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Return the status of the Requested digital inputs |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| UINT ui_NoOfChannels : No Of Channels To be Read |
| UINT *data : Data Pointer to read status |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
INT i_APCI1032_ReadMoreDigitalInput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
UINT ui_PortValue = data[0];
UINT ui_Mask = 0;
UINT ui_NoOfChannels;
ui_NoOfChannels = CR_CHAN(insn->chanspec);
if (data[1] == 0) {
*data = (UINT) inl(devpriv->iobase + APCI1032_DIGITAL_IP);
switch (ui_NoOfChannels) {
case 2:
ui_Mask = 3;
*data = (*data >> (2 * ui_PortValue)) & ui_Mask;
break;
case 4:
ui_Mask = 15;
*data = (*data >> (4 * ui_PortValue)) & ui_Mask;
break;
case 8:
ui_Mask = 255;
*data = (*data >> (8 * ui_PortValue)) & ui_Mask;
break;
case 16:
ui_Mask = 65535;
*data = (*data >> (16 * ui_PortValue)) & ui_Mask;
break;
case 31:
break;
default:
//comedi_error(dev," \nchan spec wrong\n");
return -EINVAL; // "sorry channel spec wrong "
break;
} //switch(ui_NoOfChannels)
} //if(data[1]==0)
else {
if (data[1] == 1) {
*data = ui_InterruptStatus;
} //if(data[1]==1)
} //else if(data[1]==0)
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : static void v_APCI1032_Interrupt |
| (int irq , void *d) |
+----------------------------------------------------------------------------+
| Task : Interrupt handler for the interruptible digital inputs |
+----------------------------------------------------------------------------+
| Input Parameters : int irq : irq number |
| void *d : void pointer |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
static VOID v_APCI1032_Interrupt(int irq, void *d)
{
comedi_device *dev = d;
UINT ui_Temp;
//disable the interrupt
ui_Temp = inl(devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
outl(ui_Temp & APCI1032_DIGITAL_IP_INTERRUPT_DISABLE,
devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
ui_InterruptStatus =
inl(devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_STATUS);
ui_InterruptStatus = ui_InterruptStatus & 0X0000FFFF;
send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
outl(ui_Temp, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); //enable the interrupt
return;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI1032_Reset(comedi_device *dev) | |
+----------------------------------------------------------------------------+
| Task :resets all the registers |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : |
| |
+----------------------------------------------------------------------------+
*/
INT i_APCI1032_Reset(comedi_device * dev)
{
outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); //disable the interrupts
inl(devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_STATUS); //Reset the interrupt status register
outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1); //Disable the and/or interrupt
outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2);
return 0;
}

View File

@ -0,0 +1,70 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
/********* Definitions for APCI-1032 card *****/
#define APCI1032_BOARD_VENDOR_ID 0x15B8
#define APCI1032_ADDRESS_RANGE 20
//DIGITAL INPUT DEFINE
#define APCI1032_DIGITAL_IP 0
#define APCI1032_DIGITAL_IP_INTERRUPT_MODE1 4
#define APCI1032_DIGITAL_IP_INTERRUPT_MODE2 8
#define APCI1032_DIGITAL_IP_IRQ 16
//Digital Input IRQ Function Selection
#define ADDIDATA_OR 0
#define ADDIDATA_AND 1
//Digital Input Interrupt Status
#define APCI1032_DIGITAL_IP_INTERRUPT_STATUS 12
//Digital Input Interrupt Enable Disable.
#define APCI1032_DIGITAL_IP_INTERRUPT_ENABLE 0x4
#define APCI1032_DIGITAL_IP_INTERRUPT_DISABLE 0xFFFFFFFB
//ADDIDATA Enable Disable
#define ADDIDATA_ENABLE 1
#define ADDIDATA_DISABLE 0
// Hardware Layer functions for Apci1032
//DI
// for di read
INT i_APCI1032_ConfigDigitalInput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI1032_Read1DigitalInput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI1032_ReadMoreDigitalInput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
// Interrupt functions.....
static VOID v_APCI1032_Interrupt(int irq, void *d);
//Reset
INT i_APCI1032_Reset(comedi_device * dev);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,157 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
/********* Definitions for APCI-1500 card *****/
// Card Specific information
#define APCI1500_BOARD_VENDOR_ID 0x10e8
#define APCI1500_ADDRESS_RANGE 4
//DIGITAL INPUT-OUTPUT DEFINE
#define APCI1500_DIGITAL_OP 2
#define APCI1500_DIGITAL_IP 0
#define APCI1500_AND 2
#define APCI1500_OR 4
#define APCI1500_OR_PRIORITY 6
#define APCI1500_CLK_SELECT 0
#define COUNTER1 0
#define COUNTER2 1
#define COUNTER3 2
#define APCI1500_COUNTER 0x20
#define APCI1500_TIMER 0
#define APCI1500_WATCHDOG 0
#define APCI1500_SINGLE 0
#define APCI1500_CONTINUOUS 0x80
#define APCI1500_DISABLE 0
#define APCI1500_ENABLE 1
#define APCI1500_SOFTWARE_TRIGGER 0x4
#define APCI1500_HARDWARE_TRIGGER 0x10
#define APCI1500_SOFTWARE_GATE 0
#define APCI1500_HARDWARE_GATE 0x8
#define START 0
#define STOP 1
#define TRIGGER 2
/**************************/
/* Zillog I/O enumeration */
/**************************/
enum {
APCI1500_Z8536_PORT_C,
APCI1500_Z8536_PORT_B,
APCI1500_Z8536_PORT_A,
APCI1500_Z8536_CONTROL_REGISTER
};
/******************************/
/* Z8536 CIO Internal Address */
/******************************/
enum {
APCI1500_RW_MASTER_INTERRUPT_CONTROL,
APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
APCI1500_RW_PORT_A_INTERRUPT_CONTROL,
APCI1500_RW_PORT_B_INTERRUPT_CONTROL,
APCI1500_RW_TIMER_COUNTER_INTERRUPT_VECTOR,
APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY,
APCI1500_RW_PORT_C_DATA_DIRECTION,
APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL,
APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
APCI1500_RW_CPT_TMR1_CMD_STATUS,
APCI1500_RW_CPT_TMR2_CMD_STATUS,
APCI1500_RW_CPT_TMR3_CMD_STATUS,
APCI1500_RW_PORT_A_DATA,
APCI1500_RW_PORT_B_DATA,
APCI1500_RW_PORT_C_DATA,
APCI1500_R_CPT_TMR1_VALUE_HIGH,
APCI1500_R_CPT_TMR1_VALUE_LOW,
APCI1500_R_CPT_TMR2_VALUE_HIGH,
APCI1500_R_CPT_TMR2_VALUE_LOW,
APCI1500_R_CPT_TMR3_VALUE_HIGH,
APCI1500_R_CPT_TMR3_VALUE_LOW,
APCI1500_RW_CPT_TMR1_TIME_CST_HIGH,
APCI1500_RW_CPT_TMR1_TIME_CST_LOW,
APCI1500_RW_CPT_TMR2_TIME_CST_HIGH,
APCI1500_RW_CPT_TMR2_TIME_CST_LOW,
APCI1500_RW_CPT_TMR3_TIME_CST_HIGH,
APCI1500_RW_CPT_TMR3_TIME_CST_LOW,
APCI1500_RW_CPT_TMR1_MODE_SPECIFICATION,
APCI1500_RW_CPT_TMR2_MODE_SPECIFICATION,
APCI1500_RW_CPT_TMR3_MODE_SPECIFICATION,
APCI1500_R_CURRENT_VECTOR,
APCI1500_RW_PORT_A_SPECIFICATION,
APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION,
APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY,
APCI1500_RW_PORT_A_DATA_DIRECTION,
APCI1500_RW_PORT_A_SPECIAL_IO_CONTROL,
APCI1500_RW_PORT_A_PATTERN_POLARITY,
APCI1500_RW_PORT_A_PATTERN_TRANSITION,
APCI1500_RW_PORT_A_PATTERN_MASK,
APCI1500_RW_PORT_B_SPECIFICATION,
APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION,
APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY,
APCI1500_RW_PORT_B_DATA_DIRECTION,
APCI1500_RW_PORT_B_SPECIAL_IO_CONTROL,
APCI1500_RW_PORT_B_PATTERN_POLARITY,
APCI1500_RW_PORT_B_PATTERN_TRANSITION,
APCI1500_RW_PORT_B_PATTERN_MASK
};
/*----------DIGITAL INPUT----------------*/
static int i_APCI1500_Initialisation(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
static int i_APCI1500_ConfigDigitalInputEvent(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
static int i_APCI1500_StartStopInputEvent(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
static int i_APCI1500_ReadMoreDigitalInput(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
/*---------- DIGITAL OUTPUT------------*/
static int i_APCI1500_ConfigDigitalOutputErrorInterrupt(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
static int i_APCI1500_WriteDigitalOutput(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
/*----------TIMER----------------*/
static int i_APCI1500_ConfigCounterTimerWatchdog(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
static int i_APCI1500_StartStopTriggerTimerCounterWatchdog(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
static int i_APCI1500_ReadCounterTimerWatchdog(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
static int i_APCI1500_ReadInterruptMask(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
/*----------INTERRUPT HANDLER------*/
static void v_APCI1500_Interrupt(int irq, void *d);
static int i_APCI1500_ConfigureInterrupt(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
/*----------RESET---------------*/
static int i_APCI1500_Reset(comedi_device * dev);

View File

@ -0,0 +1,542 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
/*
+-----------------------------------------------------------------------+
| (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+-----------------------------------------------------------------------+
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+-------------------------------+---------------------------------------+
| Project : APCI-1516 | Compiler : GCC |
| Module name : hwdrv_apci1516.c| Version : 2.96 |
+-------------------------------+---------------------------------------+
| Project manager: Eric Stolz | Date : 02/12/2002 |
+-------------------------------+---------------------------------------+
| Description : Hardware Layer Acces For APCI-1516 |
+-----------------------------------------------------------------------+
| UPDATES |
+----------+-----------+------------------------------------------------+
| Date | Author | Description of updates |
+----------+-----------+------------------------------------------------+
| | | |
| | | |
| | | |
+----------+-----------+------------------------------------------------+
*/
/*
+----------------------------------------------------------------------------+
| Included files |
+----------------------------------------------------------------------------+
*/
#include "hwdrv_apci1516.h"
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI1516_Read1DigitalInput |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Return the status of the digital input |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| comedi_subdevice *s, :pointer to subdevice structure
comedi_insn *insn :pointer to insn structure |
| lsampl_t *data : Data Pointer to read status |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
INT i_APCI1516_Read1DigitalInput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
UINT ui_TmpValue = 0;
UINT ui_Channel;
ui_Channel = CR_CHAN(insn->chanspec);
if (ui_Channel >= 0 && ui_Channel <= 7) {
ui_TmpValue = (UINT) inw(devpriv->iobase + APCI1516_DIGITAL_IP);
// since only 1 channel reqd to bring it to last bit it is rotated
// 8 +(chan - 1) times then ANDed with 1 for last bit.
*data = (ui_TmpValue >> ui_Channel) & 0x1;
} //if(ui_Channel >= 0 && ui_Channel <=7)
else {
//comedi_error(dev," \n chan spec wrong\n");
return -EINVAL; // "sorry channel spec wrong "
} //else if(ui_Channel >= 0 && ui_Channel <=7)
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI1516_ReadMoreDigitalInput |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Return the status of the Requested digital inputs |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| comedi_subdevice *s, :pointer to subdevice structure
comedi_insn *insn :pointer to insn structure |
| lsampl_t *data : Data Pointer to read status |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
INT i_APCI1516_ReadMoreDigitalInput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
UINT ui_PortValue = data[0];
UINT ui_Mask = 0;
UINT ui_NoOfChannels;
ui_NoOfChannels = CR_CHAN(insn->chanspec);
*data = (UINT) inw(devpriv->iobase + APCI1516_DIGITAL_IP);
switch (ui_NoOfChannels) {
case 2:
ui_Mask = 3;
*data = (*data >> (2 * ui_PortValue)) & ui_Mask;
break;
case 4:
ui_Mask = 15;
*data = (*data >> (4 * ui_PortValue)) & ui_Mask;
break;
case 7:
break;
default:
printk("\nWrong parameters\n");
return -EINVAL; // "sorry channel spec wrong "
break;
} //switch(ui_NoOfChannels)
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI1516_ConfigDigitalOutput (comedi_device *dev,
comedi_subdevice *s comedi_insn *insn,lsampl_t *data) |
| |
+----------------------------------------------------------------------------+
| Task : Configures The Digital Output Subdevice. |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| lsampl_t *data : Data Pointer contains |
| configuration parameters as below |
| comedi_subdevice *s, :pointer to subdevice structure
comedi_insn *insn :pointer to insn structure |
| data[0] :1:Memory on |
| 0:Memory off |
| |
| |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
int i_APCI1516_ConfigDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
devpriv->b_OutputMemoryStatus = data[0];
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI1516_WriteDigitalOutput |
| (comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,
lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Writes port value To the selected port |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| comedi_subdevice *s, :pointer to subdevice structure
comedi_insn *insn :pointer to insn structure |
| lsampl_t *data : Data Pointer to read status |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
INT i_APCI1516_WriteDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
UINT ui_Temp, ui_Temp1;
UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
printk("EL311003 : @=%x\n", devpriv->iobase + APCI1516_DIGITAL_OP);
if (devpriv->b_OutputMemoryStatus) {
ui_Temp = inw(devpriv->iobase + APCI1516_DIGITAL_OP);
} //if(devpriv->b_OutputMemoryStatus )
else {
ui_Temp = 0;
} //if(devpriv->b_OutputMemoryStatus )
if (data[3] == 0) {
if (data[1] == 0) {
data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
outw(data[0], devpriv->iobase + APCI1516_DIGITAL_OP);
printk("EL311003 : d=%d @=%x\n", data[0],
devpriv->iobase + APCI1516_DIGITAL_OP);
} //if(data[1]==0)
else {
if (data[1] == 1) {
switch (ui_NoOfChannel) {
case 2:
data[0] =
(data[0] << (2 *
data[2])) | ui_Temp;
break;
case 4:
data[0] =
(data[0] << (4 *
data[2])) | ui_Temp;
break;
case 7:
data[0] = data[0] | ui_Temp;
break;
default:
comedi_error(dev, " chan spec wrong");
return -EINVAL; // "sorry channel spec wrong "
} //switch(ui_NoOfChannels)
outw(data[0],
devpriv->iobase + APCI1516_DIGITAL_OP);
printk("EL311003 : d=%d @=%x\n", data[0],
devpriv->iobase + APCI1516_DIGITAL_OP);
} // if(data[1]==1)
else {
printk("\nSpecified channel not supported\n");
} //else if(data[1]==1)
} //elseif(data[1]==0)
} //if(data[3]==0)
else {
if (data[3] == 1) {
if (data[1] == 0) {
data[0] = ~data[0] & 0x1;
ui_Temp1 = 1;
ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
ui_Temp = ui_Temp | ui_Temp1;
data[0] = (data[0] << ui_NoOfChannel) ^ 0xff;
data[0] = data[0] & ui_Temp;
outw(data[0],
devpriv->iobase + APCI1516_DIGITAL_OP);
printk("EL311003 : d=%d @=%x\n", data[0],
devpriv->iobase + APCI1516_DIGITAL_OP);
} //if(data[1]==0)
else {
if (data[1] == 1) {
switch (ui_NoOfChannel) {
case 2:
data[0] = ~data[0] & 0x3;
ui_Temp1 = 3;
ui_Temp1 =
ui_Temp1 << 2 * data[2];
ui_Temp = ui_Temp | ui_Temp1;
data[0] =
((data[0] << (2 *
data
[2])) ^
0xff) & ui_Temp;
break;
case 4:
data[0] = ~data[0] & 0xf;
ui_Temp1 = 15;
ui_Temp1 =
ui_Temp1 << 4 * data[2];
ui_Temp = ui_Temp | ui_Temp1;
data[0] =
((data[0] << (4 *
data
[2])) ^
0xff) & ui_Temp;
break;
case 7:
break;
default:
comedi_error(dev,
" chan spec wrong");
return -EINVAL; // "sorry channel spec wrong "
} //switch(ui_NoOfChannels)
outw(data[0],
devpriv->iobase +
APCI1516_DIGITAL_OP);
printk("EL311003 : d=%d @=%x\n",
data[0],
devpriv->iobase +
APCI1516_DIGITAL_OP);
} // if(data[1]==1)
else {
printk("\nSpecified channel not supported\n");
} //else if(data[1]==1)
} //elseif(data[1]==0)
} //if(data[3]==1);
else {
printk("\nSpecified functionality does not exist\n");
return -EINVAL;
} //if else data[3]==1)
} //if else data[3]==0)
return (insn->n);;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI1516_ReadDigitalOutput |
| (comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,
lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Read value of the selected channel or port |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| comedi_subdevice *s, :pointer to subdevice structure
comedi_insn *insn :pointer to insn structure |
| lsampl_t *data : Data Pointer to read status |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
INT i_APCI1516_ReadDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
UINT ui_Temp;
UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
ui_Temp = data[0];
*data = inw(devpriv->iobase + APCI1516_DIGITAL_OP_RW);
if (ui_Temp == 0) {
*data = (*data >> ui_NoOfChannel) & 0x1;
} //if(ui_Temp==0)
else {
if (ui_Temp == 1) {
switch (ui_NoOfChannel) {
case 2:
*data = (*data >> (2 * data[1])) & 3;
break;
case 4:
*data = (*data >> (4 * data[1])) & 15;
break;
case 7:
break;
default:
comedi_error(dev, " chan spec wrong");
return -EINVAL; // "sorry channel spec wrong "
} //switch(ui_NoOfChannels)
} //if(ui_Temp==1)
else {
printk("\nSpecified channel not supported \n");
} //elseif(ui_Temp==1)
} //elseif(ui_Temp==0)
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI1516_ConfigWatchdog(comedi_device *dev,
comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) |
| |
+----------------------------------------------------------------------------+
| Task : Configures The Watchdog |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| comedi_subdevice *s, :pointer to subdevice structure
comedi_insn *insn :pointer to insn structure |
| lsampl_t *data : Data Pointer to read status |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
int i_APCI1516_ConfigWatchdog(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
if (data[0] == 0) {
//Disable the watchdog
outw(0x0,
devpriv->i_IobaseAddon +
APCI1516_WATCHDOG_ENABLEDISABLE);
//Loading the Reload value
outw(data[1],
devpriv->i_IobaseAddon +
APCI1516_WATCHDOG_RELOAD_VALUE);
data[1] = data[1] >> 16;
outw(data[1],
devpriv->i_IobaseAddon +
APCI1516_WATCHDOG_RELOAD_VALUE + 2);
} //if(data[0]==0)
else {
printk("\nThe input parameters are wrong\n");
return -EINVAL;
} //elseif(data[0]==0)
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI1516_StartStopWriteWatchdog |
| (comedi_device *dev,comedi_subdevice *s,
comedi_insn *insn,lsampl_t *data); |
+----------------------------------------------------------------------------+
| Task : Start / Stop The Watchdog |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| comedi_subdevice *s, :pointer to subdevice structure
comedi_insn *insn :pointer to insn structure |
| lsampl_t *data : Data Pointer to read status |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
int i_APCI1516_StartStopWriteWatchdog(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
switch (data[0]) {
case 0: //stop the watchdog
outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_ENABLEDISABLE); //disable the watchdog
break;
case 1: //start the watchdog
outw(0x0001,
devpriv->i_IobaseAddon +
APCI1516_WATCHDOG_ENABLEDISABLE);
break;
case 2: //Software trigger
outw(0x0201,
devpriv->i_IobaseAddon +
APCI1516_WATCHDOG_ENABLEDISABLE);
break;
default:
printk("\nSpecified functionality does not exist\n");
return -EINVAL;
} // switch(data[0])
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI1516_ReadWatchdog |
| (comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,
lsampl_t *data); |
+----------------------------------------------------------------------------+
| Task : Read The Watchdog |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| comedi_subdevice *s, :pointer to subdevice structure
comedi_insn *insn :pointer to insn structure |
| lsampl_t *data : Data Pointer to read status |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
int i_APCI1516_ReadWatchdog(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
data[0] = inw(devpriv->i_IobaseAddon + APCI1516_WATCHDOG_STATUS) & 0x1;
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI1516_Reset(comedi_device *dev) | |
+----------------------------------------------------------------------------+
| Task :resets all the registers |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : |
| |
+----------------------------------------------------------------------------+
*/
INT i_APCI1516_Reset(comedi_device * dev)
{
outw(0x0, devpriv->iobase + APCI1516_DIGITAL_OP); //RESETS THE DIGITAL OUTPUTS
outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_ENABLEDISABLE);
outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_RELOAD_VALUE);
outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_RELOAD_VALUE + 2);
return 0;
}

View File

@ -0,0 +1,71 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
/********* Definitions for APCI-1516 card *****/
// Card Specific information
#define APCI1516_BOARD_VENDOR_ID 0x15B8
#define APCI1516_ADDRESS_RANGE 8
//DIGITAL INPUT-OUTPUT DEFINE
#define APCI1516_DIGITAL_OP 4
#define APCI1516_DIGITAL_OP_RW 4
#define APCI1516_DIGITAL_IP 0
// TIMER COUNTER WATCHDOG DEFINES
#define ADDIDATA_WATCHDOG 2
#define APCI1516_DIGITAL_OP_WATCHDOG 0
#define APCI1516_WATCHDOG_ENABLEDISABLE 12
#define APCI1516_WATCHDOG_RELOAD_VALUE 4
#define APCI1516_WATCHDOG_STATUS 16
// Hardware Layer functions for Apci1516
//Digital Input
INT i_APCI1516_ReadMoreDigitalInput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI1516_Read1DigitalInput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
//Digital Output
int i_APCI1516_ConfigDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI1516_WriteDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI1516_ReadDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
// TIMER
// timer value is passed as u seconds
int i_APCI1516_ConfigWatchdog(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
int i_APCI1516_StartStopWriteWatchdog(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
int i_APCI1516_ReadWatchdog(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
//reset
INT i_APCI1516_Reset(comedi_device * dev);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,122 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
/********* Definitions for APCI-1564 card *****/
#define APCI1564_BOARD_VENDOR_ID 0x15B8
#define APCI1564_ADDRESS_RANGE 128
//DIGITAL INPUT-OUTPUT DEFINE
// Input defines
#define APCI1564_DIGITAL_IP 0x04
#define APCI1564_DIGITAL_IP_INTERRUPT_MODE1 4
#define APCI1564_DIGITAL_IP_INTERRUPT_MODE2 8
#define APCI1564_DIGITAL_IP_IRQ 16
// Output defines
#define APCI1564_DIGITAL_OP 0x18
#define APCI1564_DIGITAL_OP_RW 0
#define APCI1564_DIGITAL_OP_INTERRUPT 4
#define APCI1564_DIGITAL_OP_IRQ 12
//Digital Input IRQ Function Selection
#define ADDIDATA_OR 0
#define ADDIDATA_AND 1
//Digital Input Interrupt Status
#define APCI1564_DIGITAL_IP_INTERRUPT_STATUS 12
//Digital Output Interrupt Status
#define APCI1564_DIGITAL_OP_INTERRUPT_STATUS 8
//Digital Input Interrupt Enable Disable.
#define APCI1564_DIGITAL_IP_INTERRUPT_ENABLE 0x4
#define APCI1564_DIGITAL_IP_INTERRUPT_DISABLE 0xFFFFFFFB
//Digital Output Interrupt Enable Disable.
#define APCI1564_DIGITAL_OP_VCC_INTERRUPT_ENABLE 0x1
#define APCI1564_DIGITAL_OP_VCC_INTERRUPT_DISABLE 0xFFFFFFFE
#define APCI1564_DIGITAL_OP_CC_INTERRUPT_ENABLE 0x2
#define APCI1564_DIGITAL_OP_CC_INTERRUPT_DISABLE 0xFFFFFFFD
//ADDIDATA Enable Disable
#define ADDIDATA_ENABLE 1
#define ADDIDATA_DISABLE 0
// TIMER COUNTER WATCHDOG DEFINES
#define ADDIDATA_TIMER 0
#define ADDIDATA_COUNTER 1
#define ADDIDATA_WATCHDOG 2
#define APCI1564_DIGITAL_OP_WATCHDOG 0x28
#define APCI1564_TIMER 0x48
#define APCI1564_COUNTER1 0x0
#define APCI1564_COUNTER2 0x20
#define APCI1564_COUNTER3 0x40
#define APCI1564_COUNTER4 0x60
#define APCI1564_TCW_SYNC_ENABLEDISABLE 0
#define APCI1564_TCW_RELOAD_VALUE 4
#define APCI1564_TCW_TIMEBASE 8
#define APCI1564_TCW_PROG 12
#define APCI1564_TCW_TRIG_STATUS 16
#define APCI1564_TCW_IRQ 20
#define APCI1564_TCW_WARN_TIMEVAL 24
#define APCI1564_TCW_WARN_TIMEBASE 28
// Hardware Layer functions for Apci1564
//DI
// for di read
INT i_APCI1564_ConfigDigitalInput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI1564_Read1DigitalInput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI1564_ReadMoreDigitalInput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
//DO
int i_APCI1564_ConfigDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI1564_WriteDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI1564_ReadDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
int i_APCI1564_ReadInterruptStatus(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
// TIMER
// timer value is passed as u seconds
INT i_APCI1564_ConfigTimerCounterWatchdog(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
int i_APCI1564_StartStopWriteTimerCounterWatchdog(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
int i_APCI1564_ReadTimerCounterWatchdog(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
// INTERRUPT
static VOID v_APCI1564_Interrupt(int irq, void *d);
// RESET
INT i_APCI1564_Reset(comedi_device * dev);

View File

@ -0,0 +1,780 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
/*
+-----------------------------------------------------------------------+
| (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+-----------------------------------------------------------------------+
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+-----------------------------------------------------------------------+
| Project : API APCI1648 | Compiler : gcc |
| Module name : TTL.C | Version : 2.96 |
+-------------------------------+---------------------------------------+
| Project manager: S. Weber | Date : 25/05/2005 |
+-----------------------------------------------------------------------+
| Description : APCI-16XX TTL I/O module |
| |
| |
+-----------------------------------------------------------------------+
| UPDATES |
+-----------------------------------------------------------------------+
| Date | Author | Description of updates |
+----------+-----------+------------------------------------------------+
|25.05.2005| S.Weber | Creation |
| | | |
+-----------------------------------------------------------------------+
*/
/*
+----------------------------------------------------------------------------+
| Included files |
+----------------------------------------------------------------------------+
*/
#include "hwdrv_apci16xx.h"
/*
+----------------------------------------------------------------------------+
| Function Name : INT i_APCI16XX_InsnConfigInitTTLIO |
| (comedi_device *dev, |
| comedi_subdevice *s, |
| comedi_insn *insn, |
| lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task APCI16XX_TTL_INIT (using defaults) : |
| Configure the TTL I/O operating mode from all ports |
| You must calling this function be |
| for you call any other function witch access of TTL. |
| APCI16XX_TTL_INITDIRECTION(user inputs for direction) |
+----------------------------------------------------------------------------+
| Input Parameters : b_InitType = (BYTE) data[0]; |
| b_Port0Mode = (BYTE) data[1]; |
| b_Port1Mode = (BYTE) data[2]; |
| b_Port2Mode = (BYTE) data[3]; |
| b_Port3Mode = (BYTE) data[4]; |
| ........ |
+----------------------------------------------------------------------------+
| Output Parameters : - |
+----------------------------------------------------------------------------+
| Return Value :>0: No error |
| -1: Port 0 mode selection is wrong |
| -2: Port 1 mode selection is wrong |
| -3: Port 2 mode selection is wrong |
| -4: Port 3 mode selection is wrong |
| -X: Port X-1 mode selection is wrong |
| .... |
| -100 : Config command error |
| -101 : Data size error |
+----------------------------------------------------------------------------+
*/
int i_APCI16XX_InsnConfigInitTTLIO(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
{
INT i_ReturnValue = insn->n;
BYTE b_Command = 0;
BYTE b_Cpt = 0;
BYTE b_NumberOfPort =
(BYTE) (devpriv->ps_BoardInfo->i_NbrTTLChannel / 8);
/************************/
/* Test the buffer size */
/************************/
if (insn->n >= 1) {
/*******************/
/* Get the command */
/* **************** */
b_Command = (BYTE) data[0];
/********************/
/* Test the command */
/********************/
if ((b_Command == APCI16XX_TTL_INIT) ||
(b_Command == APCI16XX_TTL_INITDIRECTION) ||
(b_Command == APCI16XX_TTL_OUTPUTMEMORY)) {
/***************************************/
/* Test the initialisation buffer size */
/***************************************/
if ((b_Command == APCI16XX_TTL_INITDIRECTION)
&& ((BYTE) (insn->n - 1) != b_NumberOfPort)) {
/*******************/
/* Data size error */
/*******************/
printk("\nBuffer size error");
i_ReturnValue = -101;
}
if ((b_Command == APCI16XX_TTL_OUTPUTMEMORY)
&& ((BYTE) (insn->n) != 2)) {
/*******************/
/* Data size error */
/*******************/
printk("\nBuffer size error");
i_ReturnValue = -101;
}
} else {
/************************/
/* Config command error */
/************************/
printk("\nCommand selection error");
i_ReturnValue = -100;
}
} else {
/*******************/
/* Data size error */
/*******************/
printk("\nBuffer size error");
i_ReturnValue = -101;
}
/**************************************************************************/
/* Test if no error occur and APCI16XX_TTL_INITDIRECTION command selected */
/**************************************************************************/
if ((i_ReturnValue >= 0) && (b_Command == APCI16XX_TTL_INITDIRECTION)) {
memset(devpriv->ul_TTLPortConfiguration, 0,
sizeof(devpriv->ul_TTLPortConfiguration));
/*************************************/
/* Test the port direction selection */
/*************************************/
for (b_Cpt = 1;
(b_Cpt <= b_NumberOfPort) && (i_ReturnValue >= 0);
b_Cpt++) {
/**********************/
/* Test the direction */
/**********************/
if ((data[b_Cpt] != 0) && (data[b_Cpt] != 0xFF)) {
/************************/
/* Port direction error */
/************************/
printk("\nPort %d direction selection error",
(INT) b_Cpt);
i_ReturnValue = -(INT) b_Cpt;
}
/**************************/
/* Save the configuration */
/**************************/
devpriv->ul_TTLPortConfiguration[(b_Cpt - 1) / 4] =
devpriv->ul_TTLPortConfiguration[(b_Cpt -
1) / 4] | (data[b_Cpt] << (8 * ((b_Cpt -
1) % 4)));
}
}
/**************************/
/* Test if no error occur */
/**************************/
if (i_ReturnValue >= 0) {
/***********************************/
/* Test if TTL port initilaisation */
/***********************************/
if ((b_Command == APCI16XX_TTL_INIT)
|| (b_Command == APCI16XX_TTL_INITDIRECTION)) {
/******************************/
/* Set all port configuration */
/******************************/
for (b_Cpt = 0; b_Cpt <= b_NumberOfPort; b_Cpt++) {
if ((b_Cpt % 4) == 0) {
/*************************/
/* Set the configuration */
/*************************/
outl(devpriv->
ul_TTLPortConfiguration[b_Cpt /
4],
devpriv->iobase + 32 + b_Cpt);
}
}
}
}
/************************************************/
/* Test if output memory initialisation command */
/************************************************/
if (b_Command == APCI16XX_TTL_OUTPUTMEMORY) {
if (data[1]) {
devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
} else {
devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
}
}
return (i_ReturnValue);
}
/*
+----------------------------------------------------------------------------+
| INPUT FUNCTIONS |
+----------------------------------------------------------------------------+
*/
/*
+----------------------------------------------------------------------------+
| Function Name : INT i_APCI16XX_InsnBitsReadTTLIO |
| (comedi_device *dev, |
| comedi_subdevice *s, |
| comedi_insn *insn, |
| lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Read the status from selected TTL digital input |
| (b_InputChannel) |
+----------------------------------------------------------------------------+
| Task : Read the status from digital input port |
| (b_SelectedPort) |
+----------------------------------------------------------------------------+
| Input Parameters : |
| APCI16XX_TTL_READCHANNEL |
| b_SelectedPort= CR_RANGE(insn->chanspec); |
| b_InputChannel= CR_CHAN(insn->chanspec); |
| b_ReadType = (BYTE) data[0]; |
| |
| APCI16XX_TTL_READPORT |
| b_SelectedPort= CR_RANGE(insn->chanspec); |
| b_ReadType = (BYTE) data[0]; |
+----------------------------------------------------------------------------+
| Output Parameters : data[0] 0 : Channle is not active |
| 1 : Channle is active |
+----------------------------------------------------------------------------+
| Return Value : >0 : No error |
| -100 : Config command error |
| -101 : Data size error |
| -102 : The selected TTL input port is wrong |
| -103 : The selected TTL digital input is wrong |
+----------------------------------------------------------------------------+
*/
int i_APCI16XX_InsnBitsReadTTLIO(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
{
INT i_ReturnValue = insn->n;
BYTE b_Command = 0;
BYTE b_NumberOfPort =
(BYTE) (devpriv->ps_BoardInfo->i_NbrTTLChannel / 8);
BYTE b_SelectedPort = CR_RANGE(insn->chanspec);
BYTE b_InputChannel = CR_CHAN(insn->chanspec);
BYTE *pb_Status;
DWORD dw_Status;
/************************/
/* Test the buffer size */
/************************/
if (insn->n >= 1) {
/*******************/
/* Get the command */
/* **************** */
b_Command = (BYTE) data[0];
/********************/
/* Test the command */
/********************/
if ((b_Command == APCI16XX_TTL_READCHANNEL)
|| (b_Command == APCI16XX_TTL_READPORT)) {
/**************************/
/* Test the selected port */
/**************************/
if (b_SelectedPort < b_NumberOfPort) {
/**********************/
/* Test if input port */
/**********************/
if (((devpriv->ul_TTLPortConfiguration
[b_SelectedPort /
4] >> (8 *
(b_SelectedPort
%
4))) &
0xFF) == 0) {
/***************************/
/* Test the channel number */
/***************************/
if ((b_Command ==
APCI16XX_TTL_READCHANNEL)
&& (b_InputChannel > 7)) {
/*******************************************/
/* The selected TTL digital input is wrong */
/*******************************************/
printk("\nChannel selection error");
i_ReturnValue = -103;
}
} else {
/****************************************/
/* The selected TTL input port is wrong */
/****************************************/
printk("\nPort selection error");
i_ReturnValue = -102;
}
} else {
/****************************************/
/* The selected TTL input port is wrong */
/****************************************/
printk("\nPort selection error");
i_ReturnValue = -102;
}
} else {
/************************/
/* Config command error */
/************************/
printk("\nCommand selection error");
i_ReturnValue = -100;
}
} else {
/*******************/
/* Data size error */
/*******************/
printk("\nBuffer size error");
i_ReturnValue = -101;
}
/**************************/
/* Test if no error occur */
/**************************/
if (i_ReturnValue >= 0) {
pb_Status = (PBYTE) & data[0];
/*******************************/
/* Get the digital inpu status */
/*******************************/
dw_Status =
inl(devpriv->iobase + 8 + ((b_SelectedPort / 4) * 4));
dw_Status = (dw_Status >> (8 * (b_SelectedPort % 4))) & 0xFF;
/***********************/
/* Save the port value */
/***********************/
*pb_Status = (BYTE) dw_Status;
/***************************************/
/* Test if read channel status command */
/***************************************/
if (b_Command == APCI16XX_TTL_READCHANNEL) {
*pb_Status = (*pb_Status >> b_InputChannel) & 1;
}
}
return (i_ReturnValue);
}
/*
+----------------------------------------------------------------------------+
| Function Name : INT i_APCI16XX_InsnReadTTLIOAllPortValue |
| (comedi_device *dev, |
| comedi_subdevice *s, |
| comedi_insn *insn, |
| lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Read the status from all digital input ports |
+----------------------------------------------------------------------------+
| Input Parameters : - |
+----------------------------------------------------------------------------+
| Output Parameters : data[0] : Port 0 to 3 data |
| data[1] : Port 4 to 7 data |
| .... |
+----------------------------------------------------------------------------+
| Return Value : 0: No error |
| -100 : Read command error |
| -101 : Data size error |
+----------------------------------------------------------------------------+
*/
int i_APCI16XX_InsnReadTTLIOAllPortValue(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
{
BYTE b_Command = (BYTE) CR_AREF(insn->chanspec);
INT i_ReturnValue = insn->n;
BYTE b_Cpt = 0;
BYTE b_NumberOfPort = 0;
lsampl_t *pls_ReadData = data;
/********************/
/* Test the command */
/********************/
if ((b_Command == APCI16XX_TTL_READ_ALL_INPUTS)
|| (b_Command == APCI16XX_TTL_READ_ALL_OUTPUTS)) {
/**********************************/
/* Get the number of 32-Bit ports */
/**********************************/
b_NumberOfPort =
(BYTE) (devpriv->ps_BoardInfo->i_NbrTTLChannel / 32);
if ((b_NumberOfPort * 32) <
devpriv->ps_BoardInfo->i_NbrTTLChannel) {
b_NumberOfPort = b_NumberOfPort + 1;
}
/************************/
/* Test the buffer size */
/************************/
if (insn->n >= b_NumberOfPort) {
if (b_Command == APCI16XX_TTL_READ_ALL_INPUTS) {
/**************************/
/* Read all digital input */
/**************************/
for (b_Cpt = 0; b_Cpt < b_NumberOfPort; b_Cpt++) {
/************************/
/* Read the 32-Bit port */
/************************/
pls_ReadData[b_Cpt] =
inl(devpriv->iobase + 8 +
(b_Cpt * 4));
/**************************************/
/* Mask all channels used als outputs */
/**************************************/
pls_ReadData[b_Cpt] =
pls_ReadData[b_Cpt] &
(~devpriv->
ul_TTLPortConfiguration[b_Cpt]);
}
} else {
/****************************/
/* Read all digital outputs */
/****************************/
for (b_Cpt = 0; b_Cpt < b_NumberOfPort; b_Cpt++) {
/************************/
/* Read the 32-Bit port */
/************************/
pls_ReadData[b_Cpt] =
inl(devpriv->iobase + 20 +
(b_Cpt * 4));
/**************************************/
/* Mask all channels used als outputs */
/**************************************/
pls_ReadData[b_Cpt] =
pls_ReadData[b_Cpt] & devpriv->
ul_TTLPortConfiguration[b_Cpt];
}
}
} else {
/*******************/
/* Data size error */
/*******************/
printk("\nBuffer size error");
i_ReturnValue = -101;
}
} else {
/*****************/
/* Command error */
/*****************/
printk("\nCommand selection error");
i_ReturnValue = -100;
}
return (i_ReturnValue);
}
/*
+----------------------------------------------------------------------------+
| OUTPUT FUNCTIONS |
+----------------------------------------------------------------------------+
*/
/*
+----------------------------------------------------------------------------+
| Function Name : INT i_APCI16XX_InsnBitsWriteTTLIO |
| (comedi_device *dev, |
| comedi_subdevice *s, |
| comedi_insn *insn, |
| lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Set the state from selected TTL digital output |
| (b_OutputChannel) |
+----------------------------------------------------------------------------+
| Task : Set the state from digital output port |
| (b_SelectedPort) |
+----------------------------------------------------------------------------+
| Input Parameters : |
| APCI16XX_TTL_WRITECHANNEL_ON | APCI16XX_TTL_WRITECHANNEL_OFF |
| b_SelectedPort = CR_RANGE(insn->chanspec); |
| b_OutputChannel= CR_CHAN(insn->chanspec); |
| b_Command = (BYTE) data[0]; |
| |
| APCI16XX_TTL_WRITEPORT_ON | APCI16XX_TTL_WRITEPORT_OFF |
| b_SelectedPort = CR_RANGE(insn->chanspec); |
| b_Command = (BYTE) data[0]; |
+----------------------------------------------------------------------------+
| Output Parameters : data[0] : TTL output port 0 to 3 data |
| data[1] : TTL output port 4 to 7 data |
| .... |
+----------------------------------------------------------------------------+
| Return Value : >0 : No error |
| -100 : Command error |
| -101 : Data size error |
| -102 : The selected TTL output port is wrong |
| -103 : The selected TTL digital output is wrong |
| -104 : Output memory disabled |
+----------------------------------------------------------------------------+
*/
int i_APCI16XX_InsnBitsWriteTTLIO(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
{
INT i_ReturnValue = insn->n;
BYTE b_Command = 0;
BYTE b_NumberOfPort =
(BYTE) (devpriv->ps_BoardInfo->i_NbrTTLChannel / 8);
BYTE b_SelectedPort = CR_RANGE(insn->chanspec);
BYTE b_OutputChannel = CR_CHAN(insn->chanspec);
DWORD dw_Status = 0;
/************************/
/* Test the buffer size */
/************************/
if (insn->n >= 1) {
/*******************/
/* Get the command */
/* **************** */
b_Command = (BYTE) data[0];
/********************/
/* Test the command */
/********************/
if ((b_Command == APCI16XX_TTL_WRITECHANNEL_ON) ||
(b_Command == APCI16XX_TTL_WRITEPORT_ON) ||
(b_Command == APCI16XX_TTL_WRITECHANNEL_OFF) ||
(b_Command == APCI16XX_TTL_WRITEPORT_OFF)) {
/**************************/
/* Test the selected port */
/**************************/
if (b_SelectedPort < b_NumberOfPort) {
/***********************/
/* Test if output port */
/***********************/
if (((devpriv->ul_TTLPortConfiguration
[b_SelectedPort /
4] >> (8 *
(b_SelectedPort
%
4))) &
0xFF) == 0xFF) {
/***************************/
/* Test the channel number */
/***************************/
if (((b_Command == APCI16XX_TTL_WRITECHANNEL_ON) || (b_Command == APCI16XX_TTL_WRITECHANNEL_OFF)) && (b_OutputChannel > 7)) {
/********************************************/
/* The selected TTL digital output is wrong */
/********************************************/
printk("\nChannel selection error");
i_ReturnValue = -103;
}
if (((b_Command == APCI16XX_TTL_WRITECHANNEL_OFF) || (b_Command == APCI16XX_TTL_WRITEPORT_OFF)) && (devpriv->b_OutputMemoryStatus == ADDIDATA_DISABLE)) {
/********************************************/
/* The selected TTL digital output is wrong */
/********************************************/
printk("\nOutput memory disabled");
i_ReturnValue = -104;
}
/************************/
/* Test the buffer size */
/************************/
if (((b_Command == APCI16XX_TTL_WRITEPORT_ON) || (b_Command == APCI16XX_TTL_WRITEPORT_OFF)) && (insn->n < 2)) {
/*******************/
/* Data size error */
/*******************/
printk("\nBuffer size error");
i_ReturnValue = -101;
}
} else {
/*****************************************/
/* The selected TTL output port is wrong */
/*****************************************/
printk("\nPort selection error %lX",
(unsigned long)devpriv->
ul_TTLPortConfiguration[0]);
i_ReturnValue = -102;
}
} else {
/****************************************/
/* The selected TTL output port is wrong */
/****************************************/
printk("\nPort selection error %d %d",
b_SelectedPort, b_NumberOfPort);
i_ReturnValue = -102;
}
} else {
/************************/
/* Config command error */
/************************/
printk("\nCommand selection error");
i_ReturnValue = -100;
}
} else {
/*******************/
/* Data size error */
/*******************/
printk("\nBuffer size error");
i_ReturnValue = -101;
}
/**************************/
/* Test if no error occur */
/**************************/
if (i_ReturnValue >= 0) {
/********************************/
/* Get the digital output state */
/********************************/
dw_Status =
inl(devpriv->iobase + 20 + ((b_SelectedPort / 4) * 4));
/**********************************/
/* Test if output memory not used */
/**********************************/
if (devpriv->b_OutputMemoryStatus == ADDIDATA_DISABLE) {
/*********************************/
/* Clear the selected port value */
/*********************************/
dw_Status =
dw_Status & (0xFFFFFFFFUL -
(0xFFUL << (8 * (b_SelectedPort % 4))));
}
/******************************/
/* Test if setting channel ON */
/******************************/
if (b_Command == APCI16XX_TTL_WRITECHANNEL_ON) {
dw_Status =
dw_Status | (1UL << ((8 * (b_SelectedPort %
4)) + b_OutputChannel));
}
/***************************/
/* Test if setting port ON */
/***************************/
if (b_Command == APCI16XX_TTL_WRITEPORT_ON) {
dw_Status =
dw_Status | ((data[1] & 0xFF) << (8 *
(b_SelectedPort % 4)));
}
/*******************************/
/* Test if setting channel OFF */
/*******************************/
if (b_Command == APCI16XX_TTL_WRITECHANNEL_OFF) {
dw_Status =
dw_Status & (0xFFFFFFFFUL -
(1UL << ((8 * (b_SelectedPort % 4)) +
b_OutputChannel)));
}
/****************************/
/* Test if setting port OFF */
/****************************/
if (b_Command == APCI16XX_TTL_WRITEPORT_OFF) {
dw_Status =
dw_Status & (0xFFFFFFFFUL -
((data[1] & 0xFF) << (8 * (b_SelectedPort %
4))));
}
outl(dw_Status,
devpriv->iobase + 20 + ((b_SelectedPort / 4) * 4));
}
return (i_ReturnValue);
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI2200_Reset(comedi_device *dev) | +----------------------------------------------------------------------------+
| Task :resets all the registers |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev |
+----------------------------------------------------------------------------+
| Output Parameters : - |
+----------------------------------------------------------------------------+
| Return Value : - |
+----------------------------------------------------------------------------+
*/
int i_APCI16XX_Reset(comedi_device * dev)
{
return 0;
}

View File

@ -0,0 +1,97 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
#ifndef COMEDI_SUBD_TTLIO
#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */
#endif
#ifndef ADDIDATA_ENABLE
#define ADDIDATA_ENABLE 1
#define ADDIDATA_DISABLE 0
#endif
#define APCI16XX_TTL_INIT 0
#define APCI16XX_TTL_INITDIRECTION 1
#define APCI16XX_TTL_OUTPUTMEMORY 2
#define APCI16XX_TTL_READCHANNEL 0
#define APCI16XX_TTL_READPORT 1
#define APCI16XX_TTL_WRITECHANNEL_ON 0
#define APCI16XX_TTL_WRITECHANNEL_OFF 1
#define APCI16XX_TTL_WRITEPORT_ON 2
#define APCI16XX_TTL_WRITEPORT_OFF 3
#define APCI16XX_TTL_READ_ALL_INPUTS 0
#define APCI16XX_TTL_READ_ALL_OUTPUTS 1
#ifdef __KERNEL__
static const comedi_lrange range_apci16xx_ttl = { 12,
{BIP_RANGE(1),
BIP_RANGE(1),
BIP_RANGE(1),
BIP_RANGE(1),
BIP_RANGE(1),
BIP_RANGE(1),
BIP_RANGE(1),
BIP_RANGE(1),
BIP_RANGE(1),
BIP_RANGE(1),
BIP_RANGE(1),
BIP_RANGE(1)}
};
/*
+----------------------------------------------------------------------------+
| TTL INISIALISATION FUNCTION |
+----------------------------------------------------------------------------+
*/
int i_APCI16XX_InsnConfigInitTTLIO(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
/*
+----------------------------------------------------------------------------+
| TTL INPUT FUNCTION |
+----------------------------------------------------------------------------+
*/
int i_APCI16XX_InsnBitsReadTTLIO(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
int i_APCI16XX_InsnReadTTLIOAllPortValue(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
/*
+----------------------------------------------------------------------------+
| TTL OUTPUT FUNCTIONS |
+----------------------------------------------------------------------------+
*/
int i_APCI16XX_InsnBitsWriteTTLIO(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
int i_APCI16XX_Reset(comedi_device * dev);
#endif

View File

@ -0,0 +1,460 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
/*
+-----------------------------------------------------------------------+
| (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+-----------------------------------------------------------------------+
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+-------------------------------+---------------------------------------+
| Project : APCI-2016 | Compiler : GCC |
| Module name : hwdrv_apci2016.c| Version : 2.96 |
+-------------------------------+---------------------------------------+
| Project manager: Eric Stolz | Date : 02/12/2002 |
+-------------------------------+---------------------------------------+
| Description : Hardware Layer Acces For APCI-2016 |
+-----------------------------------------------------------------------+
| UPDATES |
+----------+-----------+------------------------------------------------+
| Date | Author | Description of updates |
+----------+-----------+------------------------------------------------+
| | | |
| | | |
| | | |
+----------+-----------+------------------------------------------------+
*/
/*
+----------------------------------------------------------------------------+
| Included files |
+----------------------------------------------------------------------------+
*/
#include "hwdrv_apci2016.h"
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI2016_ConfigDigitalOutput |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Configures The Digital Output Subdevice. |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| UINT *data : Data Pointer contains |
| configuration parameters as below |
| |
| data[0] : 1 Digital Memory On |
| 0 Digital Memory Off |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
int i_APCI2016_ConfigDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
if ((data[0] != 0) && (data[0] != 1)) {
comedi_error(dev,
"Not a valid Data !!! ,Data should be 1 or 0\n");
return -EINVAL;
} // if ((data[0]!=0) && (data[0]!=1))
if (data[0]) {
devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
} // if (data[0]
else {
devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
} // else if (data[0]
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI2016_WriteDigitalOutput |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Writes port value To the selected port |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| UINT ui_NoOfChannels : No Of Channels To Write |
| UINT *data : Data Pointer to read status |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
int i_APCI2016_WriteDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
UINT ui_NoOfChannel;
UINT ui_Temp, ui_Temp1;
ui_NoOfChannel = CR_CHAN(insn->chanspec);
if ((ui_NoOfChannel < 0) || (ui_NoOfChannel > 15)) {
comedi_error(dev,
"Invalid Channel Numbers !!!, Channel Numbers must be between 0 and 15\n");
return -EINVAL;
} // if ((ui_NoOfChannel<0) || (ui_NoOfChannel>15))
if (devpriv->b_OutputMemoryStatus) {
ui_Temp = inw(devpriv->iobase + APCI2016_DIGITAL_OP);
} // if (devpriv->b_OutputMemoryStatus )
else {
ui_Temp = 0;
} // else if (devpriv->b_OutputMemoryStatus )
if ((data[1] != 0) && (data[1] != 1)) {
comedi_error(dev,
"Invalid Data[1] value !!!, Data[1] should be 0 or 1\n");
return -EINVAL;
} // if ((data[1]!=0) && (data[1]!=1))
if (data[3] == 0) {
if (data[1] == 0) {
data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
outw(data[0], devpriv->iobase + APCI2016_DIGITAL_OP);
} // if (data[1]==0)
else {
if (data[1] == 1) {
switch (ui_NoOfChannel) {
case 2:
data[0] =
(data[0] << (2 *
data[2])) | ui_Temp;
break;
case 4:
data[0] =
(data[0] << (4 *
data[2])) | ui_Temp;
break;
case 8:
data[0] =
(data[0] << (8 *
data[2])) | ui_Temp;
break;
case 15:
data[0] = data[0] | ui_Temp;
break;
default:
comedi_error(dev, " chan spec wrong");
return -EINVAL; // "sorry channel spec wrong "
} //switch(ui_NoOfChannels)
outw(data[0],
devpriv->iobase + APCI2016_DIGITAL_OP);
} // if (data[1]==1)
else {
printk("\nSpecified channel not supported\n");
} // else if (data[1]==1)
} // else if (data[1]==0)
} // if (data[3]==0)
else {
if (data[3] == 1) {
if (data[1] == 0) {
data[0] = ~data[0] & 0x1;
ui_Temp1 = 1;
ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
ui_Temp = ui_Temp | ui_Temp1;
data[0] = (data[0] << ui_NoOfChannel) ^ 0xffff;
data[0] = data[0] & ui_Temp;
outw(data[0],
devpriv->iobase + APCI2016_DIGITAL_OP);
} // if (data[1]==0)
else {
if (data[1] == 1) {
switch (ui_NoOfChannel) {
case 2:
data[0] = ~data[0] & 0x3;
ui_Temp1 = 3;
ui_Temp1 =
ui_Temp1 << 2 * data[2];
ui_Temp = ui_Temp | ui_Temp1;
data[0] =
((data[0] << (2 *
data
[2])) ^
0xffff) & ui_Temp;
break;
case 4:
data[0] = ~data[0] & 0xf;
ui_Temp1 = 15;
ui_Temp1 =
ui_Temp1 << 4 * data[2];
ui_Temp = ui_Temp | ui_Temp1;
data[0] =
((data[0] << (4 *
data
[2])) ^
0xffff) & ui_Temp;
break;
case 8:
data[0] = ~data[0] & 0xff;
ui_Temp1 = 255;
ui_Temp1 =
ui_Temp1 << 8 * data[2];
ui_Temp = ui_Temp | ui_Temp1;
data[0] =
((data[0] << (8 *
data
[2])) ^
0xffff) & ui_Temp;
break;
case 15:
break;
default:
comedi_error(dev,
" chan spec wrong");
return -EINVAL; // "sorry channel spec wrong "
} //switch(ui_NoOfChannels)
outw(data[0],
devpriv->iobase +
APCI2016_DIGITAL_OP);
} // if(data[1]==1)
else {
printk("\nSpecified channel not supported\n");
} //else if(data[1]==1)
} //elseif(data[1]==0)
} //if(data[3]==1);
else {
printk("\nSpecified functionality does not exist\n");
return -EINVAL;
} //if else data[3]==1)
} //if else data[3]==0)
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI2016_BitsDigitalOutput |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Read value of the selected channel or port |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| UINT ui_NoOfChannels : No Of Channels To read |
| UINT *data : Data Pointer to read status |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
int i_APCI2016_BitsDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
UINT ui_Temp;
UINT ui_NoOfChannel;
ui_NoOfChannel = CR_CHAN(insn->chanspec);
if ((ui_NoOfChannel < 0) || (ui_NoOfChannel > 15)) {
comedi_error(dev,
"Invalid Channel Numbers !!!, Channel Numbers must be between 0 and 15\n");
return -EINVAL;
} // if ((ui_NoOfChannel<0) || (ui_NoOfChannel>15))
if ((data[0] != 0) && (data[0] != 1)) {
comedi_error(dev,
"Invalid Data[0] value !!!, Data[0] should be 0 or 1\n");
return -EINVAL;
} // if ((data[0]!=0) && (data[0]!=1))
ui_Temp = data[0];
*data = inw(devpriv->iobase + APCI2016_DIGITAL_OP_RW);
if (ui_Temp == 0) {
*data = (*data >> ui_NoOfChannel) & 0x1;
} // if (ui_Temp==0)
else {
if (ui_Temp == 1) {
switch (ui_NoOfChannel) {
case 2:
*data = (*data >> (2 * data[1])) & 3;
break;
case 4:
*data = (*data >> (4 * data[1])) & 15;
break;
case 8:
*data = (*data >> (8 * data[1])) & 255;
break;
case 15:
break;
default:
comedi_error(dev, " chan spec wrong");
return -EINVAL; // "sorry channel spec wrong "
} //switch(ui_NoOfChannel)
} // if (ui_Temp==1)
else {
printk("\nSpecified channel not supported \n");
} // else if (ui_Temp==1)
} // if (ui_Temp==0)
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI2016_ConfigWatchdog |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Configures The Watchdog |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| comedi_subdevice *s, :pointer to subdevice structure |
| comedi_insn *insn :pointer to insn structure |
| lsampl_t *data : Data Pointer to read status |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
int i_APCI2016_ConfigWatchdog(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
if (data[0] == 0) {
//Disable the watchdog
outw(0x0,
devpriv->i_IobaseAddon +
APCI2016_WATCHDOG_ENABLEDISABLE);
//Loading the Reload value
outw(data[1],
devpriv->i_IobaseAddon +
APCI2016_WATCHDOG_RELOAD_VALUE);
data[1] = data[1] >> 16;
outw(data[1],
devpriv->i_IobaseAddon +
APCI2016_WATCHDOG_RELOAD_VALUE + 2);
} else {
printk("\nThe input parameters are wrong\n");
}
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI2016_StartStopWriteWatchdog |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Start / Stop The Watchdog |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| comedi_subdevice *s, :pointer to subdevice structure |
| comedi_insn *insn :pointer to insn structure |
| lsampl_t *data : Data Pointer to read status |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
int i_APCI2016_StartStopWriteWatchdog(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
switch (data[0]) {
case 0: //stop the watchdog
outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_ENABLEDISABLE); //disable the watchdog
break;
case 1: //start the watchdog
outw(0x0001,
devpriv->i_IobaseAddon +
APCI2016_WATCHDOG_ENABLEDISABLE);
break;
case 2: //Software trigger
outw(0x0201,
devpriv->i_IobaseAddon +
APCI2016_WATCHDOG_ENABLEDISABLE);
break;
default:
printk("\nSpecified functionality does not exist\n");
return -EINVAL;
} // switch(data[0])
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI2016_ReadWatchdog |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Read The Watchdog |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| comedi_subdevice *s, :pointer to subdevice structure |
| comedi_insn *insn :pointer to insn structure |
| lsampl_t *data : Data Pointer to read status |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
int i_APCI2016_ReadWatchdog(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
udelay(5);
data[0] = inw(devpriv->i_IobaseAddon + APCI2016_WATCHDOG_STATUS) & 0x1;
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI2016_Reset(comedi_device *dev) | |
+----------------------------------------------------------------------------+
| Task :resets all the registers |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : |
| |
+----------------------------------------------------------------------------+
*/
INT i_APCI2016_Reset(comedi_device * dev)
{
outw(0x0, devpriv->iobase + APCI2016_DIGITAL_OP); // Resets the digital output channels
outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_ENABLEDISABLE);
outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_RELOAD_VALUE);
outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_RELOAD_VALUE + 2);
return 0;
}

View File

@ -0,0 +1,77 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
/********* Definitions for APCI-2016 card *****/
#define APCI2016_BOARD_VENDOR_ID 0x15B8
#define APCI2016_ADDRESS_RANGE 8
//DIGITAL INPUT-OUTPUT DEFINE
#define APCI2016_DIGITAL_OP 0x04
#define APCI2016_DIGITAL_OP_RW 4
//ADDIDATA Enable Disable
#define ADDIDATA_ENABLE 1
#define ADDIDATA_DISABLE 0
// TIMER COUNTER WATCHDOG DEFINES
#define ADDIDATA_WATCHDOG 2
#define APCI2016_DIGITAL_OP_WATCHDOG 0
#define APCI2016_WATCHDOG_ENABLEDISABLE 12
#define APCI2016_WATCHDOG_RELOAD_VALUE 4
#define APCI2016_WATCHDOG_STATUS 16
// Hardware Layer functions for Apci2016
//DO
int i_APCI2016_ConfigDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
int i_APCI2016_WriteDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
int i_APCI2016_BitsDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
// TIMER
// timer value is passed as u seconds
int i_APCI2016_ConfigWatchdog(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
int i_APCI2016_StartStopWriteWatchdog(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
int i_APCI2016_ReadWatchdog(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
// Interrupt functions.....
// VOID v_APCI2016_Interrupt(int irq, void *d) ;
//VOID v_APCI2016_Interrupt(int irq, void *d);
// RESET
INT i_APCI2016_Reset(comedi_device * dev);

View File

@ -0,0 +1,579 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
/*
+-----------------------------------------------------------------------+
| (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+-----------------------------------------------------------------------+
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+-------------------------------+---------------------------------------+
| Project : APCI-2032 | Compiler : GCC |
| Module name : hwdrv_apci2032.c| Version : 2.96 |
+-------------------------------+---------------------------------------+
| Project manager: Eric Stolz | Date : 02/12/2002 |
+-------------------------------+---------------------------------------+
| Description : Hardware Layer Acces For APCI-2032 |
+-----------------------------------------------------------------------+
| UPDATES |
+----------+-----------+------------------------------------------------+
| Date | Author | Description of updates |
+----------+-----------+------------------------------------------------+
| | | |
| | | |
| | | |
+----------+-----------+------------------------------------------------+
*/
/*
+----------------------------------------------------------------------------+
| Included files |
+----------------------------------------------------------------------------+
*/
#include "hwdrv_apci2032.h"
UINT ui_InterruptData, ui_Type;
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI2032_ConfigDigitalOutput |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Configures The Digital Output Subdevice. |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| UINT *data : Data Pointer contains |
| configuration parameters as below |
| |
| data[1] : 1 Enable VCC Interrupt |
| 0 Disable VCC Interrupt |
| data[2] : 1 Enable CC Interrupt |
| 0 Disable CC Interrupt |
| |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
int i_APCI2032_ConfigDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
ULONG ul_Command = 0;
devpriv->tsk_Current = current;
if ((data[0] != 0) && (data[0] != 1)) {
comedi_error(dev,
"Not a valid Data !!! ,Data should be 1 or 0\n");
return -EINVAL;
} //if ( (data[0]!=0) && (data[0]!=1) )
if (data[0]) {
devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
} // if (data[0])
else {
devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
} //else if (data[0])
if (data[1] == ADDIDATA_ENABLE) {
ul_Command = ul_Command | 0x1;
} //if (data[1] == ADDIDATA_ENABLE)
else {
ul_Command = ul_Command & 0xFFFFFFFE;
} //elseif (data[1] == ADDIDATA_ENABLE)
if (data[2] == ADDIDATA_ENABLE) {
ul_Command = ul_Command | 0x2;
} //if (data[2] == ADDIDATA_ENABLE)
else {
ul_Command = ul_Command & 0xFFFFFFFD;
} //elseif (data[2] == ADDIDATA_ENABLE)
outl(ul_Command, devpriv->iobase + APCI2032_DIGITAL_OP_INTERRUPT);
ui_InterruptData = inl(devpriv->iobase + APCI2032_DIGITAL_OP_INTERRUPT);
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI2032_WriteDigitalOutput |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Writes port value To the selected port |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| UINT ui_NoOfChannels : No Of Channels To Write |
| UINT *data : Data Pointer to read status |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
INT i_APCI2032_WriteDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
UINT ui_Temp, ui_Temp1;
UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
if (devpriv->b_OutputMemoryStatus) {
ui_Temp = inl(devpriv->iobase + APCI2032_DIGITAL_OP);
} //if(devpriv->b_OutputMemoryStatus )
else {
ui_Temp = 0;
} //if(devpriv->b_OutputMemoryStatus )
if (data[3] == 0) {
if (data[1] == 0) {
data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
outl(data[0], devpriv->iobase + APCI2032_DIGITAL_OP);
} //if(data[1]==0)
else {
if (data[1] == 1) {
switch (ui_NoOfChannel) {
case 2:
data[0] =
(data[0] << (2 *
data[2])) | ui_Temp;
break;
case 4:
data[0] =
(data[0] << (4 *
data[2])) | ui_Temp;
break;
case 8:
data[0] =
(data[0] << (8 *
data[2])) | ui_Temp;
break;
case 16:
data[0] =
(data[0] << (16 *
data[2])) | ui_Temp;
break;
case 31:
data[0] = data[0] | ui_Temp;
break;
default:
comedi_error(dev, " chan spec wrong");
return -EINVAL; // "sorry channel spec wrong "
} //switch(ui_NoOfChannels)
outl(data[0],
devpriv->iobase + APCI2032_DIGITAL_OP);
} // if(data[1]==1)
else {
printk("\nSpecified channel not supported\n");
} //else if(data[1]==1)
} //elseif(data[1]==0)
} //if(data[3]==0)
else {
if (data[3] == 1) {
if (data[1] == 0) {
data[0] = ~data[0] & 0x1;
ui_Temp1 = 1;
ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
ui_Temp = ui_Temp | ui_Temp1;
data[0] =
(data[0] << ui_NoOfChannel) ^
0xffffffff;
data[0] = data[0] & ui_Temp;
outl(data[0],
devpriv->iobase + APCI2032_DIGITAL_OP);
} //if(data[1]==0)
else {
if (data[1] == 1) {
switch (ui_NoOfChannel) {
case 2:
data[0] = ~data[0] & 0x3;
ui_Temp1 = 3;
ui_Temp1 =
ui_Temp1 << 2 * data[2];
ui_Temp = ui_Temp | ui_Temp1;
data[0] =
((data[0] << (2 *
data
[2])) ^
0xffffffff) & ui_Temp;
break;
case 4:
data[0] = ~data[0] & 0xf;
ui_Temp1 = 15;
ui_Temp1 =
ui_Temp1 << 4 * data[2];
ui_Temp = ui_Temp | ui_Temp1;
data[0] =
((data[0] << (4 *
data
[2])) ^
0xffffffff) & ui_Temp;
break;
case 8:
data[0] = ~data[0] & 0xff;
ui_Temp1 = 255;
ui_Temp1 =
ui_Temp1 << 8 * data[2];
ui_Temp = ui_Temp | ui_Temp1;
data[0] =
((data[0] << (8 *
data
[2])) ^
0xffffffff) & ui_Temp;
break;
case 16:
data[0] = ~data[0] & 0xffff;
ui_Temp1 = 65535;
ui_Temp1 =
ui_Temp1 << 16 *
data[2];
ui_Temp = ui_Temp | ui_Temp1;
data[0] =
((data[0] << (16 *
data
[2])) ^
0xffffffff) & ui_Temp;
break;
case 31:
break;
default:
comedi_error(dev,
" chan spec wrong");
return -EINVAL; // "sorry channel spec wrong "
} //switch(ui_NoOfChannels)
outl(data[0],
devpriv->iobase +
APCI2032_DIGITAL_OP);
} // if(data[1]==1)
else {
printk("\nSpecified channel not supported\n");
} //else if(data[1]==1)
} //elseif(data[1]==0)
} //if(data[3]==1);
else {
printk("\nSpecified functionality does not exist\n");
return -EINVAL;
} //if else data[3]==1)
} //if else data[3]==0)
return (insn->n);;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI2032_ReadDigitalOutput |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Read value of the selected channel or port |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| UINT ui_NoOfChannels : No Of Channels To read |
| UINT *data : Data Pointer to read status |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
INT i_APCI2032_ReadDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
UINT ui_Temp;
UINT ui_NoOfChannel;
ui_NoOfChannel = CR_CHAN(insn->chanspec);
ui_Temp = data[0];
*data = inl(devpriv->iobase + APCI2032_DIGITAL_OP_RW);
if (ui_Temp == 0) {
*data = (*data >> ui_NoOfChannel) & 0x1;
} //if (ui_Temp==0)
else {
if (ui_Temp == 1) {
switch (ui_NoOfChannel) {
case 2:
*data = (*data >> (2 * data[1])) & 3;
break;
case 4:
*data = (*data >> (4 * data[1])) & 15;
break;
case 8:
*data = (*data >> (8 * data[1])) & 255;
break;
case 16:
*data = (*data >> (16 * data[1])) & 65535;
break;
case 31:
break;
default:
comedi_error(dev, " chan spec wrong");
return -EINVAL; // "sorry channel spec wrong "
} //switch(ui_NoOfChannels)
} //if (ui_Temp==1)
else {
printk("\nSpecified channel not supported \n");
} //elseif (ui_Temp==1)
}
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : INT i_APCI2032_ConfigWatchdog(comedi_device
*dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)|
| |
+----------------------------------------------------------------------------+
| Task : Configures The Watchdog |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| comedi_subdevice *s, :pointer to subdevice structure
comedi_insn *insn :pointer to insn structure |
| lsampl_t *data : Data Pointer to read status |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
INT i_APCI2032_ConfigWatchdog(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
if (data[0] == 0) {
//Disable the watchdog
outl(0x0,
devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
APCI2032_TCW_PROG);
//Loading the Reload value
outl(data[1],
devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
APCI2032_TCW_RELOAD_VALUE);
} else {
printk("\nThe input parameters are wrong\n");
return -EINVAL;
}
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI2032_StartStopWriteWatchdog |
| (comedi_device *dev,comedi_subdevice *s,
comedi_insn *insn,lsampl_t *data); |
+----------------------------------------------------------------------------+
| Task : Start / Stop The Watchdog |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| comedi_subdevice *s, :pointer to subdevice structure
comedi_insn *insn :pointer to insn structure |
| lsampl_t *data : Data Pointer to read status |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
int i_APCI2032_StartStopWriteWatchdog(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
switch (data[0]) {
case 0: //stop the watchdog
outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + APCI2032_TCW_PROG); //disable the watchdog
break;
case 1: //start the watchdog
outl(0x0001,
devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
APCI2032_TCW_PROG);
break;
case 2: //Software trigger
outl(0x0201,
devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
APCI2032_TCW_PROG);
break;
default:
printk("\nSpecified functionality does not exist\n");
return -EINVAL;
}
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI2032_ReadWatchdog |
| (comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,
lsampl_t *data); |
+----------------------------------------------------------------------------+
| Task : Read The Watchdog |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| comedi_subdevice *s, :pointer to subdevice structure
comedi_insn *insn :pointer to insn structure |
| lsampl_t *data : Data Pointer to read status |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
int i_APCI2032_ReadWatchdog(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
data[0] =
inl(devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
APCI2032_TCW_TRIG_STATUS) & 0x1;
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : void v_APCI2032_Interrupt |
| (int irq , void *d) |
+----------------------------------------------------------------------------+
| Task : Writes port value To the selected port |
+----------------------------------------------------------------------------+
| Input Parameters : int irq : irq number |
| void *d : void pointer |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
void v_APCI2032_Interrupt(int irq, void *d)
{
comedi_device *dev = d;
unsigned int ui_DO;
ui_DO = inl(devpriv->iobase + APCI2032_DIGITAL_OP_IRQ) & 0x1; //Check if VCC OR CC interrupt has occured.
if (ui_DO == 0) {
printk("\nInterrupt from unKnown source\n");
} // if(ui_DO==0)
if (ui_DO) {
// Check for Digital Output interrupt Type - 1: Vcc interrupt 2: CC interrupt.
ui_Type =
inl(devpriv->iobase +
APCI2032_DIGITAL_OP_INTERRUPT_STATUS) & 0x3;
outl(0x0,
devpriv->iobase + APCI2032_DIGITAL_OP +
APCI2032_DIGITAL_OP_INTERRUPT);
if (ui_Type == 1) {
//Sends signal to user space
send_sig(SIGIO, devpriv->tsk_Current, 0);
} // if (ui_Type==1)
else {
if (ui_Type == 2) {
// Sends signal to user space
send_sig(SIGIO, devpriv->tsk_Current, 0);
} //if (ui_Type==2)
} //else if (ui_Type==1)
} //if(ui_DO)
return;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI2032_ReadInterruptStatus |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task :Reads the interrupt status register |
+----------------------------------------------------------------------------+
| Input Parameters : |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : |
| |
+----------------------------------------------------------------------------+
*/
int i_APCI2032_ReadInterruptStatus(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
*data = ui_Type;
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI2032_Reset(comedi_device *dev) |
| |
+----------------------------------------------------------------------------+
| Task :Resets the registers of the card |
+----------------------------------------------------------------------------+
| Input Parameters : |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : |
| |
+----------------------------------------------------------------------------+
*/
int i_APCI2032_Reset(comedi_device * dev)
{
devpriv->b_DigitalOutputRegister = 0;
ui_Type = 0;
outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP); //Resets the output channels
outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_INTERRUPT); //Disables the interrupt.
outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + APCI2032_TCW_PROG); //disable the watchdog
outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + APCI2032_TCW_RELOAD_VALUE); //reload=0
return 0;
}

View File

@ -0,0 +1,87 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
/********* Definitions for APCI-2032 card *****/
// Card Specific information
#define APCI2032_BOARD_VENDOR_ID 0x15B8
#define APCI2032_ADDRESS_RANGE 63
//DIGITAL INPUT-OUTPUT DEFINE
#define APCI2032_DIGITAL_OP 0
#define APCI2032_DIGITAL_OP_RW 0
#define APCI2032_DIGITAL_OP_INTERRUPT 4
#define APCI2032_DIGITAL_OP_IRQ 12
//Digital Output Interrupt Status
#define APCI2032_DIGITAL_OP_INTERRUPT_STATUS 8
//Digital Output Interrupt Enable Disable.
#define APCI2032_DIGITAL_OP_VCC_INTERRUPT_ENABLE 0x1
#define APCI2032_DIGITAL_OP_VCC_INTERRUPT_DISABLE 0xFFFFFFFE
#define APCI2032_DIGITAL_OP_CC_INTERRUPT_ENABLE 0x2
#define APCI2032_DIGITAL_OP_CC_INTERRUPT_DISABLE 0xFFFFFFFD
//ADDIDATA Enable Disable
#define ADDIDATA_ENABLE 1
#define ADDIDATA_DISABLE 0
// TIMER COUNTER WATCHDOG DEFINES
#define ADDIDATA_WATCHDOG 2
#define APCI2032_DIGITAL_OP_WATCHDOG 16
#define APCI2032_TCW_RELOAD_VALUE 4
#define APCI2032_TCW_TIMEBASE 8
#define APCI2032_TCW_PROG 12
#define APCI2032_TCW_TRIG_STATUS 16
#define APCI2032_TCW_IRQ 20
// Hardware Layer functions for Apci2032
//DO
int i_APCI2032_ConfigDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI2032_WriteDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI2032_ReadDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
int i_APCI2032_ReadInterruptStatus(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
// TIMER
// timer value is passed as u seconds
INT i_APCI2032_ConfigWatchdog(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
int i_APCI2032_StartStopWriteWatchdog(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
int i_APCI2032_ReadWatchdog(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
// Interrupt functions.....
void v_APCI2032_Interrupt(int irq, void *d);
//Reset functions
int i_APCI2032_Reset(comedi_device * dev);

View File

@ -0,0 +1,549 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
/*
+-----------------------------------------------------------------------+
| (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+-----------------------------------------------------------------------+
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+-------------------------------+---------------------------------------+
| Project : APCI-2200 | Compiler : GCC |
| Module name : hwdrv_apci2200.c| Version : 2.96 |
+-------------------------------+---------------------------------------+
| Project manager: Eric Stolz | Date : 02/12/2002 |
+-------------------------------+---------------------------------------+
| Description : Hardware Layer Acces For APCI-2200 |
+-----------------------------------------------------------------------+
| UPDATES |
+----------+-----------+------------------------------------------------+
| Date | Author | Description of updates |
+----------+-----------+------------------------------------------------+
| | | |
| | | |
| | | |
+----------+-----------+------------------------------------------------+
*/
/*
+----------------------------------------------------------------------------+
| Included files |
+----------------------------------------------------------------------------+
*/
#include "hwdrv_apci2200.h"
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI2200_Read1DigitalInput |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Return the status of the digital input |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| comedi_subdevice *s, :pointer to subdevice structure
comedi_insn *insn :pointer to insn structure |
| lsampl_t *data : Data Pointer to read status |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
INT i_APCI2200_Read1DigitalInput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
UINT ui_TmpValue = 0;
UINT ui_Channel;
ui_Channel = CR_CHAN(insn->chanspec);
if (ui_Channel >= 0 && ui_Channel <= 7) {
ui_TmpValue = (UINT) inw(devpriv->iobase + APCI2200_DIGITAL_IP);
*data = (ui_TmpValue >> ui_Channel) & 0x1;
} //if(ui_Channel >= 0 && ui_Channel <=7)
else {
printk("\nThe specified channel does not exist\n");
return -EINVAL; // "sorry channel spec wrong "
} //else if(ui_Channel >= 0 && ui_Channel <=7)
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI2200_ReadMoreDigitalInput |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Return the status of the Requested digital inputs |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| comedi_subdevice *s, :pointer to subdevice structure
comedi_insn *insn :pointer to insn structure |
| lsampl_t *data : Data Pointer to read status |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
INT i_APCI2200_ReadMoreDigitalInput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
UINT ui_PortValue = data[0];
UINT ui_Mask = 0;
UINT ui_NoOfChannels;
ui_NoOfChannels = CR_CHAN(insn->chanspec);
*data = (UINT) inw(devpriv->iobase + APCI2200_DIGITAL_IP);
switch (ui_NoOfChannels) {
case 2:
ui_Mask = 3;
*data = (*data >> (2 * ui_PortValue)) & ui_Mask;
break;
case 4:
ui_Mask = 15;
*data = (*data >> (4 * ui_PortValue)) & ui_Mask;
break;
case 7:
break;
default:
printk("\nWrong parameters\n");
return -EINVAL; // "sorry channel spec wrong "
break;
} //switch(ui_NoOfChannels)
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI2200_ConfigDigitalOutput (comedi_device *dev,
comedi_subdevice *s comedi_insn *insn,lsampl_t *data) |
| |
+----------------------------------------------------------------------------+
| Task : Configures The Digital Output Subdevice. |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| lsampl_t *data : Data Pointer contains |
| configuration parameters as below |
| comedi_subdevice *s, :pointer to subdevice structure
comedi_insn *insn :pointer to insn structure |
| data[0] :1:Memory on |
| 0:Memory off |
| |
| |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
int i_APCI2200_ConfigDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
devpriv->b_OutputMemoryStatus = data[0];
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI2200_WriteDigitalOutput |
| (comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,
lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Writes port value To the selected port |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| comedi_subdevice *s, :pointer to subdevice structure
comedi_insn *insn :pointer to insn structure |
| lsampl_t *data : Data Pointer to read status |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
INT i_APCI2200_WriteDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
UINT ui_Temp, ui_Temp1;
UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
if (devpriv->b_OutputMemoryStatus) {
ui_Temp = inw(devpriv->iobase + APCI2200_DIGITAL_OP);
} //if(devpriv->b_OutputMemoryStatus )
else {
ui_Temp = 0;
} //if(devpriv->b_OutputMemoryStatus )
if (data[3] == 0) {
if (data[1] == 0) {
data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
outw(data[0], devpriv->iobase + APCI2200_DIGITAL_OP);
} //if(data[1]==0)
else {
if (data[1] == 1) {
switch (ui_NoOfChannel) {
case 2:
data[0] =
(data[0] << (2 *
data[2])) | ui_Temp;
break;
case 4:
data[0] =
(data[0] << (4 *
data[2])) | ui_Temp;
break;
case 8:
data[0] =
(data[0] << (8 *
data[2])) | ui_Temp;
break;
case 15:
data[0] = data[0] | ui_Temp;
break;
default:
comedi_error(dev, " chan spec wrong");
return -EINVAL; // "sorry channel spec wrong "
} //switch(ui_NoOfChannels)
outw(data[0],
devpriv->iobase + APCI2200_DIGITAL_OP);
} // if(data[1]==1)
else {
printk("\nSpecified channel not supported\n");
} //else if(data[1]==1)
} //elseif(data[1]==0)
} //if(data[3]==0)
else {
if (data[3] == 1) {
if (data[1] == 0) {
data[0] = ~data[0] & 0x1;
ui_Temp1 = 1;
ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
ui_Temp = ui_Temp | ui_Temp1;
data[0] = (data[0] << ui_NoOfChannel) ^ 0xffff;
data[0] = data[0] & ui_Temp;
outw(data[0],
devpriv->iobase + APCI2200_DIGITAL_OP);
} //if(data[1]==0)
else {
if (data[1] == 1) {
switch (ui_NoOfChannel) {
case 2:
data[0] = ~data[0] & 0x3;
ui_Temp1 = 3;
ui_Temp1 =
ui_Temp1 << 2 * data[2];
ui_Temp = ui_Temp | ui_Temp1;
data[0] =
((data[0] << (2 *
data
[2])) ^
0xffff) & ui_Temp;
break;
case 4:
data[0] = ~data[0] & 0xf;
ui_Temp1 = 15;
ui_Temp1 =
ui_Temp1 << 4 * data[2];
ui_Temp = ui_Temp | ui_Temp1;
data[0] =
((data[0] << (4 *
data
[2])) ^
0xffff) & ui_Temp;
break;
case 8:
data[0] = ~data[0] & 0xff;
ui_Temp1 = 255;
ui_Temp1 =
ui_Temp1 << 8 * data[2];
ui_Temp = ui_Temp | ui_Temp1;
data[0] =
((data[0] << (8 *
data
[2])) ^
0xffff) & ui_Temp;
break;
case 15:
break;
default:
comedi_error(dev,
" chan spec wrong");
return -EINVAL; // "sorry channel spec wrong "
} //switch(ui_NoOfChannels)
outw(data[0],
devpriv->iobase +
APCI2200_DIGITAL_OP);
} // if(data[1]==1)
else {
printk("\nSpecified channel not supported\n");
} //else if(data[1]==1)
} //elseif(data[1]==0)
} //if(data[3]==1);
else {
printk("\nSpecified functionality does not exist\n");
return -EINVAL;
} //if else data[3]==1)
} //if else data[3]==0)
return (insn->n);;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI2200_ReadDigitalOutput |
| (comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,
lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Read value of the selected channel or port |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| comedi_subdevice *s, :pointer to subdevice structure
comedi_insn *insn :pointer to insn structure |
| lsampl_t *data : Data Pointer to read status |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
INT i_APCI2200_ReadDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
UINT ui_Temp;
UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
ui_Temp = data[0];
*data = inw(devpriv->iobase + APCI2200_DIGITAL_OP);
if (ui_Temp == 0) {
*data = (*data >> ui_NoOfChannel) & 0x1;
} //if(ui_Temp==0)
else {
if (ui_Temp == 1) {
switch (ui_NoOfChannel) {
case 2:
*data = (*data >> (2 * data[1])) & 3;
break;
case 4:
*data = (*data >> (4 * data[1])) & 15;
break;
case 8:
*data = (*data >> (8 * data[1])) & 255;
break;
case 15:
break;
default:
comedi_error(dev, " chan spec wrong");
return -EINVAL; // "sorry channel spec wrong "
} //switch(ui_NoOfChannels)
} //if(ui_Temp==1)
else {
printk("\nSpecified channel not supported \n");
} //elseif(ui_Temp==1)
} //elseif(ui_Temp==0)
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI2200_ConfigWatchdog(comedi_device *dev,
comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) |
| |
+----------------------------------------------------------------------------+
| Task : Configures The Watchdog |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| comedi_subdevice *s, :pointer to subdevice structure
comedi_insn *insn :pointer to insn structure |
| lsampl_t *data : Data Pointer to read status |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
int i_APCI2200_ConfigWatchdog(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
if (data[0] == 0) {
//Disable the watchdog
outw(0x0,
devpriv->iobase + APCI2200_WATCHDOG +
APCI2200_WATCHDOG_ENABLEDISABLE);
//Loading the Reload value
outw(data[1],
devpriv->iobase + APCI2200_WATCHDOG +
APCI2200_WATCHDOG_RELOAD_VALUE);
data[1] = data[1] >> 16;
outw(data[1],
devpriv->iobase + APCI2200_WATCHDOG +
APCI2200_WATCHDOG_RELOAD_VALUE + 2);
} //if(data[0]==0)
else {
printk("\nThe input parameters are wrong\n");
return -EINVAL;
} //elseif(data[0]==0)
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI2200_StartStopWriteWatchdog |
| (comedi_device *dev,comedi_subdevice *s,
comedi_insn *insn,lsampl_t *data); |
+----------------------------------------------------------------------------+
| Task : Start / Stop The Watchdog |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| comedi_subdevice *s, :pointer to subdevice structure
comedi_insn *insn :pointer to insn structure |
| lsampl_t *data : Data Pointer to read status |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
int i_APCI2200_StartStopWriteWatchdog(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
switch (data[0]) {
case 0: //stop the watchdog
outw(0x0, devpriv->iobase + APCI2200_WATCHDOG + APCI2200_WATCHDOG_ENABLEDISABLE); //disable the watchdog
break;
case 1: //start the watchdog
outw(0x0001,
devpriv->iobase + APCI2200_WATCHDOG +
APCI2200_WATCHDOG_ENABLEDISABLE);
break;
case 2: //Software trigger
outw(0x0201,
devpriv->iobase + APCI2200_WATCHDOG +
APCI2200_WATCHDOG_ENABLEDISABLE);
break;
default:
printk("\nSpecified functionality does not exist\n");
return -EINVAL;
} // switch(data[0])
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI2200_ReadWatchdog |
| (comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,
lsampl_t *data); |
+----------------------------------------------------------------------------+
| Task : Read The Watchdog |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| comedi_subdevice *s, :pointer to subdevice structure
comedi_insn *insn :pointer to insn structure |
| lsampl_t *data : Data Pointer to read status |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
int i_APCI2200_ReadWatchdog(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
data[0] =
inw(devpriv->iobase + APCI2200_WATCHDOG +
APCI2200_WATCHDOG_STATUS) & 0x1;
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI2200_Reset(comedi_device *dev) | |
+----------------------------------------------------------------------------+
| Task :resets all the registers |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : |
| |
+----------------------------------------------------------------------------+
*/
INT i_APCI2200_Reset(comedi_device * dev)
{
outw(0x0, devpriv->iobase + APCI2200_DIGITAL_OP); //RESETS THE DIGITAL OUTPUTS
outw(0x0,
devpriv->iobase + APCI2200_WATCHDOG +
APCI2200_WATCHDOG_ENABLEDISABLE);
outw(0x0,
devpriv->iobase + APCI2200_WATCHDOG +
APCI2200_WATCHDOG_RELOAD_VALUE);
outw(0x0,
devpriv->iobase + APCI2200_WATCHDOG +
APCI2200_WATCHDOG_RELOAD_VALUE + 2);
return 0;
}

View File

@ -0,0 +1,67 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
/********* Definitions for APCI-2200 card *****/
// Card Specific information
#define APCI2200_BOARD_VENDOR_ID 0x15b8
#define APCI2200_ADDRESS_RANGE 64
//DIGITAL INPUT-OUTPUT DEFINE
#define APCI2200_DIGITAL_OP 4
#define APCI2200_DIGITAL_IP 0
// TIMER COUNTER WATCHDOG DEFINES
#define APCI2200_WATCHDOG 0x08
#define APCI2200_WATCHDOG_ENABLEDISABLE 12
#define APCI2200_WATCHDOG_RELOAD_VALUE 4
#define APCI2200_WATCHDOG_STATUS 16
// Hardware Layer functions for Apci2200
//Digital Input
INT i_APCI2200_ReadMoreDigitalInput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI2200_Read1DigitalInput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
//Digital Output
int i_APCI2200_ConfigDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI2200_WriteDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI2200_ReadDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
// TIMER
int i_APCI2200_ConfigWatchdog(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
int i_APCI2200_StartStopWriteWatchdog(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
int i_APCI2200_ReadWatchdog(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
//reset
INT i_APCI2200_Reset(comedi_device * dev);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,276 @@
// hwdrv_apci3120.h
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
/*
+-----------------------------------------------------------------------+
| (C) ADDI-DATA GmbH Dieselstrasse 3 D-77833 Ottersweier |
+-----------------------------------------------------------------------+
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+-----------------------------------------------------------------------+
| Project : ADDI DATA | Compiler : GCC |
| Modulname : hwdrv_apci3120.h | Version : 2.96 Redhat Linux |
| | kernel-2.4.2 |
+-------------------------------+---------------------------------------+
| Author : | Date : |
+-----------------------------------------------------------------------+
| Description :Header file for apci3120 hardware abstraction layer |
+-----------------------------------------------------------------------+
| UPDATE'S |
+-----------------------------------------------------------------------+
| Date | Author | Description of updates |
+----------+-----------+------------------------------------------------+
| | | |
| | | |
| | | |
| | | |
| | | |
+----------+-----------+------------------------------------------------+
| | | |
| | | |
| | | |
+----------+-----------+------------------------------------------------+
*/
// comedi related defines
//ANALOG INPUT RANGE
static const comedi_lrange range_apci3120_ai = { 8, {
BIP_RANGE(10),
BIP_RANGE(5),
BIP_RANGE(2),
BIP_RANGE(1),
UNI_RANGE(10),
UNI_RANGE(5),
UNI_RANGE(2),
UNI_RANGE(1)
}
};
// ANALOG OUTPUT RANGE
static const comedi_lrange range_apci3120_ao = { 2, {
BIP_RANGE(10),
UNI_RANGE(10)
}
};
#define APCI3120_BIPOLAR_RANGES 4 // used for test on mixture of BIP/UNI ranges
#define APCI3120_BOARD_VENDOR_ID 0x10E8
#define APCI3120_ADDRESS_RANGE 16
#define APCI3120_DISABLE 0
#define APCI3120_ENABLE 1
#define APCI3120_START 1
#define APCI3120_STOP 0
#define APCI3120_EOC_MODE 1
#define APCI3120_EOS_MODE 2
#define APCI3120_DMA_MODE 3
//DIGITAL INPUT-OUTPUT DEFINE
#define APCI3120_DIGITAL_OUTPUT 0x0D
#define APCI3120_RD_STATUS 0x02
#define APCI3120_RD_FIFO 0x00
// digital output insn_write ON /OFF selection
#define APCI3120_SET4DIGITALOUTPUTON 1
#define APCI3120_SET4DIGITALOUTPUTOFF 0
// analog output SELECT BIT
#define APCI3120_ANALOG_OP_CHANNEL_1 0x0000
#define APCI3120_ANALOG_OP_CHANNEL_2 0x4000
#define APCI3120_ANALOG_OP_CHANNEL_3 0x8000
#define APCI3120_ANALOG_OP_CHANNEL_4 0xC000
#define APCI3120_ANALOG_OP_CHANNEL_5 0x0000
#define APCI3120_ANALOG_OP_CHANNEL_6 0x4000
#define APCI3120_ANALOG_OP_CHANNEL_7 0x8000
#define APCI3120_ANALOG_OP_CHANNEL_8 0xC000
// Enable external trigger bit in nWrAddress
#define APCI3120_ENABLE_EXT_TRIGGER 0x8000
//ANALOG OUTPUT AND INPUT DEFINE
#define APCI3120_UNIPOLAR 0x80 //$$ RAM sequence polarity BIT
#define APCI3120_BIPOLAR 0x00 //$$ RAM sequence polarity BIT
#define APCI3120_ANALOG_OUTPUT_1 0x08 // (ADDRESS )
#define APCI3120_ANALOG_OUTPUT_2 0x0A // (ADDRESS )
#define APCI3120_1_GAIN 0x00 //$$ RAM sequence Gain Bits for gain 1
#define APCI3120_2_GAIN 0x10 //$$ RAM sequence Gain Bits for gain 2
#define APCI3120_5_GAIN 0x20 //$$ RAM sequence Gain Bits for gain 5
#define APCI3120_10_GAIN 0x30 //$$ RAM sequence Gain Bits for gain 10
#define APCI3120_SEQ_RAM_ADDRESS 0x06 //$$ EARLIER NAMED APCI3120_FIFO_ADDRESS
#define APCI3120_RESET_FIFO 0x0C //(ADDRESS)
#define APCI3120_TIMER_0_MODE_2 0x01 //$$ Bits for timer mode
#define APCI3120_TIMER_0_MODE_4 0x2
#define APCI3120_SELECT_TIMER_0_WORD 0x00
#define APCI3120_ENABLE_TIMER0 0x1000 //$$Gatebit 0 in nWrAddress
#define APCI3120_CLEAR_PR 0xF0FF
#define APCI3120_CLEAR_PA 0xFFF0
#define APCI3120_CLEAR_PA_PR (APCI3120_CLEAR_PR & APCI3120_CLEAR_PA)
// nWrMode_Select
#define APCI3120_ENABLE_SCAN 0x8 //$$ bit in nWrMode_Select
#define APCI3120_DISABLE_SCAN (~APCI3120_ENABLE_SCAN)
#define APCI3120_ENABLE_EOS_INT 0x2 //$$ bit in nWrMode_Select
#define APCI3120_DISABLE_EOS_INT (~APCI3120_ENABLE_EOS_INT)
#define APCI3120_ENABLE_EOC_INT 0x1
#define APCI3120_DISABLE_EOC_INT (~APCI3120_ENABLE_EOC_INT)
#define APCI3120_DISABLE_ALL_INTERRUPT_WITHOUT_TIMER (APCI3120_DISABLE_EOS_INT & APCI3120_DISABLE_EOC_INT)
#define APCI3120_DISABLE_ALL_INTERRUPT (APCI3120_DISABLE_TIMER_INT & APCI3120_DISABLE_EOS_INT & APCI3120_DISABLE_EOC_INT)
//status register bits
#define APCI3120_EOC 0x8000
#define APCI3120_EOS 0x2000
// software trigger dummy register
#define APCI3120_START_CONVERSION 0x02 //(ADDRESS)
//TIMER DEFINE
#define APCI3120_QUARTZ_A 70
#define APCI3120_QUARTZ_B 50
#define APCI3120_TIMER 1
#define APCI3120_WATCHDOG 2
#define APCI3120_TIMER_DISABLE 0
#define APCI3120_TIMER_ENABLE 1
#define APCI3120_ENABLE_TIMER2 0x4000 //$$ gatebit 2 in nWrAddress
#define APCI3120_DISABLE_TIMER2 (~APCI3120_ENABLE_TIMER2)
#define APCI3120_ENABLE_TIMER_INT 0x04 //$$ ENAIRQ_FC_Bit in nWrModeSelect
#define APCI3120_DISABLE_TIMER_INT (~APCI3120_ENABLE_TIMER_INT)
#define APCI3120_WRITE_MODE_SELECT 0x0E // (ADDRESS)
#define APCI3120_SELECT_TIMER_0_WORD 0x00
#define APCI3120_SELECT_TIMER_1_WORD 0x01
#define APCI3120_TIMER_1_MODE_2 0x4
//$$ BIT FOR MODE IN nCsTimerCtr1
#define APCI3120_TIMER_2_MODE_0 0x0
#define APCI3120_TIMER_2_MODE_2 0x10
#define APCI3120_TIMER_2_MODE_5 0x30
//$$ BIT FOR MODE IN nCsTimerCtr0
#define APCI3120_SELECT_TIMER_2_LOW_WORD 0x02
#define APCI3120_SELECT_TIMER_2_HIGH_WORD 0x03
#define APCI3120_TIMER_CRT0 0x0D //(ADDRESS for cCsTimerCtr0)
#define APCI3120_TIMER_CRT1 0x0C //(ADDRESS for cCsTimerCtr1)
#define APCI3120_TIMER_VALUE 0x04 //ADDRESS for nCsTimerWert
#define APCI3120_TIMER_STATUS_REGISTER 0x0D //ADDRESS for delete timer 2 interrupt
#define APCI3120_RD_STATUS 0x02 //ADDRESS
#define APCI3120_WR_ADDRESS 0x00 //ADDRESS
#define APCI3120_ENABLE_WATCHDOG 0x20 //$$BIT in nWrMode_Select
#define APCI3120_DISABLE_WATCHDOG (~APCI3120_ENABLE_WATCHDOG)
#define APCI3120_ENABLE_TIMER_COUNTER 0x10 //$$BIT in nWrMode_Select
#define APCI3120_DISABLE_TIMER_COUNTER (~APCI3120_ENABLE_TIMER_COUNTER)
#define APCI3120_FC_TIMER 0x1000 //bit in status register
#define APCI3120_ENABLE_TIMER0 0x1000
#define APCI3120_ENABLE_TIMER1 0x2000
#define APCI3120_ENABLE_TIMER2 0x4000
#define APCI3120_DISABLE_TIMER0 (~APCI3120_ENABLE_TIMER0)
#define APCI3120_DISABLE_TIMER1 (~APCI3120_ENABLE_TIMER1)
#define APCI3120_DISABLE_TIMER2 (~APCI3120_ENABLE_TIMER2)
#define APCI3120_TIMER2_SELECT_EOS 0xC0 // ADDED on 20-6
#define APCI3120_COUNTER 3 // on 20-6
#define APCI3120_DISABLE_ALL_TIMER ( APCI3120_DISABLE_TIMER0 & APCI3120_DISABLE_TIMER1 & APCI3120_DISABLE_TIMER2 ) // on 20-6
#define MAX_ANALOGINPUT_CHANNELS 32
typedef struct {
BYTE b_Type; /* EOC or EOS */
BYTE b_InterruptFlag; /* Interrupt use or not */
UINT ui_ConvertTiming; /* Selection of the convertion time */
BYTE b_NbrOfChannel; /* Number of channel to read */
UINT ui_ChannelList[MAX_ANALOGINPUT_CHANNELS]; /* Number of the channel to be read */
UINT ui_RangeList[MAX_ANALOGINPUT_CHANNELS]; /* Gain of each channel */
} str_AnalogReadInformation;
// Function Declaration For APCI-3120
// Internal functions
int i_APCI3120_SetupChannelList(comedi_device * dev, comedi_subdevice * s,
int n_chan, unsigned int *chanlist, char check);
int i_APCI3120_ExttrigEnable(comedi_device * dev);
int i_APCI3120_ExttrigDisable(comedi_device * dev);
int i_APCI3120_StopCyclicAcquisition(comedi_device * dev, comedi_subdevice * s);
int i_APCI3120_Reset(comedi_device * dev);
int i_APCI3120_CyclicAnalogInput(int mode, comedi_device * dev,
comedi_subdevice * s);
// Interrupt functions
void v_APCI3120_Interrupt(int irq, void *d);
//UPDATE-0.7.57->0.7.68 void v_APCI3120_InterruptDmaMoveBlock16bit(comedi_device *dev,comedi_subdevice *s,sampl_t *dma,sampl_t *data,int n);
void v_APCI3120_InterruptDmaMoveBlock16bit(comedi_device * dev,
comedi_subdevice * s, sampl_t * dma_buffer, unsigned int num_samples);
int i_APCI3120_InterruptHandleEos(comedi_device * dev);
void v_APCI3120_InterruptDma(int irq, void *d);
// TIMER
int i_APCI3120_InsnConfigTimer(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
int i_APCI3120_InsnWriteTimer(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
int i_APCI3120_InsnReadTimer(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
//DI
// for di read
int i_APCI3120_InsnBitsDigitalInput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
int i_APCI3120_InsnReadDigitalInput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
//DO
//int i_APCI3120_WriteDigitalOutput(comedi_device *dev, BYTE data);
int i_APCI3120_InsnConfigDigitalOutput(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
int i_APCI3120_InsnBitsDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
int i_APCI3120_InsnWriteDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
//AO
//int i_APCI3120_Write1AnalogValue(comedi_device *dev,UINT ui_Range,UINT ui_Channel,UINT data );
int i_APCI3120_InsnWriteAnalogOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
//AI HArdware layer
int i_APCI3120_InsnConfigAnalogInput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
int i_APCI3120_InsnReadAnalogInput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
int i_APCI3120_CommandTestAnalogInput(comedi_device * dev, comedi_subdevice * s,
comedi_cmd * cmd);
int i_APCI3120_CommandAnalogInput(comedi_device * dev, comedi_subdevice * s);
//int i_APCI3120_CancelAnalogInput(comedi_device * dev, comedi_subdevice * s);
int i_APCI3120_StopCyclicAcquisition(comedi_device * dev, comedi_subdevice * s);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,191 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
// Card Specific information
#define APCI3200_BOARD_VENDOR_ID 0x15B8
//#define APCI3200_ADDRESS_RANGE 264
int MODULE_NO;
struct {
INT i_Gain;
INT i_Polarity;
INT i_OffsetRange;
INT i_Coupling;
INT i_SingleDiff;
INT i_AutoCalibration;
UINT ui_ReloadValue;
UINT ui_TimeUnitReloadVal;
INT i_Interrupt;
INT i_ModuleSelection;
} Config_Parameters_Module1, Config_Parameters_Module2,
Config_Parameters_Module3, Config_Parameters_Module4;
//ANALOG INPUT RANGE
static const comedi_lrange range_apci3200_ai = { 8, {
BIP_RANGE(10),
BIP_RANGE(5),
BIP_RANGE(2),
BIP_RANGE(1),
UNI_RANGE(10),
UNI_RANGE(5),
UNI_RANGE(2),
UNI_RANGE(1)
}
};
static const comedi_lrange range_apci3300_ai = { 4, {
UNI_RANGE(10),
UNI_RANGE(5),
UNI_RANGE(2),
UNI_RANGE(1)
}
};
//Analog Input related Defines
#define APCI3200_AI_OFFSET_GAIN 0
#define APCI3200_AI_SC_TEST 4
#define APCI3200_AI_IRQ 8
#define APCI3200_AI_AUTOCAL 12
#define APCI3200_RELOAD_CONV_TIME_VAL 32
#define APCI3200_CONV_TIME_TIME_BASE 36
#define APCI3200_RELOAD_DELAY_TIME_VAL 40
#define APCI3200_DELAY_TIME_TIME_BASE 44
#define APCI3200_AI_MODULE1 0
#define APCI3200_AI_MODULE2 64
#define APCI3200_AI_MODULE3 128
#define APCI3200_AI_MODULE4 192
#define TRUE 1
#define FALSE 0
#define APCI3200_AI_EOSIRQ 16
#define APCI3200_AI_EOS 20
#define APCI3200_AI_CHAN_ID 24
#define APCI3200_AI_CHAN_VAL 28
#define ANALOG_INPUT 0
#define TEMPERATURE 1
#define RESISTANCE 2
#define ENABLE_EXT_TRIG 1
#define ENABLE_EXT_GATE 2
#define ENABLE_EXT_TRIG_GATE 3
#define APCI3200_MAXVOLT 2.5
#define ADDIDATA_GREATER_THAN_TEST 0
#define ADDIDATA_LESS_THAN_TEST 1
#define ADDIDATA_UNIPOLAR 1
#define ADDIDATA_BIPOLAR 2
//BEGIN JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
#define MAX_MODULE 4
//END JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
typedef struct {
ULONG ul_NumberOfValue;
ULONG *pul_ResistanceValue;
ULONG *pul_TemperatureValue;
} str_ADDIDATA_RTDStruct, *pstr_ADDIDATA_RTDStruct;
//BEGIN JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
typedef struct {
// Begin JK 05/08/2003 change for Linux
unsigned long ul_CurrentSourceCJC;
unsigned long ul_CurrentSource[5];
// End JK 05/08/2003 change for Linux
// Begin CG 15/02/02 Rev 1.0 -> Rev 1.1 : Add Header Type 1
unsigned long ul_GainFactor[8]; // Gain Factor
unsigned int w_GainValue[10];
// End CG 15/02/02 Rev 1.0 -> Rev 1.1 : Add Header Type 1
} str_Module;
//END JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
//BEGIN JK 06.07.04: Management of sevrals boards
typedef struct {
INT i_CJCAvailable;
INT i_CJCPolarity;
INT i_CJCGain;
INT i_InterruptFlag;
INT i_ADDIDATAPolarity;
INT i_ADDIDATAGain;
INT i_AutoCalibration;
INT i_ADDIDATAConversionTime;
INT i_ADDIDATAConversionTimeUnit;
INT i_ADDIDATAType;
INT i_ChannelNo;
INT i_ChannelCount;
INT i_ScanType;
INT i_FirstChannel;
INT i_LastChannel;
INT i_Sum;
INT i_Offset;
UINT ui_Channel_num;
INT i_Count;
INT i_Initialised;
//UINT ui_InterruptChannelValue[96]; //Buffer
UINT ui_InterruptChannelValue[144]; //Buffer
BYTE b_StructInitialized;
//Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
lsampl_t ui_ScanValueArray[7 + 12]; // 7 is the maximal number of channels
//End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
//Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
INT i_ConnectionType;
INT i_NbrOfModule;
str_Module s_Module[MAX_MODULE];
//End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
} str_BoardInfos;
//END JK 06.07.04: Management of sevrals boards
// Hardware Layer functions for Apci3200
//AI
INT i_APCI3200_ConfigAnalogInput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI3200_ReadAnalogInput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI3200_InsnWriteReleaseAnalogInput(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
INT i_APCI3200_InsnBits_AnalogInput_Test(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
INT i_APCI3200_StopCyclicAcquisition(comedi_device * dev, comedi_subdevice * s);
INT i_APCI3200_InterruptHandleEos(comedi_device * dev);
INT i_APCI3200_CommandTestAnalogInput(comedi_device * dev, comedi_subdevice * s,
comedi_cmd * cmd);
INT i_APCI3200_CommandAnalogInput(comedi_device * dev, comedi_subdevice * s);
INT i_APCI3200_ReadDigitalInput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
//Interrupt
void v_APCI3200_Interrupt(int irq, void *d);
int i_APCI3200_InterruptHandleEos(comedi_device * dev);
//Reset functions
INT i_APCI3200_Reset(comedi_device * dev);
int i_APCI3200_ReadCJCCalOffset(comedi_device * dev, lsampl_t * data);
int i_APCI3200_ReadCJCValue(comedi_device * dev, lsampl_t * data);
int i_APCI3200_ReadCalibrationGainValue(comedi_device * dev, UINT * data);
int i_APCI3200_ReadCalibrationOffsetValue(comedi_device * dev, UINT * data);
int i_APCI3200_Read1AnalogInputChannel(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
int i_APCI3200_ReadCJCCalGain(comedi_device * dev, lsampl_t * data);

View File

@ -0,0 +1,742 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
/*.
+-----------------------------------------------------------------------+
| (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+-----------------------------------------------------------------------+
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+-------------------------------+---------------------------------------+
| Project : APCI-3501 | Compiler : GCC |
| Module name : hwdrv_apci3501.c| Version : 2.96 |
+-------------------------------+---------------------------------------+
| Project manager: Eric Stolz | Date : 02/12/2002 |
+-------------------------------+---------------------------------------+
| Description : Hardware Layer Acces For APCI-3501 |
+-----------------------------------------------------------------------+
| UPDATES |
+----------+-----------+------------------------------------------------+
| Date | Author | Description of updates |
+----------+-----------+------------------------------------------------+
| | | |
| | | |
| | | |
+----------+-----------+------------------------------------------------+
*/
/*
+----------------------------------------------------------------------------+
| Included files |
+----------------------------------------------------------------------------+
*/
#include "hwdrv_apci3501.h"
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI3501_ReadDigitalInput |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Read value of the selected channel or port |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| UINT ui_NoOfChannels : No Of Channels To read |
| UINT *data : Data Pointer to read status |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
INT i_APCI3501_ReadDigitalInput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
UINT ui_Temp;
UINT ui_NoOfChannel;
ui_NoOfChannel = CR_CHAN(insn->chanspec);
ui_Temp = data[0];
*data = inl(devpriv->iobase + APCI3501_DIGITAL_IP);
if (ui_Temp == 0) {
*data = (*data >> ui_NoOfChannel) & 0x1;
} //if (ui_Temp==0)
else {
if (ui_Temp == 1) {
*data = *data & 0x3;
} //if (ui_Temp==1)
else {
printk("\nSpecified channel not supported \n");
} //elseif (ui_Temp==1)
} //elseif (ui_Temp==0)
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI3501_ConfigDigitalOutput |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Configures The Digital Output Subdevice. |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| UINT *data : Data Pointer contains |
| configuration parameters as below |
| |
| data[1] : 1 Enable VCC Interrupt |
| 0 Disable VCC Interrupt |
| data[2] : 1 Enable CC Interrupt |
| 0 Disable CC Interrupt |
| |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
int i_APCI3501_ConfigDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
if ((data[0] != 0) && (data[0] != 1)) {
comedi_error(dev,
"Not a valid Data !!! ,Data should be 1 or 0\n");
return -EINVAL;
} //if ( (data[0]!=0) && (data[0]!=1) )
if (data[0]) {
devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
} // if (data[0])
else {
devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
} //else if (data[0])
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI3501_WriteDigitalOutput |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : writes To the digital Output Subdevice |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| comedi_subdevice *s : Subdevice Pointer |
| comedi_insn *insn : Insn Structure Pointer |
| lsampl_t *data : Data Pointer contains |
| configuration parameters as below |
| |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
INT i_APCI3501_WriteDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
UINT ui_Temp, ui_Temp1;
UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
if (devpriv->b_OutputMemoryStatus) {
ui_Temp = inl(devpriv->iobase + APCI3501_DIGITAL_OP);
} //if(devpriv->b_OutputMemoryStatus )
else {
ui_Temp = 0;
} //if(devpriv->b_OutputMemoryStatus )
if (data[3] == 0) {
if (data[1] == 0) {
data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
outl(data[0], devpriv->iobase + APCI3501_DIGITAL_OP);
} //if(data[1]==0)
else {
if (data[1] == 1) {
data[0] = (data[0] << (2 * data[2])) | ui_Temp;
outl(data[0],
devpriv->iobase + APCI3501_DIGITAL_OP);
} // if(data[1]==1)
else {
printk("\nSpecified channel not supported\n");
} //else if(data[1]==1)
} //elseif(data[1]==0)
} //if(data[3]==0)
else {
if (data[3] == 1) {
if (data[1] == 0) {
data[0] = ~data[0] & 0x1;
ui_Temp1 = 1;
ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
ui_Temp = ui_Temp | ui_Temp1;
data[0] =
(data[0] << ui_NoOfChannel) ^
0xffffffff;
data[0] = data[0] & ui_Temp;
outl(data[0],
devpriv->iobase + APCI3501_DIGITAL_OP);
} //if(data[1]==0)
else {
if (data[1] == 1) {
data[0] = ~data[0] & 0x3;
ui_Temp1 = 3;
ui_Temp1 = ui_Temp1 << 2 * data[2];
ui_Temp = ui_Temp | ui_Temp1;
data[0] =
((data[0] << (2 *
data[2])) ^
0xffffffff) & ui_Temp;
outl(data[0],
devpriv->iobase +
APCI3501_DIGITAL_OP);
} // if(data[1]==1)
else {
printk("\nSpecified channel not supported\n");
} //else if(data[1]==1)
} //elseif(data[1]==0)
} //if(data[3]==1);
else {
printk("\nSpecified functionality does not exist\n");
return -EINVAL;
} //if else data[3]==1)
} //if else data[3]==0)
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI3501_ReadDigitalOutput |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Read value of the selected channel or port |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| UINT ui_NoOfChannels : No Of Channels To read |
| UINT *data : Data Pointer to read status |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
INT i_APCI3501_ReadDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
UINT ui_Temp;
UINT ui_NoOfChannel;
ui_NoOfChannel = CR_CHAN(insn->chanspec);
ui_Temp = data[0];
*data = inl(devpriv->iobase + APCI3501_DIGITAL_OP);
if (ui_Temp == 0) {
*data = (*data >> ui_NoOfChannel) & 0x1;
} // if (ui_Temp==0)
else {
if (ui_Temp == 1) {
*data = *data & 0x3;
} // if (ui_Temp==1)
else {
printk("\nSpecified channel not supported \n");
} // else if (ui_Temp==1)
} // else if (ui_Temp==0)
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI3501_ConfigAnalogOutput |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Configures The Analog Output Subdevice |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| comedi_subdevice *s : Subdevice Pointer |
| comedi_insn *insn : Insn Structure Pointer |
| lsampl_t *data : Data Pointer contains |
| configuration parameters as below |
| |
| data[0] : Voltage Mode |
| 0:Mode 0 |
| 1:Mode 1 |
| |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
INT i_APCI3501_ConfigAnalogOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
outl(data[0],
devpriv->iobase + APCI3501_ANALOG_OUTPUT +
APCI3501_AO_VOLT_MODE);
if (data[0]) {
devpriv->b_InterruptMode = MODE1;
} else {
devpriv->b_InterruptMode = MODE0;
}
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI3501_WriteAnalogOutput |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Writes To the Selected Anlog Output Channel |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| comedi_subdevice *s : Subdevice Pointer |
| comedi_insn *insn : Insn Structure Pointer |
| lsampl_t *data : Data Pointer contains |
| configuration parameters as below |
| |
| |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
INT i_APCI3501_WriteAnalogOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data)
{
ULONG ul_Command1 = 0, ul_Channel_no, ul_Polarity, ul_DAC_Ready = 0;;
ul_Channel_no = CR_CHAN(insn->chanspec);
if (devpriv->b_InterruptMode == MODE1) {
ul_Polarity = 0x80000000;
if ((*data < 0) || (*data > 16384)) {
printk("\nIn WriteAnalogOutput :: Not Valid Data\n");
}
} // end if(devpriv->b_InterruptMode==MODE1)
else {
ul_Polarity = 0;
if ((*data < 0) || (*data > 8192)) {
printk("\nIn WriteAnalogOutput :: Not Valid Data\n");
}
} // end else
if ((ul_Channel_no < 0) || (ul_Channel_no > 7)) {
printk("\nIn WriteAnalogOutput :: Not Valid Channel\n");
} // end if((ul_Channel_no<0)||(ul_Channel_no>7))
ul_DAC_Ready = inl(devpriv->iobase + APCI3501_ANALOG_OUTPUT);
while (ul_DAC_Ready == 0) {
ul_DAC_Ready = inl(devpriv->iobase + APCI3501_ANALOG_OUTPUT);
ul_DAC_Ready = (ul_DAC_Ready >> 8) & 1;
}
if (ul_DAC_Ready) {
// Output the Value on the output channels.
ul_Command1 =
(ULONG) ((ULONG) (ul_Channel_no & 0xFF) |
(ULONG) ((*data << 0x8) & 0x7FFFFF00L) |
(ULONG) (ul_Polarity));
outl(ul_Command1,
devpriv->iobase + APCI3501_ANALOG_OUTPUT +
APCI3501_AO_PROG);
}
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI3501_ConfigTimerCounterWatchdog |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Configures The Timer , Counter or Watchdog |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| UINT *data : Data Pointer contains |
| configuration parameters as below |
| |
| data[0] : 0 Configure As Timer |
| 1 Configure As Counter |
| 2 Configure As Watchdog |
| data[1] : 1 Enable Interrupt |
| 0 Disable Interrupt |
| data[2] : Time Unit |
| data[3] : Reload Value |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
INT i_APCI3501_ConfigTimerCounterWatchdog(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
{
ULONG ul_Command1 = 0;
devpriv->tsk_Current = current;
if (data[0] == ADDIDATA_WATCHDOG) {
devpriv->b_TimerSelectMode = ADDIDATA_WATCHDOG;
//Disable the watchdog
outl(0x0, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); //disable Wa
if (data[1] == 1) {
//Enable TIMER int & DISABLE ALL THE OTHER int SOURCES
outl(0x02,
devpriv->iobase + APCI3501_WATCHDOG +
APCI3501_TCW_PROG);
} else {
outl(0x0, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); //disable Timer interrupt
}
//Loading the Timebase value
outl(data[2],
devpriv->iobase + APCI3501_WATCHDOG +
APCI3501_TCW_TIMEBASE);
//Loading the Reload value
outl(data[3],
devpriv->iobase + APCI3501_WATCHDOG +
APCI3501_TCW_RELOAD_VALUE);
//Set the mode
ul_Command1 = inl(devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG) | 0xFFF819E0UL; //e2->e0
outl(ul_Command1,
devpriv->iobase + APCI3501_WATCHDOG +
APCI3501_TCW_PROG);
} //end if(data[0]==ADDIDATA_WATCHDOG)
else if (data[0] == ADDIDATA_TIMER) {
//First Stop The Timer
ul_Command1 =
inl(devpriv->iobase + APCI3501_WATCHDOG +
APCI3501_TCW_PROG);
ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
outl(ul_Command1, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); //Stop The Timer
devpriv->b_TimerSelectMode = ADDIDATA_TIMER;
if (data[1] == 1) {
//Enable TIMER int & DISABLE ALL THE OTHER int SOURCES
outl(0x02,
devpriv->iobase + APCI3501_WATCHDOG +
APCI3501_TCW_PROG);
} else {
outl(0x0, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); //disable Timer interrupt
}
// Loading Timebase
outl(data[2],
devpriv->iobase + APCI3501_WATCHDOG +
APCI3501_TCW_TIMEBASE);
//Loading the Reload value
outl(data[3],
devpriv->iobase + APCI3501_WATCHDOG +
APCI3501_TCW_RELOAD_VALUE);
// printk ("\nTimer Address :: %x\n", (devpriv->iobase+APCI3501_WATCHDOG));
ul_Command1 =
inl(devpriv->iobase + APCI3501_WATCHDOG +
APCI3501_TCW_PROG);
ul_Command1 =
(ul_Command1 & 0xFFF719E2UL) | 2UL << 13UL | 0x10UL;
outl(ul_Command1, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); //mode 2
} //end if(data[0]==ADDIDATA_TIMER)
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI3501_StartStopWriteTimerCounterWatchdog |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Start / Stop The Selected Timer , Counter or Watchdog |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| UINT *data : Data Pointer contains |
| configuration parameters as below |
| |
| data[0] : 0 Timer |
| 1 Counter |
| 2 Watchdog | | data[1] : 1 Start |
| 0 Stop | 2 Trigger |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
int i_APCI3501_StartStopWriteTimerCounterWatchdog(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
{
ULONG ul_Command1 = 0;
int i_Temp;
if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
if (data[1] == 1) {
ul_Command1 =
inl(devpriv->iobase + APCI3501_WATCHDOG +
APCI3501_TCW_PROG);
ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
//Enable the Watchdog
outl(ul_Command1,
devpriv->iobase + APCI3501_WATCHDOG +
APCI3501_TCW_PROG);
}
else if (data[1] == 0) //Stop The Watchdog
{
//Stop The Watchdog
ul_Command1 =
inl(devpriv->iobase + APCI3501_WATCHDOG +
APCI3501_TCW_PROG);
ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
outl(0x0,
devpriv->iobase + APCI3501_WATCHDOG +
APCI3501_TCW_PROG);
} else if (data[1] == 2) {
ul_Command1 =
inl(devpriv->iobase + APCI3501_WATCHDOG +
APCI3501_TCW_PROG);
ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x200UL;
outl(ul_Command1,
devpriv->iobase + APCI3501_WATCHDOG +
APCI3501_TCW_PROG);
} //if(data[1]==2)
} // end if (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
if (data[1] == 1) {
ul_Command1 =
inl(devpriv->iobase + APCI3501_WATCHDOG +
APCI3501_TCW_PROG);
ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
//Enable the Timer
outl(ul_Command1,
devpriv->iobase + APCI3501_WATCHDOG +
APCI3501_TCW_PROG);
} else if (data[1] == 0) {
//Stop The Timer
ul_Command1 =
inl(devpriv->iobase + APCI3501_WATCHDOG +
APCI3501_TCW_PROG);
ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
outl(ul_Command1,
devpriv->iobase + APCI3501_WATCHDOG +
APCI3501_TCW_PROG);
}
else if (data[1] == 2) {
//Trigger the Timer
ul_Command1 =
inl(devpriv->iobase + APCI3501_WATCHDOG +
APCI3501_TCW_PROG);
ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x200UL;
outl(ul_Command1,
devpriv->iobase + APCI3501_WATCHDOG +
APCI3501_TCW_PROG);
}
} // end if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
i_Temp = inl(devpriv->iobase + APCI3501_WATCHDOG +
APCI3501_TCW_TRIG_STATUS) & 0x1;
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI3501_ReadTimerCounterWatchdog |
| (comedi_device *dev,comedi_subdevice *s, |
| comedi_insn *insn,lsampl_t *data) |
+----------------------------------------------------------------------------+
| Task : Read The Selected Timer , Counter or Watchdog |
+----------------------------------------------------------------------------+
| Input Parameters : comedi_device *dev : Driver handle |
| UINT *data : Data Pointer contains |
| configuration parameters as below |
| |
| data[0] : 0 Timer |
| 1 Counter |
| 2 Watchdog | | data[1] : Timer Counter Watchdog Number |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
int i_APCI3501_ReadTimerCounterWatchdog(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
{
if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
data[0] =
inl(devpriv->iobase + APCI3501_WATCHDOG +
APCI3501_TCW_TRIG_STATUS) & 0x1;
data[1] = inl(devpriv->iobase + APCI3501_WATCHDOG);
} // end if (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
else if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
data[0] =
inl(devpriv->iobase + APCI3501_WATCHDOG +
APCI3501_TCW_TRIG_STATUS) & 0x1;
data[1] = inl(devpriv->iobase + APCI3501_WATCHDOG);
} // end if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
else if ((devpriv->b_TimerSelectMode != ADDIDATA_TIMER)
&& (devpriv->b_TimerSelectMode != ADDIDATA_WATCHDOG)) {
printk("\nIn ReadTimerCounterWatchdog :: Invalid Subdevice \n");
}
return insn->n;
}
/*
+----------------------------------------------------------------------------+
| Function Name : int i_APCI3501_Reset(comedi_device *dev) |
| |
+----------------------------------------------------------------------------+
| Task :Resets the registers of the card |
+----------------------------------------------------------------------------+
| Input Parameters : |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : |
| |
+----------------------------------------------------------------------------+
*/
int i_APCI3501_Reset(comedi_device * dev)
{
int i_Count = 0, i_temp = 0;
ULONG ul_Command1 = 0, ul_Polarity, ul_DAC_Ready = 0;
outl(0x0, devpriv->iobase + APCI3501_DIGITAL_OP);
outl(1, devpriv->iobase + APCI3501_ANALOG_OUTPUT +
APCI3501_AO_VOLT_MODE);
ul_Polarity = 0x80000000;
for (i_Count = 0; i_Count <= 7; i_Count++) {
ul_DAC_Ready = inl(devpriv->iobase + APCI3501_ANALOG_OUTPUT);
while (ul_DAC_Ready == 0) {
ul_DAC_Ready =
inl(devpriv->iobase + APCI3501_ANALOG_OUTPUT);
ul_DAC_Ready = (ul_DAC_Ready >> 8) & 1;
}
if (ul_DAC_Ready) {
// Output the Value on the output channels.
ul_Command1 =
(ULONG) ((ULONG) (i_Count & 0xFF) |
(ULONG) ((i_temp << 0x8) & 0x7FFFFF00L) |
(ULONG) (ul_Polarity));
outl(ul_Command1,
devpriv->iobase + APCI3501_ANALOG_OUTPUT +
APCI3501_AO_PROG);
}
}
return 0;
}
/*
+----------------------------------------------------------------------------+
| Function Name : static void v_APCI3501_Interrupt |
| (int irq , void *d) |
+----------------------------------------------------------------------------+
| Task : Interrupt processing Routine |
+----------------------------------------------------------------------------+
| Input Parameters : int irq : irq number |
| void *d : void pointer |
+----------------------------------------------------------------------------+
| Output Parameters : -- |
+----------------------------------------------------------------------------+
| Return Value : TRUE : No error occur |
| : FALSE : Error occur. Return the error |
| |
+----------------------------------------------------------------------------+
*/
void v_APCI3501_Interrupt(int irq, void *d)
{
int i_temp;
comedi_device *dev = d;
unsigned int ui_Timer_AOWatchdog;
unsigned long ul_Command1;
// Disable Interrupt
ul_Command1 =
inl(devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG);
ul_Command1 = (ul_Command1 & 0xFFFFF9FDul);
outl(ul_Command1,
devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG);
ui_Timer_AOWatchdog =
inl(devpriv->iobase + APCI3501_WATCHDOG +
APCI3501_TCW_IRQ) & 0x1;
if ((!ui_Timer_AOWatchdog)) {
comedi_error(dev, "IRQ from unknow source");
return;
}
// Enable Interrupt
//Send a signal to from kernel to user space
send_sig(SIGIO, devpriv->tsk_Current, 0);
ul_Command1 =
inl(devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG);
ul_Command1 = ((ul_Command1 & 0xFFFFF9FDul) | 1 << 1);
outl(ul_Command1,
devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG);
i_temp = inl(devpriv->iobase + APCI3501_WATCHDOG +
APCI3501_TCW_TRIG_STATUS) & 0x1;
return;
}

View File

@ -0,0 +1,96 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
// Card Specific information
#define APCI3501_BOARD_VENDOR_ID 0x15B8
#define APCI3501_ADDRESS_RANGE 255
#define APCI3501_DIGITAL_IP 0x50
#define APCI3501_DIGITAL_OP 0x40
#define APCI3501_ANALOG_OUTPUT 0x00
//Analog Output related Defines
#define APCI3501_AO_VOLT_MODE 0
#define APCI3501_AO_PROG 4
#define APCI3501_AO_TRIG_SCS 8
#define UNIPOLAR 0
#define BIPOLAR 1
#define MODE0 0
#define MODE1 1
// ANALOG OUTPUT RANGE
comedi_lrange range_apci3501_ao = { 2, {
BIP_RANGE(10),
UNI_RANGE(10)
}
};
//Watchdog Related Defines
#define APCI3501_WATCHDOG 0x20
#define APCI3501_TCW_SYNC_ENABLEDISABLE 0
#define APCI3501_TCW_RELOAD_VALUE 4
#define APCI3501_TCW_TIMEBASE 8
#define APCI3501_TCW_PROG 12
#define APCI3501_TCW_TRIG_STATUS 16
#define APCI3501_TCW_IRQ 20
#define APCI3501_TCW_WARN_TIMEVAL 24
#define APCI3501_TCW_WARN_TIMEBASE 28
#define ADDIDATA_TIMER 0
#define ADDIDATA_WATCHDOG 2
// Hardware Layer functions for Apci3501
//AO
INT i_APCI3501_ConfigAnalogOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI3501_WriteAnalogOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
//DI
// for di read
//INT i_APCI3501_ReadDigitalInput(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
INT i_APCI3501_ReadDigitalInput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
//DO
int i_APCI3501_ConfigDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI3501_WriteDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
INT i_APCI3501_ReadDigitalOutput(comedi_device * dev, comedi_subdevice * s,
comedi_insn * insn, lsampl_t * data);
// TIMER
// timer value is passed as u seconds
INT i_APCI3501_ConfigTimerCounterWatchdog(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
int i_APCI3501_StartStopWriteTimerCounterWatchdog(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
int i_APCI3501_ReadTimerCounterWatchdog(comedi_device * dev,
comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
//Interrupt
void v_APCI3501_Interrupt(int irq, void *d);
//Reset functions
int i_APCI3501_Reset(comedi_device * dev);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,69 @@
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data-com
info@addi-data.com
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You shoud also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
#ifndef COMEDI_SUBD_TTLIO
#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */
#endif
#ifndef ADDIDATA_ENABLE
#define ADDIDATA_ENABLE 1
#define ADDIDATA_DISABLE 0
#endif
#define APCI3XXX_SINGLE 0
#define APCI3XXX_DIFF 1
#define APCI3XXX_CONFIGURATION 0
#define APCI3XXX_TTL_INIT_DIRECTION_PORT2 0
#ifdef __KERNEL__
static const comedi_lrange range_apci3XXX_ai = { 8, {BIP_RANGE(10),
BIP_RANGE(5),
BIP_RANGE(2),
BIP_RANGE(1),
UNI_RANGE(10),
UNI_RANGE(5),
UNI_RANGE(2),
UNI_RANGE(1)}
};
static const comedi_lrange range_apci3XXX_ttl = { 12, {BIP_RANGE(1),
BIP_RANGE(1),
BIP_RANGE(1),
BIP_RANGE(1),
BIP_RANGE(1),
BIP_RANGE(1),
BIP_RANGE(1),
BIP_RANGE(1),
BIP_RANGE(1),
BIP_RANGE(1),
BIP_RANGE(1),
BIP_RANGE(1)}
};
static const comedi_lrange range_apci3XXX_ao = { 2, {BIP_RANGE(10),
UNI_RANGE(10)}
};
#endif

View File

@ -0,0 +1,5 @@
#define CONFIG_APCI_035 1
#define ADDIDATA_WATCHDOG 2 // Or shold it be something else
#include "addi-data/addi_common.c"

View File

@ -0,0 +1,3 @@
#define CONFIG_APCI_1032 1
#include "addi-data/addi_common.c"

View File

@ -0,0 +1,3 @@
#define CONFIG_APCI_1500 1
#include "addi-data/addi_common.c"

View File

@ -0,0 +1,3 @@
#define CONFIG_APCI_1516 1
#include "addi-data/addi_common.c"

View File

@ -0,0 +1,3 @@
#define CONFIG_APCI_1564 1
#include "addi-data/addi_common.c"

View File

@ -0,0 +1,3 @@
#define CONFIG_APCI_16XX 1
#include "addi-data/addi_common.c"

View File

@ -0,0 +1,3 @@
#define CONFIG_APCI_1710 1
#include "addi-data/addi_common.c"

View File

@ -0,0 +1,3 @@
#define CONFIG_APCI_2016 1
#include "addi-data/addi_common.c"

View File

@ -0,0 +1,3 @@
#define CONFIG_APCI_2032 1
#include "addi-data/addi_common.c"

View File

@ -0,0 +1,3 @@
#define CONFIG_APCI_2200 1
#include "addi-data/addi_common.c"

View File

@ -0,0 +1,3 @@
#define CONFIG_APCI_3001 1
#include "addi-data/addi_common.c"

View File

@ -0,0 +1,3 @@
#define CONFIG_APCI_3120 1
#include "addi-data/addi_common.c"

View File

@ -0,0 +1,3 @@
#define CONFIG_APCI_3200 1
#include "addi-data/addi_common.c"

View File

@ -0,0 +1,3 @@
#define CONFIG_APCI_3300 1
#include "addi-data/addi_common.c"

View File

@ -0,0 +1,3 @@
#define CONFIG_APCI_3501 1
#include "addi-data/addi_common.c"

View File

@ -0,0 +1,3 @@
#define CONFIG_APCI_3XXX 1
#include "addi-data/addi_common.c"

View File

@ -0,0 +1,18 @@
#define CONFIG_APCI_035 1
#define CONFIG_APCI_1032 1
#define CONFIG_APCI_1500 1
#define CONFIG_APCI_1516 1
#define CONFIG_APCI_1564 1
#define CONFIG_APCI_16XX 1
#define CONFIG_APCI_1710 1
#define CONFIG_APCI_2016 1
#define CONFIG_APCI_2032 1
#define CONFIG_APCI_2200 1
#define CONFIG_APCI_3001 1
#define CONFIG_APCI_3120 1
#define CONFIG_APCI_3200 1
#define CONFIG_APCI_3300 1
#define CONFIG_APCI_3501 1
#define CONFIG_APCI_3XXX 1
#include "addi-data/addi_common.c"