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