4 Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
10 Fax: +49(0)7223/9493-92
11 http://www.addi-data-com
14 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
16 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 You shoud also find the complete GPL in the COPYING file accompanying this source code.
26 +-----------------------------------------------------------------------+
27 | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
28 +-----------------------------------------------------------------------+
29 | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
30 | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
31 +-----------------------------------------------------------------------+
32 | Project : API APCI1710 | Compiler : gcc |
33 | Module name : Inp_CPT.C | Version : 2.96 |
34 +-------------------------------+---------------------------------------+
35 | Project manager: Eric Stolz | Date : 02/12/2002 |
36 +-----------------------------------------------------------------------+
37 | Description : APCI-1710 pulse encoder module |
40 +-----------------------------------------------------------------------+
42 +-----------------------------------------------------------------------+
43 | Date | Author | Description of updates |
44 +----------+-----------+------------------------------------------------+
46 |----------|-----------|------------------------------------------------|
47 | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
49 +-----------------------------------------------------------------------+
53 +----------------------------------------------------------------------------+
55 +----------------------------------------------------------------------------+
58 #include "APCI1710_Inp_cpt.h"
61 +----------------------------------------------------------------------------+
62 | Function Name : _INT_ i_APCI1710_InitPulseEncoder |
63 | (BYTE_ b_BoardHandle, |
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. |
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 |
82 | BYTE_ b_InputLevelSelection : Input level selection |
84 | 0 : Set pulse encoder|
87 | 1 : Set pulse encoder|
90 | BYTE_ b_TriggerOutputAction : Digital TRIGGER output |
93 | 1 : Set the trigger |
99 | 2 : Set the trigger |
105 | ULONG_ ul_StartValue : Pulse encoder start value|
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];
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 +----------------------------------------------------------------------------+
126 INT
i_APCI1710_InsnConfigInitPulseEncoder(struct comedi_device
* dev
,
127 struct comedi_subdevice
* s
, struct comedi_insn
* insn
, unsigned int * data
)
129 INT i_ReturnValue
= 0;
130 DWORD dw_IntRegister
;
133 BYTE b_PulseEncoderNbr
;
134 BYTE b_InputLevelSelection
;
135 BYTE b_TriggerOutputAction
;
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];
144 i_ReturnValue
= insn
->n
;
146 /***********************************/
147 /* Test the selected module number */
148 /***********************************/
150 if (b_ModulNbr
<= 3) {
151 /*************************/
152 /* Test if pulse encoder */
153 /*************************/
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 /******************************************/
163 if (b_PulseEncoderNbr
<= 3) {
164 /************************/
165 /* Test the input level */
166 /************************/
168 if ((b_InputLevelSelection
== 0)
169 || (b_InputLevelSelection
== 1)) {
170 /*******************************************/
171 /* Test the ouput TRIGGER action selection */
172 /*******************************************/
174 if ((b_TriggerOutputAction
<= 2)
175 || (b_PulseEncoderNbr
> 0)) {
176 if (ul_StartValue
> 1) {
185 /***********************/
186 /* Set the start value */
187 /***********************/
197 /***********************/
198 /* Set the input level */
199 /***********************/
203 s_PulseEncoderModuleInfo
.
208 s_PulseEncoderModuleInfo
.
211 (1UL << (8 + b_PulseEncoderNbr
)))) | ((1UL & (~b_InputLevelSelection
)) << (8 + b_PulseEncoderNbr
));
213 /*******************************/
214 /* Test if output trigger used */
215 /*******************************/
217 if ((b_TriggerOutputAction
> 0) && (b_PulseEncoderNbr
> 1)) {
218 /****************************/
219 /* Enable the output action */
220 /****************************/
225 s_PulseEncoderModuleInfo
.
231 s_PulseEncoderModuleInfo
.
234 << (4 + b_PulseEncoderNbr
));
236 /*********************************/
237 /* Set the output TRIGGER action */
238 /*********************************/
243 s_PulseEncoderModuleInfo
.
249 s_PulseEncoderModuleInfo
.
254 (1UL << (12 + b_PulseEncoderNbr
)))) | ((1UL & (b_TriggerOutputAction
- 1)) << (12 + b_PulseEncoderNbr
));
256 /*****************************/
257 /* Disable the output action */
258 /*****************************/
263 s_PulseEncoderModuleInfo
.
269 s_PulseEncoderModuleInfo
.
274 (1UL << (4 + b_PulseEncoderNbr
)));
277 /*************************/
278 /* Set the configuration */
279 /*************************/
284 s_PulseEncoderModuleInfo
.
295 s_PulseEncoderModuleInfo
.
301 /**************************************/
302 /* Pulse encoder start value is wrong */
303 /**************************************/
305 DPRINTK("Pulse encoder start value is wrong\n");
309 /****************************************************/
310 /* Digital TRIGGER output action selection is wrong */
311 /****************************************************/
313 DPRINTK("Digital TRIGGER output action selection is wrong\n");
317 /**********************************/
318 /* Input level selection is wrong */
319 /**********************************/
321 DPRINTK("Input level selection is wrong\n");
325 /************************************/
326 /* Pulse encoder selection is wrong */
327 /************************************/
329 DPRINTK("Pulse encoder selection is wrong\n");
333 /********************************************/
334 /* The module is not a pulse encoder module */
335 /********************************************/
337 DPRINTK("The module is not a pulse encoder module\n");
341 /********************************************/
342 /* The module is not a pulse encoder module */
343 /********************************************/
345 DPRINTK("The module is not a pulse encoder module\n");
349 return (i_ReturnValue
);
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 |
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 |
373 | BYTE_ b_CycleSelection : APCI1710_CONTINUOUS: |
375 | counting value is set|
376 | on "0", the pulse |
378 | start value after |
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 |
389 | interrupts are used or |
392 | Interrupts are enabled |
393 | APCI1710_DISABLE: |
394 | Interrupts are disabled
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 +----------------------------------------------------------------------------+
417 INT
i_APCI1710_InsnWriteEnableDisablePulseEncoder(struct comedi_device
* dev
,
418 struct comedi_subdevice
* s
, struct comedi_insn
* insn
, unsigned int * data
)
420 INT i_ReturnValue
= 0;
422 BYTE b_PulseEncoderNbr
;
423 BYTE b_CycleSelection
;
424 BYTE b_InterruptHandling
;
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];
434 /***********************************/
435 /* Test the selected module number */
436 /***********************************/
438 if (b_ModulNbr
<= 3) {
439 /******************************************/
440 /* Test the selected pulse encoder number */
441 /******************************************/
443 if (b_PulseEncoderNbr
<= 3) {
444 /*************************************/
445 /* Test if pulse encoder initialised */
446 /*************************************/
448 if (devpriv
->s_ModuleInfo
[b_ModulNbr
].
449 s_PulseEncoderModuleInfo
.
450 s_PulseEncoderInfo
[b_PulseEncoderNbr
].
451 b_PulseEncoderInit
== 1) {
454 case APCI1710_ENABLE
:
455 /****************************/
456 /* Test the cycle selection */
457 /****************************/
459 if (b_CycleSelection
==
461 || b_CycleSelection
==
463 /*******************************/
464 /* Test the interrupt handling */
465 /*******************************/
467 if (b_InterruptHandling
==
469 || b_InterruptHandling
470 == APCI1710_DISABLE
) {
471 /******************************/
472 /* Test if interrupt not used */
473 /******************************/
475 if (b_InterruptHandling
479 /*************************/
480 /* Disable the interrupt */
481 /*************************/
486 s_PulseEncoderModuleInfo
.
492 s_PulseEncoderModuleInfo
.
497 (1UL << b_PulseEncoderNbr
));
500 /************************/
501 /* Enable the interrupt */
502 /************************/
507 s_PulseEncoderModuleInfo
.
513 s_PulseEncoderModuleInfo
.
518 devpriv
->tsk_Current
= current
; // Save the current process task structure
522 if (i_ReturnValue
>= 0) {
523 /***********************************/
524 /* Enable or disable the interrupt */
525 /***********************************/
530 s_PulseEncoderModuleInfo
.
538 /****************************/
539 /* Enable the pulse encoder */
540 /****************************/
544 s_PulseEncoderModuleInfo
.
550 s_PulseEncoderModuleInfo
.
556 /**********************/
557 /* Set the cycle mode */
558 /**********************/
563 s_PulseEncoderModuleInfo
.
569 s_PulseEncoderModuleInfo
.
574 (1 << (b_PulseEncoderNbr
+ 4)))) | ((b_CycleSelection
& 1UL) << (4 + b_PulseEncoderNbr
));
576 /****************************/
577 /* Enable the pulse encoder */
578 /****************************/
583 s_PulseEncoderModuleInfo
.
592 /************************************/
593 /* Interrupt handling mode is wrong */
594 /************************************/
596 DPRINTK("Interrupt handling mode is wrong\n");
600 /*********************************/
601 /* Cycle selection mode is wrong */
602 /*********************************/
604 DPRINTK("Cycle selection mode is wrong\n");
609 case APCI1710_DISABLE
:
610 devpriv
->s_ModuleInfo
[b_ModulNbr
].
611 s_PulseEncoderModuleInfo
.
614 s_ModuleInfo
[b_ModulNbr
].
615 s_PulseEncoderModuleInfo
.
618 (1UL << b_PulseEncoderNbr
));
620 /*****************************/
621 /* Disable the pulse encoder */
622 /*****************************/
624 outl(devpriv
->s_ModuleInfo
[b_ModulNbr
].
625 s_PulseEncoderModuleInfo
.
627 devpriv
->s_BoardInfos
.
635 /*********************************/
636 /* Pulse encoder not initialised */
637 /*********************************/
639 DPRINTK("Pulse encoder not initialised\n");
643 /************************************/
644 /* Pulse encoder selection is wrong */
645 /************************************/
647 DPRINTK("Pulse encoder selection is wrong\n");
651 /*****************************/
652 /* Module selection is wrong */
653 /*****************************/
655 DPRINTK("Module selection is wrong\n");
659 return (i_ReturnValue
);
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 |
674 +----------------------------------------------------------------------------+
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 |
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 |
687 APCI1710_PULSEENCODER_WRITE
688 data[2] ULONG_ ul_WriteValue : 32-bit value to be |
690 +----------------------------------------------------------------------------+
691 | Output Parameters : PBYTE_ pb_Status : Pulse encoder status. |
692 | 0 : No 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 +----------------------------------------------------------------------------+
705 /*_INT_ i_APCI1710_ReadPulseEncoderStatus (BYTE_ b_BoardHandle,
707 BYTE_ b_PulseEncoderNbr,
711 INT
i_APCI1710_InsnBitsReadWritePulseEncoder(struct comedi_device
* dev
,
712 struct comedi_subdevice
* s
, struct comedi_insn
* insn
, unsigned int * data
)
714 INT i_ReturnValue
= 0;
715 DWORD dw_StatusRegister
;
717 BYTE b_PulseEncoderNbr
;
720 PULONG pul_ReadValue
;
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];
730 /***********************************/
731 /* Test the selected module number */
732 /***********************************/
734 if (b_ModulNbr
<= 3) {
735 /******************************************/
736 /* Test the selected pulse encoder number */
737 /******************************************/
739 if (b_PulseEncoderNbr
<= 3) {
740 /*************************************/
741 /* Test if pulse encoder initialised */
742 /*************************************/
744 if (devpriv
->s_ModuleInfo
[b_ModulNbr
].
745 s_PulseEncoderModuleInfo
.
746 s_PulseEncoderInfo
[b_PulseEncoderNbr
].
747 b_PulseEncoderInit
== 1) {
750 case APCI1710_PULSEENCODER_READ
:
751 /****************************/
752 /* Read the status register */
753 /****************************/
756 inl(devpriv
->s_BoardInfos
.
760 devpriv
->s_ModuleInfo
[b_ModulNbr
].
761 s_PulseEncoderModuleInfo
.
762 dw_StatusRegister
= devpriv
->
763 s_ModuleInfo
[b_ModulNbr
].
764 s_PulseEncoderModuleInfo
.
770 s_ModuleInfo
[b_ModulNbr
].
771 s_PulseEncoderModuleInfo
.
772 dw_StatusRegister
>> (1 +
773 b_PulseEncoderNbr
)) & 1;
775 devpriv
->s_ModuleInfo
[b_ModulNbr
].
776 s_PulseEncoderModuleInfo
.
779 s_ModuleInfo
[b_ModulNbr
].
780 s_PulseEncoderModuleInfo
.
782 (0xFFFFFFFFUL
- (1 << (1 +
783 b_PulseEncoderNbr
)));
790 inl(devpriv
->s_BoardInfos
.
792 (4 * b_PulseEncoderNbr
) +
796 case APCI1710_PULSEENCODER_WRITE
:
797 ul_WriteValue
= (ULONG
) data
[2];
798 /*******************/
799 /* Write the value */
800 /*******************/
803 devpriv
->s_BoardInfos
.
805 (4 * b_PulseEncoderNbr
) +
810 /*********************************/
811 /* Pulse encoder not initialised */
812 /*********************************/
814 DPRINTK("Pulse encoder not initialised\n");
818 /************************************/
819 /* Pulse encoder selection is wrong */
820 /************************************/
822 DPRINTK("Pulse encoder selection is wrong\n");
826 /*****************************/
827 /* Module selection is wrong */
828 /*****************************/
830 DPRINTK("Module selection is wrong\n");
834 return (i_ReturnValue
);
837 INT
i_APCI1710_InsnReadInterruptPulseEncoder(struct comedi_device
* dev
,
838 struct comedi_subdevice
* s
, struct comedi_insn
* insn
, unsigned int * data
)
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
;
851 /***************************/
852 /* Increment the read FIFO */
853 /***************************/
855 devpriv
->s_InterruptParameters
.
857 s_InterruptParameters
.ui_Read
+ 1) % APCI1710_SAVE_INTERRUPT
;