APCI1710_Dig_io.c revision da91b2692e0939b307f9047192d2b9fe07793e7a
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,struct 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|                  unsigned char_ b_ModulNbr      data[0]: Module number to               |
74|                                             configure (0 to 3)             |
75|                     unsigned char_ 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|                     unsigned char_ 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	struct comedi_insn *insn, unsigned int *data)
104{
105	unsigned char b_ModulNbr, b_ChannelAMode, b_ChannelBMode;
106	unsigned char b_MemoryOnOff, b_ConfigType;
107	int i_ReturnValue = 0;
108	unsigned int dw_WriteConfig = 0;
109
110	b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
111	b_ConfigType = (unsigned char) data[0];	/*  Memory or  Init */
112	b_ChannelAMode = (unsigned char) data[1];
113	b_ChannelBMode = (unsigned char) data[2];
114	b_MemoryOnOff = (unsigned char) 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						(unsigned int) (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,	struct 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|  unsigned char_ b_ModulNbr  CR_AREF(chanspec)          : Selected module number   |
261|                                                   (0 to 3)                 |
262|  unsigned char_ 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      (unsigned char_    b_BoardHandle, */
292/*
293* unsigned char_ b_ModulNbr, unsigned char_ b_InputChannel,
294* unsigned char *_ pb_ChannelStatus)
295*/
296int i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev,
297	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
298{
299	int i_ReturnValue = 0;
300	unsigned int dw_StatusReg;
301	unsigned char b_ModulNbr, b_InputChannel;
302	unsigned char *pb_ChannelStatus;
303	b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
304	b_InputChannel = (unsigned char) CR_CHAN(insn->chanspec);
305	data[0] = 0;
306	pb_ChannelStatus = (unsigned char *) & 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/*
391* INPDW (ps_APCI1710Variable-> s_Board [b_BoardHandle].
392* s_BoardInfos. ui_Address + (64 * b_ModulNbr), &dw_StatusReg);
393*/
394
395						dw_StatusReg =
396							inl(devpriv->
397							s_BoardInfos.
398							ui_Address +
399							(64 * b_ModulNbr));
400
401						*pb_ChannelStatus =
402							(unsigned char) ((dw_StatusReg ^
403								0x1C) >>
404							b_InputChannel) & 1;
405
406					}	/*  if (i_ReturnValue == 0) */
407				} else {
408		    /*******************************/
409					/* Digital I/O not initialised */
410		    /*******************************/
411					DPRINTK("Digital I/O not initialised\n");
412					i_ReturnValue = -5;
413				}
414			} else {
415		 /********************************/
416				/* Selected digital input error */
417		 /********************************/
418				DPRINTK("Selected digital input error\n");
419				i_ReturnValue = -4;
420			}
421		} else {
422	      /******************************************/
423			/* The module is not a digital I/O module */
424	      /******************************************/
425			DPRINTK("The module is not a digital I/O module\n");
426			i_ReturnValue = -3;
427		}
428	} else {
429	   /***********************/
430		/* Module number error */
431	   /***********************/
432		DPRINTK("Module number error\n");
433		i_ReturnValue = -2;
434	}
435
436	return (i_ReturnValue);
437}
438
439/*
440+----------------------------------------------------------------------------+
441|                            OUTPUT FUNCTIONS                                |
442+----------------------------------------------------------------------------+
443*/
444
445/*
446+----------------------------------------------------------------------------+
447| Function Name     : int i_APCI1710_InsnWriteDigitalIOChlOnOff(comedi_device
448|*dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)
449
450+----------------------------------------------------------------------------+
451| Task              : Sets or resets the output witch has been passed with the         |
452|                     parameter b_Channel. Setting an output means setting   |
453|                     an ouput high.                                         |
454+----------------------------------------------------------------------------+
455| Input Parameters  : unsigned char_ b_BoardHandle   : Handle of board APCI-1710      |
456|                     unsigned char_ b_ModulNbr (aref )    : Selected module number (0 to 3)|
457|                     unsigned char_ b_OutputChannel (CR_CHAN) : Selection from digital output  |
458|                                             channel (0 to 2)               |
459|                                                0 : Channel H               |
460|                                                1 : Channel A               |
461|                                                2 : Channel B               |
462+----------------------------------------------------------------------------+
463| Output Parameters : -                                                      |
464+----------------------------------------------------------------------------+
465| Return Value      : 0: No error                                            |
466|                    -1: The handle parameter of the board is wrong          |
467|                    -2: The module parameter is wrong                       |
468|                    -3: The module is not a digital I/O module              |
469|                    -4: The selected digital output is wrong                |
470|                    -5: digital I/O not initialised see function            |
471|                        " i_APCI1710_InitDigitalIO"                         |
472|                    -6: The digital channel A is used for input             |
473|                    -7: The digital channel B is used for input
474					 -8: Digital Output Memory OFF.                          |
475|                        Use previously the function                         |
476|                        "i_APCI1710_SetDigitalIOMemoryOn".            |
477+----------------------------------------------------------------------------+
478*/
479
480/*
481* _INT_ i_APCI1710_SetDigitalIOChlOn (unsigned char_ b_BoardHandle,
482* unsigned char_ b_ModulNbr, unsigned char_ b_OutputChannel)
483*/
484int i_APCI1710_InsnWriteDigitalIOChlOnOff(struct comedi_device *dev,
485	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
486{
487	int i_ReturnValue = 0;
488	unsigned int dw_WriteValue = 0;
489	unsigned char 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. ui_Address + (64 * b_ModulNbr),
645					 * dw_WriteValue);
646					 */
647*/
648					outl(dw_WriteValue,
649						devpriv->s_BoardInfos.
650						ui_Address + (64 * b_ModulNbr));
651				}
652			} else {
653		 /*******************************/
654				/* Digital I/O not initialised */
655		 /*******************************/
656
657				i_ReturnValue = -5;
658			}
659		} else {
660	      /******************************************/
661			/* The module is not a digital I/O module */
662	      /******************************************/
663
664			i_ReturnValue = -3;
665		}
666	} else {
667	   /***********************/
668		/* Module number error */
669	   /***********************/
670
671		i_ReturnValue = -2;
672	}
673
674	return (i_ReturnValue);
675}
676
677/*
678+----------------------------------------------------------------------------+
679
680|INT i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device *dev,comedi_subdevice
681	*s,	struct comedi_insn *insn,unsigned int *data)
682+----------------------------------------------------------------------------+
683| Task              : write:
684					  Sets or resets one or several outputs from port.                 |
685|                     Setting an output means setting an output high.        |
686|                     If you have switched OFF the digital output memory     |
687|                     (OFF), all the other output are set to "0".
688
689|                      read:
690					  Read the status from digital input port                |
691|                     from selected digital I/O module (b_ModulNbr)
692+----------------------------------------------------------------------------+
693| Input Parameters  :
694	unsigned char_ b_BoardHandle   : Handle of board APCI-1710      |
695|   unsigned char_ b_ModulNbr  CR_AREF(aref)    : Selected module number (0 to 3)|
696|   unsigned char_ b_PortValue CR_CHAN(chanspec) : Output Value ( 0 To 7 )
697|                       data[0]           read or write port
698                        data[1]            if write then indicate ON or OFF
699
700                        if read : data[1] will return port status.
701+----------------------------------------------------------------------------+
702| Output Parameters : -                                                      |
703+----------------------------------------------------------------------------+
704| Return Value      :
705
706                INPUT :
707
708					  0: No error                                            |
709|                    -1: The handle parameter of the board is wrong          |
710|                    -2: The module parameter is wrong                       |
711|                    -3: The module is not a digital I/O module              |
712|                    -4: Digital I/O not initialised
713
714				OUTPUT:	  0: No error                                            |
715|                    -1: The handle parameter of the board is wrong          |
716|                    -2: The module parameter is wrong                       |
717|                    -3: The module is not a digital I/O module              |
718|                    -4: Output value wrong                                  |
719|                    -5: digital I/O not initialised see function            |
720|                        " i_APCI1710_InitDigitalIO"                         |
721|                    -6: The digital channel A is used for input             |
722|                    -7: The digital channel B is used for input
723					-8: Digital Output Memory OFF.                          |
724|                        Use previously the function                         |
725|                        "i_APCI1710_SetDigitalIOMemoryOn".               |
726+----------------------------------------------------------------------------+
727*/
728
729/*
730 * _INT_ i_APCI1710_SetDigitalIOPortOn (unsigned char_
731 * b_BoardHandle, unsigned char_ b_ModulNbr, unsigned char_
732 * b_PortValue)
733*/
734int i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device *dev,
735	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
736{
737	int i_ReturnValue = 0;
738	unsigned int dw_WriteValue = 0;
739	unsigned int dw_StatusReg;
740	unsigned char b_ModulNbr, b_PortValue;
741	unsigned char b_PortOperation, b_PortOnOFF;
742
743	unsigned char *pb_PortValue;
744
745	b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
746	b_PortOperation = (unsigned char) data[0];	/*  Input or output */
747	b_PortOnOFF = (unsigned char) data[1];	/*  if output then On or Off */
748	b_PortValue = (unsigned char) data[2];	/*  if out put then Value */
749	i_ReturnValue = insn->n;
750	pb_PortValue = (unsigned char *) & data[0];
751/* if input then read value */
752
753	switch (b_PortOperation) {
754	case APCI1710_INPUT:
755		/**************************/
756		/* Test the module number */
757		/**************************/
758
759		if (b_ModulNbr < 4) {
760			/*******************************/
761			/* Test if digital I/O counter */
762			/*******************************/
763
764			if ((devpriv->s_BoardInfos.
765					dw_MolduleConfiguration[b_ModulNbr] &
766					0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
767				/**********************************************/
768				/* Test if the digital I/O module initialised */
769				/**********************************************/
770
771				if (devpriv->s_ModuleInfo[b_ModulNbr].
772					s_DigitalIOInfo.b_DigitalInit == 1) {
773					/**************************/
774					/* Read all digital input */
775					/**************************/
776
777					/* INPDW (ps_APCI1710Variable->
778					 * s_Board [b_BoardHandle].
779					 * s_BoardInfos.
780					 * ui_Address + (64 * b_ModulNbr),
781					 * &dw_StatusReg);
782					 */
783
784					dw_StatusReg =
785						inl(devpriv->s_BoardInfos.
786						ui_Address + (64 * b_ModulNbr));
787					*pb_PortValue =
788						(unsigned char) (dw_StatusReg ^ 0x1C);
789
790				} else {
791					/*******************************/
792					/* Digital I/O not initialised */
793					/*******************************/
794
795					i_ReturnValue = -4;
796				}
797			} else {
798				/******************************************/
799				/* The module is not a digital I/O module */
800				/******************************************/
801
802				i_ReturnValue = -3;
803			}
804		} else {
805	   /***********************/
806			/* Module number error */
807	   /***********************/
808
809			i_ReturnValue = -2;
810		}
811
812		break;
813
814	case APCI1710_OUTPUT:
815	/**************************/
816		/* Test the module number */
817	/**************************/
818
819		if (b_ModulNbr < 4) {
820	   /*******************************/
821			/* Test if digital I/O counter */
822	   /*******************************/
823
824			if ((devpriv->s_BoardInfos.
825					dw_MolduleConfiguration[b_ModulNbr] &
826					0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
827	      /**********************************************/
828				/* Test if the digital I/O module initialised */
829	      /**********************************************/
830
831				if (devpriv->s_ModuleInfo[b_ModulNbr].
832					s_DigitalIOInfo.b_DigitalInit == 1) {
833		 /***********************/
834					/* Test the port value */
835		 /***********************/
836
837					if (b_PortValue <= 7) {
838		    /***********************************/
839						/* Test the digital output channel */
840		    /***********************************/
841
842		    /**************************/
843						/* Test if channel A used */
844		    /**************************/
845
846						if ((b_PortValue & 2) == 2) {
847							if (devpriv->
848								s_ModuleInfo
849								[b_ModulNbr].
850								s_DigitalIOInfo.
851								b_ChannelAMode
852								!= 1) {
853			  /*******************************************/
854								/* The digital channel A is used for input */
855			  /*******************************************/
856
857								i_ReturnValue =
858									-6;
859							}
860						}	/*  if ((b_PortValue & 2) == 2) */
861
862						/**************************/
863						/* Test if channel B used */
864						/**************************/
865
866						if ((b_PortValue & 4) == 4) {
867							if (devpriv->
868								s_ModuleInfo
869								[b_ModulNbr].
870								s_DigitalIOInfo.
871								b_ChannelBMode
872								!= 1) {
873								/*******************************************/
874								/* The digital channel B is used for input */
875								/*******************************************/
876
877								i_ReturnValue =
878									-7;
879							}
880						}	/*  if ((b_PortValue & 4) == 4) */
881
882						/***********************/
883						/* Test if error occur */
884						/***********************/
885
886						if (i_ReturnValue >= 0) {
887
888							/* if(data[1]) { */
889
890							switch (b_PortOnOFF) {
891								/*********************************/
892								/* Test if set Port ON                   */
893								/*********************************/
894
895							case APCI1710_ON:
896
897								/*********************************/
898								/* Test if output memory enabled */
899								/*********************************/
900
901								if (devpriv->
902									s_ModuleInfo
903									[b_ModulNbr].
904									s_DigitalIOInfo.
905									b_OutputMemoryEnabled
906									== 1) {
907									dw_WriteValue
908										=
909										devpriv->
910										s_ModuleInfo
911										[b_ModulNbr].
912										s_DigitalIOInfo.
913										dw_OutputMemory
914										|
915										b_PortValue;
916
917									devpriv->
918										s_ModuleInfo
919										[b_ModulNbr].
920										s_DigitalIOInfo.
921										dw_OutputMemory
922										=
923										dw_WriteValue;
924								} else {
925									dw_WriteValue
926										=
927										b_PortValue;
928								}
929								break;
930
931								/*  If Set PORT  OFF */
932							case APCI1710_OFF:
933
934			   /*********************************/
935								/* Test if output memory enabled */
936		       /*********************************/
937
938								if (devpriv->
939									s_ModuleInfo
940									[b_ModulNbr].
941									s_DigitalIOInfo.
942									b_OutputMemoryEnabled
943									== 1) {
944									dw_WriteValue
945										=
946										devpriv->
947										s_ModuleInfo
948										[b_ModulNbr].
949										s_DigitalIOInfo.
950										dw_OutputMemory
951										&
952										(0xFFFFFFFFUL
953										-
954										b_PortValue);
955
956									devpriv->
957										s_ModuleInfo
958										[b_ModulNbr].
959										s_DigitalIOInfo.
960										dw_OutputMemory
961										=
962										dw_WriteValue;
963								} else {
964									/*****************************/
965									/* Digital Output Memory OFF */
966									/*****************************/
967
968									i_ReturnValue
969										=
970										-8;
971								}
972							}	/*  switch */
973
974							/*******************/
975							/* Write the value */
976							/*******************/
977
978							/* OUTPDW (ps_APCI1710Variable->
979							 * s_Board [b_BoardHandle].
980							 * s_BoardInfos.
981							 * ui_Address + (64 * b_ModulNbr),
982							 * dw_WriteValue); */
983
984							outl(dw_WriteValue,
985								devpriv->
986								s_BoardInfos.
987								ui_Address +
988								(64 * b_ModulNbr));
989						}
990					} else {
991						/**********************/
992						/* Output value wrong */
993						/**********************/
994
995						i_ReturnValue = -4;
996					}
997				} else {
998					/*******************************/
999					/* Digital I/O not initialised */
1000					/*******************************/
1001
1002					i_ReturnValue = -5;
1003				}
1004			} else {
1005	      /******************************************/
1006				/* The module is not a digital I/O module */
1007	      /******************************************/
1008
1009				i_ReturnValue = -3;
1010			}
1011		} else {
1012	   /***********************/
1013			/* Module number error */
1014	   /***********************/
1015
1016			i_ReturnValue = -2;
1017		}
1018		break;
1019
1020	default:
1021		i_ReturnValue = -9;
1022		DPRINTK("NO INPUT/OUTPUT specified\n");
1023	}			/* switch INPUT / OUTPUT */
1024	return (i_ReturnValue);
1025}
1026