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 | (unsigned char_ b_BoardHandle, |
64 | unsigned char_ b_ModulNbr, |
65 | unsigned char_ b_PulseEncoderNbr, |
66 | unsigned char_ b_InputLevelSelection, |
67 | unsigned char_ 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 : unsigned char_ b_BoardHandle : Handle of board APCI-1710|
78 | unsigned char_ b_ModulNbr : Module number to |
79 | configure (0 to 3) |
80 | unsigned char_ b_PulseEncoderNbr : Pulse encoder selection |
82 | unsigned char_ b_InputLevelSelection : Input level selection |
84 | 0 : Set pulse encoder|
87 | 1 : Set pulse encoder|
90 | unsigned char_ 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 =(unsigned char) CR_AREF(insn->chanspec);
108 b_PulseEncoderNbr =(unsigned char) data[0];
109 b_InputLevelSelection =(unsigned char) data[1];
110 b_TriggerOutputAction =(unsigned char) data[2];
111 ul_StartValue =(unsigned int) 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 unsigned int dw_IntRegister;
132 unsigned char b_ModulNbr;
133 unsigned char b_PulseEncoderNbr;
134 unsigned char b_InputLevelSelection;
135 unsigned char b_TriggerOutputAction;
136 unsigned int ul_StartValue;
138 b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
139 b_PulseEncoderNbr = (unsigned char) data[0];
140 b_InputLevelSelection = (unsigned char) data[1];
141 b_TriggerOutputAction = (unsigned char) data[2];
142 ul_StartValue = (unsigned int) 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 | (unsigned char_ b_BoardHandle, |
356 | unsigned char_ b_ModulNbr, |
357 | unsigned char_ b_PulseEncoderNbr, |
358 | unsigned char_ b_CycleSelection, |
359 | unsigned char_ 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 : unsigned char_ b_BoardHandle : Handle of board APCI-1710|
369 | unsigned char_ b_ModulNbr : Module number to |
370 | configure (0 to 3) |
371 | unsigned char_ b_PulseEncoderNbr : Pulse encoder selection |
373 | unsigned char_ 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 | unsigned char_ 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 =(unsigned char) CR_AREF(insn->chanspec);
397 b_Action =(unsigned char) data[0];
398 b_PulseEncoderNbr =(unsigned char) data[1];
399 b_CycleSelection =(unsigned char) data[2];
400 b_InterruptHandling =(unsigned char) 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;
421 unsigned char b_ModulNbr;
422 unsigned char b_PulseEncoderNbr;
423 unsigned char b_CycleSelection;
424 unsigned char b_InterruptHandling;
425 unsigned char b_Action;
427 i_ReturnValue = insn->n;
428 b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
429 b_Action = (unsigned char) data[0];
430 b_PulseEncoderNbr = (unsigned char) data[1];
431 b_CycleSelection = (unsigned char) data[2];
432 b_InterruptHandling = (unsigned char) 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 | (unsigned char_ b_BoardHandle, |
666 | unsigned char_ b_ModulNbr, |
667 | unsigned char_ b_PulseEncoderNbr, |
668 | unsigned char *_ 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 +----------------------------------------------------------------------------+
675 unsigned char 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 |
681 APCI1710_PULSEENCODER_READ
682 | Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710|
683 | CRAREF() unsigned char_ b_ModulNbr : Module number to |
684 | configure (0 to 3) |
685 | data[1] unsigned char_ b_PulseEncoderNbr : Pulse encoder selection |
687 APCI1710_PULSEENCODER_WRITE
688 data[2] ULONG_ ul_WriteValue : 32-bit value to be |
690 +----------------------------------------------------------------------------+
691 | Output Parameters : unsigned char *_ 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 (unsigned char_ b_BoardHandle,
706 unsigned char_ b_ModulNbr,
707 unsigned char_ b_PulseEncoderNbr,
709 unsigned char *_ pb_Status)
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 unsigned int dw_StatusRegister;
716 unsigned char b_ModulNbr;
717 unsigned char b_PulseEncoderNbr;
718 unsigned char *pb_Status;
719 unsigned char b_Type;
720 unsigned int *pul_ReadValue;
721 unsigned int ul_WriteValue;
723 i_ReturnValue = insn->n;
724 b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
725 b_Type = (unsigned char) data[0];
726 b_PulseEncoderNbr = (unsigned char) data[1];
727 pb_Status = (unsigned char *) &data[0];
728 pul_ReadValue = (unsigned int *) &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.
769 (unsigned char) (devpriv->
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 = (unsigned int) data[2];
798 /*******************/
799 /* Write the value */
800 /*******************/
803 devpriv->s_BoardInfos.
805 (4 * b_PulseEncoderNbr) +
808 } /* end of switch */
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;