4 Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
10 Fax: +49(0)7223/9493-92
11 http://www.addi-data.com
14 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.
16 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.
18 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
20 You should also find the complete GPL in the COPYING file accompanying this source code.
26 +-----------------------------------------------------------------------+
27 | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
28 +-----------------------------------------------------------------------+
29 | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
30 | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
31 +-----------------------------------------------------------------------+
32 | Project : API APCI1710 | Compiler : gcc |
33 | Module name : DIG_IO.C | Version : 2.96 |
34 +-------------------------------+---------------------------------------+
35 | Project manager: Eric Stolz | Date : 02/12/2002 |
36 +-----------------------------------------------------------------------+
37 | Description : APCI-1710 digital I/O module |
40 +-----------------------------------------------------------------------+
42 +-----------------------------------------------------------------------+
43 | Date | Author | Description of updates |
44 +----------+-----------+------------------------------------------------+
45 | 16/06/98 | S. Weber | Digital input / output implementation |
46 |----------|-----------|------------------------------------------------|
47 | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
49 +-----------------------------------------------------------------------+
52 +-----------------------------------------------------------------------+
55 /* Digital Output ON or OFF */
57 #define APCI1710_OFF 0
60 #define APCI1710_INPUT 0
61 #define APCI1710_OUTPUT 1
63 #define APCI1710_DIGIO_MEMORYONOFF 0x10
64 #define APCI1710_DIGIO_INIT 0x11
67 +----------------------------------------------------------------------------+
68 | Function Name : int i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev, |
69 | struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)|
70 +----------------------------------------------------------------------------+
71 | Task : Configure the digital I/O operating mode from selected |
72 | module (b_ModulNbr). You must calling this function be|
73 | for you call any other function witch access of digital|
75 +----------------------------------------------------------------------------+
76 | Input Parameters : |
77 | unsigned char_ b_ModulNbr data[0]: Module number to |
78 | configure (0 to 3) |
79 | unsigned char_ b_ChannelAMode data[1] : Channel A mode selection |
80 | 0 : Channel used for digital |
82 | 1 : Channel used for digital |
84 | unsigned char_ b_ChannelBMode data[2] : Channel B mode selection |
85 | 0 : Channel used for digital |
87 | 1 : Channel used for digital |
90 Activates and deactivates the digital output memory.
92 | called up this function with memory on,the output you have previously|
93 | activated with the function are not reset
94 +----------------------------------------------------------------------------+
95 | Output Parameters : - |
96 +----------------------------------------------------------------------------+
97 | Return Value : 0: No error |
98 | -1: The handle parameter of the board is wrong |
99 | -2: The module parameter is wrong |
100 | -3: The module is not a digital I/O module |
101 | -4: Bi-directional channel A configuration error |
102 | -5: Bi-directional channel B configuration error |
103 +----------------------------------------------------------------------------+
106 static int i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev,
107 struct comedi_subdevice *s,
108 struct comedi_insn *insn,
111 struct addi_private *devpriv = dev->private;
112 unsigned char b_ModulNbr, b_ChannelAMode, b_ChannelBMode;
113 unsigned char b_MemoryOnOff, b_ConfigType;
114 int i_ReturnValue = 0;
115 unsigned int dw_WriteConfig = 0;
117 b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
118 b_ConfigType = (unsigned char) data[0]; /* Memory or Init */
119 b_ChannelAMode = (unsigned char) data[1];
120 b_ChannelBMode = (unsigned char) data[2];
121 b_MemoryOnOff = (unsigned char) data[1]; /* if memory operation */
122 i_ReturnValue = insn->n;
124 /**************************/
125 /* Test the module number */
126 /**************************/
128 if (b_ModulNbr >= 4) {
129 DPRINTK("Module Number invalid\n");
131 return i_ReturnValue;
133 switch (b_ConfigType) {
134 case APCI1710_DIGIO_MEMORYONOFF:
136 if (b_MemoryOnOff) /* If Memory ON */
138 /****************************/
139 /* Set the output memory on */
140 /****************************/
142 devpriv->s_ModuleInfo[b_ModulNbr].
143 s_DigitalIOInfo.b_OutputMemoryEnabled = 1;
145 /***************************/
146 /* Clear the output memory */
147 /***************************/
148 devpriv->s_ModuleInfo[b_ModulNbr].
149 s_DigitalIOInfo.dw_OutputMemory = 0;
150 } else /* If memory off */
152 /*****************************/
153 /* Set the output memory off */
154 /*****************************/
156 devpriv->s_ModuleInfo[b_ModulNbr].
157 s_DigitalIOInfo.b_OutputMemoryEnabled = 0;
161 case APCI1710_DIGIO_INIT:
163 /*******************************/
164 /* Test if digital I/O counter */
165 /*******************************/
167 if ((devpriv->s_BoardInfos.
168 dw_MolduleConfiguration[b_ModulNbr] &
169 0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
171 /***************************************************/
172 /* Test the bi-directional channel A configuration */
173 /***************************************************/
175 if ((b_ChannelAMode == 0) || (b_ChannelAMode == 1)) {
176 /***************************************************/
177 /* Test the bi-directional channel B configuration */
178 /***************************************************/
180 if ((b_ChannelBMode == 0)
181 || (b_ChannelBMode == 1)) {
182 devpriv->s_ModuleInfo[b_ModulNbr].
183 s_DigitalIOInfo.b_DigitalInit =
186 /********************************/
187 /* Save channel A configuration */
188 /********************************/
190 devpriv->s_ModuleInfo[b_ModulNbr].
192 b_ChannelAMode = b_ChannelAMode;
194 /********************************/
195 /* Save channel B configuration */
196 /********************************/
198 devpriv->s_ModuleInfo[b_ModulNbr].
200 b_ChannelBMode = b_ChannelBMode;
202 /*****************************************/
203 /* Set the channel A and B configuration */
204 /*****************************************/
207 (unsigned int) (b_ChannelAMode |
208 (b_ChannelBMode * 2));
210 /***************************/
211 /* Write the configuration */
212 /***************************/
215 devpriv->s_BoardInfos.
220 /************************************************/
221 /* Bi-directional channel B configuration error */
222 /************************************************/
223 DPRINTK("Bi-directional channel B configuration error\n");
228 /************************************************/
229 /* Bi-directional channel A configuration error */
230 /************************************************/
231 DPRINTK("Bi-directional channel A configuration error\n");
237 /******************************************/
238 /* The module is not a digital I/O module */
239 /******************************************/
240 DPRINTK("The module is not a digital I/O module\n");
243 } /* end of Switch */
244 printk("Return Value %d\n", i_ReturnValue);
245 return i_ReturnValue;
249 +----------------------------------------------------------------------------+
251 +----------------------------------------------------------------------------+
255 +----------------------------------------------------------------------------+
257 |INT i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev,comedi_subdevice
258 *s, struct comedi_insn *insn,unsigned int *data)
260 +----------------------------------------------------------------------------+
261 | Task : Read the status from selected digital I/O digital input|
263 +----------------------------------------------------------------------------|
267 | unsigned char_ b_ModulNbr CR_AREF(chanspec) : Selected module number |
269 | unsigned char_ b_InputChannel CR_CHAN(chanspec) : Selection from digital |
281 +----------------------------------------------------------------------------+
282 | Output Parameters : data[0] : Digital input channel |
284 | 0 : Channle is not active|
285 | 1 : Channle is active |
286 +----------------------------------------------------------------------------+
287 | Return Value : 0: No error |
288 | -1: The handle parameter of the board is wrong |
289 | -2: The module parameter is wrong |
290 | -3: The module is not a digital I/O module |
291 | -4: The selected digital I/O digital input is wrong |
292 | -5: Digital I/O not initialised |
293 | -6: The digital channel A is used for output |
294 | -7: The digital channel B is used for output |
295 +----------------------------------------------------------------------------+
298 /* _INT_ i_APCI1710_ReadDigitalIOChlValue (unsigned char_ b_BoardHandle, */
300 * unsigned char_ b_ModulNbr, unsigned char_ b_InputChannel,
301 * unsigned char *_ pb_ChannelStatus)
303 static int i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev,
304 struct comedi_subdevice *s,
305 struct comedi_insn *insn,
308 struct addi_private *devpriv = dev->private;
309 int i_ReturnValue = 0;
310 unsigned int dw_StatusReg;
311 unsigned char b_ModulNbr, b_InputChannel;
312 unsigned char *pb_ChannelStatus;
313 b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
314 b_InputChannel = (unsigned char) CR_CHAN(insn->chanspec);
316 pb_ChannelStatus = (unsigned char *) &data[0];
317 i_ReturnValue = insn->n;
319 /**************************/
320 /* Test the module number */
321 /**************************/
323 if (b_ModulNbr < 4) {
324 /*******************************/
325 /* Test if digital I/O counter */
326 /*******************************/
328 if ((devpriv->s_BoardInfos.
329 dw_MolduleConfiguration[b_ModulNbr] &
330 0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
331 /******************************************/
332 /* Test the digital imnput channel number */
333 /******************************************/
335 if (b_InputChannel <= 6) {
336 /**********************************************/
337 /* Test if the digital I/O module initialised */
338 /**********************************************/
340 if (devpriv->s_ModuleInfo[b_ModulNbr].
341 s_DigitalIOInfo.b_DigitalInit == 1) {
342 /**********************************/
343 /* Test if channel A or channel B */
344 /**********************************/
346 if (b_InputChannel > 4) {
347 /*********************/
348 /* Test if channel A */
349 /*********************/
351 if (b_InputChannel == 5) {
352 /***************************/
353 /* Test the channel A mode */
354 /***************************/
362 /********************************************/
363 /* The digital channel A is used for output */
364 /********************************************/
369 } /* if (b_InputChannel == 5) */
371 /***************************/
372 /* Test the channel B mode */
373 /***************************/
381 /********************************************/
382 /* The digital channel B is used for output */
383 /********************************************/
388 } /* if (b_InputChannel == 5) */
389 } /* if (b_InputChannel > 4) */
391 /***********************/
392 /* Test if error occur */
393 /***********************/
395 if (i_ReturnValue >= 0) {
396 /**************************/
397 /* Read all digital input */
398 /**************************/
401 * INPDW (ps_APCI1710Variable-> s_Board [b_BoardHandle].
402 * s_BoardInfos. ui_Address + (64 * b_ModulNbr), &dw_StatusReg);
412 (unsigned char) ((dw_StatusReg ^
416 } /* if (i_ReturnValue == 0) */
418 /*******************************/
419 /* Digital I/O not initialised */
420 /*******************************/
421 DPRINTK("Digital I/O not initialised\n");
425 /********************************/
426 /* Selected digital input error */
427 /********************************/
428 DPRINTK("Selected digital input error\n");
432 /******************************************/
433 /* The module is not a digital I/O module */
434 /******************************************/
435 DPRINTK("The module is not a digital I/O module\n");
439 /***********************/
440 /* Module number error */
441 /***********************/
442 DPRINTK("Module number error\n");
446 return i_ReturnValue;
450 +----------------------------------------------------------------------------+
452 +----------------------------------------------------------------------------+
456 +----------------------------------------------------------------------------+
457 | Function Name : int i_APCI1710_InsnWriteDigitalIOChlOnOff(comedi_device
458 |*dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)
460 +----------------------------------------------------------------------------+
461 | Task : Sets or resets the output witch has been passed with the |
462 | parameter b_Channel. Setting an output means setting |
464 +----------------------------------------------------------------------------+
465 | Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
466 | unsigned char_ b_ModulNbr (aref ) : Selected module number (0 to 3)|
467 | unsigned char_ b_OutputChannel (CR_CHAN) : Selection from digital output |
472 +----------------------------------------------------------------------------+
473 | Output Parameters : - |
474 +----------------------------------------------------------------------------+
475 | Return Value : 0: No error |
476 | -1: The handle parameter of the board is wrong |
477 | -2: The module parameter is wrong |
478 | -3: The module is not a digital I/O module |
479 | -4: The selected digital output is wrong |
480 | -5: digital I/O not initialised see function |
481 | " i_APCI1710_InitDigitalIO" |
482 | -6: The digital channel A is used for input |
483 | -7: The digital channel B is used for input
484 -8: Digital Output Memory OFF. |
485 | Use previously the function |
486 | "i_APCI1710_SetDigitalIOMemoryOn". |
487 +----------------------------------------------------------------------------+
491 * _INT_ i_APCI1710_SetDigitalIOChlOn (unsigned char_ b_BoardHandle,
492 * unsigned char_ b_ModulNbr, unsigned char_ b_OutputChannel)
494 static int i_APCI1710_InsnWriteDigitalIOChlOnOff(struct comedi_device *dev,
495 struct comedi_subdevice *s,
496 struct comedi_insn *insn,
499 struct addi_private *devpriv = dev->private;
500 int i_ReturnValue = 0;
501 unsigned int dw_WriteValue = 0;
502 unsigned char b_ModulNbr, b_OutputChannel;
503 i_ReturnValue = insn->n;
504 b_ModulNbr = CR_AREF(insn->chanspec);
505 b_OutputChannel = CR_CHAN(insn->chanspec);
507 /**************************/
508 /* Test the module number */
509 /**************************/
511 if (b_ModulNbr < 4) {
512 /*******************************/
513 /* Test if digital I/O counter */
514 /*******************************/
516 if ((devpriv->s_BoardInfos.
517 dw_MolduleConfiguration[b_ModulNbr] &
518 0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
519 /**********************************************/
520 /* Test if the digital I/O module initialised */
521 /**********************************************/
523 if (devpriv->s_ModuleInfo[b_ModulNbr].
524 s_DigitalIOInfo.b_DigitalInit == 1) {
525 /******************************************/
526 /* Test the digital output channel number */
527 /******************************************/
529 switch (b_OutputChannel) {
542 if (devpriv->s_ModuleInfo[b_ModulNbr].
544 b_ChannelAMode != 1) {
545 /*******************************************/
546 /* The digital channel A is used for input */
547 /*******************************************/
558 if (devpriv->s_ModuleInfo[b_ModulNbr].
560 b_ChannelBMode != 1) {
561 /*******************************************/
562 /* The digital channel B is used for input */
563 /*******************************************/
570 /****************************************/
571 /* The selected digital output is wrong */
572 /****************************************/
578 /***********************/
579 /* Test if error occur */
580 /***********************/
582 if (i_ReturnValue >= 0) {
584 /*********************************/
585 /* Test if set channel ON */
586 /*********************************/
588 /*********************************/
589 /* Test if output memory enabled */
590 /*********************************/
596 b_OutputMemoryEnabled ==
618 } /* set channel off */
624 b_OutputMemoryEnabled ==
634 (1 << b_OutputChannel));
643 /*****************************/
644 /* Digital Output Memory OFF */
645 /*****************************/
646 /* +Use previously the function "i_APCI1710_SetDigitalIOMemoryOn" */
651 /*******************/
652 /* Write the value */
653 /*******************/
655 /* OUTPDW (ps_APCI1710Variable->
656 * s_Board [b_BoardHandle].
657 * s_BoardInfos. ui_Address + (64 * b_ModulNbr),
662 devpriv->s_BoardInfos.
663 ui_Address + (64 * b_ModulNbr));
666 /*******************************/
667 /* Digital I/O not initialised */
668 /*******************************/
673 /******************************************/
674 /* The module is not a digital I/O module */
675 /******************************************/
680 /***********************/
681 /* Module number error */
682 /***********************/
687 return i_ReturnValue;
691 +----------------------------------------------------------------------------+
693 |INT i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device *dev,comedi_subdevice
694 *s, struct comedi_insn *insn,unsigned int *data)
695 +----------------------------------------------------------------------------+
697 Sets or resets one or several outputs from port. |
698 | Setting an output means setting an output high. |
699 | If you have switched OFF the digital output memory |
700 | (OFF), all the other output are set to "0".
703 Read the status from digital input port |
704 | from selected digital I/O module (b_ModulNbr)
705 +----------------------------------------------------------------------------+
707 unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
708 | unsigned char_ b_ModulNbr CR_AREF(aref) : Selected module number (0 to 3)|
709 | unsigned char_ b_PortValue CR_CHAN(chanspec) : Output Value ( 0 To 7 )
710 | data[0] read or write port
711 | data[1] if write then indicate ON or OFF
713 | if read : data[1] will return port status.
714 +----------------------------------------------------------------------------+
715 | Output Parameters : - |
716 +----------------------------------------------------------------------------+
722 | -1: The handle parameter of the board is wrong |
723 | -2: The module parameter is wrong |
724 | -3: The module is not a digital I/O module |
725 | -4: Digital I/O not initialised
727 OUTPUT: 0: No error |
728 | -1: The handle parameter of the board is wrong |
729 | -2: The module parameter is wrong |
730 | -3: The module is not a digital I/O module |
731 | -4: Output value wrong |
732 | -5: digital I/O not initialised see function |
733 | " i_APCI1710_InitDigitalIO" |
734 | -6: The digital channel A is used for input |
735 | -7: The digital channel B is used for input
736 -8: Digital Output Memory OFF. |
737 | Use previously the function |
738 | "i_APCI1710_SetDigitalIOMemoryOn". |
739 +----------------------------------------------------------------------------+
743 * _INT_ i_APCI1710_SetDigitalIOPortOn (unsigned char_
744 * b_BoardHandle, unsigned char_ b_ModulNbr, unsigned char_
747 static int i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device *dev,
748 struct comedi_subdevice *s,
749 struct comedi_insn *insn,
752 struct addi_private *devpriv = dev->private;
753 int i_ReturnValue = 0;
754 unsigned int dw_WriteValue = 0;
755 unsigned int dw_StatusReg;
756 unsigned char b_ModulNbr, b_PortValue;
757 unsigned char b_PortOperation, b_PortOnOFF;
759 unsigned char *pb_PortValue;
761 b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
762 b_PortOperation = (unsigned char) data[0]; /* Input or output */
763 b_PortOnOFF = (unsigned char) data[1]; /* if output then On or Off */
764 b_PortValue = (unsigned char) data[2]; /* if out put then Value */
765 i_ReturnValue = insn->n;
766 pb_PortValue = (unsigned char *) &data[0];
767 /* if input then read value */
769 switch (b_PortOperation) {
771 /**************************/
772 /* Test the module number */
773 /**************************/
775 if (b_ModulNbr < 4) {
776 /*******************************/
777 /* Test if digital I/O counter */
778 /*******************************/
780 if ((devpriv->s_BoardInfos.
781 dw_MolduleConfiguration[b_ModulNbr] &
782 0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
783 /**********************************************/
784 /* Test if the digital I/O module initialised */
785 /**********************************************/
787 if (devpriv->s_ModuleInfo[b_ModulNbr].
788 s_DigitalIOInfo.b_DigitalInit == 1) {
789 /**************************/
790 /* Read all digital input */
791 /**************************/
793 /* INPDW (ps_APCI1710Variable->
794 * s_Board [b_BoardHandle].
796 * ui_Address + (64 * b_ModulNbr),
801 inl(devpriv->s_BoardInfos.
802 ui_Address + (64 * b_ModulNbr));
804 (unsigned char) (dw_StatusReg ^ 0x1C);
807 /*******************************/
808 /* Digital I/O not initialised */
809 /*******************************/
814 /******************************************/
815 /* The module is not a digital I/O module */
816 /******************************************/
821 /***********************/
822 /* Module number error */
823 /***********************/
830 case APCI1710_OUTPUT:
831 /**************************/
832 /* Test the module number */
833 /**************************/
835 if (b_ModulNbr < 4) {
836 /*******************************/
837 /* Test if digital I/O counter */
838 /*******************************/
840 if ((devpriv->s_BoardInfos.
841 dw_MolduleConfiguration[b_ModulNbr] &
842 0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
843 /**********************************************/
844 /* Test if the digital I/O module initialised */
845 /**********************************************/
847 if (devpriv->s_ModuleInfo[b_ModulNbr].
848 s_DigitalIOInfo.b_DigitalInit == 1) {
849 /***********************/
850 /* Test the port value */
851 /***********************/
853 if (b_PortValue <= 7) {
854 /***********************************/
855 /* Test the digital output channel */
856 /***********************************/
858 /**************************/
859 /* Test if channel A used */
860 /**************************/
862 if ((b_PortValue & 2) == 2) {
869 /*******************************************/
870 /* The digital channel A is used for input */
871 /*******************************************/
876 } /* if ((b_PortValue & 2) == 2) */
878 /**************************/
879 /* Test if channel B used */
880 /**************************/
882 if ((b_PortValue & 4) == 4) {
889 /*******************************************/
890 /* The digital channel B is used for input */
891 /*******************************************/
896 } /* if ((b_PortValue & 4) == 4) */
898 /***********************/
899 /* Test if error occur */
900 /***********************/
902 if (i_ReturnValue >= 0) {
906 switch (b_PortOnOFF) {
907 /*********************************/
908 /* Test if set Port ON */
909 /*********************************/
913 /*********************************/
914 /* Test if output memory enabled */
915 /*********************************/
921 b_OutputMemoryEnabled
947 /* If Set PORT OFF */
950 /*********************************/
951 /* Test if output memory enabled */
952 /*********************************/
958 b_OutputMemoryEnabled
980 /*****************************/
981 /* Digital Output Memory OFF */
982 /*****************************/
990 /*******************/
991 /* Write the value */
992 /*******************/
994 /* OUTPDW (ps_APCI1710Variable->
995 * s_Board [b_BoardHandle].
997 * ui_Address + (64 * b_ModulNbr),
1007 /**********************/
1008 /* Output value wrong */
1009 /**********************/
1014 /*******************************/
1015 /* Digital I/O not initialised */
1016 /*******************************/
1021 /******************************************/
1022 /* The module is not a digital I/O module */
1023 /******************************************/
1028 /***********************/
1029 /* Module number error */
1030 /***********************/
1038 DPRINTK("NO INPUT/OUTPUT specified\n");
1039 } /* switch INPUT / OUTPUT */
1040 return i_ReturnValue;