APCI1710_Inp_cpt.c revision 71b5f4f11971dea972832ad63a994c7e5b45db6b
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 : Inp_CPT.C       | Version  : 2.96                       |
34  +-------------------------------+---------------------------------------+
35  | Project manager: Eric Stolz   | Date     :  02/12/2002                |
36  +-----------------------------------------------------------------------+
37  | Description :   APCI-1710 pulse encoder module                        |
38  |                                                                       |
39  |                                                                       |
40  +-----------------------------------------------------------------------+
41  |                             UPDATES                                   |
42  +-----------------------------------------------------------------------+
43  |   Date   |   Author  |          Description of updates                |
44  +----------+-----------+------------------------------------------------+
45  |          |           |                                                |
46  |----------|-----------|------------------------------------------------|
47  | 08/05/00 | Guinot C  | - 0400/0228 All Function in RING 0             |
48  |          |           |   available                                    |
49  +-----------------------------------------------------------------------+
50*/
51
52/*
53+----------------------------------------------------------------------------+
54|                               Included files                               |
55+----------------------------------------------------------------------------+
56*/
57
58#include "APCI1710_Inp_cpt.h"
59
60/*
61+----------------------------------------------------------------------------+
62| Function Name     : _INT_ i_APCI1710_InitPulseEncoder                      |
63|                               (BYTE_          b_BoardHandle,               |
64|                                BYTE_          b_ModulNbr,                  |
65|                                BYTE_          b_PulseEncoderNbr,           |
66|                                BYTE_          b_InputLevelSelection,       |
67|                                BYTE_          b_TriggerOutputAction,       |
68|                                ULONG_        ul_StartValue)                |
69+----------------------------------------------------------------------------+
70| Task              : Configure the pulse encoder operating mode selected via|
71|                     b_ModulNbr and b_PulseEncoderNbr. The pulse encoder    |
72|                     after each pulse decrement the counter value from 1.   |
73|                                                                            |
74|                     You must calling this function be for you call any     |
75|                     other function witch access of pulse encoders.         |
76+----------------------------------------------------------------------------+
77| Input Parameters  : BYTE_ b_BoardHandle         : Handle of board APCI-1710|
78|                     BYTE_ b_ModulNbr            : Module number to         |
79|                                                   configure (0 to 3)       |
80|                     BYTE_ b_PulseEncoderNbr     : Pulse encoder selection  |
81|                                                   (0 to 3)                 |
82|                     BYTE_ b_InputLevelSelection : Input level selection    |
83|                                                   (0 or 1)                 |
84|                                                       0 : Set pulse encoder|
85|                                                           count the the low|
86|                                                           level pulse.     |
87|                                                       1 : Set pulse encoder|
88|                                                           count the the    |
89|                                                           high level pulse.|
90|                     BYTE_ b_TriggerOutputAction : Digital TRIGGER output   |
91|                                                   action                   |
92|                                                       0 : No action        |
93|                                                       1 : Set the trigger  |
94|                                                           output to "1"    |
95|                                                           (high) after the |
96|                                                           passage from 1 to|
97|                                                           0 from pulse     |
98|                                                           encoder.         |
99|                                                       2 : Set the trigger  |
100|                                                           output to "0"    |
101|                                                           (low) after the  |
102|                                                           passage from 1 to|
103|                                                           0 from pulse     |
104|                                                           encoder          |
105|                     ULONG_ ul_StartValue        : Pulse encoder start value|
106|                                                   (1 to 4294967295)
107	b_ModulNbr				=(BYTE) CR_AREF(insn->chanspec);
108	b_PulseEncoderNbr		=(BYTE) data[0];
109	b_InputLevelSelection	=(BYTE) data[1];
110	b_TriggerOutputAction	=(BYTE) data[2];
111	ul_StartValue			=(ULONG) data[3];
112       |
113+----------------------------------------------------------------------------+
114| Output Parameters : -                                                      |
115+----------------------------------------------------------------------------+
116| Return Value      : 0: No error                                            |
117|                    -1: The handle parameter of the board is wrong          |
118|                    -2: The module is not a pulse encoder module            |
119|                    -3: Pulse encoder selection is wrong                    |
120|                    -4: Input level selection is wrong                      |
121|                    -5: Digital TRIGGER output action selection is wrong    |
122|                    -6: Pulse encoder start value is wrong                  |
123+----------------------------------------------------------------------------+
124*/
125
126INT i_APCI1710_InsnConfigInitPulseEncoder(struct comedi_device * dev,
127	comedi_subdevice * s, comedi_insn * insn, unsigned int * data)
128{
129	INT i_ReturnValue = 0;
130	DWORD dw_IntRegister;
131
132	BYTE b_ModulNbr;
133	BYTE b_PulseEncoderNbr;
134	BYTE b_InputLevelSelection;
135	BYTE b_TriggerOutputAction;
136	ULONG ul_StartValue;
137
138	b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
139	b_PulseEncoderNbr = (BYTE) data[0];
140	b_InputLevelSelection = (BYTE) data[1];
141	b_TriggerOutputAction = (BYTE) data[2];
142	ul_StartValue = (ULONG) data[3];
143
144	i_ReturnValue = insn->n;
145
146	/***********************************/
147	/* Test the selected module number */
148	/***********************************/
149
150	if (b_ModulNbr <= 3) {
151	   /*************************/
152		/* Test if pulse encoder */
153	   /*************************/
154
155		if ((devpriv->s_BoardInfos.
156				dw_MolduleConfiguration[b_ModulNbr] &
157				APCI1710_PULSE_ENCODER) ==
158			APCI1710_PULSE_ENCODER) {
159	      /******************************************/
160			/* Test the selected pulse encoder number */
161	      /******************************************/
162
163			if (b_PulseEncoderNbr <= 3) {
164		 /************************/
165				/* Test the input level */
166		 /************************/
167
168				if ((b_InputLevelSelection == 0)
169					|| (b_InputLevelSelection == 1)) {
170		    /*******************************************/
171					/* Test the ouput TRIGGER action selection */
172		    /*******************************************/
173
174					if ((b_TriggerOutputAction <= 2)
175						|| (b_PulseEncoderNbr > 0)) {
176						if (ul_StartValue > 1) {
177
178							dw_IntRegister =
179								inl(devpriv->
180								s_BoardInfos.
181								ui_Address +
182								20 +
183								(64 * b_ModulNbr));
184
185			  /***********************/
186							/* Set the start value */
187			  /***********************/
188
189							outl(ul_StartValue,
190								devpriv->
191								s_BoardInfos.
192								ui_Address +
193								(b_PulseEncoderNbr
194									* 4) +
195								(64 * b_ModulNbr));
196
197			  /***********************/
198							/* Set the input level */
199			  /***********************/
200							devpriv->
201								s_ModuleInfo
202								[b_ModulNbr].
203								s_PulseEncoderModuleInfo.
204								dw_SetRegister =
205								(devpriv->
206								s_ModuleInfo
207								[b_ModulNbr].
208								s_PulseEncoderModuleInfo.
209								dw_SetRegister &
210								(0xFFFFFFFFUL -
211									(1UL << (8 + b_PulseEncoderNbr)))) | ((1UL & (~b_InputLevelSelection)) << (8 + b_PulseEncoderNbr));
212
213			  /*******************************/
214							/* Test if output trigger used */
215			  /*******************************/
216
217							if ((b_TriggerOutputAction > 0) && (b_PulseEncoderNbr > 1)) {
218			     /****************************/
219								/* Enable the output action */
220			     /****************************/
221
222								devpriv->
223									s_ModuleInfo
224									[b_ModulNbr].
225									s_PulseEncoderModuleInfo.
226									dw_SetRegister
227									=
228									devpriv->
229									s_ModuleInfo
230									[b_ModulNbr].
231									s_PulseEncoderModuleInfo.
232									dw_SetRegister
233									| (1UL
234									<< (4 + b_PulseEncoderNbr));
235
236			     /*********************************/
237								/* Set the output TRIGGER action */
238			     /*********************************/
239
240								devpriv->
241									s_ModuleInfo
242									[b_ModulNbr].
243									s_PulseEncoderModuleInfo.
244									dw_SetRegister
245									=
246									(devpriv->
247									s_ModuleInfo
248									[b_ModulNbr].
249									s_PulseEncoderModuleInfo.
250									dw_SetRegister
251									&
252									(0xFFFFFFFFUL
253										-
254										(1UL << (12 + b_PulseEncoderNbr)))) | ((1UL & (b_TriggerOutputAction - 1)) << (12 + b_PulseEncoderNbr));
255							} else {
256			     /*****************************/
257								/* Disable the output action */
258			     /*****************************/
259
260								devpriv->
261									s_ModuleInfo
262									[b_ModulNbr].
263									s_PulseEncoderModuleInfo.
264									dw_SetRegister
265									=
266									devpriv->
267									s_ModuleInfo
268									[b_ModulNbr].
269									s_PulseEncoderModuleInfo.
270									dw_SetRegister
271									&
272									(0xFFFFFFFFUL
273									-
274									(1UL << (4 + b_PulseEncoderNbr)));
275							}
276
277			  /*************************/
278							/* Set the configuration */
279			  /*************************/
280
281							outl(devpriv->
282								s_ModuleInfo
283								[b_ModulNbr].
284								s_PulseEncoderModuleInfo.
285								dw_SetRegister,
286								devpriv->
287								s_BoardInfos.
288								ui_Address +
289								20 +
290								(64 * b_ModulNbr));
291
292							devpriv->
293								s_ModuleInfo
294								[b_ModulNbr].
295								s_PulseEncoderModuleInfo.
296								s_PulseEncoderInfo
297								[b_PulseEncoderNbr].
298								b_PulseEncoderInit
299								= 1;
300						} else {
301			  /**************************************/
302							/* Pulse encoder start value is wrong */
303			  /**************************************/
304
305							DPRINTK("Pulse encoder start value is wrong\n");
306							i_ReturnValue = -6;
307						}
308					} else {
309		       /****************************************************/
310						/* Digital TRIGGER output action selection is wrong */
311		       /****************************************************/
312
313						DPRINTK("Digital TRIGGER output action selection is wrong\n");
314						i_ReturnValue = -5;
315					}
316				} else {
317		    /**********************************/
318					/* Input level selection is wrong */
319		    /**********************************/
320
321					DPRINTK("Input level selection is wrong\n");
322					i_ReturnValue = -4;
323				}
324			} else {
325		 /************************************/
326				/* Pulse encoder selection is wrong */
327		 /************************************/
328
329				DPRINTK("Pulse encoder selection is wrong\n");
330				i_ReturnValue = -3;
331			}
332		} else {
333	      /********************************************/
334			/* The module is not a pulse encoder module */
335	      /********************************************/
336
337			DPRINTK("The module is not a pulse encoder module\n");
338			i_ReturnValue = -2;
339		}
340	} else {
341	   /********************************************/
342		/* The module is not a pulse encoder module */
343	   /********************************************/
344
345		DPRINTK("The module is not a pulse encoder module\n");
346		i_ReturnValue = -2;
347	}
348
349	return (i_ReturnValue);
350}
351
352/*
353+----------------------------------------------------------------------------+
354| Function Name     : _INT_ i_APCI1710_EnablePulseEncoder                    |
355|                                       (BYTE_  b_BoardHandle,               |
356|                                        BYTE_  b_ModulNbr,                  |
357|                                        BYTE_  b_PulseEncoderNbr,           |
358|                                        BYTE_  b_CycleSelection,            |
359|                                        BYTE_  b_InterruptHandling)         |
360+----------------------------------------------------------------------------+
361| Task              : Enableor disable  the selected pulse encoder (b_PulseEncoderNbr)  |
362|                     from selected module (b_ModulNbr). Each input pulse    |
363|                     decrement the pulse encoder counter value from 1.      |
364|                     If you enabled the interrupt (b_InterruptHandling), a  |
365|                     interrupt is generated when the pulse encoder has run  |
366|                     down.                                                  |
367+----------------------------------------------------------------------------+
368| Input Parameters  : BYTE_   b_BoardHandle       : Handle of board APCI-1710|
369|                     BYTE_   b_ModulNbr          : Module number to         |
370|                                                   configure (0 to 3)       |
371|                     BYTE_   b_PulseEncoderNbr   : Pulse encoder selection  |
372|                                                   (0 to 3)                 |
373|                     BYTE_   b_CycleSelection    : APCI1710_CONTINUOUS:     |
374|                                                       Each time the        |
375|                                                       counting value is set|
376|                                                       on "0", the pulse    |
377|                                                       encoder load the     |
378|                                                       start value after    |
379|                                                       the next pulse.      |
380|                                                   APCI1710_SINGLE:         |
381|                                                       If the counter is set|
382|                                                       on "0", the pulse    |
383|                                                       encoder is stopped.  |
384|                     BYTE_   b_InterruptHandling : Interrupts can be        |
385|                                                   generated, when the pulse|
386|                                                   encoder has run down.    |
387|                                                   With this parameter the  |
388|                                                   user decides if          |
389|                                                   interrupts are used or   |
390|                                                   not.                     |
391|                                                     APCI1710_ENABLE:       |
392|                                                     Interrupts are enabled |
393|                                                     APCI1710_DISABLE:      |
394|                                                     Interrupts are disabled
395
396  	b_ModulNbr			=(BYTE) CR_AREF(insn->chanspec);
397	b_Action			=(BYTE) data[0];
398	b_PulseEncoderNbr	=(BYTE) data[1];
399	b_CycleSelection	=(BYTE) data[2];
400	b_InterruptHandling	=(BYTE) data[3];|
401+----------------------------------------------------------------------------+
402| Output Parameters : -                                                      |
403+----------------------------------------------------------------------------+
404| Return Value      :  0: No error                                           |
405|                     -1: The handle parameter of the board is wrong         |
406|                     -2: Module selection is wrong                          |
407|                     -3: Pulse encoder selection is wrong                   |
408|                     -4: Pulse encoder not initialised.                     |
409|                         See function "i_APCI1710_InitPulseEncoder"         |
410|                     -5: Cycle selection mode is wrong                      |
411|                     -6: Interrupt handling mode is wrong                   |
412|                     -7: Interrupt routine not installed.                   |
413|                         See function "i_APCI1710_SetBoardIntRoutineX"      |
414+----------------------------------------------------------------------------+
415*/
416
417INT i_APCI1710_InsnWriteEnableDisablePulseEncoder(struct comedi_device * dev,
418	comedi_subdevice * s, comedi_insn * insn, unsigned int * data)
419{
420	INT i_ReturnValue = 0;
421	BYTE b_ModulNbr;
422	BYTE b_PulseEncoderNbr;
423	BYTE b_CycleSelection;
424	BYTE b_InterruptHandling;
425	BYTE b_Action;
426
427	i_ReturnValue = insn->n;
428	b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
429	b_Action = (BYTE) data[0];
430	b_PulseEncoderNbr = (BYTE) data[1];
431	b_CycleSelection = (BYTE) data[2];
432	b_InterruptHandling = (BYTE) data[3];
433
434	/***********************************/
435	/* Test the selected module number */
436	/***********************************/
437
438	if (b_ModulNbr <= 3) {
439	   /******************************************/
440		/* Test the selected pulse encoder number */
441	   /******************************************/
442
443		if (b_PulseEncoderNbr <= 3) {
444	      /*************************************/
445			/* Test if pulse encoder initialised */
446	      /*************************************/
447
448			if (devpriv->s_ModuleInfo[b_ModulNbr].
449				s_PulseEncoderModuleInfo.
450				s_PulseEncoderInfo[b_PulseEncoderNbr].
451				b_PulseEncoderInit == 1) {
452				switch (b_Action) {
453
454				case APCI1710_ENABLE:
455		 /****************************/
456					/* Test the cycle selection */
457		 /****************************/
458
459					if (b_CycleSelection ==
460						APCI1710_CONTINUOUS
461						|| b_CycleSelection ==
462						APCI1710_SINGLE) {
463		    /*******************************/
464						/* Test the interrupt handling */
465		    /*******************************/
466
467						if (b_InterruptHandling ==
468							APCI1710_ENABLE
469							|| b_InterruptHandling
470							== APCI1710_DISABLE) {
471		       /******************************/
472							/* Test if interrupt not used */
473		       /******************************/
474
475							if (b_InterruptHandling
476								==
477								APCI1710_DISABLE)
478							{
479			  /*************************/
480								/* Disable the interrupt */
481			  /*************************/
482
483								devpriv->
484									s_ModuleInfo
485									[b_ModulNbr].
486									s_PulseEncoderModuleInfo.
487									dw_SetRegister
488									=
489									devpriv->
490									s_ModuleInfo
491									[b_ModulNbr].
492									s_PulseEncoderModuleInfo.
493									dw_SetRegister
494									&
495									(0xFFFFFFFFUL
496									-
497									(1UL << b_PulseEncoderNbr));
498							} else {
499
500			     /************************/
501								/* Enable the interrupt */
502			     /************************/
503
504								devpriv->
505									s_ModuleInfo
506									[b_ModulNbr].
507									s_PulseEncoderModuleInfo.
508									dw_SetRegister
509									=
510									devpriv->
511									s_ModuleInfo
512									[b_ModulNbr].
513									s_PulseEncoderModuleInfo.
514									dw_SetRegister
515									| (1UL
516									<<
517									b_PulseEncoderNbr);
518								devpriv->tsk_Current = current;	// Save the current process task structure
519
520							}
521
522							if (i_ReturnValue >= 0) {
523			  /***********************************/
524								/* Enable or disable the interrupt */
525			  /***********************************/
526
527								outl(devpriv->
528									s_ModuleInfo
529									[b_ModulNbr].
530									s_PulseEncoderModuleInfo.
531									dw_SetRegister,
532									devpriv->
533									s_BoardInfos.
534									ui_Address
535									+ 20 +
536									(64 * b_ModulNbr));
537
538			  /****************************/
539								/* Enable the pulse encoder */
540			  /****************************/
541								devpriv->
542									s_ModuleInfo
543									[b_ModulNbr].
544									s_PulseEncoderModuleInfo.
545									dw_ControlRegister
546									=
547									devpriv->
548									s_ModuleInfo
549									[b_ModulNbr].
550									s_PulseEncoderModuleInfo.
551									dw_ControlRegister
552									| (1UL
553									<<
554									b_PulseEncoderNbr);
555
556			  /**********************/
557								/* Set the cycle mode */
558			  /**********************/
559
560								devpriv->
561									s_ModuleInfo
562									[b_ModulNbr].
563									s_PulseEncoderModuleInfo.
564									dw_ControlRegister
565									=
566									(devpriv->
567									s_ModuleInfo
568									[b_ModulNbr].
569									s_PulseEncoderModuleInfo.
570									dw_ControlRegister
571									&
572									(0xFFFFFFFFUL
573										-
574										(1 << (b_PulseEncoderNbr + 4)))) | ((b_CycleSelection & 1UL) << (4 + b_PulseEncoderNbr));
575
576			  /****************************/
577								/* Enable the pulse encoder */
578			  /****************************/
579
580								outl(devpriv->
581									s_ModuleInfo
582									[b_ModulNbr].
583									s_PulseEncoderModuleInfo.
584									dw_ControlRegister,
585									devpriv->
586									s_BoardInfos.
587									ui_Address
588									+ 16 +
589									(64 * b_ModulNbr));
590							}
591						} else {
592		       /************************************/
593							/* Interrupt handling mode is wrong */
594		       /************************************/
595
596							DPRINTK("Interrupt handling mode is wrong\n");
597							i_ReturnValue = -6;
598						}
599					} else {
600		    /*********************************/
601						/* Cycle selection mode is wrong */
602		    /*********************************/
603
604						DPRINTK("Cycle selection mode is wrong\n");
605						i_ReturnValue = -5;
606					}
607					break;
608
609				case APCI1710_DISABLE:
610					devpriv->s_ModuleInfo[b_ModulNbr].
611						s_PulseEncoderModuleInfo.
612						dw_ControlRegister =
613						devpriv->
614						s_ModuleInfo[b_ModulNbr].
615						s_PulseEncoderModuleInfo.
616						dw_ControlRegister &
617						(0xFFFFFFFFUL -
618						(1UL << b_PulseEncoderNbr));
619
620		 /*****************************/
621					/* Disable the pulse encoder */
622		 /*****************************/
623
624					outl(devpriv->s_ModuleInfo[b_ModulNbr].
625						s_PulseEncoderModuleInfo.
626						dw_ControlRegister,
627						devpriv->s_BoardInfos.
628						ui_Address + 16 +
629						(64 * b_ModulNbr));
630
631					break;
632				}	// switch End
633
634			} else {
635		 /*********************************/
636				/* Pulse encoder not initialised */
637		 /*********************************/
638
639				DPRINTK("Pulse encoder not initialised\n");
640				i_ReturnValue = -4;
641			}
642		} else {
643	      /************************************/
644			/* Pulse encoder selection is wrong */
645	      /************************************/
646
647			DPRINTK("Pulse encoder selection is wrong\n");
648			i_ReturnValue = -3;
649		}
650	} else {
651	   /*****************************/
652		/* Module selection is wrong */
653	   /*****************************/
654
655		DPRINTK("Module selection is wrong\n");
656		i_ReturnValue = -2;
657	}
658
659	return (i_ReturnValue);
660}
661
662/*
663+----------------------------------------------------------------------------+
664| Function Name     : _INT_ i_APCI1710_ReadPulseEncoderStatus                |
665|                                       (BYTE_  b_BoardHandle,               |
666|                                        BYTE_  b_ModulNbr,                  |
667|                                        BYTE_  b_PulseEncoderNbr,           |
668|                                        PBYTE_ pb_Status)                   |
669+----------------------------------------------------------------------------+
670| Task    APCI1710_PULSEENCODER_READ          : Reads the pulse encoder status
671											and valuefrom selected pulse     |
672|                     encoder (b_PulseEncoderNbr) from selected module       |
673|                     (b_ModulNbr).                                          |
674+----------------------------------------------------------------------------+
675	BYTE   b_Type; data[0]
676   APCI1710_PULSEENCODER_WRITE
677 Writes a 32-bit value (ul_WriteValue) into the selected|
678|                     pulse encoder (b_PulseEncoderNbr) from selected module |
679|                     (b_ModulNbr). This operation set the new start pulse   |
680|                     encoder value.
681 APCI1710_PULSEENCODER_READ
682| Input Parameters  : BYTE_   b_BoardHandle       : Handle of board APCI-1710|
683|            CRAREF()         BYTE_   b_ModulNbr          : Module number to         |
684|                                                   configure (0 to 3)       |
685|              data[1]       BYTE_   b_PulseEncoderNbr   : Pulse encoder selection  |
686|                                                   (0 to 3)
687   APCI1710_PULSEENCODER_WRITE
688				data[2]		ULONG_ ul_WriteValue        : 32-bit value to be       |
689|                                                   written             |
690+----------------------------------------------------------------------------+
691| Output Parameters : PBYTE_ pb_Status            : Pulse encoder status.    |
692|                                                       0 : No overflow occur|
693|                                                       1 : Overflow occur
694						PULONG_ pul_ReadValue       : Pulse encoder value      |  |
695+----------------------------------------------------------------------------+
696| Return Value      :  0: No error                                           |
697|                     -1: The handle parameter of the board is wrong         |
698|                     -2: Module selection is wrong                          |
699|                     -3: Pulse encoder selection is wrong                   |
700|                     -4: Pulse encoder not initialised.                     |
701|                         See function "i_APCI1710_InitPulseEncoder"         |
702+----------------------------------------------------------------------------+
703*/
704
705/*_INT_   i_APCI1710_ReadPulseEncoderStatus       (BYTE_   b_BoardHandle,
706						 BYTE_   b_ModulNbr,
707						 BYTE_   b_PulseEncoderNbr,
708
709   						 PBYTE_ pb_Status)
710						 */
711INT i_APCI1710_InsnBitsReadWritePulseEncoder(struct comedi_device * dev,
712	comedi_subdevice * s, comedi_insn * insn, unsigned int * data)
713{
714	INT i_ReturnValue = 0;
715	DWORD dw_StatusRegister;
716	BYTE b_ModulNbr;
717	BYTE b_PulseEncoderNbr;
718	PBYTE pb_Status;
719	BYTE b_Type;
720	PULONG pul_ReadValue;
721	ULONG ul_WriteValue;
722
723	i_ReturnValue = insn->n;
724	b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
725	b_Type = (BYTE) data[0];
726	b_PulseEncoderNbr = (BYTE) data[1];
727	pb_Status = (PBYTE) & data[0];
728	pul_ReadValue = (PULONG) & data[1];
729
730	/***********************************/
731	/* Test the selected module number */
732	/***********************************/
733
734	if (b_ModulNbr <= 3) {
735	   /******************************************/
736		/* Test the selected pulse encoder number */
737	   /******************************************/
738
739		if (b_PulseEncoderNbr <= 3) {
740	      /*************************************/
741			/* Test if pulse encoder initialised */
742	      /*************************************/
743
744			if (devpriv->s_ModuleInfo[b_ModulNbr].
745				s_PulseEncoderModuleInfo.
746				s_PulseEncoderInfo[b_PulseEncoderNbr].
747				b_PulseEncoderInit == 1) {
748
749				switch (b_Type) {
750				case APCI1710_PULSEENCODER_READ:
751		 /****************************/
752					/* Read the status register */
753		 /****************************/
754
755					dw_StatusRegister =
756						inl(devpriv->s_BoardInfos.
757						ui_Address + 16 +
758						(64 * b_ModulNbr));
759
760					devpriv->s_ModuleInfo[b_ModulNbr].
761						s_PulseEncoderModuleInfo.
762						dw_StatusRegister = devpriv->
763						s_ModuleInfo[b_ModulNbr].
764						s_PulseEncoderModuleInfo.
765						dw_StatusRegister |
766						dw_StatusRegister;
767
768					*pb_Status =
769						(BYTE) (devpriv->
770						s_ModuleInfo[b_ModulNbr].
771						s_PulseEncoderModuleInfo.
772						dw_StatusRegister >> (1 +
773							b_PulseEncoderNbr)) & 1;
774
775					devpriv->s_ModuleInfo[b_ModulNbr].
776						s_PulseEncoderModuleInfo.
777						dw_StatusRegister =
778						devpriv->
779						s_ModuleInfo[b_ModulNbr].
780						s_PulseEncoderModuleInfo.
781						dw_StatusRegister &
782						(0xFFFFFFFFUL - (1 << (1 +
783								b_PulseEncoderNbr)));
784
785		 /******************/
786					/* Read the value */
787		 /******************/
788
789					*pul_ReadValue =
790						inl(devpriv->s_BoardInfos.
791						ui_Address +
792						(4 * b_PulseEncoderNbr) +
793						(64 * b_ModulNbr));
794					break;
795
796				case APCI1710_PULSEENCODER_WRITE:
797					ul_WriteValue = (ULONG) data[2];
798			/*******************/
799					/* Write the value */
800			/*******************/
801
802					outl(ul_WriteValue,
803						devpriv->s_BoardInfos.
804						ui_Address +
805						(4 * b_PulseEncoderNbr) +
806						(64 * b_ModulNbr));
807
808				}	//end of switch
809			} else {
810		 /*********************************/
811				/* Pulse encoder not initialised */
812		 /*********************************/
813
814				DPRINTK("Pulse encoder not initialised\n");
815				i_ReturnValue = -4;
816			}
817		} else {
818	      /************************************/
819			/* Pulse encoder selection is wrong */
820	      /************************************/
821
822			DPRINTK("Pulse encoder selection is wrong\n");
823			i_ReturnValue = -3;
824		}
825	} else {
826	   /*****************************/
827		/* Module selection is wrong */
828	   /*****************************/
829
830		DPRINTK("Module selection is wrong\n");
831		i_ReturnValue = -2;
832	}
833
834	return (i_ReturnValue);
835}
836
837INT i_APCI1710_InsnReadInterruptPulseEncoder(struct comedi_device * dev,
838	comedi_subdevice * s, comedi_insn * insn, unsigned int * data)
839{
840
841	data[0] = devpriv->s_InterruptParameters.
842		s_FIFOInterruptParameters[devpriv->
843		s_InterruptParameters.ui_Read].b_OldModuleMask;
844	data[1] = devpriv->s_InterruptParameters.
845		s_FIFOInterruptParameters[devpriv->
846		s_InterruptParameters.ui_Read].ul_OldInterruptMask;
847	data[2] = devpriv->s_InterruptParameters.
848		s_FIFOInterruptParameters[devpriv->
849		s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
850
851	/***************************/
852	/* Increment the read FIFO */
853	/***************************/
854
855	devpriv->s_InterruptParameters.
856		ui_Read = (devpriv->
857		s_InterruptParameters.ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
858
859	return insn->n;
860
861}
862