Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
APCI1710_Chrono.c
Go to the documentation of this file.
1 
24 /*
25 
26  +-----------------------------------------------------------------------+
27  | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
28  +-----------------------------------------------------------------------+
29  | Tel : +49 (0) 7223/9493-0 | email : [email protected] |
30  | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
31  +-----------------------------------------------------------------------+
32  | Project : API APCI1710 | Compiler : gcc |
33  | Module name : CHRONO.C | Version : 2.96 |
34  +-------------------------------+---------------------------------------+
35  | Project manager: Eric Stolz | Date : 02/12/2002 |
36  +-----------------------------------------------------------------------+
37  | Description : APCI-1710 chronometer module |
38  | |
39  | |
40  +-----------------------------------------------------------------------+
41  | UPDATES |
42  +-----------------------------------------------------------------------+
43  | Date | Author | Description of updates |
44  +----------+-----------+------------------------------------------------+
45  | 29/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_Chrono.h"
61 
62 /*
63 +----------------------------------------------------------------------------+
64 | Function Name : _INT_ i_APCI1710_InitChrono |
65 | (unsigned char_ b_BoardHandle, |
66 | unsigned char_ b_ModulNbr, |
67 | unsigned char_ b_ChronoMode, |
68 | unsigned char_ b_PCIInputClock, |
69 | unsigned char_ b_TimingUnit, |
70 | ULONG_ ul_TimingInterval, |
71 | PULONG_ pul_RealTimingInterval)
72 
73 +----------------------------------------------------------------------------+
74 | Task : Configure the chronometer operating mode (b_ChronoMode)|
75 | from selected module (b_ModulNbr). |
76 | The ul_TimingInterval and ul_TimingUnit determine the |
77 | timing base for the measurement. |
78 | The pul_RealTimingInterval return the real timing |
79 | value. You must calling this function be for you call |
80 | any other function witch access of the chronometer. |
81 | |
82 | Witch this functionality from the APCI-1710 you have |
83 | the possibility to measure the timing witch two event. |
84 | |
85 | The mode 0 and 1 is appropriate for period measurement.|
86 | The mode 2 and 3 is appropriate for frequent |
87 | measurement. |
88 | The mode 4 to 7 is appropriate for measuring the timing|
89 | between two event. |
90 +----------------------------------------------------------------------------+
91 | Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
92 | unsigned char_ b_ModulNbr CR_AREF(insn->chanspec) : Module number to configure |
93 | (0 to 3) |
94 | unsigned char_ b_ChronoMode data[0] : Chronometer action mode |
95 | (0 to 7). |
96 | unsigned char_ b_PCIInputClock data[1] : Selection from PCI bus clock|
97 | - APCI1710_30MHZ : |
98 | The PC have a PCI bus |
99 | clock from 30 MHz |
100 | - APCI1710_33MHZ : |
101 | The PC have a PCI bus |
102 | clock from 33 MHz |
103 | - APCI1710_40MHZ |
104 | The APCI-1710 have a |
105 | integrated 40Mhz |
106 | quartz. |
107 | unsigned char_ b_TimingUnit data[2] : Base timing unity (0 to 4) |
108 | 0 : ns |
109 | 1 : µs |
110 | 2 : ms |
111 | 3 : s |
112 | 4 : mn |
113 | ULONG_ ul_TimingInterval : data[3] Base timing value. |
114 +----------------------------------------------------------------------------+
115 | Output Parameters : PULONG_ pul_RealTimingInterval : Real base timing |
116 | value.
117 | data[0]
118 +----------------------------------------------------------------------------+
119 | Return Value : 0: No error |
120 | -1: The handle parameter of the board is wrong |
121 | -2: Module selection wrong |
122 | -3: The module is not a Chronometer module |
123 | -4: Chronometer mode selection is wrong |
124 | -5: The selected PCI input clock is wrong |
125 | -6: Timing unity selection is wrong |
126 | -7: Base timing selection is wrong |
127 | -8: You can not used the 40MHz clock selection with |
128 | this board |
129 | -9: You can not used the 40MHz clock selection with |
130 | this CHRONOS version |
131 +----------------------------------------------------------------------------+
132 */
133 
135  struct comedi_insn *insn, unsigned int *data)
136 {
137  int i_ReturnValue = 0;
138  unsigned int ul_TimerValue = 0;
139  unsigned int ul_TimingInterval = 0;
140  unsigned int ul_RealTimingInterval = 0;
141  double d_RealTimingInterval = 0;
142  unsigned int dw_ModeArray[8] =
143  { 0x01, 0x05, 0x00, 0x04, 0x02, 0x0E, 0x0A, 0x06 };
144  unsigned char b_ModulNbr, b_ChronoMode, b_PCIInputClock, b_TimingUnit;
145 
146  b_ModulNbr = CR_AREF(insn->chanspec);
147  b_ChronoMode = (unsigned char) data[0];
148  b_PCIInputClock = (unsigned char) data[1];
149  b_TimingUnit = (unsigned char) data[2];
150  ul_TimingInterval = (unsigned int) data[3];
151  i_ReturnValue = insn->n;
152 
153  /**************************/
154  /* Test the module number */
155  /**************************/
156 
157  if (b_ModulNbr < 4) {
158  /***********************/
159  /* Test if chronometer */
160  /***********************/
161 
162  if ((devpriv->s_BoardInfos.
163  dw_MolduleConfiguration[b_ModulNbr] &
164  0xFFFF0000UL) == APCI1710_CHRONOMETER) {
165  /*****************************/
166  /* Test the chronometer mode */
167  /*****************************/
168 
169  if (b_ChronoMode <= 7) {
170  /**************************/
171  /* Test the PCI bus clock */
172  /**************************/
173 
174  if ((b_PCIInputClock == APCI1710_30MHZ) ||
175  (b_PCIInputClock == APCI1710_33MHZ) ||
176  (b_PCIInputClock == APCI1710_40MHZ)) {
177  /*************************/
178  /* Test the timing unity */
179  /*************************/
180 
181  if (b_TimingUnit <= 4) {
182  /**********************************/
183  /* Test the base timing selection */
184  /**********************************/
185 
186  if (((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 66) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 143165576UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 143165UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 143UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 2UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 60) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 130150240UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 130150UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 130UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 2UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 50) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 107374182UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 107374UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 107UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 1UL))) {
187  /**************************/
188  /* Test the board version */
189  /**************************/
190 
191  if (((b_PCIInputClock == APCI1710_40MHZ) && (devpriv->s_BoardInfos.b_BoardVersion > 0)) || (b_PCIInputClock != APCI1710_40MHZ)) {
192  /************************/
193  /* Test the TOR version */
194  /************************/
195 
196  if (((b_PCIInputClock == APCI1710_40MHZ) && ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) >= 0x3131)) || (b_PCIInputClock != APCI1710_40MHZ)) {
197  fpu_begin
198  ();
199 
200  /****************************************/
201  /* Calculate the timer 0 division fator */
202  /****************************************/
203 
204  switch (b_TimingUnit) {
205  /******/
206  /* ns */
207  /******/
208 
209  case 0:
210 
211  /******************/
212  /* Timer 0 factor */
213  /******************/
214 
215  ul_TimerValue
216  =
217  (unsigned int)
218  (ul_TimingInterval
219  *
220  (0.001 * b_PCIInputClock));
221 
222  /*******************/
223  /* Round the value */
224  /*******************/
225 
226  if ((double)((double)ul_TimingInterval * (0.001 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
227  ul_TimerValue
228  =
229  ul_TimerValue
230  +
231  1;
232  }
233 
234  /*****************************/
235  /* Calculate the real timing */
236  /*****************************/
237 
238  ul_RealTimingInterval
239  =
240  (unsigned int)
241  (ul_TimerValue
242  /
243  (0.001 * (double)b_PCIInputClock));
244  d_RealTimingInterval
245  =
246  (double)
247  ul_TimerValue
248  /
249  (0.001
250  *
251  (double)
252  b_PCIInputClock);
253 
254  if ((double)((double)ul_TimerValue / (0.001 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
255  ul_RealTimingInterval
256  =
257  ul_RealTimingInterval
258  +
259  1;
260  }
261 
262  ul_TimingInterval
263  =
264  ul_TimingInterval
265  -
266  1;
267  ul_TimerValue
268  =
269  ul_TimerValue
270  -
271  2;
272  if (b_PCIInputClock != APCI1710_40MHZ) {
273  ul_TimerValue
274  =
275  (unsigned int)
276  (
277  (double)
278  (ul_TimerValue)
279  *
280  0.99392);
281  }
282 
283  break;
284 
285  /******/
286  /* æs */
287  /******/
288 
289  case 1:
290 
291  /******************/
292  /* Timer 0 factor */
293  /******************/
294 
295  ul_TimerValue
296  =
297  (unsigned int)
298  (ul_TimingInterval
299  *
300  (1.0 * b_PCIInputClock));
301 
302  /*******************/
303  /* Round the value */
304  /*******************/
305 
306  if ((double)((double)ul_TimingInterval * (1.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
307  ul_TimerValue
308  =
309  ul_TimerValue
310  +
311  1;
312  }
313 
314  /*****************************/
315  /* Calculate the real timing */
316  /*****************************/
317 
318  ul_RealTimingInterval
319  =
320  (unsigned int)
321  (ul_TimerValue
322  /
323  (1.0 * (double)b_PCIInputClock));
324  d_RealTimingInterval
325  =
326  (double)
327  ul_TimerValue
328  /
329  (
330  (double)
331  1.0
332  *
333  (double)
334  b_PCIInputClock);
335 
336  if ((double)((double)ul_TimerValue / (1.0 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
337  ul_RealTimingInterval
338  =
339  ul_RealTimingInterval
340  +
341  1;
342  }
343 
344  ul_TimingInterval
345  =
346  ul_TimingInterval
347  -
348  1;
349  ul_TimerValue
350  =
351  ul_TimerValue
352  -
353  2;
354  if (b_PCIInputClock != APCI1710_40MHZ) {
355  ul_TimerValue
356  =
357  (unsigned int)
358  (
359  (double)
360  (ul_TimerValue)
361  *
362  0.99392);
363  }
364 
365  break;
366 
367  /******/
368  /* ms */
369  /******/
370 
371  case 2:
372 
373  /******************/
374  /* Timer 0 factor */
375  /******************/
376 
377  ul_TimerValue
378  =
379  ul_TimingInterval
380  *
381  (1000
382  *
383  b_PCIInputClock);
384 
385  /*******************/
386  /* Round the value */
387  /*******************/
388 
389  if ((double)((double)ul_TimingInterval * (1000.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
390  ul_TimerValue
391  =
392  ul_TimerValue
393  +
394  1;
395  }
396 
397  /*****************************/
398  /* Calculate the real timing */
399  /*****************************/
400 
401  ul_RealTimingInterval
402  =
403  (unsigned int)
404  (ul_TimerValue
405  /
406  (1000.0 * (double)b_PCIInputClock));
407  d_RealTimingInterval
408  =
409  (double)
410  ul_TimerValue
411  /
412  (1000.0
413  *
414  (double)
415  b_PCIInputClock);
416 
417  if ((double)((double)ul_TimerValue / (1000.0 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
418  ul_RealTimingInterval
419  =
420  ul_RealTimingInterval
421  +
422  1;
423  }
424 
425  ul_TimingInterval
426  =
427  ul_TimingInterval
428  -
429  1;
430  ul_TimerValue
431  =
432  ul_TimerValue
433  -
434  2;
435  if (b_PCIInputClock != APCI1710_40MHZ) {
436  ul_TimerValue
437  =
438  (unsigned int)
439  (
440  (double)
441  (ul_TimerValue)
442  *
443  0.99392);
444  }
445 
446  break;
447 
448  /*****/
449  /* s */
450  /*****/
451 
452  case 3:
453 
454  /******************/
455  /* Timer 0 factor */
456  /******************/
457 
458  ul_TimerValue
459  =
460  (unsigned int)
461  (ul_TimingInterval
462  *
463  (1000000.0
464  *
465  b_PCIInputClock));
466 
467  /*******************/
468  /* Round the value */
469  /*******************/
470 
471  if ((double)((double)ul_TimingInterval * (1000000.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
472  ul_TimerValue
473  =
474  ul_TimerValue
475  +
476  1;
477  }
478 
479  /*****************************/
480  /* Calculate the real timing */
481  /*****************************/
482 
483  ul_RealTimingInterval
484  =
485  (unsigned int)
486  (ul_TimerValue
487  /
488  (1000000.0
489  *
490  (double)
491  b_PCIInputClock));
492  d_RealTimingInterval
493  =
494  (double)
495  ul_TimerValue
496  /
497  (1000000.0
498  *
499  (double)
500  b_PCIInputClock);
501 
502  if ((double)((double)ul_TimerValue / (1000000.0 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
503  ul_RealTimingInterval
504  =
505  ul_RealTimingInterval
506  +
507  1;
508  }
509 
510  ul_TimingInterval
511  =
512  ul_TimingInterval
513  -
514  1;
515  ul_TimerValue
516  =
517  ul_TimerValue
518  -
519  2;
520  if (b_PCIInputClock != APCI1710_40MHZ) {
521  ul_TimerValue
522  =
523  (unsigned int)
524  (
525  (double)
526  (ul_TimerValue)
527  *
528  0.99392);
529  }
530 
531  break;
532 
533  /******/
534  /* mn */
535  /******/
536 
537  case 4:
538 
539  /******************/
540  /* Timer 0 factor */
541  /******************/
542 
543  ul_TimerValue
544  =
545  (unsigned int)
546  (
547  (ul_TimingInterval
548  *
549  60)
550  *
551  (1000000.0
552  *
553  b_PCIInputClock));
554 
555  /*******************/
556  /* Round the value */
557  /*******************/
558 
559  if ((double)((double)(ul_TimingInterval * 60.0) * (1000000.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
560  ul_TimerValue
561  =
562  ul_TimerValue
563  +
564  1;
565  }
566 
567  /*****************************/
568  /* Calculate the real timing */
569  /*****************************/
570 
571  ul_RealTimingInterval
572  =
573  (unsigned int)
574  (ul_TimerValue
575  /
576  (1000000.0
577  *
578  (double)
579  b_PCIInputClock))
580  /
581  60;
582  d_RealTimingInterval
583  =
584  (
585  (double)
586  ul_TimerValue
587  /
588  (0.001 * (double)b_PCIInputClock)) / 60.0;
589 
590  if ((double)(((double)ul_TimerValue / (1000000.0 * (double)b_PCIInputClock)) / 60.0) >= (double)((double)ul_RealTimingInterval + 0.5)) {
591  ul_RealTimingInterval
592  =
593  ul_RealTimingInterval
594  +
595  1;
596  }
597 
598  ul_TimingInterval
599  =
600  ul_TimingInterval
601  -
602  1;
603  ul_TimerValue
604  =
605  ul_TimerValue
606  -
607  2;
608  if (b_PCIInputClock != APCI1710_40MHZ) {
609  ul_TimerValue
610  =
611  (unsigned int)
612  (
613  (double)
614  (ul_TimerValue)
615  *
616  0.99392);
617  }
618 
619  break;
620  }
621 
622  fpu_end();
623 
624  /****************************/
625  /* Save the PCI input clock */
626  /****************************/
627 
628  devpriv->
629  s_ModuleInfo
630  [b_ModulNbr].
631  s_ChronoModuleInfo.
632  b_PCIInputClock
633  =
634  b_PCIInputClock;
635 
636  /*************************/
637  /* Save the timing unity */
638  /*************************/
639 
640  devpriv->
641  s_ModuleInfo
642  [b_ModulNbr].
643  s_ChronoModuleInfo.
644  b_TimingUnit
645  =
646  b_TimingUnit;
647 
648  /************************/
649  /* Save the base timing */
650  /************************/
651 
652  devpriv->
653  s_ModuleInfo
654  [b_ModulNbr].
655  s_ChronoModuleInfo.
656  d_TimingInterval
657  =
658  d_RealTimingInterval;
659 
660  /****************************/
661  /* Set the chronometer mode */
662  /****************************/
663 
664  devpriv->
665  s_ModuleInfo
666  [b_ModulNbr].
667  s_ChronoModuleInfo.
668  dw_ConfigReg
669  =
670  dw_ModeArray
671  [b_ChronoMode];
672 
673  /***********************/
674  /* Test if 40 MHz used */
675  /***********************/
676 
677  if (b_PCIInputClock == APCI1710_40MHZ) {
678  devpriv->
679  s_ModuleInfo
680  [b_ModulNbr].
681  s_ChronoModuleInfo.
682  dw_ConfigReg
683  =
684  devpriv->
685  s_ModuleInfo
686  [b_ModulNbr].
687  s_ChronoModuleInfo.
688  dw_ConfigReg
689  |
690  0x80;
691  }
692 
693  outl(devpriv->s_ModuleInfo[b_ModulNbr].s_ChronoModuleInfo.dw_ConfigReg, devpriv->s_BoardInfos.ui_Address + 16 + (64 * b_ModulNbr));
694 
695  /***********************/
696  /* Write timer 0 value */
697  /***********************/
698 
699  outl(ul_TimerValue, devpriv->s_BoardInfos.ui_Address + (64 * b_ModulNbr));
700 
701  /*********************/
702  /* Chronometer init. */
703  /*********************/
704 
705  devpriv->
706  s_ModuleInfo
707  [b_ModulNbr].
708  s_ChronoModuleInfo.
709  b_ChronoInit
710  =
711  1;
712  } else {
713  /***********************************************/
714  /* TOR version error for 40MHz clock selection */
715  /***********************************************/
716 
717  DPRINTK("TOR version error for 40MHz clock selection\n");
718  i_ReturnValue
719  =
720  -9;
721  }
722  } else {
723  /**************************************************************/
724  /* You can not use the 40MHz clock selection with this board */
725  /**************************************************************/
726 
727  DPRINTK("You can not used the 40MHz clock selection with this board\n");
728  i_ReturnValue =
729  -8;
730  }
731  } else {
732  /**********************************/
733  /* Base timing selection is wrong */
734  /**********************************/
735 
736  DPRINTK("Base timing selection is wrong\n");
737  i_ReturnValue = -7;
738  }
739  } /* if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4)) */
740  else {
741  /***********************************/
742  /* Timing unity selection is wrong */
743  /***********************************/
744 
745  DPRINTK("Timing unity selection is wrong\n");
746  i_ReturnValue = -6;
747  } /* if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4)) */
748  } /* if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ)) */
749  else {
750  /*****************************************/
751  /* The selected PCI input clock is wrong */
752  /*****************************************/
753 
754  DPRINTK("The selected PCI input clock is wrong\n");
755  i_ReturnValue = -5;
756  } /* if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ)) */
757  } /* if (b_ChronoMode >= 0 && b_ChronoMode <= 7) */
758  else {
759  /***************************************/
760  /* Chronometer mode selection is wrong */
761  /***************************************/
762 
763  DPRINTK("Chronometer mode selection is wrong\n");
764  i_ReturnValue = -4;
765  } /* if (b_ChronoMode >= 0 && b_ChronoMode <= 7) */
766  } else {
767  /******************************************/
768  /* The module is not a Chronometer module */
769  /******************************************/
770 
771  DPRINTK("The module is not a Chronometer module\n");
772  i_ReturnValue = -3;
773  }
774  } else {
775  /***********************/
776  /* Module number error */
777  /***********************/
778 
779  DPRINTK("Module number error\n");
780  i_ReturnValue = -2;
781  }
782  data[0] = ul_RealTimingInterval;
783  return i_ReturnValue;
784 }
785 
786 /*
787 +----------------------------------------------------------------------------+
788 | Function Name : _INT_ i_APCI1710_EnableChrono |
789 | (unsigned char_ b_BoardHandle, |
790 | unsigned char_ b_ModulNbr, |
791 | unsigned char_ b_CycleMode, |
792 | unsigned char_ b_InterruptEnable)
793 int i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device *dev,
794 struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
795 +----------------------------------------------------------------------------+
796 | Task : Enable the chronometer from selected module |
797 | (b_ModulNbr). You must calling the |
798 | "i_APCI1710_InitChrono" function be for you call this |
799 | function. |
800 | If you enable the chronometer interrupt, the |
801 | chronometer generate a interrupt after the stop signal.|
802 | See function "i_APCI1710_SetBoardIntRoutineX" and the |
803 | Interrupt mask description chapter from this manual. |
804 | The b_CycleMode parameter determine if you will |
805 | measured a single or more cycle.
806 
807 | Disable the chronometer from selected module |
808 | (b_ModulNbr). If you disable the chronometer after a |
809 | start signal occur and you restart the chronometer |
810 | witch the " i_APCI1710_EnableChrono" function, if no |
811 | stop signal occur this start signal is ignored.
812 +----------------------------------------------------------------------------+
813 | Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
814 | unsigned char_ b_ModulNbr CR_AREF(chanspec) : Selected module number (0 to 3) |
815  data[0] ENABle/Disable chrono
816 | unsigned char_ b_CycleMode : Selected the chronometer |
817 | data[1] acquisition mode |
818 | unsigned char_ b_InterruptEnable : Enable or disable the |
819 | data[2] chronometer interrupt. |
820 | APCI1710_ENABLE: |
821 | Enable the chronometer |
822 | interrupt |
823 | APCI1710_DISABLE: |
824 | Disable the chronometer |
825 | interrupt |
826 +----------------------------------------------------------------------------+
827 | Output Parameters : - |
828 +----------------------------------------------------------------------------+
829 | Return Value : 0: No error |
830 | -1: The handle parameter of the board is wrong |
831 | -2: Module selection wrong |
832 | -3: The module is not a Chronometer module |
833 | -4: Chronometer not initialised see function |
834 | "i_APCI1710_InitChrono" |
835 | -5: Chronometer acquisition mode cycle is wrong |
836 | -6: Interrupt parameter is wrong |
837 | -7: Interrupt function not initialised. |
838 | See function "i_APCI1710_SetBoardIntRoutineX"
839  -8: data[0] wrong input |
840 +----------------------------------------------------------------------------+
841 */
842 
844  struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
845 {
846  int i_ReturnValue = 0;
847  unsigned char b_ModulNbr, b_CycleMode, b_InterruptEnable, b_Action;
848  b_ModulNbr = CR_AREF(insn->chanspec);
849  b_Action = (unsigned char) data[0];
850  b_CycleMode = (unsigned char) data[1];
851  b_InterruptEnable = (unsigned char) data[2];
852  i_ReturnValue = insn->n;
853 
854  /**************************/
855  /* Test the module number */
856  /**************************/
857 
858  if (b_ModulNbr < 4) {
859  /***********************/
860  /* Test if chronometer */
861  /***********************/
862 
863  if ((devpriv->s_BoardInfos.
864  dw_MolduleConfiguration[b_ModulNbr] &
865  0xFFFF0000UL) == APCI1710_CHRONOMETER) {
866  /***********************************/
867  /* Test if chronometer initialised */
868  /***********************************/
869 
870  if (devpriv->s_ModuleInfo[b_ModulNbr].
871  s_ChronoModuleInfo.b_ChronoInit == 1) {
872 
873  switch (b_Action) {
874 
875  case APCI1710_ENABLE:
876 
877  /*********************************/
878  /* Test the cycle mode parameter */
879  /*********************************/
880 
881  if ((b_CycleMode == APCI1710_SINGLE)
882  || (b_CycleMode ==
884  /***************************/
885  /* Test the interrupt flag */
886  /***************************/
887 
888  if ((b_InterruptEnable ==
890  || (b_InterruptEnable ==
892  {
893 
894  /***************************/
895  /* Save the interrupt flag */
896  /***************************/
897 
898  devpriv->
899  s_ModuleInfo
900  [b_ModulNbr].
901  s_ChronoModuleInfo.
902  b_InterruptMask
903  =
905 
906  /***********************/
907  /* Save the cycle mode */
908  /***********************/
909 
910  devpriv->
911  s_ModuleInfo
912  [b_ModulNbr].
913  s_ChronoModuleInfo.
914  b_CycleMode =
915  b_CycleMode;
916 
917  devpriv->
918  s_ModuleInfo
919  [b_ModulNbr].
920  s_ChronoModuleInfo.
921  dw_ConfigReg =
922  (devpriv->
923  s_ModuleInfo
924  [b_ModulNbr].
925  s_ChronoModuleInfo.
926  dw_ConfigReg &
927  0x8F) | ((1 &
928  b_InterruptEnable)
929  << 5) | ((1 &
930  b_CycleMode)
931  << 6) | 0x10;
932 
933  /*****************************/
934  /* Test if interrupt enabled */
935  /*****************************/
936 
937  if (b_InterruptEnable ==
939  {
940  /****************************/
941  /* Clear the interrupt flag */
942  /****************************/
943 
944  outl(devpriv->
945  s_ModuleInfo
946  [b_ModulNbr].
947  s_ChronoModuleInfo.
948  dw_ConfigReg,
949  devpriv->
950  s_BoardInfos.
951  ui_Address
952  + 32 +
953  (64 * b_ModulNbr));
954  devpriv->tsk_Current = current; /* Save the current process task structure */
955  }
956 
957  /***********************************/
958  /* Enable or disable the interrupt */
959  /* Enable the chronometer */
960  /***********************************/
961 
962  outl(devpriv->
963  s_ModuleInfo
964  [b_ModulNbr].
965  s_ChronoModuleInfo.
966  dw_ConfigReg,
967  devpriv->
968  s_BoardInfos.
969  ui_Address +
970  16 +
971  (64 * b_ModulNbr));
972 
973  /*************************/
974  /* Clear status register */
975  /*************************/
976 
977  outl(0, devpriv->
978  s_BoardInfos.
979  ui_Address +
980  36 +
981  (64 * b_ModulNbr));
982 
983  } /* if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE)) */
984  else {
985  /********************************/
986  /* Interrupt parameter is wrong */
987  /********************************/
988 
989  DPRINTK("Interrupt parameter is wrong\n");
990  i_ReturnValue = -6;
991  } /* if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE)) */
992  } /* if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS)) */
993  else {
994  /***********************************************/
995  /* Chronometer acquisition mode cycle is wrong */
996  /***********************************************/
997 
998  DPRINTK("Chronometer acquisition mode cycle is wrong\n");
999  i_ReturnValue = -5;
1000  } /* if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS)) */
1001  break;
1002 
1003  case APCI1710_DISABLE:
1004 
1005  devpriv->s_ModuleInfo[b_ModulNbr].
1006  s_ChronoModuleInfo.
1007  b_InterruptMask = 0;
1008 
1009  devpriv->s_ModuleInfo[b_ModulNbr].
1010  s_ChronoModuleInfo.
1011  dw_ConfigReg =
1012  devpriv->
1013  s_ModuleInfo[b_ModulNbr].
1014  s_ChronoModuleInfo.
1015  dw_ConfigReg & 0x2F;
1016 
1017  /***************************/
1018  /* Disable the interrupt */
1019  /* Disable the chronometer */
1020  /***************************/
1021 
1022  outl(devpriv->s_ModuleInfo[b_ModulNbr].
1023  s_ChronoModuleInfo.dw_ConfigReg,
1024  devpriv->s_BoardInfos.
1025  ui_Address + 16 +
1026  (64 * b_ModulNbr));
1027 
1028  /***************************/
1029  /* Test if continuous mode */
1030  /***************************/
1031 
1032  if (devpriv->s_ModuleInfo[b_ModulNbr].
1033  s_ChronoModuleInfo.
1034  b_CycleMode ==
1036  /*************************/
1037  /* Clear status register */
1038  /*************************/
1039 
1040  outl(0, devpriv->s_BoardInfos.
1041  ui_Address + 36 +
1042  (64 * b_ModulNbr));
1043  }
1044  break;
1045 
1046  default:
1047  DPRINTK("Inputs wrong! Enable or Disable chrono\n");
1048  i_ReturnValue = -8;
1049  } /* switch ENABLE/DISABLE */
1050  } else {
1051  /*******************************/
1052  /* Chronometer not initialised */
1053  /*******************************/
1054 
1055  DPRINTK("Chronometer not initialised\n");
1056  i_ReturnValue = -4;
1057  }
1058  } else {
1059  /******************************************/
1060  /* The module is not a Chronometer module */
1061  /******************************************/
1062 
1063  DPRINTK("The module is not a Chronometer module\n");
1064  i_ReturnValue = -3;
1065  }
1066  } else {
1067  /***********************/
1068  /* Module number error */
1069  /***********************/
1070 
1071  DPRINTK("Module number error\n");
1072  i_ReturnValue = -2;
1073  }
1074 
1075  return i_ReturnValue;
1076 }
1077 
1078 /*
1079 +----------------------------------------------------------------------------+
1080 | Function Name :INT i_APCI1710_InsnReadChrono(struct comedi_device *dev,struct comedi_subdevice *s,
1081 struct comedi_insn *insn,unsigned int *data) |
1082 +----------------------------------------------------------------------------+
1083 | Task : Read functions for Timer |
1084 +----------------------------------------------------------------------------+
1085 | Input Parameters :
1086 +----------------------------------------------------------------------------+
1087 | Output Parameters : - |
1088 +----------------------------------------------------------------------------+
1089 | Return Value :
1090 +----------------------------------------------------------------------------+
1091 */
1092 
1094  struct comedi_insn *insn, unsigned int *data)
1095 {
1096  unsigned char b_ReadType;
1097  int i_ReturnValue = insn->n;
1098 
1099  b_ReadType = CR_CHAN(insn->chanspec);
1100 
1101  switch (b_ReadType) {
1103  i_ReturnValue = i_APCI1710_GetChronoProgressStatus(dev,
1104  (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]);
1105  break;
1106 
1108  i_ReturnValue = i_APCI1710_ReadChronoValue(dev,
1109  (unsigned char) CR_AREF(insn->chanspec),
1110  (unsigned int) insn->unused[0],
1111  (unsigned char *) &data[0], (unsigned int *) &data[1]);
1112  break;
1113 
1115  i_ReturnValue = i_APCI1710_ConvertChronoValue(dev,
1116  (unsigned char) CR_AREF(insn->chanspec),
1117  (unsigned int) insn->unused[0],
1118  (unsigned int *) &data[0],
1119  (unsigned char *) &data[1],
1120  (unsigned char *) &data[2],
1121  (unsigned int *) &data[3],
1122  (unsigned int *) &data[4], (unsigned int *) &data[5]);
1123  break;
1124 
1126  printk("In Chrono Read Interrupt\n");
1127 
1128  data[0] = devpriv->s_InterruptParameters.
1129  s_FIFOInterruptParameters[devpriv->
1130  s_InterruptParameters.ui_Read].b_OldModuleMask;
1131  data[1] = devpriv->s_InterruptParameters.
1132  s_FIFOInterruptParameters[devpriv->
1133  s_InterruptParameters.ui_Read].ul_OldInterruptMask;
1134  data[2] = devpriv->s_InterruptParameters.
1135  s_FIFOInterruptParameters[devpriv->
1136  s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
1137 
1138  /**************************/
1139  /* Increment the read FIFO */
1140  /***************************/
1141 
1142  devpriv->
1143  s_InterruptParameters.
1144  ui_Read = (devpriv->
1145  s_InterruptParameters.
1146  ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
1147  break;
1148 
1149  default:
1150  printk("ReadType Parameter wrong\n");
1151  }
1152 
1153  if (i_ReturnValue >= 0)
1154  i_ReturnValue = insn->n;
1155  return i_ReturnValue;
1156 
1157 }
1158 
1159 /*
1160 +----------------------------------------------------------------------------+
1161 | Function Name : _INT_ i_APCI1710_GetChronoProgressStatus |
1162 | (unsigned char_ b_BoardHandle, |
1163 | unsigned char_ b_ModulNbr, |
1164 | unsigned char *_ pb_ChronoStatus) |
1165 +----------------------------------------------------------------------------+
1166 | Task : Return the chronometer status (pb_ChronoStatus) from |
1167 | selected chronometer module (b_ModulNbr). |
1168 +----------------------------------------------------------------------------+
1169 | Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
1170 | unsigned char_ b_ModulNbr : Selected module number (0 to 3) |
1171 +----------------------------------------------------------------------------+
1172 | Output Parameters : PULONG_ pb_ChronoStatus : Return the chronometer |
1173 | status. |
1174 | 0 : Measurement not started.|
1175 | No start signal occur. |
1176 | 1 : Measurement started. |
1177 | A start signal occur. |
1178 | 2 : Measurement stopped. |
1179 | A stop signal occur. |
1180 | The measurement is |
1181 | terminate. |
1182 | 3: A overflow occur. You |
1183 | must change the base |
1184 | timing witch the |
1185 | function |
1186 | "i_APCI1710_InitChrono" |
1187 +----------------------------------------------------------------------------+
1188 | Return Value : 0: No error |
1189 | -1: The handle parameter of the board is wrong |
1190 | -2: Module selection wrong |
1191 | -3: The module is not a Chronometer module |
1192 | -4: Chronometer not initialised see function |
1193 | "i_APCI1710_InitChrono" |
1194 +----------------------------------------------------------------------------+
1195 */
1196 
1198  unsigned char b_ModulNbr, unsigned char *pb_ChronoStatus)
1199 {
1200  int i_ReturnValue = 0;
1201  unsigned int dw_Status;
1202 
1203  /**************************/
1204  /* Test the module number */
1205  /**************************/
1206 
1207  if (b_ModulNbr < 4) {
1208  /***********************/
1209  /* Test if chronometer */
1210  /***********************/
1211 
1212  if ((devpriv->s_BoardInfos.
1213  dw_MolduleConfiguration[b_ModulNbr] &
1214  0xFFFF0000UL) == APCI1710_CHRONOMETER) {
1215  /***********************************/
1216  /* Test if chronometer initialised */
1217  /***********************************/
1218 
1219  if (devpriv->
1220  s_ModuleInfo[b_ModulNbr].
1221  s_ChronoModuleInfo.b_ChronoInit == 1) {
1222 
1223  dw_Status = inl(devpriv->s_BoardInfos.
1224  ui_Address + 8 + (64 * b_ModulNbr));
1225 
1226  /********************/
1227  /* Test if overflow */
1228  /********************/
1229 
1230  if ((dw_Status & 8) == 8) {
1231  /******************/
1232  /* Overflow occur */
1233  /******************/
1234 
1235  *pb_ChronoStatus = 3;
1236  } /* if ((dw_Status & 8) == 8) */
1237  else {
1238  /*******************************/
1239  /* Test if measurement stopped */
1240  /*******************************/
1241 
1242  if ((dw_Status & 2) == 2) {
1243  /***********************/
1244  /* A stop signal occur */
1245  /***********************/
1246 
1247  *pb_ChronoStatus = 2;
1248  } /* if ((dw_Status & 2) == 2) */
1249  else {
1250  /*******************************/
1251  /* Test if measurement started */
1252  /*******************************/
1253 
1254  if ((dw_Status & 1) == 1) {
1255  /************************/
1256  /* A start signal occur */
1257  /************************/
1258 
1259  *pb_ChronoStatus = 1;
1260  } /* if ((dw_Status & 1) == 1) */
1261  else {
1262  /***************************/
1263  /* Measurement not started */
1264  /***************************/
1265 
1266  *pb_ChronoStatus = 0;
1267  } /* if ((dw_Status & 1) == 1) */
1268  } /* if ((dw_Status & 2) == 2) */
1269  } /* if ((dw_Status & 8) == 8) */
1270  } else {
1271  /*******************************/
1272  /* Chronometer not initialised */
1273  /*******************************/
1274  DPRINTK("Chronometer not initialised\n");
1275  i_ReturnValue = -4;
1276  }
1277  } else {
1278  /******************************************/
1279  /* The module is not a Chronometer module */
1280  /******************************************/
1281  DPRINTK("The module is not a Chronometer module\n");
1282  i_ReturnValue = -3;
1283  }
1284  } else {
1285  /***********************/
1286  /* Module number error */
1287  /***********************/
1288  DPRINTK("Module number error\n");
1289  i_ReturnValue = -2;
1290  }
1291 
1292  return i_ReturnValue;
1293 }
1294 
1295 /*
1296 +----------------------------------------------------------------------------+
1297 | Function Name : _INT_ i_APCI1710_ReadChronoValue |
1298 | (unsigned char_ b_BoardHandle, |
1299 | unsigned char_ b_ModulNbr, |
1300 | unsigned int_ ui_TimeOut, |
1301 | unsigned char *_ pb_ChronoStatus, |
1302 | PULONG_ pul_ChronoValue) |
1303 +----------------------------------------------------------------------------+
1304 | Task : Return the chronometer status (pb_ChronoStatus) and the|
1305 | timing value (pul_ChronoValue) after a stop signal |
1306 | occur from selected chronometer module (b_ModulNbr). |
1307 | This function are only avaible if you have disabled |
1308 | the interrupt functionality. See function |
1309 | "i_APCI1710_EnableChrono" and the Interrupt mask |
1310 | description chapter. |
1311 | You can test the chronometer status witch the |
1312 | "i_APCI1710_GetChronoProgressStatus" function. |
1313 | |
1314 | The returned value from pul_ChronoValue parameter is |
1315 | not real measured timing. |
1316 | You must used the "i_APCI1710_ConvertChronoValue" |
1317 | function or make this operation for calculate the |
1318 | timing: |
1319 | |
1320 | Timing = pul_ChronoValue * pul_RealTimingInterval. |
1321 | |
1322 | pul_RealTimingInterval is the returned parameter from |
1323 | "i_APCI1710_InitChrono" function and the time unity is |
1324 | the b_TimingUnit from "i_APCI1710_InitChrono" function|
1325 +----------------------------------------------------------------------------+
1326 | Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
1327 | unsigned char_ b_ModulNbr : Selected module number (0 to 3) |
1328 +----------------------------------------------------------------------------+
1329 | Output Parameters : PULONG_ pb_ChronoStatus : Return the chronometer |
1330 | status. |
1331 | 0 : Measurement not started.|
1332 | No start signal occur. |
1333 | 1 : Measurement started. |
1334 | A start signal occur. |
1335 | 2 : Measurement stopped. |
1336 | A stop signal occur. |
1337 | The measurement is |
1338 | terminate. |
1339 | 3: A overflow occur. You |
1340 | must change the base |
1341 | timing witch the |
1342 | function |
1343 | "i_APCI1710_InitChrono" |
1344 | unsigned int * pul_ChronoValue : Chronometer timing value. |
1345 +----------------------------------------------------------------------------+
1346 | Return Value : 0: No error |
1347 | -1: The handle parameter of the board is wrong |
1348 | -2: Module selection wrong |
1349 | -3: The module is not a Chronometer module |
1350 | -4: Chronometer not initialised see function |
1351 | "i_APCI1710_InitChrono" |
1352 | -5: Timeout parameter is wrong (0 to 65535) |
1353 | -6: Interrupt routine installed. You can not read |
1354 | directly the chronometer measured timing. |
1355 +----------------------------------------------------------------------------+
1356 */
1357 
1359  unsigned char b_ModulNbr,
1360  unsigned int ui_TimeOut, unsigned char *pb_ChronoStatus, unsigned int *pul_ChronoValue)
1361 {
1362  int i_ReturnValue = 0;
1363  unsigned int dw_Status;
1364  unsigned int dw_TimeOut = 0;
1365 
1366  /**************************/
1367  /* Test the module number */
1368  /**************************/
1369 
1370  if (b_ModulNbr < 4) {
1371  /***********************/
1372  /* Test if chronometer */
1373  /***********************/
1374 
1375  if ((devpriv->s_BoardInfos.
1376  dw_MolduleConfiguration[b_ModulNbr] &
1377  0xFFFF0000UL) == APCI1710_CHRONOMETER) {
1378  /***********************************/
1379  /* Test if chronometer initialised */
1380  /***********************************/
1381 
1382  if (devpriv->
1383  s_ModuleInfo[b_ModulNbr].
1384  s_ChronoModuleInfo.b_ChronoInit == 1) {
1385  /*****************************/
1386  /* Test the timout parameter */
1387  /*****************************/
1388 
1389  if (ui_TimeOut <= 65535UL) {
1390 
1391  for (;;) {
1392  /*******************/
1393  /* Read the status */
1394  /*******************/
1395 
1396  dw_Status =
1397  inl(devpriv->
1398  s_BoardInfos.
1399  ui_Address + 8 +
1400  (64 * b_ModulNbr));
1401 
1402  /********************/
1403  /* Test if overflow */
1404  /********************/
1405 
1406  if ((dw_Status & 8) == 8) {
1407  /******************/
1408  /* Overflow occur */
1409  /******************/
1410 
1411  *pb_ChronoStatus = 3;
1412 
1413  /***************************/
1414  /* Test if continuous mode */
1415  /***************************/
1416 
1417  if (devpriv->
1418  s_ModuleInfo
1419  [b_ModulNbr].
1420  s_ChronoModuleInfo.
1421  b_CycleMode ==
1423  {
1424  /*************************/
1425  /* Clear status register */
1426  /*************************/
1427 
1428  outl(0, devpriv->s_BoardInfos.ui_Address + 36 + (64 * b_ModulNbr));
1429  }
1430 
1431  break;
1432  } /* if ((dw_Status & 8) == 8) */
1433  else {
1434  /*******************************/
1435  /* Test if measurement stopped */
1436  /*******************************/
1437 
1438  if ((dw_Status & 2) ==
1439  2) {
1440  /***********************/
1441  /* A stop signal occur */
1442  /***********************/
1443 
1444  *pb_ChronoStatus
1445  = 2;
1446 
1447  /***************************/
1448  /* Test if continnous mode */
1449  /***************************/
1450 
1451  if (devpriv->
1452  s_ModuleInfo
1453  [b_ModulNbr].
1454  s_ChronoModuleInfo.
1455  b_CycleMode
1456  ==
1458  {
1459  /*************************/
1460  /* Clear status register */
1461  /*************************/
1462 
1463  outl(0, devpriv->s_BoardInfos.ui_Address + 36 + (64 * b_ModulNbr));
1464  }
1465  break;
1466  } /* if ((dw_Status & 2) == 2) */
1467  else {
1468  /*******************************/
1469  /* Test if measurement started */
1470  /*******************************/
1471 
1472  if ((dw_Status & 1) == 1) {
1473  /************************/
1474  /* A start signal occur */
1475  /************************/
1476 
1477  *pb_ChronoStatus
1478  =
1479  1;
1480  } /* if ((dw_Status & 1) == 1) */
1481  else {
1482  /***************************/
1483  /* Measurement not started */
1484  /***************************/
1485 
1486  *pb_ChronoStatus
1487  =
1488  0;
1489  } /* if ((dw_Status & 1) == 1) */
1490  } /* if ((dw_Status & 2) == 2) */
1491  } /* if ((dw_Status & 8) == 8) */
1492 
1493  if (dw_TimeOut == ui_TimeOut) {
1494  /*****************/
1495  /* Timeout occur */
1496  /*****************/
1497 
1498  break;
1499  } else {
1500  /*************************/
1501  /* Increment the timeout */
1502  /*************************/
1503 
1504  dw_TimeOut =
1505  dw_TimeOut + 1;
1506  mdelay(1000);
1507 
1508  }
1509  } /* for (;;) */
1510 
1511  /*****************************/
1512  /* Test if stop signal occur */
1513  /*****************************/
1514 
1515  if (*pb_ChronoStatus == 2) {
1516  /**********************************/
1517  /* Read the measured timing value */
1518  /**********************************/
1519 
1520  *pul_ChronoValue =
1521  inl(devpriv->
1522  s_BoardInfos.
1523  ui_Address + 4 +
1524  (64 * b_ModulNbr));
1525 
1526  if (*pul_ChronoValue != 0) {
1527  *pul_ChronoValue =
1528  *pul_ChronoValue
1529  - 1;
1530  }
1531  } else {
1532  /*************************/
1533  /* Test if timeout occur */
1534  /*************************/
1535 
1536  if ((*pb_ChronoStatus != 3)
1537  && (dw_TimeOut ==
1538  ui_TimeOut)
1539  && (ui_TimeOut != 0)) {
1540  /*****************/
1541  /* Timeout occur */
1542  /*****************/
1543 
1544  *pb_ChronoStatus = 4;
1545  }
1546  }
1547 
1548  } else {
1549  /******************************/
1550  /* Timeout parameter is wrong */
1551  /******************************/
1552  DPRINTK("Timeout parameter is wrong\n");
1553  i_ReturnValue = -5;
1554  }
1555  } else {
1556  /*******************************/
1557  /* Chronometer not initialised */
1558  /*******************************/
1559  DPRINTK("Chronometer not initialised\n");
1560  i_ReturnValue = -4;
1561  }
1562  } else {
1563  /******************************************/
1564  /* The module is not a Chronometer module */
1565  /******************************************/
1566  DPRINTK("The module is not a Chronometer module\n");
1567  i_ReturnValue = -3;
1568  }
1569  } else {
1570  /***********************/
1571  /* Module number error */
1572  /***********************/
1573  DPRINTK("Module number error\n");
1574  i_ReturnValue = -2;
1575  }
1576 
1577  return i_ReturnValue;
1578 }
1579 
1580 /*
1581 +----------------------------------------------------------------------------+
1582 | Function Name : _INT_ i_APCI1710_ConvertChronoValue |
1583 | (unsigned char_ b_BoardHandle, |
1584 | unsigned char_ b_ModulNbr, |
1585 | ULONG_ ul_ChronoValue, |
1586 | PULONG_ pul_Hour, |
1587 | unsigned char *_ pb_Minute, |
1588 | unsigned char *_ pb_Second, |
1589 | unsigned int *_ pui_MilliSecond, |
1590 | unsigned int *_ pui_MicroSecond, |
1591 | unsigned int *_ pui_NanoSecond) |
1592 +----------------------------------------------------------------------------+
1593 | Task : Convert the chronometer measured timing |
1594 | (ul_ChronoValue) in to h, mn, s, ms, µs, ns. |
1595 +----------------------------------------------------------------------------+
1596 | Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
1597 | unsigned char_ b_ModulNbr : Selected module number (0 to 3)|
1598 | ULONG_ ul_ChronoValue : Measured chronometer timing |
1599 | value. |
1600 | See"i_APCI1710_ReadChronoValue"|
1601 +----------------------------------------------------------------------------+
1602 | Output Parameters : PULONG_ pul_Hour : Chronometer timing hour |
1603 | unsigned char *_ pb_Minute : Chronometer timing minute |
1604 | unsigned char *_ pb_Second : Chronometer timing second |
1605 | unsigned int *_ pui_MilliSecond : Chronometer timing mini |
1606 | second |
1607 | unsigned int *_ pui_MicroSecond : Chronometer timing micro |
1608 | second |
1609 | unsigned int *_ pui_NanoSecond : Chronometer timing nano |
1610 | second |
1611 +----------------------------------------------------------------------------+
1612 | Return Value : 0: No error |
1613 | -1: The handle parameter of the board is wrong |
1614 | -2: Module selection wrong |
1615 | -3: The module is not a Chronometer module |
1616 | -4: Chronometer not initialised see function |
1617 | "i_APCI1710_InitChrono" |
1618 +----------------------------------------------------------------------------+
1619 */
1620 
1622  unsigned char b_ModulNbr,
1623  unsigned int ul_ChronoValue,
1624  unsigned int *pul_Hour,
1625  unsigned char *pb_Minute,
1626  unsigned char *pb_Second,
1627  unsigned int *pui_MilliSecond, unsigned int *pui_MicroSecond, unsigned int *pui_NanoSecond)
1628 {
1629  int i_ReturnValue = 0;
1630  double d_Hour;
1631  double d_Minute;
1632  double d_Second;
1633  double d_MilliSecond;
1634  double d_MicroSecond;
1635  double d_NanoSecond;
1636 
1637  /**************************/
1638  /* Test the module number */
1639  /**************************/
1640 
1641  if (b_ModulNbr < 4) {
1642  /***********************/
1643  /* Test if chronometer */
1644  /***********************/
1645 
1646  if ((devpriv->s_BoardInfos.
1647  dw_MolduleConfiguration[b_ModulNbr] &
1648  0xFFFF0000UL) == APCI1710_CHRONOMETER) {
1649  /***********************************/
1650  /* Test if chronometer initialised */
1651  /***********************************/
1652 
1653  if (devpriv->
1654  s_ModuleInfo[b_ModulNbr].
1655  s_ChronoModuleInfo.b_ChronoInit == 1) {
1656  fpu_begin();
1657 
1658  d_Hour = (double)ul_ChronoValue *(double)
1659  devpriv->s_ModuleInfo[b_ModulNbr].
1660  s_ChronoModuleInfo.d_TimingInterval;
1661 
1662  switch (devpriv->
1663  s_ModuleInfo[b_ModulNbr].
1664  s_ChronoModuleInfo.b_TimingUnit) {
1665  case 0:
1666  d_Hour = d_Hour / (double)1000.0;
1667 
1668  case 1:
1669  d_Hour = d_Hour / (double)1000.0;
1670 
1671  case 2:
1672  d_Hour = d_Hour / (double)1000.0;
1673 
1674  case 3:
1675  d_Hour = d_Hour / (double)60.0;
1676 
1677  case 4:
1678  /**********************/
1679  /* Calculate the hour */
1680  /**********************/
1681 
1682  d_Hour = d_Hour / (double)60.0;
1683  *pul_Hour = (unsigned int) d_Hour;
1684 
1685  /************************/
1686  /* Calculate the minute */
1687  /************************/
1688 
1689  d_Minute = d_Hour - *pul_Hour;
1690  d_Minute = d_Minute * 60;
1691  *pb_Minute = (unsigned char) d_Minute;
1692 
1693  /************************/
1694  /* Calculate the second */
1695  /************************/
1696 
1697  d_Second = d_Minute - *pb_Minute;
1698  d_Second = d_Second * 60;
1699  *pb_Second = (unsigned char) d_Second;
1700 
1701  /*****************************/
1702  /* Calculate the mini second */
1703  /*****************************/
1704 
1705  d_MilliSecond = d_Second - *pb_Second;
1706  d_MilliSecond = d_MilliSecond * 1000;
1707  *pui_MilliSecond = (unsigned int) d_MilliSecond;
1708 
1709  /******************************/
1710  /* Calculate the micro second */
1711  /******************************/
1712 
1713  d_MicroSecond =
1714  d_MilliSecond -
1715  *pui_MilliSecond;
1716  d_MicroSecond = d_MicroSecond * 1000;
1717  *pui_MicroSecond = (unsigned int) d_MicroSecond;
1718 
1719  /******************************/
1720  /* Calculate the micro second */
1721  /******************************/
1722 
1723  d_NanoSecond =
1724  d_MicroSecond -
1725  *pui_MicroSecond;
1726  d_NanoSecond = d_NanoSecond * 1000;
1727  *pui_NanoSecond = (unsigned int) d_NanoSecond;
1728  break;
1729  }
1730 
1731  fpu_end();
1732  } else {
1733  /*******************************/
1734  /* Chronometer not initialised */
1735  /*******************************/
1736  DPRINTK("Chronometer not initialised\n");
1737  i_ReturnValue = -4;
1738  }
1739  } else {
1740  /******************************************/
1741  /* The module is not a Chronometer module */
1742  /******************************************/
1743  DPRINTK("The module is not a Chronometer module\n");
1744  i_ReturnValue = -3;
1745  }
1746  } else {
1747  /***********************/
1748  /* Module number error */
1749  /***********************/
1750  DPRINTK("Module number error\n");
1751  i_ReturnValue = -2;
1752  }
1753 
1754  return i_ReturnValue;
1755 }
1756 
1757 /*
1758 +----------------------------------------------------------------------------+
1759 | Function Name : int i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device *dev,struct comedi_subdevice *s,
1760  struct comedi_insn *insn,unsigned int *data) |
1761 +----------------------------------------------------------------------------+
1762 | Task : Sets the output witch has been passed with the |
1763 | parameter b_Channel. Setting an output means setting an|
1764 | output high. |
1765 +----------------------------------------------------------------------------+
1766 | Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
1767 | unsigned char_ b_ModulNbr : Selected module number (0 to 3)|
1768 | unsigned char_ b_OutputChannel : Selection from digital output |
1769 | CR_CHAN() channel (0 to 2) |
1770 | 0 : Channel H |
1771 | 1 : Channel A |
1772 | 2 : Channel B |
1773 +----------------------------------------------------------------------------+
1774 | Output Parameters : - |
1775 +----------------------------------------------------------------------------+
1776 | Return Value : 0: No error |
1777 | -1: The handle parameter of the board is wrong |
1778 | -2: Module selection wrong |
1779 | -3: The module is not a Chronometer module |
1780 | -4: The selected digital output is wrong |
1781 | -5: Chronometer not initialised see function |
1782 | "i_APCI1710_InitChrono" |
1783 +----------------------------------------------------------------------------+
1784 */
1785 
1786 /*
1787 +----------------------------------------------------------------------------+
1788 | Function Name : _INT_ i_APCI1710_SetChronoChlOff |
1789 | (unsigned char_ b_BoardHandle, |
1790 | unsigned char_ b_ModulNbr, |
1791 | unsigned char_ b_OutputChannel) |
1792 +----------------------------------------------------------------------------+
1793 | Task : Resets the output witch has been passed with the |
1794 | parameter b_Channel. Resetting an output means setting |
1795 | an output low. |
1796 +----------------------------------------------------------------------------+
1797 | Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710
1798  data[0] : Chl ON, Chl OFF , Chl Read , Port Read
1799 
1800 | unsigned char_ b_ModulNbr CR_AREF : Selected module number (0 to 3)|
1801 | unsigned char_ b_OutputChannel CR_CHAN : Selection from digital output |
1802 | channel (0 to 2) |
1803 | 0 : Channel H |
1804 | 1 : Channel A |
1805 | 2 : Channel B |
1806 +----------------------------------------------------------------------------+
1807 | Output Parameters : - |
1808 +----------------------------------------------------------------------------+
1809 | Return Value : 0: No error |
1810 | -1: The handle parameter of the board is wrong |
1811 | -2: Module selection wrong |
1812 | -3: The module is not a Chronometer module |
1813 | -4: The selected digital output is wrong |
1814 | -5: Chronometer not initialised see function |
1815 | "i_APCI1710_InitChrono" |
1816 +----------------------------------------------------------------------------+
1817 */
1818 
1819 /*
1820 +----------------------------------------------------------------------------+
1821 | Function Name : _INT_ i_APCI1710_ReadChronoChlValue |
1822 | (unsigned char_ b_BoardHandle, |
1823 | unsigned char_ b_ModulNbr, |
1824 | unsigned char_ b_InputChannel, |
1825 | unsigned char *_ pb_ChannelStatus) |
1826 +----------------------------------------------------------------------------+
1827 | Task : Return the status from selected digital input |
1828 | (b_InputChannel) from selected chronometer |
1829 | module (b_ModulNbr). |
1830 +----------------------------------------------------------------------------+
1831 | Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
1832 | unsigned char_ b_ModulNbr : Selected module number (0 to 3)|
1833 | unsigned char_ b_InputChannel : Selection from digital input |
1834 | channel (0 to 2) |
1835 | CR_CHAN() 0 : Channel E |
1836 | 1 : Channel F |
1837 | 2 : Channel G |
1838 +----------------------------------------------------------------------------+
1839 | Output Parameters : unsigned char *_ pb_ChannelStatus : Digital input channel status.|
1840 | data[0] 0 : Channel is not active |
1841 | 1 : Channel is active |
1842 +----------------------------------------------------------------------------+
1843 | Return Value : 0: No error |
1844 | -1: The handle parameter of the board is wrong |
1845 | -2: Module selection wrong |
1846 | -3: The module is not a Chronometer module |
1847 | -4: The selected digital input is wrong |
1848 | -5: Chronometer not initialised see function |
1849 | "i_APCI1710_InitChrono" |
1850 +----------------------------------------------------------------------------+
1851 */
1852 
1853 /*
1854 +----------------------------------------------------------------------------+
1855 | Function Name : _INT_ i_APCI1710_ReadChronoPortValue |
1856 | (unsigned char_ b_BoardHandle, |
1857 | unsigned char_ b_ModulNbr, |
1858 | unsigned char *_ pb_PortValue) |
1859 +----------------------------------------------------------------------------+
1860 | Task : Return the status from digital inputs port from |
1861 | selected (b_ModulNbr) chronometer module. |
1862 +----------------------------------------------------------------------------+
1863 | Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
1864 | unsigned char_ b_ModulNbr : Selected module number (0 to 3)|
1865 +----------------------------------------------------------------------------+
1866 | Output Parameters : unsigned char *_ pb_PortValue : Digital inputs port status.
1867 | data[0]
1868 +----------------------------------------------------------------------------+
1869 | Return Value : 0: No error |
1870 | -1: The handle parameter of the board is wrong |
1871 | -2: Module selection wrong |
1872 | -3: The module is not a Chronometer module |
1873 | -4: Chronometer not initialised see function |
1874 | "i_APCI1710_InitChrono" |
1875 +----------------------------------------------------------------------------+
1876 */
1877 
1879  struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
1880 {
1881  int i_ReturnValue = 0;
1882  unsigned char b_ModulNbr, b_OutputChannel, b_InputChannel, b_IOType;
1883  unsigned int dw_Status;
1884  unsigned char *pb_ChannelStatus;
1885  unsigned char *pb_PortValue;
1886 
1887  b_ModulNbr = CR_AREF(insn->chanspec);
1888  i_ReturnValue = insn->n;
1889  b_IOType = (unsigned char) data[0];
1890 
1891  /**************************/
1892  /* Test the module number */
1893  /**************************/
1894 
1895  if (b_ModulNbr < 4) {
1896  /***********************/
1897  /* Test if chronometer */
1898  /***********************/
1899 
1900  if ((devpriv->s_BoardInfos.
1901  dw_MolduleConfiguration[b_ModulNbr] &
1902  0xFFFF0000UL) == APCI1710_CHRONOMETER) {
1903  /***********************************/
1904  /* Test if chronometer initialised */
1905  /***********************************/
1906 
1907  if (devpriv->s_ModuleInfo[b_ModulNbr].
1908  s_ChronoModuleInfo.b_ChronoInit == 1) {
1909  /***********************************/
1910  /* Test the digital output channel */
1911  /***********************************/
1912  switch (b_IOType) {
1913 
1915 
1916  b_OutputChannel =
1917  (unsigned char) CR_CHAN(insn->chanspec);
1918  if (b_OutputChannel <= 2) {
1919 
1920  outl(0, devpriv->s_BoardInfos.
1921  ui_Address + 20 +
1922  (b_OutputChannel * 4) +
1923  (64 * b_ModulNbr));
1924  } /* if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2)) */
1925  else {
1926  /****************************************/
1927  /* The selected digital output is wrong */
1928  /****************************************/
1929 
1930  DPRINTK("The selected digital output is wrong\n");
1931  i_ReturnValue = -4;
1932 
1933  } /* if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2)) */
1934 
1935  break;
1936 
1938 
1939  b_OutputChannel =
1940  (unsigned char) CR_CHAN(insn->chanspec);
1941  if (b_OutputChannel <= 2) {
1942 
1943  outl(1, devpriv->s_BoardInfos.
1944  ui_Address + 20 +
1945  (b_OutputChannel * 4) +
1946  (64 * b_ModulNbr));
1947  } /* if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2)) */
1948  else {
1949  /****************************************/
1950  /* The selected digital output is wrong */
1951  /****************************************/
1952 
1953  DPRINTK("The selected digital output is wrong\n");
1954  i_ReturnValue = -4;
1955 
1956  } /* if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2)) */
1957 
1958  break;
1959 
1961  /**********************************/
1962  /* Test the digital input channel */
1963  /**********************************/
1964  pb_ChannelStatus = (unsigned char *) &data[0];
1965  b_InputChannel =
1966  (unsigned char) CR_CHAN(insn->chanspec);
1967 
1968  if (b_InputChannel <= 2) {
1969 
1970  dw_Status =
1971  inl(devpriv->
1972  s_BoardInfos.
1973  ui_Address + 12 +
1974  (64 * b_ModulNbr));
1975 
1976  *pb_ChannelStatus =
1977  (unsigned char) (((dw_Status >>
1978  b_InputChannel)
1979  & 1) ^ 1);
1980  } /* if ((b_InputChannel >= 0) && (b_InputChannel <= 2)) */
1981  else {
1982  /***************************************/
1983  /* The selected digital input is wrong */
1984  /***************************************/
1985 
1986  DPRINTK("The selected digital input is wrong\n");
1987  i_ReturnValue = -4;
1988  } /* if ((b_InputChannel >= 0) && (b_InputChannel <= 2)) */
1989 
1990  break;
1991 
1993 
1994  pb_PortValue = (unsigned char *) &data[0];
1995 
1996  dw_Status =
1997  inl(devpriv->s_BoardInfos.
1998  ui_Address + 12 +
1999  (64 * b_ModulNbr));
2000 
2001  *pb_PortValue =
2002  (unsigned char) ((dw_Status & 0x7) ^ 7);
2003  break;
2004  }
2005  } else {
2006  /*******************************/
2007  /* Chronometer not initialised */
2008  /*******************************/
2009 
2010  DPRINTK("Chronometer not initialised\n");
2011  i_ReturnValue = -5;
2012  }
2013  } else {
2014  /******************************************/
2015  /* The module is not a Chronometer module */
2016  /******************************************/
2017 
2018  DPRINTK("The module is not a Chronometer module\n");
2019  i_ReturnValue = -3;
2020  }
2021  } else {
2022  /***********************/
2023  /* Module number error */
2024  /***********************/
2025 
2026  DPRINTK("Module number error\n");
2027  i_ReturnValue = -2;
2028  }
2029 
2030  return i_ReturnValue;
2031 }