]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c
Staging: comedi: Remove comedi_device typedef
[net-next-2.6.git] / drivers / staging / comedi / drivers / addi-data / APCI1710_Chrono.c
CommitLineData
c995fe94
ADG
1/**
2@verbatim
3
4Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
5
6 ADDI-DATA GmbH
7 Dieselstrasse 3
8 D-77833 Ottersweier
9 Tel: +19(0)7223/9493-0
10 Fax: +49(0)7223/9493-92
11 http://www.addi-data-com
12 info@addi-data.com
13
14This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
15
16This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20You shoud also find the complete GPL in the COPYING file accompanying this source code.
21
22@endverbatim
23*/
24/*
25
26 +-----------------------------------------------------------------------+
27 | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
28 +-----------------------------------------------------------------------+
29 | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
30 | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
31 +-----------------------------------------------------------------------+
32 | Project : API APCI1710 | Compiler : gcc |
33 | Module name : 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| (BYTE_ b_BoardHandle, |
66| BYTE_ b_ModulNbr, |
67| BYTE_ b_ChronoMode, |
68| BYTE_ b_PCIInputClock, |
69| BYTE_ 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 : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
92| BYTE_ b_ModulNbr CR_AREF(insn->chanspec) : Module number to configure |
93| (0 to 3) |
94| BYTE_ b_ChronoMode data[0] : Chronometer action mode |
95| (0 to 7). |
96| BYTE_ 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| BYTE_ 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 wich |
128| this board |
129| -9: You can not used the 40MHz clock selection wich |
130| this CHRONOS version |
131+----------------------------------------------------------------------------+
132*/
133
71b5f4f1 134INT i_APCI1710_InsnConfigInitChrono(struct comedi_device * dev, comedi_subdevice * s,
790c5541 135 comedi_insn * insn, unsigned int * data)
c995fe94
ADG
136{
137 INT i_ReturnValue = 0;
138 ULONG ul_TimerValue = 0;
139 ULONG ul_TimingInterval = 0;
140 ULONG ul_RealTimingInterval = 0;
141 double d_RealTimingInterval = 0;
142 DWORD dw_ModeArray[8] =
143 { 0x01, 0x05, 0x00, 0x04, 0x02, 0x0E, 0x0A, 0x06 };
144 BYTE b_ModulNbr, b_ChronoMode, b_PCIInputClock, b_TimingUnit;
145
146 b_ModulNbr = CR_AREF(insn->chanspec);
147 b_ChronoMode = (BYTE) data[0];
148 b_PCIInputClock = (BYTE) data[1];
149 b_TimingUnit = (BYTE) data[2];
150 ul_TimingInterval = (ULONG) 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 (ULONG)
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 (ULONG)
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 (ULONG)
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 (ULONG)
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 (ULONG)
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 (ULONG)
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 (ULONG)
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 (ULONG)
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 (ULONG)
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 (ULONG)
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 (ULONG)
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 (ULONG)
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 (ULONG)
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 (ULONG)
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 used the 40MHz clock selection wich this board */
725 /**************************************************************/
726
727 DPRINTK("You can not used the 40MHz clock selection wich 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| (BYTE_ b_BoardHandle, |
790| BYTE_ b_ModulNbr, |
791| BYTE_ b_CycleMode, |
792| BYTE_ b_InterruptEnable)
71b5f4f1 793INT i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device *dev,
790c5541 794comedi_subdevice *s,comedi_insn *insn,unsigned int *data) |
c995fe94
ADG
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 : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
814| BYTE_ b_ModulNbr CR_AREF(chanspec) : Selected module number (0 to 3) |
815 data[0] ENABle/Disable chrono
816| BYTE_ b_CycleMode : Selected the chronometer |
817| data[1] acquisition mode |
818| BYTE_ 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
71b5f4f1 843INT i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device * dev,
790c5541 844 comedi_subdevice * s, comedi_insn * insn, unsigned int * data)
c995fe94
ADG
845{
846 INT i_ReturnValue = 0;
847 BYTE b_ModulNbr, b_CycleMode, b_InterruptEnable, b_Action;
848 b_ModulNbr = CR_AREF(insn->chanspec);
849 b_Action = (BYTE) data[0];
850 b_CycleMode = (BYTE) data[1];
851 b_InterruptEnable = (BYTE) 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 ==
883 APCI1710_CONTINUOUS)) {
884 /***************************/
885 /* Test the interrupt flag */
886 /***************************/
887
888 if ((b_InterruptEnable ==
889 APCI1710_ENABLE)
890 || (b_InterruptEnable ==
891 APCI1710_DISABLE))
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 =
904 b_InterruptEnable;
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 ==
938 APCI1710_ENABLE)
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 ==
1035 APCI1710_CONTINUOUS) {
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+----------------------------------------------------------------------------+
71b5f4f1 1080| Function Name :INT i_APCI1710_InsnReadChrono(struct comedi_device *dev,comedi_subdevice *s,
790c5541 1081comedi_insn *insn,unsigned int *data) |
c995fe94
ADG
1082+----------------------------------------------------------------------------+
1083| Task : Read functions for Timer |
1084+----------------------------------------------------------------------------+
1085| Input Parameters :
1086+----------------------------------------------------------------------------+
1087| Output Parameters : - |
1088+----------------------------------------------------------------------------+
1089| Return Value :
1090+----------------------------------------------------------------------------+
1091*/
1092
71b5f4f1 1093INT i_APCI1710_InsnReadChrono(struct comedi_device * dev, comedi_subdevice * s,
790c5541 1094 comedi_insn * insn, unsigned int * data)
c995fe94
ADG
1095{
1096 BYTE b_ReadType;
1097 INT i_ReturnValue = insn->n;
1098
1099 b_ReadType = CR_CHAN(insn->chanspec);
1100
1101 switch (b_ReadType) {
1102 case APCI1710_CHRONO_PROGRESS_STATUS:
1103 i_ReturnValue = i_APCI1710_GetChronoProgressStatus(dev,
1104 (BYTE) CR_AREF(insn->chanspec), (PBYTE) & data[0]);
1105 break;
1106
1107 case APCI1710_CHRONO_READVALUE:
1108 i_ReturnValue = i_APCI1710_ReadChronoValue(dev,
1109 (BYTE) CR_AREF(insn->chanspec),
1110 (UINT) insn->unused[0],
1111 (PBYTE) & data[0], (PULONG) & data[1]);
1112 break;
1113
1114 case APCI1710_CHRONO_CONVERTVALUE:
1115 i_ReturnValue = i_APCI1710_ConvertChronoValue(dev,
1116 (BYTE) CR_AREF(insn->chanspec),
1117 (ULONG) insn->unused[0],
1118 (PULONG) & data[0],
1119 (PBYTE) & data[1],
1120 (PBYTE) & data[2],
1121 (PUINT) & data[3],
1122 (PUINT) & data[4], (PUINT) & data[5]);
1123 break;
1124
1125 case APCI1710_CHRONO_READINTERRUPT:
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| (BYTE_ b_BoardHandle, |
1163| BYTE_ b_ModulNbr, |
1164| PBYTE_ pb_ChronoStatus) |
1165+----------------------------------------------------------------------------+
1166| Task : Return the chronometer status (pb_ChronoStatus) from |
1167| selected chronometer module (b_ModulNbr). |
1168+----------------------------------------------------------------------------+
1169| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
1170| BYTE_ 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
71b5f4f1 1197INT i_APCI1710_GetChronoProgressStatus(struct comedi_device * dev,
c995fe94
ADG
1198 BYTE b_ModulNbr, PBYTE pb_ChronoStatus)
1199{
1200 INT i_ReturnValue = 0;
1201 DWORD 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| (BYTE_ b_BoardHandle, |
1299| BYTE_ b_ModulNbr, |
1300| UINT_ ui_TimeOut, |
1301| PBYTE_ 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 : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
1327| BYTE_ 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| PULONG 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
71b5f4f1 1358INT i_APCI1710_ReadChronoValue(struct comedi_device * dev,
c995fe94
ADG
1359 BYTE b_ModulNbr,
1360 UINT ui_TimeOut, PBYTE pb_ChronoStatus, PULONG pul_ChronoValue)
1361{
1362 INT i_ReturnValue = 0;
1363 DWORD dw_Status;
1364 DWORD 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 >= 0)
1390 && (ui_TimeOut <= 65535UL)) {
1391
1392 for (;;) {
1393 /*******************/
1394 /* Read the status */
1395 /*******************/
1396
1397 dw_Status =
1398 inl(devpriv->
1399 s_BoardInfos.
1400 ui_Address + 8 +
1401 (64 * b_ModulNbr));
1402
1403 /********************/
1404 /* Test if overflow */
1405 /********************/
1406
1407 if ((dw_Status & 8) == 8) {
1408 /******************/
1409 /* Overflow occur */
1410 /******************/
1411
1412 *pb_ChronoStatus = 3;
1413
1414 /***************************/
1415 /* Test if continuous mode */
1416 /***************************/
1417
1418 if (devpriv->
1419 s_ModuleInfo
1420 [b_ModulNbr].
1421 s_ChronoModuleInfo.
1422 b_CycleMode ==
1423 APCI1710_CONTINUOUS)
1424 {
1425 /*************************/
1426 /* Clear status register */
1427 /*************************/
1428
1429 outl(0, devpriv->s_BoardInfos.ui_Address + 36 + (64 * b_ModulNbr));
1430 }
1431
1432 break;
1433 } // if ((dw_Status & 8) == 8)
1434 else {
1435 /*******************************/
1436 /* Test if measurement stopped */
1437 /*******************************/
1438
1439 if ((dw_Status & 2) ==
1440 2) {
1441 /***********************/
1442 /* A stop signal occur */
1443 /***********************/
1444
1445 *pb_ChronoStatus
1446 = 2;
1447
1448 /***************************/
1449 /* Test if continnous mode */
1450 /***************************/
1451
1452 if (devpriv->
1453 s_ModuleInfo
1454 [b_ModulNbr].
1455 s_ChronoModuleInfo.
1456 b_CycleMode
1457 ==
1458 APCI1710_CONTINUOUS)
1459 {
1460 /*************************/
1461 /* Clear status register */
1462 /*************************/
1463
1464 outl(0, devpriv->s_BoardInfos.ui_Address + 36 + (64 * b_ModulNbr));
1465 }
1466 break;
1467 } // if ((dw_Status & 2) == 2)
1468 else {
1469 /*******************************/
1470 /* Test if measurement started */
1471 /*******************************/
1472
1473 if ((dw_Status & 1) == 1) {
1474 /************************/
1475 /* A start signal occur */
1476 /************************/
1477
1478 *pb_ChronoStatus
1479 =
1480 1;
1481 } // if ((dw_Status & 1) == 1)
1482 else {
1483 /***************************/
1484 /* Measurement not started */
1485 /***************************/
1486
1487 *pb_ChronoStatus
1488 =
1489 0;
1490 } // if ((dw_Status & 1) == 1)
1491 } // if ((dw_Status & 2) == 2)
1492 } // if ((dw_Status & 8) == 8)
1493
1494 if (dw_TimeOut == ui_TimeOut) {
1495 /*****************/
1496 /* Timeout occur */
1497 /*****************/
1498
1499 break;
1500 } else {
1501 /*************************/
1502 /* Increment the timeout */
1503 /*************************/
1504
1505 dw_TimeOut =
1506 dw_TimeOut + 1;
1507 mdelay(1000);
1508
1509 }
1510 } // for (;;)
1511
1512 /*****************************/
1513 /* Test if stop signal occur */
1514 /*****************************/
1515
1516 if (*pb_ChronoStatus == 2) {
1517 /**********************************/
1518 /* Read the measured timing value */
1519 /**********************************/
1520
1521 *pul_ChronoValue =
1522 inl(devpriv->
1523 s_BoardInfos.
1524 ui_Address + 4 +
1525 (64 * b_ModulNbr));
1526
1527 if (*pul_ChronoValue != 0) {
1528 *pul_ChronoValue =
1529 *pul_ChronoValue
1530 - 1;
1531 }
1532 } else {
1533 /*************************/
1534 /* Test if timeout occur */
1535 /*************************/
1536
1537 if ((*pb_ChronoStatus != 3)
1538 && (dw_TimeOut ==
1539 ui_TimeOut)
1540 && (ui_TimeOut != 0)) {
1541 /*****************/
1542 /* Timeout occur */
1543 /*****************/
1544
1545 *pb_ChronoStatus = 4;
1546 }
1547 }
1548
1549 } else {
1550 /******************************/
1551 /* Timeout parameter is wrong */
1552 /******************************/
1553 DPRINTK("Timeout parameter is wrong\n");
1554 i_ReturnValue = -5;
1555 }
1556 } else {
1557 /*******************************/
1558 /* Chronometer not initialised */
1559 /*******************************/
1560 DPRINTK("Chronometer not initialised\n");
1561 i_ReturnValue = -4;
1562 }
1563 } else {
1564 /******************************************/
1565 /* The module is not a Chronometer module */
1566 /******************************************/
1567 DPRINTK("The module is not a Chronometer module\n");
1568 i_ReturnValue = -3;
1569 }
1570 } else {
1571 /***********************/
1572 /* Module number error */
1573 /***********************/
1574 DPRINTK("Module number error\n");
1575 i_ReturnValue = -2;
1576 }
1577
1578 return (i_ReturnValue);
1579}
1580
1581/*
1582+----------------------------------------------------------------------------+
1583| Function Name : _INT_ i_APCI1710_ConvertChronoValue |
1584| (BYTE_ b_BoardHandle, |
1585| BYTE_ b_ModulNbr, |
1586| ULONG_ ul_ChronoValue, |
1587| PULONG_ pul_Hour, |
1588| PBYTE_ pb_Minute, |
1589| PBYTE_ pb_Second, |
1590| PUINT_ pui_MilliSecond, |
1591| PUINT_ pui_MicroSecond, |
1592| PUINT_ pui_NanoSecond) |
1593+----------------------------------------------------------------------------+
1594| Task : Convert the chronometer measured timing |
1595| (ul_ChronoValue) in to h, mn, s, ms, µs, ns. |
1596+----------------------------------------------------------------------------+
1597| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
1598| BYTE_ b_ModulNbr : Selected module number (0 to 3)|
1599| ULONG_ ul_ChronoValue : Measured chronometer timing |
1600| value. |
1601| See"i_APCI1710_ReadChronoValue"|
1602+----------------------------------------------------------------------------+
1603| Output Parameters : PULONG_ pul_Hour : Chronometer timing hour |
1604| PBYTE_ pb_Minute : Chronometer timing minute |
1605| PBYTE_ pb_Second : Chronometer timing second |
1606| PUINT_ pui_MilliSecond : Chronometer timing mini |
1607| second |
1608| PUINT_ pui_MicroSecond : Chronometer timing micro |
1609| second |
1610| PUINT_ pui_NanoSecond : Chronometer timing nano |
1611| second |
1612+----------------------------------------------------------------------------+
1613| Return Value : 0: No error |
1614| -1: The handle parameter of the board is wrong |
1615| -2: Module selection wrong |
1616| -3: The module is not a Chronometer module |
1617| -4: Chronometer not initialised see function |
1618| "i_APCI1710_InitChrono" |
1619+----------------------------------------------------------------------------+
1620*/
1621
71b5f4f1 1622INT i_APCI1710_ConvertChronoValue(struct comedi_device * dev,
c995fe94
ADG
1623 BYTE b_ModulNbr,
1624 ULONG ul_ChronoValue,
1625 PULONG pul_Hour,
1626 PBYTE pb_Minute,
1627 PBYTE pb_Second,
1628 PUINT pui_MilliSecond, PUINT pui_MicroSecond, PUINT pui_NanoSecond)
1629{
1630 INT i_ReturnValue = 0;
1631 double d_Hour;
1632 double d_Minute;
1633 double d_Second;
1634 double d_MilliSecond;
1635 double d_MicroSecond;
1636 double d_NanoSecond;
1637
1638 /**************************/
1639 /* Test the module number */
1640 /**************************/
1641
1642 if (b_ModulNbr < 4) {
1643 /***********************/
1644 /* Test if chronometer */
1645 /***********************/
1646
1647 if ((devpriv->s_BoardInfos.
1648 dw_MolduleConfiguration[b_ModulNbr] &
1649 0xFFFF0000UL) == APCI1710_CHRONOMETER) {
1650 /***********************************/
1651 /* Test if chronometer initialised */
1652 /***********************************/
1653
1654 if (devpriv->
1655 s_ModuleInfo[b_ModulNbr].
1656 s_ChronoModuleInfo.b_ChronoInit == 1) {
1657 fpu_begin();
1658
1659 d_Hour = (double)ul_ChronoValue *(double)
1660 devpriv->s_ModuleInfo[b_ModulNbr].
1661 s_ChronoModuleInfo.d_TimingInterval;
1662
1663 switch (devpriv->
1664 s_ModuleInfo[b_ModulNbr].
1665 s_ChronoModuleInfo.b_TimingUnit) {
1666 case 0:
1667 d_Hour = d_Hour / (double)1000.0;
1668
1669 case 1:
1670 d_Hour = d_Hour / (double)1000.0;
1671
1672 case 2:
1673 d_Hour = d_Hour / (double)1000.0;
1674
1675 case 3:
1676 d_Hour = d_Hour / (double)60.0;
1677
1678 case 4:
1679 /**********************/
1680 /* Calculate the hour */
1681 /**********************/
1682
1683 d_Hour = d_Hour / (double)60.0;
1684 *pul_Hour = (ULONG) d_Hour;
1685
1686 /************************/
1687 /* Calculate the minute */
1688 /************************/
1689
1690 d_Minute = d_Hour - *pul_Hour;
1691 d_Minute = d_Minute * 60;
1692 *pb_Minute = (BYTE) d_Minute;
1693
1694 /************************/
1695 /* Calculate the second */
1696 /************************/
1697
1698 d_Second = d_Minute - *pb_Minute;
1699 d_Second = d_Second * 60;
1700 *pb_Second = (BYTE) d_Second;
1701
1702 /*****************************/
1703 /* Calculate the mini second */
1704 /*****************************/
1705
1706 d_MilliSecond = d_Second - *pb_Second;
1707 d_MilliSecond = d_MilliSecond * 1000;
1708 *pui_MilliSecond = (UINT) d_MilliSecond;
1709
1710 /******************************/
1711 /* Calculate the micro second */
1712 /******************************/
1713
1714 d_MicroSecond =
1715 d_MilliSecond -
1716 *pui_MilliSecond;
1717 d_MicroSecond = d_MicroSecond * 1000;
1718 *pui_MicroSecond = (UINT) d_MicroSecond;
1719
1720 /******************************/
1721 /* Calculate the micro second */
1722 /******************************/
1723
1724 d_NanoSecond =
1725 d_MicroSecond -
1726 *pui_MicroSecond;
1727 d_NanoSecond = d_NanoSecond * 1000;
1728 *pui_NanoSecond = (UINT) d_NanoSecond;
1729 break;
1730 }
1731
1732 fpu_end();
1733 } else {
1734 /*******************************/
1735 /* Chronometer not initialised */
1736 /*******************************/
1737 DPRINTK("Chronometer not initialised\n");
1738 i_ReturnValue = -4;
1739 }
1740 } else {
1741 /******************************************/
1742 /* The module is not a Chronometer module */
1743 /******************************************/
1744 DPRINTK("The module is not a Chronometer module\n");
1745 i_ReturnValue = -3;
1746 }
1747 } else {
1748 /***********************/
1749 /* Module number error */
1750 /***********************/
1751 DPRINTK("Module number error\n");
1752 i_ReturnValue = -2;
1753 }
1754
1755 return (i_ReturnValue);
1756}
1757
1758/*
1759+----------------------------------------------------------------------------+
71b5f4f1 1760| Function Name : INT i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device *dev,comedi_subdevice *s,
790c5541 1761 comedi_insn *insn,unsigned int *data) |
c995fe94
ADG
1762+----------------------------------------------------------------------------+
1763| Task : Sets the output witch has been passed with the |
1764| parameter b_Channel. Setting an output means setting an|
1765| output high. |
1766+----------------------------------------------------------------------------+
1767| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
1768| BYTE_ b_ModulNbr : Selected module number (0 to 3)|
1769| BYTE_ b_OutputChannel : Selection from digital output |
1770| CR_CHAN() channel (0 to 2) |
1771| 0 : Channel H |
1772| 1 : Channel A |
1773| 2 : Channel B |
1774+----------------------------------------------------------------------------+
1775| Output Parameters : - |
1776+----------------------------------------------------------------------------+
1777| Return Value : 0: No error |
1778| -1: The handle parameter of the board is wrong |
1779| -2: Module selection wrong |
1780| -3: The module is not a Chronometer module |
1781| -4: The selected digital output is wrong |
1782| -5: Chronometer not initialised see function |
1783| "i_APCI1710_InitChrono" |
1784+----------------------------------------------------------------------------+
1785*/
1786
1787/*
1788+----------------------------------------------------------------------------+
1789| Function Name : _INT_ i_APCI1710_SetChronoChlOff |
1790| (BYTE_ b_BoardHandle, |
1791| BYTE_ b_ModulNbr, |
1792| BYTE_ b_OutputChannel) |
1793+----------------------------------------------------------------------------+
1794| Task : Resets the output witch has been passed with the |
1795| parameter b_Channel. Resetting an output means setting |
1796| an output low. |
1797+----------------------------------------------------------------------------+
1798| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710
1799 data[0] : Chl ON, Chl OFF , Chl Read , Port Read
1800
1801| BYTE_ b_ModulNbr CR_AREF : Selected module number (0 to 3)|
1802| BYTE_ b_OutputChannel CR_CHAN : Selection from digital output |
1803| channel (0 to 2) |
1804| 0 : Channel H |
1805| 1 : Channel A |
1806| 2 : Channel B |
1807+----------------------------------------------------------------------------+
1808| Output Parameters : - |
1809+----------------------------------------------------------------------------+
1810| Return Value : 0: No error |
1811| -1: The handle parameter of the board is wrong |
1812| -2: Module selection wrong |
1813| -3: The module is not a Chronometer module |
1814| -4: The selected digital output is wrong |
1815| -5: Chronometer not initialised see function |
1816| "i_APCI1710_InitChrono" |
1817+----------------------------------------------------------------------------+
1818*/
1819
1820/*
1821+----------------------------------------------------------------------------+
1822| Function Name : _INT_ i_APCI1710_ReadChronoChlValue |
1823| (BYTE_ b_BoardHandle, |
1824| BYTE_ b_ModulNbr, |
1825| BYTE_ b_InputChannel, |
1826| PBYTE_ pb_ChannelStatus) |
1827+----------------------------------------------------------------------------+
1828| Task : Return the status from selected digital input |
1829| (b_InputChannel) from selected chronometer |
1830| module (b_ModulNbr). |
1831+----------------------------------------------------------------------------+
1832| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
1833| BYTE_ b_ModulNbr : Selected module number (0 to 3)|
1834| BYTE_ b_InputChannel : Selection from digital input |
1835| channel (0 to 2) |
1836| CR_CHAN() 0 : Channel E |
1837| 1 : Channel F |
1838| 2 : Channel G |
1839+----------------------------------------------------------------------------+
1840| Output Parameters : PBYTE_ pb_ChannelStatus : Digital input channel status.|
1841| data[0] 0 : Channel is not active |
1842| 1 : Channel is active |
1843+----------------------------------------------------------------------------+
1844| Return Value : 0: No error |
1845| -1: The handle parameter of the board is wrong |
1846| -2: Module selection wrong |
1847| -3: The module is not a Chronometer module |
1848| -4: The selected digital input is wrong |
1849| -5: Chronometer not initialised see function |
1850| "i_APCI1710_InitChrono" |
1851+----------------------------------------------------------------------------+
1852*/
1853
1854/*
1855+----------------------------------------------------------------------------+
1856| Function Name : _INT_ i_APCI1710_ReadChronoPortValue |
1857| (BYTE_ b_BoardHandle, |
1858| BYTE_ b_ModulNbr, |
1859| PBYTE_ pb_PortValue) |
1860+----------------------------------------------------------------------------+
1861| Task : Return the status from digital inputs port from |
1862| selected (b_ModulNbr) chronometer module. |
1863+----------------------------------------------------------------------------+
1864| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
1865| BYTE_ b_ModulNbr : Selected module number (0 to 3)|
1866+----------------------------------------------------------------------------+
1867| Output Parameters : PBYTE_ pb_PortValue : Digital inputs port status.
1868| data[0]
1869+----------------------------------------------------------------------------+
1870| Return Value : 0: No error |
1871| -1: The handle parameter of the board is wrong |
1872| -2: Module selection wrong |
1873| -3: The module is not a Chronometer module |
1874| -4: Chronometer not initialised see function |
1875| "i_APCI1710_InitChrono" |
1876+----------------------------------------------------------------------------+
1877*/
1878
71b5f4f1 1879INT i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device * dev,
790c5541 1880 comedi_subdevice * s, comedi_insn * insn, unsigned int * data)
c995fe94
ADG
1881{
1882 INT i_ReturnValue = 0;
1883 BYTE b_ModulNbr, b_OutputChannel, b_InputChannel, b_IOType;
1884 DWORD dw_Status;
1885 PBYTE pb_ChannelStatus;
1886 PBYTE pb_PortValue;
1887
1888 b_ModulNbr = CR_AREF(insn->chanspec);
1889 i_ReturnValue = insn->n;
1890 b_IOType = (BYTE) data[0];
1891
1892 /**************************/
1893 /* Test the module number */
1894 /**************************/
1895
1896 if (b_ModulNbr < 4) {
1897 /***********************/
1898 /* Test if chronometer */
1899 /***********************/
1900
1901 if ((devpriv->s_BoardInfos.
1902 dw_MolduleConfiguration[b_ModulNbr] &
1903 0xFFFF0000UL) == APCI1710_CHRONOMETER) {
1904 /***********************************/
1905 /* Test if chronometer initialised */
1906 /***********************************/
1907
1908 if (devpriv->s_ModuleInfo[b_ModulNbr].
1909 s_ChronoModuleInfo.b_ChronoInit == 1) {
1910 /***********************************/
1911 /* Test the digital output channel */
1912 /***********************************/
1913 switch (b_IOType) {
1914
1915 case APCI1710_CHRONO_SET_CHANNELOFF:
1916
1917 b_OutputChannel =
1918 (BYTE) CR_CHAN(insn->chanspec);
1919 if (b_OutputChannel <= 2) {
1920
1921 outl(0, devpriv->s_BoardInfos.
1922 ui_Address + 20 +
1923 (b_OutputChannel * 4) +
1924 (64 * b_ModulNbr));
1925 } // if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2))
1926 else {
1927 /****************************************/
1928 /* The selected digital output is wrong */
1929 /****************************************/
1930
1931 DPRINTK("The selected digital output is wrong\n");
1932 i_ReturnValue = -4;
1933
1934 } // if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2))
1935
1936 break;
1937
1938 case APCI1710_CHRONO_SET_CHANNELON:
1939
1940 b_OutputChannel =
1941 (BYTE) CR_CHAN(insn->chanspec);
1942 if (b_OutputChannel <= 2) {
1943
1944 outl(1, devpriv->s_BoardInfos.
1945 ui_Address + 20 +
1946 (b_OutputChannel * 4) +
1947 (64 * b_ModulNbr));
1948 } // if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2))
1949 else {
1950 /****************************************/
1951 /* The selected digital output is wrong */
1952 /****************************************/
1953
1954 DPRINTK("The selected digital output is wrong\n");
1955 i_ReturnValue = -4;
1956
1957 } // if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2))
1958
1959 break;
1960
1961 case APCI1710_CHRONO_READ_CHANNEL:
1962 /**********************************/
1963 /* Test the digital input channel */
1964 /**********************************/
1965 pb_ChannelStatus = (PBYTE) & data[0];
1966 b_InputChannel =
1967 (BYTE) CR_CHAN(insn->chanspec);
1968
1969 if (b_InputChannel <= 2) {
1970
1971 dw_Status =
1972 inl(devpriv->
1973 s_BoardInfos.
1974 ui_Address + 12 +
1975 (64 * b_ModulNbr));
1976
1977 *pb_ChannelStatus =
1978 (BYTE) (((dw_Status >>
1979 b_InputChannel)
1980 & 1) ^ 1);
1981 } // if ((b_InputChannel >= 0) && (b_InputChannel <= 2))
1982 else {
1983 /***************************************/
1984 /* The selected digital input is wrong */
1985 /***************************************/
1986
1987 DPRINTK("The selected digital input is wrong\n");
1988 i_ReturnValue = -4;
1989 } // if ((b_InputChannel >= 0) && (b_InputChannel <= 2))
1990
1991 break;
1992
1993 case APCI1710_CHRONO_READ_PORT:
1994
1995 pb_PortValue = (PBYTE) & data[0];
1996
1997 dw_Status =
1998 inl(devpriv->s_BoardInfos.
1999 ui_Address + 12 +
2000 (64 * b_ModulNbr));
2001
2002 *pb_PortValue =
2003 (BYTE) ((dw_Status & 0x7) ^ 7);
2004 break;
2005 }
2006 } else {
2007 /*******************************/
2008 /* Chronometer not initialised */
2009 /*******************************/
2010
2011 DPRINTK("Chronometer not initialised\n");
2012 i_ReturnValue = -5;
2013 }
2014 } else {
2015 /******************************************/
2016 /* The module is not a Chronometer module */
2017 /******************************************/
2018
2019 DPRINTK("The module is not a Chronometer module\n");
2020 i_ReturnValue = -3;
2021 }
2022 } else {
2023 /***********************/
2024 /* Module number error */
2025 /***********************/
2026
2027 DPRINTK("Module number error\n");
2028 i_ReturnValue = -2;
2029 }
2030
2031 return (i_ReturnValue);
2032}