APCI1710_Dig_io.c revision 34c43922e62708d45e9660eee4b4f1fb7b4bf2c7
1/**
2@verbatim
3
4Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
5
6        ADDI-DATA GmbH
7        Dieselstrasse 3
8        D-77833 Ottersweier
9        Tel: +19(0)7223/9493-0
10        Fax: +49(0)7223/9493-92
11        http://www.addi-data-com
12        info@addi-data.com
13
14This 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.
15
16This 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.
17
18You 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
19
20You shoud also find the complete GPL in the COPYING file accompanying this source code.
21
22@endverbatim
23*/
24/*
25
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                          |
38  |                                                                       |
39  |                                                                       |
40  +-----------------------------------------------------------------------+
41  |                             UPDATES                                   |
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             |
48  |          |           |   available                                    |
49  +-----------------------------------------------------------------------+
50  |          |           |                                                |
51  |          |           |                                                |
52  +-----------------------------------------------------------------------+
53*/
54
55/*
56+----------------------------------------------------------------------------+
57|                               Included files                               |
58+----------------------------------------------------------------------------+
59*/
60#include "APCI1710_Dig_io.h"
61
62/*
63+----------------------------------------------------------------------------+
64| Function Name     : INT i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev, |
65|						struct comedi_subdevice *s,comedi_insn *insn,unsigned int *data)|
66+----------------------------------------------------------------------------+
67| Task              : Configure the digital I/O operating mode from selected |
68|                     module  (b_ModulNbr). You must calling this function be|
69|                     for you call any other function witch access of digital|
70|                     I/O.                                                   |
71+----------------------------------------------------------------------------+
72| Input Parameters  :													     |
73|                  BYTE_ b_ModulNbr      data[0]: Module number to               |
74|                                             configure (0 to 3)             |
75|                     BYTE_ b_ChannelAMode data[1]  : Channel A mode selection       |
76|                                             0 : Channel used for digital   |
77|                                                 input                      |
78|                                             1 : Channel used for digital   |
79|                                                 output                     |
80|                     BYTE_ b_ChannelBMode data[2] : Channel B mode selection       |
81|                                             0 : Channel used for digital   |
82|                                                 input                      |
83|                                             1 : Channel used for digital   |
84|                                                 output					 |
85						data[0]	  memory on/off
86Activates and deactivates the digital output memory.
87						After having      |
88|                 called up this function with memory on,the output you have previously|
89|                     activated with the function are not reset
90+----------------------------------------------------------------------------+
91| Output Parameters : -                                                      |
92+----------------------------------------------------------------------------+
93| Return Value      : 0: No error                                            |
94|                    -1: The handle parameter of the board is wrong          |
95|                    -2: The module parameter is wrong                       |
96|                    -3: The module is not a digital I/O module              |
97|                    -4: Bi-directional channel A configuration error        |
98|                    -5: Bi-directional channel B configuration error        |
99+----------------------------------------------------------------------------+
100*/
101
102INT i_APCI1710_InsnConfigDigitalIO(struct comedi_device * dev, struct comedi_subdevice * s,
103	comedi_insn * insn, unsigned int * data)
104{
105	BYTE b_ModulNbr, b_ChannelAMode, b_ChannelBMode;
106	BYTE b_MemoryOnOff, b_ConfigType;
107	INT i_ReturnValue = 0;
108	DWORD dw_WriteConfig = 0;
109
110	b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
111	b_ConfigType = (BYTE) data[0];	// Memory or  Init
112	b_ChannelAMode = (BYTE) data[1];
113	b_ChannelBMode = (BYTE) data[2];
114	b_MemoryOnOff = (BYTE) data[1];	// if memory operation
115	i_ReturnValue = insn->n;
116
117		/**************************/
118	/* Test the module number */
119		/**************************/
120
121	if (b_ModulNbr >= 4) {
122		DPRINTK("Module Number invalid\n");
123		i_ReturnValue = -2;
124		return i_ReturnValue;
125	}
126	switch (b_ConfigType) {
127	case APCI1710_DIGIO_MEMORYONOFF:
128
129		if (b_MemoryOnOff)	// If Memory ON
130		{
131		 /****************************/
132			/* Set the output memory on */
133		 /****************************/
134
135			devpriv->s_ModuleInfo[b_ModulNbr].
136				s_DigitalIOInfo.b_OutputMemoryEnabled = 1;
137
138		 /***************************/
139			/* Clear the output memory */
140		 /***************************/
141			devpriv->s_ModuleInfo[b_ModulNbr].
142				s_DigitalIOInfo.dw_OutputMemory = 0;
143		} else		// If memory off
144		{
145		 /*****************************/
146			/* Set the output memory off */
147		 /*****************************/
148
149			devpriv->s_ModuleInfo[b_ModulNbr].
150				s_DigitalIOInfo.b_OutputMemoryEnabled = 0;
151		}
152		break;
153
154	case APCI1710_DIGIO_INIT:
155
156	/*******************************/
157		/* Test if digital I/O counter */
158	/*******************************/
159
160		if ((devpriv->s_BoardInfos.
161				dw_MolduleConfiguration[b_ModulNbr] &
162				0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
163
164	/***************************************************/
165			/* Test the bi-directional channel A configuration */
166	/***************************************************/
167
168			if ((b_ChannelAMode == 0) || (b_ChannelAMode == 1)) {
169	/***************************************************/
170				/* Test the bi-directional channel B configuration */
171	/***************************************************/
172
173				if ((b_ChannelBMode == 0)
174					|| (b_ChannelBMode == 1)) {
175					devpriv->s_ModuleInfo[b_ModulNbr].
176						s_DigitalIOInfo.b_DigitalInit =
177						1;
178
179	/********************************/
180					/* Save channel A configuration */
181	/********************************/
182
183					devpriv->s_ModuleInfo[b_ModulNbr].
184						s_DigitalIOInfo.
185						b_ChannelAMode = b_ChannelAMode;
186
187	/********************************/
188					/* Save channel B configuration */
189	/********************************/
190
191					devpriv->s_ModuleInfo[b_ModulNbr].
192						s_DigitalIOInfo.
193						b_ChannelBMode = b_ChannelBMode;
194
195	/*****************************************/
196					/* Set the channel A and B configuration */
197	/*****************************************/
198
199					dw_WriteConfig =
200						(DWORD) (b_ChannelAMode |
201						(b_ChannelBMode * 2));
202
203	/***************************/
204					/* Write the configuration */
205	/***************************/
206
207					outl(dw_WriteConfig,
208						devpriv->s_BoardInfos.
209						ui_Address + 4 +
210						(64 * b_ModulNbr));
211
212				} else {
213	/************************************************/
214					/* Bi-directional channel B configuration error */
215	/************************************************/
216					DPRINTK("Bi-directional channel B configuration error\n");
217					i_ReturnValue = -5;
218				}
219
220			} else {
221	/************************************************/
222				/* Bi-directional channel A configuration error */
223	/************************************************/
224				DPRINTK("Bi-directional channel A configuration error\n");
225				i_ReturnValue = -4;
226
227			}
228
229		} else {
230	/******************************************/
231			/* The module is not a digital I/O module */
232	/******************************************/
233			DPRINTK("The module is not a digital I/O module\n");
234			i_ReturnValue = -3;
235		}
236	}			// end of Switch
237	printk("Return Value %d\n", i_ReturnValue);
238	return i_ReturnValue;
239}
240
241/*
242+----------------------------------------------------------------------------+
243|                            INPUT FUNCTIONS                                 |
244+----------------------------------------------------------------------------+
245*/
246
247/*
248+----------------------------------------------------------------------------+
249
250|INT i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev,comedi_subdevice
251*s,	comedi_insn *insn,unsigned int *data)
252
253+----------------------------------------------------------------------------+
254| Task              : Read the status from selected digital I/O digital input|
255|                     (b_InputChannel)                                       |
256+----------------------------------------------------------------------------|
257
258
259|
260|  BYTE_ b_ModulNbr  CR_AREF(chanspec)          : Selected module number   |
261|                                                   (0 to 3)                 |
262|  BYTE_ b_InputChannel CR_CHAN(chanspec)        : Selection from digital   |
263|                                                   input ( 0 to 6)          |
264|                                                      0 : Channel C         |
265|                                                      1 : Channel D         |
266|                                                      2 : Channel E         |
267|                                                      3 : Channel F         |
268|                                                      4 : Channel G         |
269|                                                      5 : Channel A         |
270|                                                      6 : Channel B
271
272
273	|
274+----------------------------------------------------------------------------+
275| Output Parameters :					 data[0]   : Digital input channel    |
276|                                                   status                   |
277|                                                   0 : Channle is not active|
278|                                                   1 : Channle is active    |
279+----------------------------------------------------------------------------+
280| Return Value      : 0: No error                                            |
281|                    -1: The handle parameter of the board is wrong          |
282|                    -2: The module parameter is wrong                       |
283|                    -3: The module is not a digital I/O module              |
284|                    -4: The selected digital I/O digital input is wrong     |
285|                    -5: Digital I/O not initialised                         |
286|                    -6: The digital channel A is used for output            |
287|                    -7: The digital channel B is used for output            |
288+----------------------------------------------------------------------------+
289*/
290
291//_INT_   i_APCI1710_ReadDigitalIOChlValue      (BYTE_    b_BoardHandle,
292//                                             BYTE_    b_ModulNbr,
293//                                             BYTE_    b_InputChannel,
294//
295//                                             PBYTE_  pb_ChannelStatus)
296INT i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device * dev,
297	struct comedi_subdevice * s, comedi_insn * insn, unsigned int * data)
298{
299	INT i_ReturnValue = 0;
300	DWORD dw_StatusReg;
301	BYTE b_ModulNbr, b_InputChannel;
302	PBYTE pb_ChannelStatus;
303	b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
304	b_InputChannel = (BYTE) CR_CHAN(insn->chanspec);
305	data[0] = 0;
306	pb_ChannelStatus = (PBYTE) & data[0];
307	i_ReturnValue = insn->n;
308
309	/**************************/
310	/* Test the module number */
311	/**************************/
312
313	if (b_ModulNbr < 4) {
314	   /*******************************/
315		/* Test if digital I/O counter */
316	   /*******************************/
317
318		if ((devpriv->s_BoardInfos.
319				dw_MolduleConfiguration[b_ModulNbr] &
320				0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
321	      /******************************************/
322			/* Test the digital imnput channel number */
323	      /******************************************/
324
325			if (b_InputChannel <= 6) {
326		 /**********************************************/
327				/* Test if the digital I/O module initialised */
328		 /**********************************************/
329
330				if (devpriv->s_ModuleInfo[b_ModulNbr].
331					s_DigitalIOInfo.b_DigitalInit == 1) {
332		    /**********************************/
333					/* Test if channel A or channel B */
334		    /**********************************/
335
336					if (b_InputChannel > 4) {
337		       /*********************/
338						/* Test if channel A */
339		       /*********************/
340
341						if (b_InputChannel == 5) {
342			  /***************************/
343							/* Test the channel A mode */
344			  /***************************/
345
346							if (devpriv->
347								s_ModuleInfo
348								[b_ModulNbr].
349								s_DigitalIOInfo.
350								b_ChannelAMode
351								!= 0) {
352			     /********************************************/
353								/* The digital channel A is used for output */
354			     /********************************************/
355
356								i_ReturnValue =
357									-6;
358							}
359						}	// if (b_InputChannel == 5)
360						else {
361			  /***************************/
362							/* Test the channel B mode */
363			  /***************************/
364
365							if (devpriv->
366								s_ModuleInfo
367								[b_ModulNbr].
368								s_DigitalIOInfo.
369								b_ChannelBMode
370								!= 0) {
371			     /********************************************/
372								/* The digital channel B is used for output */
373			     /********************************************/
374
375								i_ReturnValue =
376									-7;
377							}
378						}	// if (b_InputChannel == 5)
379					}	// if (b_InputChannel > 4)
380
381		    /***********************/
382					/* Test if error occur */
383		    /***********************/
384
385					if (i_ReturnValue >= 0) {
386		       /**************************/
387						/* Read all digital input */
388		       /**************************/
389
390						//INPDW (ps_APCI1710Variable->
391						//   s_Board [b_BoardHandle].
392						//   s_BoardInfos.
393						//  ui_Address + (64 * b_ModulNbr),
394						// &dw_StatusReg);
395
396						dw_StatusReg =
397							inl(devpriv->
398							s_BoardInfos.
399							ui_Address +
400							(64 * b_ModulNbr));
401
402						*pb_ChannelStatus =
403							(BYTE) ((dw_StatusReg ^
404								0x1C) >>
405							b_InputChannel) & 1;
406
407					}	// if (i_ReturnValue == 0)
408				} else {
409		    /*******************************/
410					/* Digital I/O not initialised */
411		    /*******************************/
412					DPRINTK("Digital I/O not initialised\n");
413					i_ReturnValue = -5;
414				}
415			} else {
416		 /********************************/
417				/* Selected digital input error */
418		 /********************************/
419				DPRINTK("Selected digital input error\n");
420				i_ReturnValue = -4;
421			}
422		} else {
423	      /******************************************/
424			/* The module is not a digital I/O module */
425	      /******************************************/
426			DPRINTK("The module is not a digital I/O module\n");
427			i_ReturnValue = -3;
428		}
429	} else {
430	   /***********************/
431		/* Module number error */
432	   /***********************/
433		DPRINTK("Module number error\n");
434		i_ReturnValue = -2;
435	}
436
437	return (i_ReturnValue);
438}
439
440/*
441+----------------------------------------------------------------------------+
442|                            OUTPUT FUNCTIONS                                |
443+----------------------------------------------------------------------------+
444*/
445
446/*
447+----------------------------------------------------------------------------+
448| Function Name     : INT i_APCI1710_InsnWriteDigitalIOChlOnOff(comedi_device
449|*dev,struct comedi_subdevice *s,comedi_insn *insn,unsigned int *data)
450
451+----------------------------------------------------------------------------+
452| Task              : Sets or resets the output witch has been passed with the         |
453|                     parameter b_Channel. Setting an output means setting   |
454|                     an ouput high.                                         |
455+----------------------------------------------------------------------------+
456| Input Parameters  : BYTE_ b_BoardHandle   : Handle of board APCI-1710      |
457|                     BYTE_ b_ModulNbr (aref )    : Selected module number (0 to 3)|
458|                     BYTE_ b_OutputChannel (CR_CHAN) : Selection from digital output  |
459|                                             channel (0 to 2)               |
460|                                                0 : Channel H               |
461|                                                1 : Channel A               |
462|                                                2 : Channel B               |
463+----------------------------------------------------------------------------+
464| Output Parameters : -                                                      |
465+----------------------------------------------------------------------------+
466| Return Value      : 0: No error                                            |
467|                    -1: The handle parameter of the board is wrong          |
468|                    -2: The module parameter is wrong                       |
469|                    -3: The module is not a digital I/O module              |
470|                    -4: The selected digital output is wrong                |
471|                    -5: digital I/O not initialised see function            |
472|                        " i_APCI1710_InitDigitalIO"                         |
473|                    -6: The digital channel A is used for input             |
474|                    -7: The digital channel B is used for input
475					 -8: Digital Output Memory OFF.                          |
476|                        Use previously the function                         |
477|                        "i_APCI1710_SetDigitalIOMemoryOn".            |
478+----------------------------------------------------------------------------+
479*/
480
481//_INT_   i_APCI1710_SetDigitalIOChlOn    (BYTE_ b_BoardHandle,
482//                                       BYTE_ b_ModulNbr,
483//                                       BYTE_ b_OutputChannel)
484INT i_APCI1710_InsnWriteDigitalIOChlOnOff(struct comedi_device * dev,
485	struct comedi_subdevice * s, comedi_insn * insn, unsigned int * data)
486{
487	INT i_ReturnValue = 0;
488	DWORD dw_WriteValue = 0;
489	BYTE b_ModulNbr, b_OutputChannel;
490	i_ReturnValue = insn->n;
491	b_ModulNbr = CR_AREF(insn->chanspec);
492	b_OutputChannel = CR_CHAN(insn->chanspec);
493
494	/**************************/
495	/* Test the module number */
496	/**************************/
497
498	if (b_ModulNbr < 4) {
499	   /*******************************/
500		/* Test if digital I/O counter */
501	   /*******************************/
502
503		if ((devpriv->s_BoardInfos.
504				dw_MolduleConfiguration[b_ModulNbr] &
505				0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
506	      /**********************************************/
507			/* Test if the digital I/O module initialised */
508	      /**********************************************/
509
510			if (devpriv->s_ModuleInfo[b_ModulNbr].
511				s_DigitalIOInfo.b_DigitalInit == 1) {
512		 /******************************************/
513				/* Test the digital output channel number */
514		 /******************************************/
515
516				switch (b_OutputChannel) {
517		    /*************/
518					/* Channel H */
519		    /*************/
520
521				case 0:
522					break;
523
524		    /*************/
525					/* Channel A */
526		    /*************/
527
528				case 1:
529					if (devpriv->s_ModuleInfo[b_ModulNbr].
530						s_DigitalIOInfo.
531						b_ChannelAMode != 1) {
532			    /*******************************************/
533						/* The digital channel A is used for input */
534			    /*******************************************/
535
536						i_ReturnValue = -6;
537					}
538					break;
539
540		    /*************/
541					/* Channel B */
542		    /*************/
543
544				case 2:
545					if (devpriv->s_ModuleInfo[b_ModulNbr].
546						s_DigitalIOInfo.
547						b_ChannelBMode != 1) {
548			    /*******************************************/
549						/* The digital channel B is used for input */
550			    /*******************************************/
551
552						i_ReturnValue = -7;
553					}
554					break;
555
556				default:
557			 /****************************************/
558					/* The selected digital output is wrong */
559			 /****************************************/
560
561					i_ReturnValue = -4;
562					break;
563				}
564
565		 /***********************/
566				/* Test if error occur */
567		 /***********************/
568
569				if (i_ReturnValue >= 0) {
570
571			/*********************************/
572					/* Test if set channel ON        */
573		    /*********************************/
574					if (data[0]) {
575		    /*********************************/
576						/* Test if output memory enabled */
577		    /*********************************/
578
579						if (devpriv->
580							s_ModuleInfo
581							[b_ModulNbr].
582							s_DigitalIOInfo.
583							b_OutputMemoryEnabled ==
584							1) {
585							dw_WriteValue =
586								devpriv->
587								s_ModuleInfo
588								[b_ModulNbr].
589								s_DigitalIOInfo.
590								dw_OutputMemory
591								| (1 <<
592								b_OutputChannel);
593
594							devpriv->
595								s_ModuleInfo
596								[b_ModulNbr].
597								s_DigitalIOInfo.
598								dw_OutputMemory
599								= dw_WriteValue;
600						} else {
601							dw_WriteValue =
602								1 <<
603								b_OutputChannel;
604						}
605					}	// set channel off
606					else {
607						if (devpriv->
608							s_ModuleInfo
609							[b_ModulNbr].
610							s_DigitalIOInfo.
611							b_OutputMemoryEnabled ==
612							1) {
613							dw_WriteValue =
614								devpriv->
615								s_ModuleInfo
616								[b_ModulNbr].
617								s_DigitalIOInfo.
618								dw_OutputMemory
619								& (0xFFFFFFFFUL
620								-
621								(1 << b_OutputChannel));
622
623							devpriv->
624								s_ModuleInfo
625								[b_ModulNbr].
626								s_DigitalIOInfo.
627								dw_OutputMemory
628								= dw_WriteValue;
629						} else {
630		       /*****************************/
631							/* Digital Output Memory OFF */
632		       /*****************************/
633							// +Use previously the function "i_APCI1710_SetDigitalIOMemoryOn"
634							i_ReturnValue = -8;
635						}
636
637					}
638		    /*******************/
639					/* Write the value */
640		    /*******************/
641
642					//OUTPDW (ps_APCI1710Variable->
643					//    s_Board [b_BoardHandle].
644					//   s_BoardInfos.
645					//   ui_Address + (64 * b_ModulNbr),
646					//   dw_WriteValue);
647					outl(dw_WriteValue,
648						devpriv->s_BoardInfos.
649						ui_Address + (64 * b_ModulNbr));
650				}
651			} else {
652		 /*******************************/
653				/* Digital I/O not initialised */
654		 /*******************************/
655
656				i_ReturnValue = -5;
657			}
658		} else {
659	      /******************************************/
660			/* The module is not a digital I/O module */
661	      /******************************************/
662
663			i_ReturnValue = -3;
664		}
665	} else {
666	   /***********************/
667		/* Module number error */
668	   /***********************/
669
670		i_ReturnValue = -2;
671	}
672
673	return (i_ReturnValue);
674}
675
676/*
677+----------------------------------------------------------------------------+
678
679|INT i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device *dev,comedi_subdevice
680	*s,	comedi_insn *insn,unsigned int *data)
681+----------------------------------------------------------------------------+
682| Task              : write:
683					  Sets or resets one or several outputs from port.                 |
684|                     Setting an output means setting an output high.        |
685|                     If you have switched OFF the digital output memory     |
686|                     (OFF), all the other output are set to "0".
687
688|                      read:
689					  Read the status from digital input port                |
690|                     from selected digital I/O module (b_ModulNbr)
691+----------------------------------------------------------------------------+
692| Input Parameters  :
693	BYTE_ b_BoardHandle   : Handle of board APCI-1710      |
694|   BYTE_ b_ModulNbr  CR_AREF(aref)    : Selected module number (0 to 3)|
695|   BYTE_ b_PortValue CR_CHAN(chanspec) : Output Value ( 0 To 7 )
696|                       data[0]           read or write port
697                        data[1]            if write then indicate ON or OFF
698
699                        if read : data[1] will return port status.
700+----------------------------------------------------------------------------+
701| Output Parameters : -                                                      |
702+----------------------------------------------------------------------------+
703| Return Value      :
704
705                INPUT :
706
707					  0: No error                                            |
708|                    -1: The handle parameter of the board is wrong          |
709|                    -2: The module parameter is wrong                       |
710|                    -3: The module is not a digital I/O module              |
711|                    -4: Digital I/O not initialised
712
713				OUTPUT:	  0: No error                                            |
714|                    -1: The handle parameter of the board is wrong          |
715|                    -2: The module parameter is wrong                       |
716|                    -3: The module is not a digital I/O module              |
717|                    -4: Output value wrong                                  |
718|                    -5: digital I/O not initialised see function            |
719|                        " i_APCI1710_InitDigitalIO"                         |
720|                    -6: The digital channel A is used for input             |
721|                    -7: The digital channel B is used for input
722					-8: Digital Output Memory OFF.                          |
723|                        Use previously the function                         |
724|                        "i_APCI1710_SetDigitalIOMemoryOn".               |
725+----------------------------------------------------------------------------+
726*/
727
728//_INT_   i_APCI1710_SetDigitalIOPortOn   (BYTE_ b_BoardHandle,
729//                                       BYTE_ b_ModulNbr,
730//                                       BYTE_ b_PortValue)
731INT i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device * dev,
732	struct comedi_subdevice * s, comedi_insn * insn, unsigned int * data)
733{
734	INT i_ReturnValue = 0;
735	DWORD dw_WriteValue = 0;
736	DWORD dw_StatusReg;
737	BYTE b_ModulNbr, b_PortValue;
738	BYTE b_PortOperation, b_PortOnOFF;
739
740	PBYTE pb_PortValue;
741
742	b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
743	b_PortOperation = (BYTE) data[0];	// Input or output
744	b_PortOnOFF = (BYTE) data[1];	// if output then On or Off
745	b_PortValue = (BYTE) data[2];	// if out put then Value
746	i_ReturnValue = insn->n;
747	pb_PortValue = (PBYTE) & data[0];
748// if input then read value
749
750	switch (b_PortOperation) {
751	case APCI1710_INPUT:
752	/**************************/
753		/* Test the module number */
754	/**************************/
755
756		if (b_ModulNbr < 4) {
757	   /*******************************/
758			/* Test if digital I/O counter */
759	   /*******************************/
760
761			if ((devpriv->s_BoardInfos.
762					dw_MolduleConfiguration[b_ModulNbr] &
763					0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
764	      /**********************************************/
765				/* Test if the digital I/O module initialised */
766	      /**********************************************/
767
768				if (devpriv->s_ModuleInfo[b_ModulNbr].
769					s_DigitalIOInfo.b_DigitalInit == 1) {
770		 /**************************/
771					/* Read all digital input */
772		 /**************************/
773
774					//INPDW (ps_APCI1710Variable->
775					//      s_Board [b_BoardHandle].
776					//      s_BoardInfos.
777					//      ui_Address + (64 * b_ModulNbr),
778					//      &dw_StatusReg);
779
780					dw_StatusReg =
781						inl(devpriv->s_BoardInfos.
782						ui_Address + (64 * b_ModulNbr));
783					*pb_PortValue =
784						(BYTE) (dw_StatusReg ^ 0x1C);
785
786				} else {
787		 /*******************************/
788					/* Digital I/O not initialised */
789		 /*******************************/
790
791					i_ReturnValue = -4;
792				}
793			} else {
794	      /******************************************/
795				/* The module is not a digital I/O module */
796	      /******************************************/
797
798				i_ReturnValue = -3;
799			}
800		} else {
801	   /***********************/
802			/* Module number error */
803	   /***********************/
804
805			i_ReturnValue = -2;
806		}
807
808		break;
809
810	case APCI1710_OUTPUT:
811	/**************************/
812		/* Test the module number */
813	/**************************/
814
815		if (b_ModulNbr < 4) {
816	   /*******************************/
817			/* Test if digital I/O counter */
818	   /*******************************/
819
820			if ((devpriv->s_BoardInfos.
821					dw_MolduleConfiguration[b_ModulNbr] &
822					0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
823	      /**********************************************/
824				/* Test if the digital I/O module initialised */
825	      /**********************************************/
826
827				if (devpriv->s_ModuleInfo[b_ModulNbr].
828					s_DigitalIOInfo.b_DigitalInit == 1) {
829		 /***********************/
830					/* Test the port value */
831		 /***********************/
832
833					if (b_PortValue <= 7) {
834		    /***********************************/
835						/* Test the digital output channel */
836		    /***********************************/
837
838		    /**************************/
839						/* Test if channel A used */
840		    /**************************/
841
842						if ((b_PortValue & 2) == 2) {
843							if (devpriv->
844								s_ModuleInfo
845								[b_ModulNbr].
846								s_DigitalIOInfo.
847								b_ChannelAMode
848								!= 1) {
849			  /*******************************************/
850								/* The digital channel A is used for input */
851			  /*******************************************/
852
853								i_ReturnValue =
854									-6;
855							}
856						}	// if ((b_PortValue & 2) == 2)
857
858		    /**************************/
859						/* Test if channel B used */
860		    /**************************/
861
862						if ((b_PortValue & 4) == 4) {
863							if (devpriv->
864								s_ModuleInfo
865								[b_ModulNbr].
866								s_DigitalIOInfo.
867								b_ChannelBMode
868								!= 1) {
869			  /*******************************************/
870								/* The digital channel B is used for input */
871			  /*******************************************/
872
873								i_ReturnValue =
874									-7;
875							}
876						}	// if ((b_PortValue & 4) == 4)
877
878		    /***********************/
879						/* Test if error occur */
880		    /***********************/
881
882						if (i_ReturnValue >= 0) {
883
884							//if(data[1])
885							//{
886							switch (b_PortOnOFF) {
887			   /*********************************/
888								/* Test if set Port ON                   */
889		       /*********************************/
890
891							case APCI1710_ON:
892
893		       /*********************************/
894								/* Test if output memory enabled */
895		       /*********************************/
896
897								if (devpriv->
898									s_ModuleInfo
899									[b_ModulNbr].
900									s_DigitalIOInfo.
901									b_OutputMemoryEnabled
902									== 1) {
903									dw_WriteValue
904										=
905										devpriv->
906										s_ModuleInfo
907										[b_ModulNbr].
908										s_DigitalIOInfo.
909										dw_OutputMemory
910										|
911										b_PortValue;
912
913									devpriv->
914										s_ModuleInfo
915										[b_ModulNbr].
916										s_DigitalIOInfo.
917										dw_OutputMemory
918										=
919										dw_WriteValue;
920								} else {
921									dw_WriteValue
922										=
923										b_PortValue;
924								}
925								break;
926
927								// If Set PORT  OFF
928							case APCI1710_OFF:
929
930			   /*********************************/
931								/* Test if output memory enabled */
932		       /*********************************/
933
934								if (devpriv->
935									s_ModuleInfo
936									[b_ModulNbr].
937									s_DigitalIOInfo.
938									b_OutputMemoryEnabled
939									== 1) {
940									dw_WriteValue
941										=
942										devpriv->
943										s_ModuleInfo
944										[b_ModulNbr].
945										s_DigitalIOInfo.
946										dw_OutputMemory
947										&
948										(0xFFFFFFFFUL
949										-
950										b_PortValue);
951
952									devpriv->
953										s_ModuleInfo
954										[b_ModulNbr].
955										s_DigitalIOInfo.
956										dw_OutputMemory
957										=
958										dw_WriteValue;
959								} else {
960			  /*****************************/
961									/* Digital Output Memory OFF */
962			  /*****************************/
963
964									i_ReturnValue
965										=
966										-8;
967								}
968							}	// switch
969
970		       /*******************/
971							/* Write the value */
972		       /*******************/
973
974							//  OUTPDW (ps_APCI1710Variable->
975							//      s_Board [b_BoardHandle].
976							//      s_BoardInfos.
977							//      ui_Address + (64 * b_ModulNbr),
978							//      dw_WriteValue);
979							outl(dw_WriteValue,
980								devpriv->
981								s_BoardInfos.
982								ui_Address +
983								(64 * b_ModulNbr));
984						}
985					} else {
986		    /**********************/
987						/* Output value wrong */
988		    /**********************/
989
990						i_ReturnValue = -4;
991					}
992				} else {
993		 /*******************************/
994					/* Digital I/O not initialised */
995		 /*******************************/
996
997					i_ReturnValue = -5;
998				}
999			} else {
1000	      /******************************************/
1001				/* The module is not a digital I/O module */
1002	      /******************************************/
1003
1004				i_ReturnValue = -3;
1005			}
1006		} else {
1007	   /***********************/
1008			/* Module number error */
1009	   /***********************/
1010
1011			i_ReturnValue = -2;
1012		}
1013		break;
1014
1015	default:
1016		i_ReturnValue = -9;
1017		DPRINTK("NO INPUT/OUTPUT specified\n");
1018	}			//switch INPUT / OUTPUT
1019	return (i_ReturnValue);
1020}
1021