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