APCI1710_Pwm.c revision c995fe9475e062bab6f5a45ed28cd2d3d955ef43
1/**
2@verbatim
3
4Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
5
6        ADDI-DATA GmbH
7        Dieselstrasse 3
8        D-77833 Ottersweier
9        Tel: +19(0)7223/9493-0
10        Fax: +49(0)7223/9493-92
11        http://www.addi-data-com
12        info@addi-data.com
13
14This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
15
16This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20You shoud also find the complete GPL in the COPYING file accompanying this source code.
21
22@endverbatim
23*/
24/*
25
26  +-----------------------------------------------------------------------+
27  | (C) ADDI-DATA GmbH          Dieselstraße 3       D-77833 Ottersweier  |
28  +-----------------------------------------------------------------------+
29  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
30  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
31  +-----------------------------------------------------------------------+
32  | Project     : API APCI1710    | Compiler : gcc                        |
33  | Module name : PWM.C           | Version  : 2.96                       |
34  +-------------------------------+---------------------------------------+
35  | Project manager: Eric Stolz   | Date     :  02/12/2002                |
36  +-----------------------------------------------------------------------+
37  | Description :   APCI-1710 Wulse wide modulation module                |
38  |                                                                       |
39  |                                                                       |
40  +-----------------------------------------------------------------------+
41  |                             UPDATES                                   |
42  +-----------------------------------------------------------------------+
43  |   Date   |   Author  |          Description of updates                |
44  +-----------------------------------------------------------------------+
45  | 08/05/00 | Guinot C  | - 0400/0228 All Function in RING 0             |
46  |          |           |   available                                    |
47  +-----------------------------------------------------------------------+
48*/
49
50/*
51+----------------------------------------------------------------------------+
52|                               Included files                               |
53+----------------------------------------------------------------------------+
54*/
55
56#include "APCI1710_Pwm.h"
57
58/*
59+----------------------------------------------------------------------------+
60| Function Name     :INT i_APCI1710_InsnConfigPWM(comedi_device *dev,
61comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)                        |
62+----------------------------------------------------------------------------+
63| Task              : Pwm Init and Get Pwm Initialisation                    |
64+----------------------------------------------------------------------------+
65| Input Parameters  :
66+----------------------------------------------------------------------------+
67| Output Parameters : -                                                      |
68+----------------------------------------------------------------------------+
69| Return Value      :
70+----------------------------------------------------------------------------+
71*/
72
73INT i_APCI1710_InsnConfigPWM(comedi_device * dev, comedi_subdevice * s,
74	comedi_insn * insn, lsampl_t * data)
75{
76	BYTE b_ConfigType;
77	INT i_ReturnValue = 0;
78	b_ConfigType = CR_CHAN(insn->chanspec);
79
80	switch (b_ConfigType) {
81	case APCI1710_PWM_INIT:
82		i_ReturnValue = i_APCI1710_InitPWM(dev, (BYTE) CR_AREF(insn->chanspec),	//  b_ModulNbr
83			(BYTE) data[0],	//b_PWM
84			(BYTE) data[1],	// b_ClockSelection
85			(BYTE) data[2],	// b_TimingUnit
86			(ULONG) data[3],	//ul_LowTiming
87			(ULONG) data[4],	//ul_HighTiming
88			(PULONG) & data[0],	//pul_RealLowTiming
89			(PULONG) & data[1]	//pul_RealHighTiming
90			);
91		break;
92
93	case APCI1710_PWM_GETINITDATA:
94		i_ReturnValue = i_APCI1710_GetPWMInitialisation(dev, (BYTE) CR_AREF(insn->chanspec),	// b_ModulNbr
95			(BYTE) data[0],	//b_PWM
96			(PBYTE) & data[0],	//pb_TimingUnit
97			(PULONG) & data[1],	//pul_LowTiming
98			(PULONG) & data[2],	//pul_HighTiming
99			(PBYTE) & data[3],	// pb_StartLevel
100			(PBYTE) & data[4],	// pb_StopMode
101			(PBYTE) & data[5],	// pb_StopLevel
102			(PBYTE) & data[6],	// pb_ExternGate
103			(PBYTE) & data[7],	// pb_InterruptEnable
104			(PBYTE) & data[8]	// pb_Enable
105			);
106		break;
107
108	default:
109		printk(" Config Parameter Wrong\n");
110	}
111
112	if (i_ReturnValue >= 0)
113		i_ReturnValue = insn->n;
114	return (i_ReturnValue);
115}
116
117/*
118+----------------------------------------------------------------------------+
119| Function Name     : _INT_ i_APCI1710_InitPWM                               |
120|                                       (BYTE_     b_BoardHandle,            |
121|                                        BYTE_     b_ModulNbr,               |
122|                                        BYTE_     b_PWM,                    |
123|                                        BYTE_     b_ClockSelection,         |
124|                                        BYTE_     b_TimingUnit,             |
125|                                        ULONG_   ul_LowTiming,              |
126|                                        ULONG_   ul_HighTiming,             |
127|                                        PULONG_ pul_RealLowTiming,          |
128|                                        PULONG_ pul_RealHighTiming)         |
129+----------------------------------------------------------------------------+
130| Task              : Configure the selected PWM (b_PWM) from selected module|
131|                     (b_ModulNbr). The ul_LowTiming, ul_HighTiming and      |
132|                     ul_TimingUnit determine the low/high timing base for   |
133|                     the period. pul_RealLowTiming, pul_RealHighTiming      |
134|                     return the real timing value.                          |
135|                     You must calling this function be for you call any     |
136|                     other function witch access of the PWM.                |
137+----------------------------------------------------------------------------+
138| Input Parameters  : BYTE_     b_BoardHandle    : Handle of board APCI-1710 |
139|                     BYTE_     b_ModulNbr       : Module number to configure|
140|                                                  (0 to 3)                  |
141|                     BYTE_     b_PWM            : Selected PWM (0 or 1).    |
142|                     BYTE_     b_ClockSelection : Selection from PCI bus    |
143|                                                  clock                     |
144|                                                   - APCI1710_30MHZ :       |
145|                                                     The PC have a 30 MHz   |
146|                                                     PCI bus clock          |
147|                                                   - APCI1710_33MHZ :       |
148|                                                     The PC have a 33 MHz   |
149|                                                     PCI bus clock          |
150|                                                   - APCI1710_40MHZ         |
151|                                                     The APCI-1710 have a   |
152|                                                     integrated 40Mhz       |
153|                                                     quartz.                |
154|                     BYTE_     b_TimingUnit     : Base timing Unit (0 to 4) |
155|                                                       0 : ns               |
156|                                                       1 : æs               |
157|                                                       2 : ms               |
158|                                                       3 : s                |
159|                                                       4 : mn               |
160|                     ULONG_    ul_LowTiming     : Low base timing value.    |
161|                     ULONG_    ul_HighTiming    : High base timing value.   |
162+----------------------------------------------------------------------------+
163| Output Parameters : PULONG_  pul_RealLowTiming  : Real low base timing     |
164|                                                   value.                   |
165|                     PULONG_  pul_RealHighTiming : Real high base timing    |
166|                                                   value.                   |
167+----------------------------------------------------------------------------+
168| Return Value      : 0: No error                                            |
169|                    -1: The handle parameter of the board is wrong          |
170|                    -2: Module selection wrong                              |
171|                    -3: The module is not a PWM module                      |
172|                    -4: PWM selection is wrong                              |
173|                    -5: The selected input clock is wrong                   |
174|                    -6: Timing Unit selection is wrong                      |
175|                    -7: Low base timing selection is wrong                  |
176|                    -8: High base timing selection is wrong                 |
177|                    -9: You can not used the 40MHz clock selection with     |
178|                        this board                                          |
179+----------------------------------------------------------------------------+
180*/
181
182INT i_APCI1710_InitPWM(comedi_device * dev,
183	BYTE b_ModulNbr,
184	BYTE b_PWM,
185	BYTE b_ClockSelection,
186	BYTE b_TimingUnit,
187	ULONG ul_LowTiming,
188	ULONG ul_HighTiming,
189	PULONG pul_RealLowTiming, PULONG pul_RealHighTiming)
190{
191	INT i_ReturnValue = 0;
192	ULONG ul_LowTimerValue = 0;
193	ULONG ul_HighTimerValue = 0;
194	DWORD dw_Command;
195	double d_RealLowTiming = 0;
196	double d_RealHighTiming = 0;
197
198	/**************************/
199	/* Test the module number */
200	/**************************/
201
202	if (b_ModulNbr < 4) {
203	   /***************/
204		/* Test if PWM */
205	   /***************/
206
207		if ((devpriv->s_BoardInfos.
208				dw_MolduleConfiguration[b_ModulNbr] &
209				0xFFFF0000UL) == APCI1710_PWM) {
210	      /**************************/
211			/* Test the PWM selection */
212	      /**************************/
213
214			if (b_PWM <= 1) {
215		 /******************/
216				/* Test the clock */
217		 /******************/
218
219				if ((b_ClockSelection == APCI1710_30MHZ) ||
220					(b_ClockSelection == APCI1710_33MHZ) ||
221					(b_ClockSelection == APCI1710_40MHZ)) {
222		    /************************/
223					/* Test the timing unit */
224		    /************************/
225
226					if (b_TimingUnit <= 4) {
227		       /*********************************/
228						/* Test the low timing selection */
229		       /*********************************/
230
231						if (((b_ClockSelection ==
232									APCI1710_30MHZ)
233								&& (b_TimingUnit
234									== 0)
235								&& (ul_LowTiming
236									>= 266)
237								&& (ul_LowTiming
238									<=
239									0xFFFFFFFFUL))
240							|| ((b_ClockSelection ==
241									APCI1710_30MHZ)
242								&& (b_TimingUnit
243									== 1)
244								&& (ul_LowTiming
245									>= 1)
246								&& (ul_LowTiming
247									<=
248									571230650UL))
249							|| ((b_ClockSelection ==
250									APCI1710_30MHZ)
251								&& (b_TimingUnit
252									== 2)
253								&& (ul_LowTiming
254									>= 1)
255								&& (ul_LowTiming
256									<=
257									571230UL))
258							|| ((b_ClockSelection ==
259									APCI1710_30MHZ)
260								&& (b_TimingUnit
261									== 3)
262								&& (ul_LowTiming
263									>= 1)
264								&& (ul_LowTiming
265									<=
266									571UL))
267							|| ((b_ClockSelection ==
268									APCI1710_30MHZ)
269								&& (b_TimingUnit
270									== 4)
271								&& (ul_LowTiming
272									>= 1)
273								&& (ul_LowTiming
274									<= 9UL))
275							|| ((b_ClockSelection ==
276									APCI1710_33MHZ)
277								&& (b_TimingUnit
278									== 0)
279								&& (ul_LowTiming
280									>= 242)
281								&& (ul_LowTiming
282									<=
283									0xFFFFFFFFUL))
284							|| ((b_ClockSelection ==
285									APCI1710_33MHZ)
286								&& (b_TimingUnit
287									== 1)
288								&& (ul_LowTiming
289									>= 1)
290								&& (ul_LowTiming
291									<=
292									519691043UL))
293							|| ((b_ClockSelection ==
294									APCI1710_33MHZ)
295								&& (b_TimingUnit
296									== 2)
297								&& (ul_LowTiming
298									>= 1)
299								&& (ul_LowTiming
300									<=
301									519691UL))
302							|| ((b_ClockSelection ==
303									APCI1710_33MHZ)
304								&& (b_TimingUnit
305									== 3)
306								&& (ul_LowTiming
307									>= 1)
308								&& (ul_LowTiming
309									<=
310									520UL))
311							|| ((b_ClockSelection ==
312									APCI1710_33MHZ)
313								&& (b_TimingUnit
314									== 4)
315								&& (ul_LowTiming
316									>= 1)
317								&& (ul_LowTiming
318									<= 8UL))
319							|| ((b_ClockSelection ==
320									APCI1710_40MHZ)
321								&& (b_TimingUnit
322									== 0)
323								&& (ul_LowTiming
324									>= 200)
325								&& (ul_LowTiming
326									<=
327									0xFFFFFFFFUL))
328							|| ((b_ClockSelection ==
329									APCI1710_40MHZ)
330								&& (b_TimingUnit
331									== 1)
332								&& (ul_LowTiming
333									>= 1)
334								&& (ul_LowTiming
335									<=
336									429496729UL))
337							|| ((b_ClockSelection ==
338									APCI1710_40MHZ)
339								&& (b_TimingUnit
340									== 2)
341								&& (ul_LowTiming
342									>= 1)
343								&& (ul_LowTiming
344									<=
345									429496UL))
346							|| ((b_ClockSelection ==
347									APCI1710_40MHZ)
348								&& (b_TimingUnit
349									== 3)
350								&& (ul_LowTiming
351									>= 1)
352								&& (ul_LowTiming
353									<=
354									429UL))
355							|| ((b_ClockSelection ==
356									APCI1710_40MHZ)
357								&& (b_TimingUnit
358									== 4)
359								&& (ul_LowTiming
360									>= 1)
361								&& (ul_LowTiming
362									<=
363									7UL))) {
364			  /**********************************/
365							/* Test the High timing selection */
366			  /**********************************/
367
368							if (((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 266) && (ul_HighTiming <= 0xFFFFFFFFUL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571230650UL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571230UL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571UL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 9UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 242) && (ul_HighTiming <= 0xFFFFFFFFUL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 519691043UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 519691UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 520UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 8UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 200) && (ul_HighTiming <= 0xFFFFFFFFUL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429496729UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429496UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 7UL))) {
369			     /**************************/
370								/* Test the board version */
371			     /**************************/
372
373								if (((b_ClockSelection == APCI1710_40MHZ) && (devpriv->s_BoardInfos.b_BoardVersion > 0)) || (b_ClockSelection != APCI1710_40MHZ)) {
374
375				/************************************/
376									/* Calculate the low division fator */
377				/************************************/
378
379									fpu_begin
380										();
381
382									switch (b_TimingUnit) {
383				   /******/
384										/* ns */
385				   /******/
386
387									case 0:
388
389					   /******************/
390										/* Timer 0 factor */
391					   /******************/
392
393										ul_LowTimerValue
394											=
395											(ULONG)
396											(ul_LowTiming
397											*
398											(0.00025 * b_ClockSelection));
399
400					   /*******************/
401										/* Round the value */
402					   /*******************/
403
404										if ((double)((double)ul_LowTiming * (0.00025 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
405											ul_LowTimerValue
406												=
407												ul_LowTimerValue
408												+
409												1;
410										}
411
412					   /*****************************/
413										/* Calculate the real timing */
414					   /*****************************/
415
416										*pul_RealLowTiming
417											=
418											(ULONG)
419											(ul_LowTimerValue
420											/
421											(0.00025 * (double)b_ClockSelection));
422										d_RealLowTiming
423											=
424											(double)
425											ul_LowTimerValue
426											/
427											(0.00025
428											*
429											(double)
430											b_ClockSelection);
431
432										if ((double)((double)ul_LowTimerValue / (0.00025 * (double)b_ClockSelection)) >= (double)((double)*pul_RealLowTiming + 0.5)) {
433											*pul_RealLowTiming
434												=
435												*pul_RealLowTiming
436												+
437												1;
438										}
439
440										ul_LowTiming
441											=
442											ul_LowTiming
443											-
444											1;
445										ul_LowTimerValue
446											=
447											ul_LowTimerValue
448											-
449											2;
450
451										if (b_ClockSelection != APCI1710_40MHZ) {
452											ul_LowTimerValue
453												=
454												(ULONG)
455												(
456												(double)
457												(ul_LowTimerValue)
458												*
459												1.007752288);
460										}
461
462										break;
463
464				   /******/
465										/* æs */
466				   /******/
467
468									case 1:
469
470					   /******************/
471										/* Timer 0 factor */
472					   /******************/
473
474										ul_LowTimerValue
475											=
476											(ULONG)
477											(ul_LowTiming
478											*
479											(0.25 * b_ClockSelection));
480
481					   /*******************/
482										/* Round the value */
483					   /*******************/
484
485										if ((double)((double)ul_LowTiming * (0.25 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
486											ul_LowTimerValue
487												=
488												ul_LowTimerValue
489												+
490												1;
491										}
492
493					   /*****************************/
494										/* Calculate the real timing */
495					   /*****************************/
496
497										*pul_RealLowTiming
498											=
499											(ULONG)
500											(ul_LowTimerValue
501											/
502											(0.25 * (double)b_ClockSelection));
503										d_RealLowTiming
504											=
505											(double)
506											ul_LowTimerValue
507											/
508											(
509											(double)
510											0.25
511											*
512											(double)
513											b_ClockSelection);
514
515										if ((double)((double)ul_LowTimerValue / (0.25 * (double)b_ClockSelection)) >= (double)((double)*pul_RealLowTiming + 0.5)) {
516											*pul_RealLowTiming
517												=
518												*pul_RealLowTiming
519												+
520												1;
521										}
522
523										ul_LowTiming
524											=
525											ul_LowTiming
526											-
527											1;
528										ul_LowTimerValue
529											=
530											ul_LowTimerValue
531											-
532											2;
533
534										if (b_ClockSelection != APCI1710_40MHZ) {
535											ul_LowTimerValue
536												=
537												(ULONG)
538												(
539												(double)
540												(ul_LowTimerValue)
541												*
542												1.007752288);
543										}
544
545										break;
546
547				   /******/
548										/* ms */
549				   /******/
550
551									case 2:
552
553					   /******************/
554										/* Timer 0 factor */
555					   /******************/
556
557										ul_LowTimerValue
558											=
559											ul_LowTiming
560											*
561											(250.0
562											*
563											b_ClockSelection);
564
565					   /*******************/
566										/* Round the value */
567					   /*******************/
568
569										if ((double)((double)ul_LowTiming * (250.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
570											ul_LowTimerValue
571												=
572												ul_LowTimerValue
573												+
574												1;
575										}
576
577					   /*****************************/
578										/* Calculate the real timing */
579					   /*****************************/
580
581										*pul_RealLowTiming
582											=
583											(ULONG)
584											(ul_LowTimerValue
585											/
586											(250.0 * (double)b_ClockSelection));
587										d_RealLowTiming
588											=
589											(double)
590											ul_LowTimerValue
591											/
592											(250.0
593											*
594											(double)
595											b_ClockSelection);
596
597										if ((double)((double)ul_LowTimerValue / (250.0 * (double)b_ClockSelection)) >= (double)((double)*pul_RealLowTiming + 0.5)) {
598											*pul_RealLowTiming
599												=
600												*pul_RealLowTiming
601												+
602												1;
603										}
604
605										ul_LowTiming
606											=
607											ul_LowTiming
608											-
609											1;
610										ul_LowTimerValue
611											=
612											ul_LowTimerValue
613											-
614											2;
615
616										if (b_ClockSelection != APCI1710_40MHZ) {
617											ul_LowTimerValue
618												=
619												(ULONG)
620												(
621												(double)
622												(ul_LowTimerValue)
623												*
624												1.007752288);
625										}
626
627										break;
628
629				   /*****/
630										/* s */
631				   /*****/
632
633									case 3:
634					   /******************/
635										/* Timer 0 factor */
636					   /******************/
637
638										ul_LowTimerValue
639											=
640											(ULONG)
641											(ul_LowTiming
642											*
643											(250000.0
644												*
645												b_ClockSelection));
646
647					   /*******************/
648										/* Round the value */
649					   /*******************/
650
651										if ((double)((double)ul_LowTiming * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
652											ul_LowTimerValue
653												=
654												ul_LowTimerValue
655												+
656												1;
657										}
658
659					   /*****************************/
660										/* Calculate the real timing */
661					   /*****************************/
662
663										*pul_RealLowTiming
664											=
665											(ULONG)
666											(ul_LowTimerValue
667											/
668											(250000.0
669												*
670												(double)
671												b_ClockSelection));
672										d_RealLowTiming
673											=
674											(double)
675											ul_LowTimerValue
676											/
677											(250000.0
678											*
679											(double)
680											b_ClockSelection);
681
682										if ((double)((double)ul_LowTimerValue / (250000.0 * (double)b_ClockSelection)) >= (double)((double)*pul_RealLowTiming + 0.5)) {
683											*pul_RealLowTiming
684												=
685												*pul_RealLowTiming
686												+
687												1;
688										}
689
690										ul_LowTiming
691											=
692											ul_LowTiming
693											-
694											1;
695										ul_LowTimerValue
696											=
697											ul_LowTimerValue
698											-
699											2;
700
701										if (b_ClockSelection != APCI1710_40MHZ) {
702											ul_LowTimerValue
703												=
704												(ULONG)
705												(
706												(double)
707												(ul_LowTimerValue)
708												*
709												1.007752288);
710										}
711
712										break;
713
714				   /******/
715										/* mn */
716				   /******/
717
718									case 4:
719
720					   /******************/
721										/* Timer 0 factor */
722					   /******************/
723
724										ul_LowTimerValue
725											=
726											(ULONG)
727											(
728											(ul_LowTiming
729												*
730												60)
731											*
732											(250000.0
733												*
734												b_ClockSelection));
735
736					   /*******************/
737										/* Round the value */
738					   /*******************/
739
740										if ((double)((double)(ul_LowTiming * 60.0) * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
741											ul_LowTimerValue
742												=
743												ul_LowTimerValue
744												+
745												1;
746										}
747
748					   /*****************************/
749										/* Calculate the real timing */
750					   /*****************************/
751
752										*pul_RealLowTiming
753											=
754											(ULONG)
755											(ul_LowTimerValue
756											/
757											(250000.0
758												*
759												(double)
760												b_ClockSelection))
761											/
762											60;
763										d_RealLowTiming
764											=
765											(
766											(double)
767											ul_LowTimerValue
768											/
769											(250000.0
770												*
771												(double)
772												b_ClockSelection))
773											/
774											60.0;
775
776										if ((double)(((double)ul_LowTimerValue / (250000.0 * (double)b_ClockSelection)) / 60.0) >= (double)((double)*pul_RealLowTiming + 0.5)) {
777											*pul_RealLowTiming
778												=
779												*pul_RealLowTiming
780												+
781												1;
782										}
783
784										ul_LowTiming
785											=
786											ul_LowTiming
787											-
788											1;
789										ul_LowTimerValue
790											=
791											ul_LowTimerValue
792											-
793											2;
794
795										if (b_ClockSelection != APCI1710_40MHZ) {
796											ul_LowTimerValue
797												=
798												(ULONG)
799												(
800												(double)
801												(ul_LowTimerValue)
802												*
803												1.007752288);
804										}
805
806										break;
807									}
808
809				/*************************************/
810									/* Calculate the high division fator */
811				/*************************************/
812
813									switch (b_TimingUnit) {
814				   /******/
815										/* ns */
816				   /******/
817
818									case 0:
819
820					   /******************/
821										/* Timer 0 factor */
822					   /******************/
823
824										ul_HighTimerValue
825											=
826											(ULONG)
827											(ul_HighTiming
828											*
829											(0.00025 * b_ClockSelection));
830
831					   /*******************/
832										/* Round the value */
833					   /*******************/
834
835										if ((double)((double)ul_HighTiming * (0.00025 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
836											ul_HighTimerValue
837												=
838												ul_HighTimerValue
839												+
840												1;
841										}
842
843					   /*****************************/
844										/* Calculate the real timing */
845					   /*****************************/
846
847										*pul_RealHighTiming
848											=
849											(ULONG)
850											(ul_HighTimerValue
851											/
852											(0.00025 * (double)b_ClockSelection));
853										d_RealHighTiming
854											=
855											(double)
856											ul_HighTimerValue
857											/
858											(0.00025
859											*
860											(double)
861											b_ClockSelection);
862
863										if ((double)((double)ul_HighTimerValue / (0.00025 * (double)b_ClockSelection)) >= (double)((double)*pul_RealHighTiming + 0.5)) {
864											*pul_RealHighTiming
865												=
866												*pul_RealHighTiming
867												+
868												1;
869										}
870
871										ul_HighTiming
872											=
873											ul_HighTiming
874											-
875											1;
876										ul_HighTimerValue
877											=
878											ul_HighTimerValue
879											-
880											2;
881
882										if (b_ClockSelection != APCI1710_40MHZ) {
883											ul_HighTimerValue
884												=
885												(ULONG)
886												(
887												(double)
888												(ul_HighTimerValue)
889												*
890												1.007752288);
891										}
892
893										break;
894
895				   /******/
896										/* æs */
897				   /******/
898
899									case 1:
900
901					   /******************/
902										/* Timer 0 factor */
903					   /******************/
904
905										ul_HighTimerValue
906											=
907											(ULONG)
908											(ul_HighTiming
909											*
910											(0.25 * b_ClockSelection));
911
912					   /*******************/
913										/* Round the value */
914					   /*******************/
915
916										if ((double)((double)ul_HighTiming * (0.25 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
917											ul_HighTimerValue
918												=
919												ul_HighTimerValue
920												+
921												1;
922										}
923
924					   /*****************************/
925										/* Calculate the real timing */
926					   /*****************************/
927
928										*pul_RealHighTiming
929											=
930											(ULONG)
931											(ul_HighTimerValue
932											/
933											(0.25 * (double)b_ClockSelection));
934										d_RealHighTiming
935											=
936											(double)
937											ul_HighTimerValue
938											/
939											(
940											(double)
941											0.25
942											*
943											(double)
944											b_ClockSelection);
945
946										if ((double)((double)ul_HighTimerValue / (0.25 * (double)b_ClockSelection)) >= (double)((double)*pul_RealHighTiming + 0.5)) {
947											*pul_RealHighTiming
948												=
949												*pul_RealHighTiming
950												+
951												1;
952										}
953
954										ul_HighTiming
955											=
956											ul_HighTiming
957											-
958											1;
959										ul_HighTimerValue
960											=
961											ul_HighTimerValue
962											-
963											2;
964
965										if (b_ClockSelection != APCI1710_40MHZ) {
966											ul_HighTimerValue
967												=
968												(ULONG)
969												(
970												(double)
971												(ul_HighTimerValue)
972												*
973												1.007752288);
974										}
975
976										break;
977
978				   /******/
979										/* ms */
980				   /******/
981
982									case 2:
983
984					   /******************/
985										/* Timer 0 factor */
986					   /******************/
987
988										ul_HighTimerValue
989											=
990											ul_HighTiming
991											*
992											(250.0
993											*
994											b_ClockSelection);
995
996					   /*******************/
997										/* Round the value */
998					   /*******************/
999
1000										if ((double)((double)ul_HighTiming * (250.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
1001											ul_HighTimerValue
1002												=
1003												ul_HighTimerValue
1004												+
1005												1;
1006										}
1007
1008					   /*****************************/
1009										/* Calculate the real timing */
1010					   /*****************************/
1011
1012										*pul_RealHighTiming
1013											=
1014											(ULONG)
1015											(ul_HighTimerValue
1016											/
1017											(250.0 * (double)b_ClockSelection));
1018										d_RealHighTiming
1019											=
1020											(double)
1021											ul_HighTimerValue
1022											/
1023											(250.0
1024											*
1025											(double)
1026											b_ClockSelection);
1027
1028										if ((double)((double)ul_HighTimerValue / (250.0 * (double)b_ClockSelection)) >= (double)((double)*pul_RealHighTiming + 0.5)) {
1029											*pul_RealHighTiming
1030												=
1031												*pul_RealHighTiming
1032												+
1033												1;
1034										}
1035
1036										ul_HighTiming
1037											=
1038											ul_HighTiming
1039											-
1040											1;
1041										ul_HighTimerValue
1042											=
1043											ul_HighTimerValue
1044											-
1045											2;
1046
1047										if (b_ClockSelection != APCI1710_40MHZ) {
1048											ul_HighTimerValue
1049												=
1050												(ULONG)
1051												(
1052												(double)
1053												(ul_HighTimerValue)
1054												*
1055												1.007752288);
1056										}
1057
1058										break;
1059
1060				   /*****/
1061										/* s */
1062				   /*****/
1063
1064									case 3:
1065
1066					   /******************/
1067										/* Timer 0 factor */
1068					   /******************/
1069
1070										ul_HighTimerValue
1071											=
1072											(ULONG)
1073											(ul_HighTiming
1074											*
1075											(250000.0
1076												*
1077												b_ClockSelection));
1078
1079					   /*******************/
1080										/* Round the value */
1081					   /*******************/
1082
1083										if ((double)((double)ul_HighTiming * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
1084											ul_HighTimerValue
1085												=
1086												ul_HighTimerValue
1087												+
1088												1;
1089										}
1090
1091					   /*****************************/
1092										/* Calculate the real timing */
1093					   /*****************************/
1094
1095										*pul_RealHighTiming
1096											=
1097											(ULONG)
1098											(ul_HighTimerValue
1099											/
1100											(250000.0
1101												*
1102												(double)
1103												b_ClockSelection));
1104										d_RealHighTiming
1105											=
1106											(double)
1107											ul_HighTimerValue
1108											/
1109											(250000.0
1110											*
1111											(double)
1112											b_ClockSelection);
1113
1114										if ((double)((double)ul_HighTimerValue / (250000.0 * (double)b_ClockSelection)) >= (double)((double)*pul_RealHighTiming + 0.5)) {
1115											*pul_RealHighTiming
1116												=
1117												*pul_RealHighTiming
1118												+
1119												1;
1120										}
1121
1122										ul_HighTiming
1123											=
1124											ul_HighTiming
1125											-
1126											1;
1127										ul_HighTimerValue
1128											=
1129											ul_HighTimerValue
1130											-
1131											2;
1132
1133										if (b_ClockSelection != APCI1710_40MHZ) {
1134											ul_HighTimerValue
1135												=
1136												(ULONG)
1137												(
1138												(double)
1139												(ul_HighTimerValue)
1140												*
1141												1.007752288);
1142										}
1143
1144										break;
1145
1146				   /******/
1147										/* mn */
1148				   /******/
1149
1150									case 4:
1151
1152					   /******************/
1153										/* Timer 0 factor */
1154					   /******************/
1155
1156										ul_HighTimerValue
1157											=
1158											(ULONG)
1159											(
1160											(ul_HighTiming
1161												*
1162												60)
1163											*
1164											(250000.0
1165												*
1166												b_ClockSelection));
1167
1168					   /*******************/
1169										/* Round the value */
1170					   /*******************/
1171
1172										if ((double)((double)(ul_HighTiming * 60.0) * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
1173											ul_HighTimerValue
1174												=
1175												ul_HighTimerValue
1176												+
1177												1;
1178										}
1179
1180					   /*****************************/
1181										/* Calculate the real timing */
1182					   /*****************************/
1183
1184										*pul_RealHighTiming
1185											=
1186											(ULONG)
1187											(ul_HighTimerValue
1188											/
1189											(250000.0
1190												*
1191												(double)
1192												b_ClockSelection))
1193											/
1194											60;
1195										d_RealHighTiming
1196											=
1197											(
1198											(double)
1199											ul_HighTimerValue
1200											/
1201											(250000.0
1202												*
1203												(double)
1204												b_ClockSelection))
1205											/
1206											60.0;
1207
1208										if ((double)(((double)ul_HighTimerValue / (250000.0 * (double)b_ClockSelection)) / 60.0) >= (double)((double)*pul_RealHighTiming + 0.5)) {
1209											*pul_RealHighTiming
1210												=
1211												*pul_RealHighTiming
1212												+
1213												1;
1214										}
1215
1216										ul_HighTiming
1217											=
1218											ul_HighTiming
1219											-
1220											1;
1221										ul_HighTimerValue
1222											=
1223											ul_HighTimerValue
1224											-
1225											2;
1226
1227										if (b_ClockSelection != APCI1710_40MHZ) {
1228											ul_HighTimerValue
1229												=
1230												(ULONG)
1231												(
1232												(double)
1233												(ul_HighTimerValue)
1234												*
1235												1.007752288);
1236										}
1237
1238										break;
1239									}
1240
1241									fpu_end();
1242				/****************************/
1243									/* Save the clock selection */
1244				/****************************/
1245
1246									devpriv->
1247										s_ModuleInfo
1248										[b_ModulNbr].
1249										s_PWMModuleInfo.
1250										b_ClockSelection
1251										=
1252										b_ClockSelection;
1253
1254				/************************/
1255									/* Save the timing unit */
1256				/************************/
1257
1258									devpriv->
1259										s_ModuleInfo
1260										[b_ModulNbr].
1261										s_PWMModuleInfo.
1262										s_PWMInfo
1263										[b_PWM].
1264										b_TimingUnit
1265										=
1266										b_TimingUnit;
1267
1268				/****************************/
1269									/* Save the low base timing */
1270				/****************************/
1271
1272									devpriv->
1273										s_ModuleInfo
1274										[b_ModulNbr].
1275										s_PWMModuleInfo.
1276										s_PWMInfo
1277										[b_PWM].
1278										d_LowTiming
1279										=
1280										d_RealLowTiming;
1281
1282									devpriv->
1283										s_ModuleInfo
1284										[b_ModulNbr].
1285										s_PWMModuleInfo.
1286										s_PWMInfo
1287										[b_PWM].
1288										ul_RealLowTiming
1289										=
1290										*pul_RealLowTiming;
1291
1292				/****************************/
1293									/* Save the high base timing */
1294				/****************************/
1295
1296									devpriv->
1297										s_ModuleInfo
1298										[b_ModulNbr].
1299										s_PWMModuleInfo.
1300										s_PWMInfo
1301										[b_PWM].
1302										d_HighTiming
1303										=
1304										d_RealHighTiming;
1305
1306									devpriv->
1307										s_ModuleInfo
1308										[b_ModulNbr].
1309										s_PWMModuleInfo.
1310										s_PWMInfo
1311										[b_PWM].
1312										ul_RealHighTiming
1313										=
1314										*pul_RealHighTiming;
1315
1316				/************************/
1317									/* Write the low timing */
1318				/************************/
1319
1320									outl(ul_LowTimerValue, devpriv->s_BoardInfos.ui_Address + 0 + (20 * b_PWM) + (64 * b_ModulNbr));
1321
1322				/*************************/
1323									/* Write the high timing */
1324				/*************************/
1325
1326									outl(ul_HighTimerValue, devpriv->s_BoardInfos.ui_Address + 4 + (20 * b_PWM) + (64 * b_ModulNbr));
1327
1328				/***************************/
1329									/* Set the clock selection */
1330				/***************************/
1331
1332									dw_Command
1333										=
1334										inl
1335										(devpriv->
1336										s_BoardInfos.
1337										ui_Address
1338										+
1339										8
1340										+
1341										(20 * b_PWM) + (64 * b_ModulNbr));
1342
1343									dw_Command
1344										=
1345										dw_Command
1346										&
1347										0x7F;
1348
1349									if (b_ClockSelection == APCI1710_40MHZ) {
1350										dw_Command
1351											=
1352											dw_Command
1353											|
1354											0x80;
1355									}
1356
1357				/***************************/
1358									/* Set the clock selection */
1359				/***************************/
1360
1361									outl(dw_Command, devpriv->s_BoardInfos.ui_Address + 8 + (20 * b_PWM) + (64 * b_ModulNbr));
1362
1363				/*************/
1364									/* PWM init. */
1365				/*************/
1366									devpriv->
1367										s_ModuleInfo
1368										[b_ModulNbr].
1369										s_PWMModuleInfo.
1370										s_PWMInfo
1371										[b_PWM].
1372										b_PWMInit
1373										=
1374										1;
1375								} else {
1376				/***************************************************/
1377									/* You can not used the 40MHz clock selection with */
1378									/* this board                                      */
1379				/***************************************************/
1380									DPRINTK("You can not used the 40MHz clock selection with this board\n");
1381									i_ReturnValue
1382										=
1383										-9;
1384								}
1385							} else {
1386			     /***************************************/
1387								/* High base timing selection is wrong */
1388			     /***************************************/
1389								DPRINTK("High base timing selection is wrong\n");
1390								i_ReturnValue =
1391									-8;
1392							}
1393						} else {
1394			  /**************************************/
1395							/* Low base timing selection is wrong */
1396			  /**************************************/
1397							DPRINTK("Low base timing selection is wrong\n");
1398							i_ReturnValue = -7;
1399						}
1400					}	// if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
1401					else {
1402		       /**********************************/
1403						/* Timing unit selection is wrong */
1404		       /**********************************/
1405						DPRINTK("Timing unit selection is wrong\n");
1406						i_ReturnValue = -6;
1407					}	// if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
1408				}	// if ((b_ClockSelection == APCI1710_30MHZ) || (b_ClockSelection == APCI1710_33MHZ) || (b_ClockSelection == APCI1710_40MHZ))
1409				else {
1410		    /*******************************/
1411					/* The selected clock is wrong */
1412		    /*******************************/
1413					DPRINTK("The selected clock is wrong\n");
1414					i_ReturnValue = -5;
1415				}	// if ((b_ClockSelection == APCI1710_30MHZ) || (b_ClockSelection == APCI1710_33MHZ) || (b_ClockSelection == APCI1710_40MHZ))
1416			}	// if (b_PWM >= 0 && b_PWM <= 1)
1417			else {
1418		 /******************************/
1419				/* Tor PWM selection is wrong */
1420		 /******************************/
1421				DPRINTK("Tor PWM selection is wrong\n");
1422				i_ReturnValue = -4;
1423			}	// if (b_PWM >= 0 && b_PWM <= 1)
1424		} else {
1425	      /**********************************/
1426			/* The module is not a PWM module */
1427	      /**********************************/
1428			DPRINTK("The module is not a PWM module\n");
1429			i_ReturnValue = -3;
1430		}
1431	} else {
1432	   /***********************/
1433		/* Module number error */
1434	   /***********************/
1435		DPRINTK("Module number error\n");
1436		i_ReturnValue = -2;
1437	}
1438
1439	return (i_ReturnValue);
1440}
1441
1442/*
1443+----------------------------------------------------------------------------+
1444| Function Name     : _INT_ i_APCI1710_GetPWMInitialisation                  |
1445|                                       (BYTE_     b_BoardHandle,            |
1446|                                        BYTE_     b_ModulNbr,               |
1447|                                        BYTE_     b_PWM,                    |
1448|                                        PBYTE_   pb_TimingUnit,             |
1449|                                        PULONG_ pul_LowTiming,              |
1450|                                        PULONG_ pul_HighTiming,             |
1451|                                        PBYTE_   pb_StartLevel,             |
1452|                                        PBYTE_   pb_StopMode,               |
1453|                                        PBYTE_   pb_StopLevel,              |
1454|                                        PBYTE_   pb_ExternGate,             |
1455|                                        PBYTE_   pb_InterruptEnable,        |
1456|                                        PBYTE_   pb_Enable)                 |
1457+----------------------------------------------------------------------------+
1458| Task              : Return the PWM (b_PWM) initialisation from selected    |
1459|                     module (b_ModulNbr). You must calling the              |
1460|                     "i_APCI1710_InitPWM" function be for you call this     |
1461|                     function.                                              |
1462+----------------------------------------------------------------------------+
1463| Input Parameters  : BYTE_ b_BoardHandle : Handle of board APCI-1710        |
1464|                     BYTE_ b_ModulNbr    : Selected module number (0 to 3)  |
1465|                     BYTE_ b_PWM         : Selected PWM (0 or 1)            |
1466+----------------------------------------------------------------------------+
1467| Output Parameters : PBYTE_  pb_TimingUnit      : Base timing Unit (0 to 4) |
1468|                                                       0 : ns               |
1469|                                                       1 : æs               |
1470|                                                       2 : ms               |
1471|                                                       3 : s                |
1472|                                                       4 : mn               |
1473|                     PULONG_ pul_LowTiming      : Low base timing value.    |
1474|                     PULONG_ pul_HighTiming     : High base timing value.   |
1475|                     PBYTE_  pb_StartLevel      : Start period level        |
1476|                                                  selection                 |
1477|                                                       0 : The period start |
1478|                                                           with a low level |
1479|                                                       1 : The period start |
1480|                                                           with a high level|
1481|                     PBYTE_  pb_StopMode        : Stop mode selection       |
1482|                                                  0 : The PWM is stopped    |
1483|                                                      directly after the    |
1484|                                                     "i_APCI1710_DisablePWM"|
1485|                                                      function and break the|
1486|                                                      last period           |
1487|                                                  1 : After the             |
1488|                                                     "i_APCI1710_DisablePWM"|
1489|                                                      function the PWM is   |
1490|                                                      stopped at the end    |
1491|                                                      from last period cycle|
1492|                     PBYTE_  pb_StopLevel        : Stop PWM level selection |
1493|                                                    0 : The output signal   |
1494|                                                        keep the level after|
1495|                                                        the                 |
1496|                                                     "i_APCI1710_DisablePWM"|
1497|                                                        function            |
1498|                                                    1 : The output signal is|
1499|                                                        set to low after the|
1500|                                                     "i_APCI1710_DisablePWM"|
1501|                                                        function            |
1502|                                                    2 : The output signal is|
1503|                                                        set to high after   |
1504|                                                        the                 |
1505|                                                     "i_APCI1710_DisablePWM"|
1506|                                                        function            |
1507|                     PBYTE_  pb_ExternGate      : Extern gate action        |
1508|                                                  selection                 |
1509|                                                   0 : Extern gate signal   |
1510|                                                       not used.            |
1511|                                                   1 : Extern gate signal   |
1512|                                                       used.                |
1513|                     PBYTE_  pb_InterruptEnable : Enable or disable the PWM |
1514|                                                  interrupt.                |
1515|                                                  - APCI1710_ENABLE :       |
1516|                                                    Enable the PWM interrupt|
1517|                                                    A interrupt occur after |
1518|                                                    each period             |
1519|                                                  - APCI1710_DISABLE :      |
1520|                                                    Disable the PWM         |
1521|                                                    interrupt               |
1522|                     PBYTE_  pb_Enable          : Indicate if the PWM is    |
1523|                                                  enabled or no             |
1524|                                                       0 : PWM not enabled  |
1525|                                                       1 : PWM enabled      |
1526+----------------------------------------------------------------------------+
1527| Return Value      :  0: No error                                           |
1528|                     -1: The handle parameter of the board is wrong         |
1529|                     -2: Module selection wrong                             |
1530|                     -3: The module is not a PWM module                     |
1531|                     -4: PWM selection is wrong                             |
1532|                     -5: PWM not initialised see function                   |
1533|                         "i_APCI1710_InitPWM"                               |
1534+----------------------------------------------------------------------------+
1535*/
1536
1537INT i_APCI1710_GetPWMInitialisation(comedi_device * dev,
1538	BYTE b_ModulNbr,
1539	BYTE b_PWM,
1540	PBYTE pb_TimingUnit,
1541	PULONG pul_LowTiming,
1542	PULONG pul_HighTiming,
1543	PBYTE pb_StartLevel,
1544	PBYTE pb_StopMode,
1545	PBYTE pb_StopLevel,
1546	PBYTE pb_ExternGate, PBYTE pb_InterruptEnable, PBYTE pb_Enable)
1547{
1548	INT i_ReturnValue = 0;
1549	DWORD dw_Status;
1550	DWORD dw_Command;
1551
1552	/**************************/
1553	/* Test the module number */
1554	/**************************/
1555
1556	if (b_ModulNbr < 4) {
1557	   /***************/
1558		/* Test if PWM */
1559	   /***************/
1560
1561		if ((devpriv->s_BoardInfos.
1562				dw_MolduleConfiguration[b_ModulNbr] &
1563				0xFFFF0000UL) == APCI1710_PWM) {
1564	      /**************************/
1565			/* Test the PWM selection */
1566	      /**************************/
1567
1568			if (b_PWM <= 1) {
1569		 /***************************/
1570				/* Test if PWM initialised */
1571		 /***************************/
1572
1573				dw_Status = inl(devpriv->s_BoardInfos.
1574					ui_Address + 12 + (20 * b_PWM) +
1575					(64 * b_ModulNbr));
1576
1577				if (dw_Status & 0x10) {
1578		    /***********************/
1579					/* Read the low timing */
1580		    /***********************/
1581
1582					*pul_LowTiming =
1583						inl(devpriv->s_BoardInfos.
1584						ui_Address + 0 + (20 * b_PWM) +
1585						(64 * b_ModulNbr));
1586
1587		    /************************/
1588					/* Read the high timing */
1589		    /************************/
1590
1591					*pul_HighTiming =
1592						inl(devpriv->s_BoardInfos.
1593						ui_Address + 4 + (20 * b_PWM) +
1594						(64 * b_ModulNbr));
1595
1596		    /********************/
1597					/* Read the command */
1598		    /********************/
1599
1600					dw_Command = inl(devpriv->s_BoardInfos.
1601						ui_Address + 8 + (20 * b_PWM) +
1602						(64 * b_ModulNbr));
1603
1604					*pb_StartLevel =
1605						(BYTE) ((dw_Command >> 5) & 1);
1606					*pb_StopMode =
1607						(BYTE) ((dw_Command >> 0) & 1);
1608					*pb_StopLevel =
1609						(BYTE) ((dw_Command >> 1) & 1);
1610					*pb_ExternGate =
1611						(BYTE) ((dw_Command >> 4) & 1);
1612					*pb_InterruptEnable =
1613						(BYTE) ((dw_Command >> 3) & 1);
1614
1615					if (*pb_StopLevel) {
1616						*pb_StopLevel =
1617							*pb_StopLevel +
1618							(BYTE) ((dw_Command >>
1619								2) & 1);
1620					}
1621
1622		    /********************/
1623					/* Read the command */
1624		    /********************/
1625
1626					dw_Command = inl(devpriv->s_BoardInfos.
1627						ui_Address + 8 + (20 * b_PWM) +
1628						(64 * b_ModulNbr));
1629
1630					*pb_Enable =
1631						(BYTE) ((dw_Command >> 0) & 1);
1632
1633					*pb_TimingUnit = devpriv->
1634						s_ModuleInfo[b_ModulNbr].
1635						s_PWMModuleInfo.
1636						s_PWMInfo[b_PWM].b_TimingUnit;
1637				}	// if (dw_Status & 0x10)
1638				else {
1639		    /***********************/
1640					/* PWM not initialised */
1641		    /***********************/
1642					DPRINTK("PWM not initialised\n");
1643					i_ReturnValue = -5;
1644				}	// if (dw_Status & 0x10)
1645			}	// if (b_PWM >= 0 && b_PWM <= 1)
1646			else {
1647		 /******************************/
1648				/* Tor PWM selection is wrong */
1649		 /******************************/
1650				DPRINTK("Tor PWM selection is wrong\n");
1651				i_ReturnValue = -4;
1652			}	// if (b_PWM >= 0 && b_PWM <= 1)
1653		} else {
1654	      /**********************************/
1655			/* The module is not a PWM module */
1656	      /**********************************/
1657			DPRINTK("The module is not a PWM module\n");
1658			i_ReturnValue = -3;
1659		}
1660	} else {
1661	   /***********************/
1662		/* Module number error */
1663	   /***********************/
1664		DPRINTK("Module number error\n");
1665		i_ReturnValue = -2;
1666	}
1667
1668	return (i_ReturnValue);
1669}
1670
1671/*
1672+----------------------------------------------------------------------------+
1673| Function Name     :INT i_APCI1710_InsnWritePWM(comedi_device *dev,
1674comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)                        |
1675+----------------------------------------------------------------------------+
1676| Task              : Pwm Enable Disable and Set New Timing                  |
1677+----------------------------------------------------------------------------+
1678| Input Parameters  :
1679+----------------------------------------------------------------------------+
1680| Output Parameters : -                                                      |
1681+----------------------------------------------------------------------------+
1682| Return Value      :
1683+----------------------------------------------------------------------------+
1684*/
1685
1686INT i_APCI1710_InsnWritePWM(comedi_device * dev, comedi_subdevice * s,
1687	comedi_insn * insn, lsampl_t * data)
1688{
1689	BYTE b_WriteType;
1690	INT i_ReturnValue = 0;
1691	b_WriteType = CR_CHAN(insn->chanspec);
1692
1693	switch (b_WriteType) {
1694	case APCI1710_PWM_ENABLE:
1695		i_ReturnValue = i_APCI1710_EnablePWM(dev,
1696			(BYTE) CR_AREF(insn->chanspec),
1697			(BYTE) data[0],
1698			(BYTE) data[1],
1699			(BYTE) data[2],
1700			(BYTE) data[3], (BYTE) data[4], (BYTE) data[5]);
1701		break;
1702
1703	case APCI1710_PWM_DISABLE:
1704		i_ReturnValue = i_APCI1710_DisablePWM(dev,
1705			(BYTE) CR_AREF(insn->chanspec), (BYTE) data[0]);
1706		break;
1707
1708	case APCI1710_PWM_NEWTIMING:
1709		i_ReturnValue = i_APCI1710_SetNewPWMTiming(dev,
1710			(BYTE) CR_AREF(insn->chanspec),
1711			(BYTE) data[0],
1712			(BYTE) data[1], (ULONG) data[2], (ULONG) data[3]);
1713		break;
1714
1715	default:
1716		printk("Write Config Parameter Wrong\n");
1717	}
1718
1719	if (i_ReturnValue >= 0)
1720		i_ReturnValue = insn->n;
1721	return (i_ReturnValue);
1722}
1723
1724/*
1725+----------------------------------------------------------------------------+
1726| Function Name     : _INT_     i_APCI1710_EnablePWM                         |
1727|                                       (BYTE_  b_BoardHandle,               |
1728|                                        BYTE_  b_ModulNbr,                  |
1729|                                        BYTE_  b_PWM,                       |
1730|                                        BYTE_  b_StartLevel,                |
1731|                                        BYTE_  b_StopMode,                  |
1732|                                        BYTE_  b_StopLevel,                 |
1733|                                        BYTE_  b_ExternGate,                |
1734|                                        BYTE_  b_InterruptEnable)           |
1735+----------------------------------------------------------------------------+
1736| Task              : Enable the selected PWM (b_PWM) from selected module   |
1737|                     (b_ModulNbr). You must calling the "i_APCI1710_InitPWM"|
1738|                     function be for you call this function.                |
1739|                     If you enable the PWM interrupt, the PWM generate a    |
1740|                     interrupt after each period.                           |
1741|                     See function "i_APCI1710_SetBoardIntRoutineX" and the  |
1742|                     Interrupt mask description chapter.                    |
1743+----------------------------------------------------------------------------+
1744| Input Parameters  : BYTE_ b_BoardHandle     : Handle of board APCI-1710    |
1745|                     BYTE_ b_ModulNbr        : Selected module number       |
1746|                                               (0 to 3)                     |
1747|                     BYTE_ b_PWM             : Selected PWM (0 or 1)        |
1748|                     BYTE_ b_StartLevel      : Start period level selection |
1749|                                                0 : The period start with a |
1750|                                                    low level               |
1751|                                                1 : The period start with a |
1752|                                                    high level              |
1753|                     BYTE_ b_StopMode        : Stop mode selection          |
1754|                                                0 : The PWM is stopped      |
1755|                                                    directly after the      |
1756|                                                    "i_APCI1710_DisablePWM" |
1757|                                                    function and break the  |
1758|                                                    last period             |
1759|                                                1 : After the               |
1760|                                                    "i_APCI1710_DisablePWM" |
1761|                                                     function the PWM is    |
1762|                                                     stopped at the end from|
1763|                                                     last period cycle.     |
1764|                     BYTE_ b_StopLevel       : Stop PWM level selection     |
1765|                                                0 : The output signal keep  |
1766|                                                    the level after the     |
1767|                                                    "i_APCI1710_DisablePWM" |
1768|                                                    function                |
1769|                                                1 : The output signal is set|
1770|                                                    to low after the        |
1771|                                                    "i_APCI1710_DisablePWM" |
1772|                                                    function                |
1773|                                                2 : The output signal is set|
1774|                                                    to high after the       |
1775|                                                    "i_APCI1710_DisablePWM" |
1776|                                                    function                |
1777|                     BYTE_ b_ExternGate      : Extern gate action selection |
1778|                                                0 : Extern gate signal not  |
1779|                                                    used.                   |
1780|                                                1 : Extern gate signal used.|
1781|                     BYTE_ b_InterruptEnable : Enable or disable the PWM    |
1782|                                               interrupt.                   |
1783|                                               - APCI1710_ENABLE :          |
1784|                                                 Enable the PWM interrupt   |
1785|                                                 A interrupt occur after    |
1786|                                                 each period                |
1787|                                               - APCI1710_DISABLE :         |
1788|                                                 Disable the PWM interrupt  |
1789+----------------------------------------------------------------------------+
1790| Output Parameters : -                                                      |
1791+----------------------------------------------------------------------------+
1792| Return Value      : 0:  No error                                           |
1793|                    -1:  The handle parameter of the board is wrong         |
1794|                    -2:  Module selection wrong                             |
1795|                    -3:  The module is not a PWM module                     |
1796|                    -4:  PWM selection is wrong                             |
1797|                    -5:  PWM not initialised see function                   |
1798|                         "i_APCI1710_InitPWM"                               |
1799|                    -6:  PWM start level selection is wrong                 |
1800|                    -7:  PWM stop mode selection is wrong                   |
1801|                    -8:  PWM stop level selection is wrong                  |
1802|                    -9:  Extern gate signal selection is wrong              |
1803|                    -10: Interrupt parameter is wrong                       |
1804|                    -11: Interrupt function not initialised.                |
1805|                         See function "i_APCI1710_SetBoardIntRoutineX"      |
1806+----------------------------------------------------------------------------+
1807*/
1808
1809INT i_APCI1710_EnablePWM(comedi_device * dev,
1810	BYTE b_ModulNbr,
1811	BYTE b_PWM,
1812	BYTE b_StartLevel,
1813	BYTE b_StopMode,
1814	BYTE b_StopLevel, BYTE b_ExternGate, BYTE b_InterruptEnable)
1815{
1816	INT i_ReturnValue = 0;
1817	DWORD dw_Status;
1818	DWORD dw_Command;
1819
1820	devpriv->tsk_Current = current;	// Save the current process task structure
1821	/**************************/
1822	/* Test the module number */
1823	/**************************/
1824
1825	if (b_ModulNbr < 4) {
1826	   /***************/
1827		/* Test if PWM */
1828	   /***************/
1829
1830		if ((devpriv->s_BoardInfos.
1831				dw_MolduleConfiguration[b_ModulNbr] &
1832				0xFFFF0000UL) == APCI1710_PWM) {
1833	      /**************************/
1834			/* Test the PWM selection */
1835	      /**************************/
1836
1837			if (b_PWM <= 1) {
1838		 /***************************/
1839				/* Test if PWM initialised */
1840		 /***************************/
1841
1842				dw_Status = inl(devpriv->s_BoardInfos.
1843					ui_Address + 12 + (20 * b_PWM) +
1844					(64 * b_ModulNbr));
1845
1846				if (dw_Status & 0x10) {
1847		    /**********************************/
1848					/* Test the start level selection */
1849		    /**********************************/
1850
1851					if (b_StartLevel <= 1) {
1852		       /**********************/
1853						/* Test the stop mode */
1854		       /**********************/
1855
1856						if (b_StopMode <= 1) {
1857			  /***********************/
1858							/* Test the stop level */
1859			  /***********************/
1860
1861							if (b_StopLevel <= 2) {
1862			     /*****************************/
1863								/* Test the extern gate mode */
1864			     /*****************************/
1865
1866								if (b_ExternGate
1867									<= 1) {
1868				/*****************************/
1869									/* Test the interrupt action */
1870				/*****************************/
1871
1872									if (b_InterruptEnable == APCI1710_ENABLE || b_InterruptEnable == APCI1710_DISABLE) {
1873				   /******************************************/
1874										/* Test if interrupt function initialised */
1875				   /******************************************/
1876
1877				      /********************/
1878										/* Read the command */
1879				      /********************/
1880
1881										dw_Command
1882											=
1883											inl
1884											(devpriv->
1885											s_BoardInfos.
1886											ui_Address
1887											+
1888											8
1889											+
1890											(20 * b_PWM) + (64 * b_ModulNbr));
1891
1892										dw_Command
1893											=
1894											dw_Command
1895											&
1896											0x80;
1897
1898				      /********************/
1899										/* Make the command */
1900				      /********************/
1901
1902										dw_Command
1903											=
1904											dw_Command
1905											|
1906											b_StopMode
1907											|
1908											(b_InterruptEnable
1909											<<
1910											3)
1911											|
1912											(b_ExternGate
1913											<<
1914											4)
1915											|
1916											(b_StartLevel
1917											<<
1918											5);
1919
1920										if (b_StopLevel & 3) {
1921											dw_Command
1922												=
1923												dw_Command
1924												|
1925												2;
1926
1927											if (b_StopLevel & 2) {
1928												dw_Command
1929													=
1930													dw_Command
1931													|
1932													4;
1933											}
1934										}
1935
1936										devpriv->
1937											s_ModuleInfo
1938											[b_ModulNbr].
1939											s_PWMModuleInfo.
1940											s_PWMInfo
1941											[b_PWM].
1942											b_InterruptEnable
1943											=
1944											b_InterruptEnable;
1945
1946				      /*******************/
1947										/* Set the command */
1948				      /*******************/
1949
1950										outl(dw_Command, devpriv->s_BoardInfos.ui_Address + 8 + (20 * b_PWM) + (64 * b_ModulNbr));
1951
1952				      /******************/
1953										/* Enable the PWM */
1954				      /******************/
1955										outl(1, devpriv->s_BoardInfos.ui_Address + 12 + (20 * b_PWM) + (64 * b_ModulNbr));
1956									}	// if (b_InterruptEnable == APCI1710_ENABLE || b_InterruptEnable == APCI1710_DISABLE)
1957									else {
1958				   /********************************/
1959										/* Interrupt parameter is wrong */
1960				   /********************************/
1961										DPRINTK("Interrupt parameter is wrong\n");
1962										i_ReturnValue
1963											=
1964											-10;
1965									}	// if (b_InterruptEnable == APCI1710_ENABLE || b_InterruptEnable == APCI1710_DISABLE)
1966								}	// if (b_ExternGate >= 0 && b_ExternGate <= 1)
1967								else {
1968				/*****************************************/
1969									/* Extern gate signal selection is wrong */
1970				/*****************************************/
1971									DPRINTK("Extern gate signal selection is wrong\n");
1972									i_ReturnValue
1973										=
1974										-9;
1975								}	// if (b_ExternGate >= 0 && b_ExternGate <= 1)
1976							}	// if (b_StopLevel >= 0 && b_StopLevel <= 2)
1977							else {
1978			     /*************************************/
1979								/* PWM stop level selection is wrong */
1980			     /*************************************/
1981								DPRINTK("PWM stop level selection is wrong\n");
1982								i_ReturnValue =
1983									-8;
1984							}	// if (b_StopLevel >= 0 && b_StopLevel <= 2)
1985						}	// if (b_StopMode >= 0 && b_StopMode <= 1)
1986						else {
1987			  /************************************/
1988							/* PWM stop mode selection is wrong */
1989			  /************************************/
1990							DPRINTK("PWM stop mode selection is wrong\n");
1991							i_ReturnValue = -7;
1992						}	// if (b_StopMode >= 0 && b_StopMode <= 1)
1993					}	// if (b_StartLevel >= 0 && b_StartLevel <= 1)
1994					else {
1995		       /**************************************/
1996						/* PWM start level selection is wrong */
1997		       /**************************************/
1998						DPRINTK("PWM start level selection is wrong\n");
1999						i_ReturnValue = -6;
2000					}	// if (b_StartLevel >= 0 && b_StartLevel <= 1)
2001				}	// if (dw_Status & 0x10)
2002				else {
2003		    /***********************/
2004					/* PWM not initialised */
2005		    /***********************/
2006					DPRINTK("PWM not initialised\n");
2007					i_ReturnValue = -5;
2008				}	// if (dw_Status & 0x10)
2009			}	// if (b_PWM >= 0 && b_PWM <= 1)
2010			else {
2011		 /******************************/
2012				/* Tor PWM selection is wrong */
2013		 /******************************/
2014				DPRINTK("Tor PWM selection is wrong\n");
2015				i_ReturnValue = -4;
2016			}	// if (b_PWM >= 0 && b_PWM <= 1)
2017		} else {
2018	      /**********************************/
2019			/* The module is not a PWM module */
2020	      /**********************************/
2021			DPRINTK("The module is not a PWM module\n");
2022			i_ReturnValue = -3;
2023		}
2024	} else {
2025	   /***********************/
2026		/* Module number error */
2027	   /***********************/
2028		DPRINTK("Module number error\n");
2029		i_ReturnValue = -2;
2030	}
2031
2032	return (i_ReturnValue);
2033}
2034
2035/*
2036+----------------------------------------------------------------------------+
2037| Function Name     : _INT_ i_APCI1710_DisablePWM (BYTE_  b_BoardHandle,     |
2038|                                                  BYTE_  b_ModulNbr,        |
2039|                                                  BYTE_  b_PWM)             |
2040+----------------------------------------------------------------------------+
2041| Task              : Disable the selected PWM (b_PWM) from selected module  |
2042|                     (b_ModulNbr). The output signal level depend of the    |
2043|                     initialisation by the "i_APCI1710_EnablePWM".          |
2044|                     See the b_StartLevel, b_StopMode and b_StopLevel       |
2045|                     parameters from this function.                         |
2046+----------------------------------------------------------------------------+
2047| Input Parameters  :BYTE_ b_BoardHandle : Handle of board APCI-1710         |
2048|                    BYTE_ b_ModulNbr    : Selected module number (0 to 3)   |
2049|                    BYTE_ b_PWM         : Selected PWM (0 or 1)             |
2050+----------------------------------------------------------------------------+
2051| Output Parameters : -                                                      |
2052+----------------------------------------------------------------------------+
2053| Return Value      :  0: No error                                           |
2054|                     -1: The handle parameter of the board is wrong         |
2055|                     -2: Module selection wrong                             |
2056|                     -3: The module is not a PWM module                     |
2057|                     -4: PWM selection is wrong                             |
2058|                     -5: PWM not initialised see function                   |
2059|                         "i_APCI1710_InitPWM"                               |
2060|                     -6: PWM not enabled see function                       |
2061|                         "i_APCI1710_EnablePWM"                             |
2062+----------------------------------------------------------------------------+
2063*/
2064
2065INT i_APCI1710_DisablePWM(comedi_device * dev, BYTE b_ModulNbr, BYTE b_PWM)
2066{
2067	INT i_ReturnValue = 0;
2068	DWORD dw_Status;
2069
2070	/**************************/
2071	/* Test the module number */
2072	/**************************/
2073
2074	if (b_ModulNbr < 4) {
2075	   /***************/
2076		/* Test if PWM */
2077	   /***************/
2078
2079		if ((devpriv->s_BoardInfos.
2080				dw_MolduleConfiguration[b_ModulNbr] &
2081				0xFFFF0000UL) == APCI1710_PWM) {
2082	      /**************************/
2083			/* Test the PWM selection */
2084	      /**************************/
2085
2086			if (b_PWM <= 1) {
2087		 /***************************/
2088				/* Test if PWM initialised */
2089		 /***************************/
2090
2091				dw_Status = inl(devpriv->s_BoardInfos.
2092					ui_Address + 12 + (20 * b_PWM) +
2093					(64 * b_ModulNbr));
2094
2095				if (dw_Status & 0x10) {
2096		    /***********************/
2097					/* Test if PWM enabled */
2098		    /***********************/
2099
2100					if (dw_Status & 0x1) {
2101		       /*******************/
2102						/* Disable the PWM */
2103		       /*******************/
2104						outl(0, devpriv->s_BoardInfos.
2105							ui_Address + 12 +
2106							(20 * b_PWM) +
2107							(64 * b_ModulNbr));
2108					}	// if (dw_Status & 0x1)
2109					else {
2110		       /*******************/
2111						/* PWM not enabled */
2112		       /*******************/
2113						DPRINTK("PWM not enabled\n");
2114						i_ReturnValue = -6;
2115					}	// if (dw_Status & 0x1)
2116				}	// if (dw_Status & 0x10)
2117				else {
2118		    /***********************/
2119					/* PWM not initialised */
2120		    /***********************/
2121					DPRINTK(" PWM not initialised\n");
2122					i_ReturnValue = -5;
2123				}	// if (dw_Status & 0x10)
2124			}	// if (b_PWM >= 0 && b_PWM <= 1)
2125			else {
2126		 /******************************/
2127				/* Tor PWM selection is wrong */
2128		 /******************************/
2129				DPRINTK("Tor PWM selection is wrong\n");
2130				i_ReturnValue = -4;
2131			}	// if (b_PWM >= 0 && b_PWM <= 1)
2132		} else {
2133	      /**********************************/
2134			/* The module is not a PWM module */
2135	      /**********************************/
2136			DPRINTK("The module is not a PWM module\n");
2137			i_ReturnValue = -3;
2138		}
2139	} else {
2140	   /***********************/
2141		/* Module number error */
2142	   /***********************/
2143		DPRINTK("Module number error\n");
2144		i_ReturnValue = -2;
2145	}
2146
2147	return (i_ReturnValue);
2148}
2149
2150/*
2151+----------------------------------------------------------------------------+
2152| Function Name     : _INT_ i_APCI1710_SetNewPWMTiming                       |
2153|                                       (BYTE_     b_BoardHandle,            |
2154|                                        BYTE_     b_ModulNbr,               |
2155|                                        BYTE_     b_PWM,                    |
2156|                                        BYTE_     b_ClockSelection,         |
2157|                                        BYTE_     b_TimingUnit,             |
2158|                                        ULONG_   ul_LowTiming,              |
2159|                                        ULONG_   ul_HighTiming)             |
2160+----------------------------------------------------------------------------+
2161| Task              : Set a new timing. The ul_LowTiming, ul_HighTiming and  |
2162|                     ul_TimingUnit determine the low/high timing base for   |
2163|                     the period.                                            |
2164+----------------------------------------------------------------------------+
2165| Input Parameters  : BYTE_     b_BoardHandle    : Handle of board APCI-1710 |
2166|                     BYTE_     b_ModulNbr       : Module number to configure|
2167|                                                  (0 to 3)                  |
2168|                     BYTE_     b_PWM            : Selected PWM (0 or 1).    |
2169|                     BYTE_     b_TimingUnit     : Base timing Unit (0 to 4) |
2170|                                                       0 : ns               |
2171|                                                       1 : æs               |
2172|                                                       2 : ms               |
2173|                                                       3 : s                |
2174|                                                       4 : mn               |
2175|                     ULONG_    ul_LowTiming     : Low base timing value.    |
2176|                     ULONG_    ul_HighTiming    : High base timing value.   |
2177+----------------------------------------------------------------------------+
2178| Output Parameters : -                                                      |
2179+----------------------------------------------------------------------------+
2180| Return Value      : 0: No error                                            |
2181|                    -1: The handle parameter of the board is wrong          |
2182|                    -2: Module selection wrong                              |
2183|                    -3: The module is not a PWM module                      |
2184|                    -4: PWM selection is wrong                              |
2185|                    -5: PWM not initialised                                 |
2186|                    -6: Timing Unit selection is wrong                      |
2187|                    -7: Low base timing selection is wrong                  |
2188|                    -8: High base timing selection is wrong                 |
2189+----------------------------------------------------------------------------+
2190*/
2191
2192INT i_APCI1710_SetNewPWMTiming(comedi_device * dev,
2193	BYTE b_ModulNbr,
2194	BYTE b_PWM, BYTE b_TimingUnit, ULONG ul_LowTiming, ULONG ul_HighTiming)
2195{
2196	BYTE b_ClockSelection;
2197	INT i_ReturnValue = 0;
2198	ULONG ul_LowTimerValue = 0;
2199	ULONG ul_HighTimerValue = 0;
2200	ULONG ul_RealLowTiming = 0;
2201	ULONG ul_RealHighTiming = 0;
2202	DWORD dw_Status;
2203	DWORD dw_Command;
2204	double d_RealLowTiming = 0;
2205	double d_RealHighTiming = 0;
2206
2207	/**************************/
2208	/* Test the module number */
2209	/**************************/
2210
2211	if (b_ModulNbr < 4) {
2212	   /***************/
2213		/* Test if PWM */
2214	   /***************/
2215
2216		if ((devpriv->s_BoardInfos.
2217				dw_MolduleConfiguration[b_ModulNbr] &
2218				0xFFFF0000UL) == APCI1710_PWM) {
2219	      /**************************/
2220			/* Test the PWM selection */
2221	      /**************************/
2222
2223			if (b_PWM <= 1) {
2224		 /***************************/
2225				/* Test if PWM initialised */
2226		 /***************************/
2227
2228				dw_Status = inl(devpriv->s_BoardInfos.
2229					ui_Address + 12 + (20 * b_PWM) +
2230					(64 * b_ModulNbr));
2231
2232				if (dw_Status & 0x10) {
2233					b_ClockSelection = devpriv->
2234						s_ModuleInfo[b_ModulNbr].
2235						s_PWMModuleInfo.
2236						b_ClockSelection;
2237
2238		    /************************/
2239					/* Test the timing unit */
2240		    /************************/
2241
2242					if (b_TimingUnit <= 4) {
2243		       /*********************************/
2244						/* Test the low timing selection */
2245		       /*********************************/
2246
2247						if (((b_ClockSelection ==
2248									APCI1710_30MHZ)
2249								&& (b_TimingUnit
2250									== 0)
2251								&& (ul_LowTiming
2252									>= 266)
2253								&& (ul_LowTiming
2254									<=
2255									0xFFFFFFFFUL))
2256							|| ((b_ClockSelection ==
2257									APCI1710_30MHZ)
2258								&& (b_TimingUnit
2259									== 1)
2260								&& (ul_LowTiming
2261									>= 1)
2262								&& (ul_LowTiming
2263									<=
2264									571230650UL))
2265							|| ((b_ClockSelection ==
2266									APCI1710_30MHZ)
2267								&& (b_TimingUnit
2268									== 2)
2269								&& (ul_LowTiming
2270									>= 1)
2271								&& (ul_LowTiming
2272									<=
2273									571230UL))
2274							|| ((b_ClockSelection ==
2275									APCI1710_30MHZ)
2276								&& (b_TimingUnit
2277									== 3)
2278								&& (ul_LowTiming
2279									>= 1)
2280								&& (ul_LowTiming
2281									<=
2282									571UL))
2283							|| ((b_ClockSelection ==
2284									APCI1710_30MHZ)
2285								&& (b_TimingUnit
2286									== 4)
2287								&& (ul_LowTiming
2288									>= 1)
2289								&& (ul_LowTiming
2290									<= 9UL))
2291							|| ((b_ClockSelection ==
2292									APCI1710_33MHZ)
2293								&& (b_TimingUnit
2294									== 0)
2295								&& (ul_LowTiming
2296									>= 242)
2297								&& (ul_LowTiming
2298									<=
2299									0xFFFFFFFFUL))
2300							|| ((b_ClockSelection ==
2301									APCI1710_33MHZ)
2302								&& (b_TimingUnit
2303									== 1)
2304								&& (ul_LowTiming
2305									>= 1)
2306								&& (ul_LowTiming
2307									<=
2308									519691043UL))
2309							|| ((b_ClockSelection ==
2310									APCI1710_33MHZ)
2311								&& (b_TimingUnit
2312									== 2)
2313								&& (ul_LowTiming
2314									>= 1)
2315								&& (ul_LowTiming
2316									<=
2317									519691UL))
2318							|| ((b_ClockSelection ==
2319									APCI1710_33MHZ)
2320								&& (b_TimingUnit
2321									== 3)
2322								&& (ul_LowTiming
2323									>= 1)
2324								&& (ul_LowTiming
2325									<=
2326									520UL))
2327							|| ((b_ClockSelection ==
2328									APCI1710_33MHZ)
2329								&& (b_TimingUnit
2330									== 4)
2331								&& (ul_LowTiming
2332									>= 1)
2333								&& (ul_LowTiming
2334									<= 8UL))
2335							|| ((b_ClockSelection ==
2336									APCI1710_40MHZ)
2337								&& (b_TimingUnit
2338									== 0)
2339								&& (ul_LowTiming
2340									>= 200)
2341								&& (ul_LowTiming
2342									<=
2343									0xFFFFFFFFUL))
2344							|| ((b_ClockSelection ==
2345									APCI1710_40MHZ)
2346								&& (b_TimingUnit
2347									== 1)
2348								&& (ul_LowTiming
2349									>= 1)
2350								&& (ul_LowTiming
2351									<=
2352									429496729UL))
2353							|| ((b_ClockSelection ==
2354									APCI1710_40MHZ)
2355								&& (b_TimingUnit
2356									== 2)
2357								&& (ul_LowTiming
2358									>= 1)
2359								&& (ul_LowTiming
2360									<=
2361									429496UL))
2362							|| ((b_ClockSelection ==
2363									APCI1710_40MHZ)
2364								&& (b_TimingUnit
2365									== 3)
2366								&& (ul_LowTiming
2367									>= 1)
2368								&& (ul_LowTiming
2369									<=
2370									429UL))
2371							|| ((b_ClockSelection ==
2372									APCI1710_40MHZ)
2373								&& (b_TimingUnit
2374									== 4)
2375								&& (ul_LowTiming
2376									>= 1)
2377								&& (ul_LowTiming
2378									<=
2379									7UL))) {
2380			  /**********************************/
2381							/* Test the High timing selection */
2382			  /**********************************/
2383
2384							if (((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 266) && (ul_HighTiming <= 0xFFFFFFFFUL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571230650UL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571230UL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571UL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 9UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 242) && (ul_HighTiming <= 0xFFFFFFFFUL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 519691043UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 519691UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 520UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 8UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 200) && (ul_HighTiming <= 0xFFFFFFFFUL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429496729UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429496UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 7UL))) {
2385			     /************************************/
2386								/* Calculate the low division fator */
2387			     /************************************/
2388
2389								fpu_begin();
2390								switch (b_TimingUnit) {
2391				/******/
2392									/* ns */
2393				/******/
2394
2395								case 0:
2396
2397					/******************/
2398									/* Timer 0 factor */
2399					/******************/
2400
2401									ul_LowTimerValue
2402										=
2403										(ULONG)
2404										(ul_LowTiming
2405										*
2406										(0.00025 * b_ClockSelection));
2407
2408					/*******************/
2409									/* Round the value */
2410					/*******************/
2411
2412									if ((double)((double)ul_LowTiming * (0.00025 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
2413										ul_LowTimerValue
2414											=
2415											ul_LowTimerValue
2416											+
2417											1;
2418									}
2419
2420					/*****************************/
2421									/* Calculate the real timing */
2422					/*****************************/
2423
2424									ul_RealLowTiming
2425										=
2426										(ULONG)
2427										(ul_LowTimerValue
2428										/
2429										(0.00025 * (double)b_ClockSelection));
2430									d_RealLowTiming
2431										=
2432										(double)
2433										ul_LowTimerValue
2434										/
2435										(0.00025
2436										*
2437										(double)
2438										b_ClockSelection);
2439
2440									if ((double)((double)ul_LowTimerValue / (0.00025 * (double)b_ClockSelection)) >= (double)((double)ul_RealLowTiming + 0.5)) {
2441										ul_RealLowTiming
2442											=
2443											ul_RealLowTiming
2444											+
2445											1;
2446									}
2447
2448									ul_LowTiming
2449										=
2450										ul_LowTiming
2451										-
2452										1;
2453									ul_LowTimerValue
2454										=
2455										ul_LowTimerValue
2456										-
2457										2;
2458
2459									if (b_ClockSelection != APCI1710_40MHZ) {
2460										ul_LowTimerValue
2461											=
2462											(ULONG)
2463											(
2464											(double)
2465											(ul_LowTimerValue)
2466											*
2467											1.007752288);
2468									}
2469
2470									break;
2471
2472				/******/
2473									/* æs */
2474				/******/
2475
2476								case 1:
2477
2478					/******************/
2479									/* Timer 0 factor */
2480					/******************/
2481
2482									ul_LowTimerValue
2483										=
2484										(ULONG)
2485										(ul_LowTiming
2486										*
2487										(0.25 * b_ClockSelection));
2488
2489					/*******************/
2490									/* Round the value */
2491					/*******************/
2492
2493									if ((double)((double)ul_LowTiming * (0.25 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
2494										ul_LowTimerValue
2495											=
2496											ul_LowTimerValue
2497											+
2498											1;
2499									}
2500
2501					/*****************************/
2502									/* Calculate the real timing */
2503					/*****************************/
2504
2505									ul_RealLowTiming
2506										=
2507										(ULONG)
2508										(ul_LowTimerValue
2509										/
2510										(0.25 * (double)b_ClockSelection));
2511									d_RealLowTiming
2512										=
2513										(double)
2514										ul_LowTimerValue
2515										/
2516										(
2517										(double)
2518										0.25
2519										*
2520										(double)
2521										b_ClockSelection);
2522
2523									if ((double)((double)ul_LowTimerValue / (0.25 * (double)b_ClockSelection)) >= (double)((double)ul_RealLowTiming + 0.5)) {
2524										ul_RealLowTiming
2525											=
2526											ul_RealLowTiming
2527											+
2528											1;
2529									}
2530
2531									ul_LowTiming
2532										=
2533										ul_LowTiming
2534										-
2535										1;
2536									ul_LowTimerValue
2537										=
2538										ul_LowTimerValue
2539										-
2540										2;
2541
2542									if (b_ClockSelection != APCI1710_40MHZ) {
2543										ul_LowTimerValue
2544											=
2545											(ULONG)
2546											(
2547											(double)
2548											(ul_LowTimerValue)
2549											*
2550											1.007752288);
2551									}
2552
2553									break;
2554
2555				/******/
2556									/* ms */
2557				/******/
2558
2559								case 2:
2560
2561					/******************/
2562									/* Timer 0 factor */
2563					/******************/
2564
2565									ul_LowTimerValue
2566										=
2567										ul_LowTiming
2568										*
2569										(250.0
2570										*
2571										b_ClockSelection);
2572
2573					/*******************/
2574									/* Round the value */
2575					/*******************/
2576
2577									if ((double)((double)ul_LowTiming * (250.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
2578										ul_LowTimerValue
2579											=
2580											ul_LowTimerValue
2581											+
2582											1;
2583									}
2584
2585					/*****************************/
2586									/* Calculate the real timing */
2587					/*****************************/
2588
2589									ul_RealLowTiming
2590										=
2591										(ULONG)
2592										(ul_LowTimerValue
2593										/
2594										(250.0 * (double)b_ClockSelection));
2595									d_RealLowTiming
2596										=
2597										(double)
2598										ul_LowTimerValue
2599										/
2600										(250.0
2601										*
2602										(double)
2603										b_ClockSelection);
2604
2605									if ((double)((double)ul_LowTimerValue / (250.0 * (double)b_ClockSelection)) >= (double)((double)ul_RealLowTiming + 0.5)) {
2606										ul_RealLowTiming
2607											=
2608											ul_RealLowTiming
2609											+
2610											1;
2611									}
2612
2613									ul_LowTiming
2614										=
2615										ul_LowTiming
2616										-
2617										1;
2618									ul_LowTimerValue
2619										=
2620										ul_LowTimerValue
2621										-
2622										2;
2623
2624									if (b_ClockSelection != APCI1710_40MHZ) {
2625										ul_LowTimerValue
2626											=
2627											(ULONG)
2628											(
2629											(double)
2630											(ul_LowTimerValue)
2631											*
2632											1.007752288);
2633									}
2634
2635									break;
2636
2637				/*****/
2638									/* s */
2639				/*****/
2640
2641								case 3:
2642
2643					/******************/
2644									/* Timer 0 factor */
2645					/******************/
2646
2647									ul_LowTimerValue
2648										=
2649										(ULONG)
2650										(ul_LowTiming
2651										*
2652										(250000.0
2653											*
2654											b_ClockSelection));
2655
2656					/*******************/
2657									/* Round the value */
2658					/*******************/
2659
2660									if ((double)((double)ul_LowTiming * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
2661										ul_LowTimerValue
2662											=
2663											ul_LowTimerValue
2664											+
2665											1;
2666									}
2667
2668					/*****************************/
2669									/* Calculate the real timing */
2670					/*****************************/
2671
2672									ul_RealLowTiming
2673										=
2674										(ULONG)
2675										(ul_LowTimerValue
2676										/
2677										(250000.0
2678											*
2679											(double)
2680											b_ClockSelection));
2681									d_RealLowTiming
2682										=
2683										(double)
2684										ul_LowTimerValue
2685										/
2686										(250000.0
2687										*
2688										(double)
2689										b_ClockSelection);
2690
2691									if ((double)((double)ul_LowTimerValue / (250000.0 * (double)b_ClockSelection)) >= (double)((double)ul_RealLowTiming + 0.5)) {
2692										ul_RealLowTiming
2693											=
2694											ul_RealLowTiming
2695											+
2696											1;
2697									}
2698
2699									ul_LowTiming
2700										=
2701										ul_LowTiming
2702										-
2703										1;
2704									ul_LowTimerValue
2705										=
2706										ul_LowTimerValue
2707										-
2708										2;
2709
2710									if (b_ClockSelection != APCI1710_40MHZ) {
2711										ul_LowTimerValue
2712											=
2713											(ULONG)
2714											(
2715											(double)
2716											(ul_LowTimerValue)
2717											*
2718											1.007752288);
2719									}
2720
2721									break;
2722
2723				/******/
2724									/* mn */
2725				/******/
2726
2727								case 4:
2728
2729					/******************/
2730									/* Timer 0 factor */
2731					/******************/
2732
2733									ul_LowTimerValue
2734										=
2735										(ULONG)
2736										(
2737										(ul_LowTiming
2738											*
2739											60)
2740										*
2741										(250000.0
2742											*
2743											b_ClockSelection));
2744
2745					/*******************/
2746									/* Round the value */
2747					/*******************/
2748
2749									if ((double)((double)(ul_LowTiming * 60.0) * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
2750										ul_LowTimerValue
2751											=
2752											ul_LowTimerValue
2753											+
2754											1;
2755									}
2756
2757					/*****************************/
2758									/* Calculate the real timing */
2759					/*****************************/
2760
2761									ul_RealLowTiming
2762										=
2763										(ULONG)
2764										(ul_LowTimerValue
2765										/
2766										(250000.0
2767											*
2768											(double)
2769											b_ClockSelection))
2770										/
2771										60;
2772									d_RealLowTiming
2773										=
2774										(
2775										(double)
2776										ul_LowTimerValue
2777										/
2778										(250000.0
2779											*
2780											(double)
2781											b_ClockSelection))
2782										/
2783										60.0;
2784
2785									if ((double)(((double)ul_LowTimerValue / (250000.0 * (double)b_ClockSelection)) / 60.0) >= (double)((double)ul_RealLowTiming + 0.5)) {
2786										ul_RealLowTiming
2787											=
2788											ul_RealLowTiming
2789											+
2790											1;
2791									}
2792
2793									ul_LowTiming
2794										=
2795										ul_LowTiming
2796										-
2797										1;
2798									ul_LowTimerValue
2799										=
2800										ul_LowTimerValue
2801										-
2802										2;
2803
2804									if (b_ClockSelection != APCI1710_40MHZ) {
2805										ul_LowTimerValue
2806											=
2807											(ULONG)
2808											(
2809											(double)
2810											(ul_LowTimerValue)
2811											*
2812											1.007752288);
2813									}
2814
2815									break;
2816								}
2817
2818			     /*************************************/
2819								/* Calculate the high division fator */
2820			     /*************************************/
2821
2822								switch (b_TimingUnit) {
2823				/******/
2824									/* ns */
2825				/******/
2826
2827								case 0:
2828
2829					/******************/
2830									/* Timer 0 factor */
2831					/******************/
2832
2833									ul_HighTimerValue
2834										=
2835										(ULONG)
2836										(ul_HighTiming
2837										*
2838										(0.00025 * b_ClockSelection));
2839
2840					/*******************/
2841									/* Round the value */
2842					/*******************/
2843
2844									if ((double)((double)ul_HighTiming * (0.00025 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
2845										ul_HighTimerValue
2846											=
2847											ul_HighTimerValue
2848											+
2849											1;
2850									}
2851
2852					/*****************************/
2853									/* Calculate the real timing */
2854					/*****************************/
2855
2856									ul_RealHighTiming
2857										=
2858										(ULONG)
2859										(ul_HighTimerValue
2860										/
2861										(0.00025 * (double)b_ClockSelection));
2862									d_RealHighTiming
2863										=
2864										(double)
2865										ul_HighTimerValue
2866										/
2867										(0.00025
2868										*
2869										(double)
2870										b_ClockSelection);
2871
2872									if ((double)((double)ul_HighTimerValue / (0.00025 * (double)b_ClockSelection)) >= (double)((double)ul_RealHighTiming + 0.5)) {
2873										ul_RealHighTiming
2874											=
2875											ul_RealHighTiming
2876											+
2877											1;
2878									}
2879
2880									ul_HighTiming
2881										=
2882										ul_HighTiming
2883										-
2884										1;
2885									ul_HighTimerValue
2886										=
2887										ul_HighTimerValue
2888										-
2889										2;
2890
2891									if (b_ClockSelection != APCI1710_40MHZ) {
2892										ul_HighTimerValue
2893											=
2894											(ULONG)
2895											(
2896											(double)
2897											(ul_HighTimerValue)
2898											*
2899											1.007752288);
2900									}
2901
2902									break;
2903
2904				/******/
2905									/* æs */
2906				/******/
2907
2908								case 1:
2909
2910					/******************/
2911									/* Timer 0 factor */
2912					/******************/
2913
2914									ul_HighTimerValue
2915										=
2916										(ULONG)
2917										(ul_HighTiming
2918										*
2919										(0.25 * b_ClockSelection));
2920
2921					/*******************/
2922									/* Round the value */
2923					/*******************/
2924
2925									if ((double)((double)ul_HighTiming * (0.25 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
2926										ul_HighTimerValue
2927											=
2928											ul_HighTimerValue
2929											+
2930											1;
2931									}
2932
2933					/*****************************/
2934									/* Calculate the real timing */
2935					/*****************************/
2936
2937									ul_RealHighTiming
2938										=
2939										(ULONG)
2940										(ul_HighTimerValue
2941										/
2942										(0.25 * (double)b_ClockSelection));
2943									d_RealHighTiming
2944										=
2945										(double)
2946										ul_HighTimerValue
2947										/
2948										(
2949										(double)
2950										0.25
2951										*
2952										(double)
2953										b_ClockSelection);
2954
2955									if ((double)((double)ul_HighTimerValue / (0.25 * (double)b_ClockSelection)) >= (double)((double)ul_RealHighTiming + 0.5)) {
2956										ul_RealHighTiming
2957											=
2958											ul_RealHighTiming
2959											+
2960											1;
2961									}
2962
2963									ul_HighTiming
2964										=
2965										ul_HighTiming
2966										-
2967										1;
2968									ul_HighTimerValue
2969										=
2970										ul_HighTimerValue
2971										-
2972										2;
2973
2974									if (b_ClockSelection != APCI1710_40MHZ) {
2975										ul_HighTimerValue
2976											=
2977											(ULONG)
2978											(
2979											(double)
2980											(ul_HighTimerValue)
2981											*
2982											1.007752288);
2983									}
2984
2985									break;
2986
2987				/******/
2988									/* ms */
2989				/******/
2990
2991								case 2:
2992
2993					/******************/
2994									/* Timer 0 factor */
2995					/******************/
2996
2997									ul_HighTimerValue
2998										=
2999										ul_HighTiming
3000										*
3001										(250.0
3002										*
3003										b_ClockSelection);
3004
3005					/*******************/
3006									/* Round the value */
3007					/*******************/
3008
3009									if ((double)((double)ul_HighTiming * (250.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
3010										ul_HighTimerValue
3011											=
3012											ul_HighTimerValue
3013											+
3014											1;
3015									}
3016
3017					/*****************************/
3018									/* Calculate the real timing */
3019					/*****************************/
3020
3021									ul_RealHighTiming
3022										=
3023										(ULONG)
3024										(ul_HighTimerValue
3025										/
3026										(250.0 * (double)b_ClockSelection));
3027									d_RealHighTiming
3028										=
3029										(double)
3030										ul_HighTimerValue
3031										/
3032										(250.0
3033										*
3034										(double)
3035										b_ClockSelection);
3036
3037									if ((double)((double)ul_HighTimerValue / (250.0 * (double)b_ClockSelection)) >= (double)((double)ul_RealHighTiming + 0.5)) {
3038										ul_RealHighTiming
3039											=
3040											ul_RealHighTiming
3041											+
3042											1;
3043									}
3044
3045									ul_HighTiming
3046										=
3047										ul_HighTiming
3048										-
3049										1;
3050									ul_HighTimerValue
3051										=
3052										ul_HighTimerValue
3053										-
3054										2;
3055
3056									if (b_ClockSelection != APCI1710_40MHZ) {
3057										ul_HighTimerValue
3058											=
3059											(ULONG)
3060											(
3061											(double)
3062											(ul_HighTimerValue)
3063											*
3064											1.007752288);
3065									}
3066
3067									break;
3068
3069				/*****/
3070									/* s */
3071				/*****/
3072
3073								case 3:
3074
3075					/******************/
3076									/* Timer 0 factor */
3077					/******************/
3078
3079									ul_HighTimerValue
3080										=
3081										(ULONG)
3082										(ul_HighTiming
3083										*
3084										(250000.0
3085											*
3086											b_ClockSelection));
3087
3088					/*******************/
3089									/* Round the value */
3090					/*******************/
3091
3092									if ((double)((double)ul_HighTiming * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
3093										ul_HighTimerValue
3094											=
3095											ul_HighTimerValue
3096											+
3097											1;
3098									}
3099
3100					/*****************************/
3101									/* Calculate the real timing */
3102					/*****************************/
3103
3104									ul_RealHighTiming
3105										=
3106										(ULONG)
3107										(ul_HighTimerValue
3108										/
3109										(250000.0
3110											*
3111											(double)
3112											b_ClockSelection));
3113									d_RealHighTiming
3114										=
3115										(double)
3116										ul_HighTimerValue
3117										/
3118										(250000.0
3119										*
3120										(double)
3121										b_ClockSelection);
3122
3123									if ((double)((double)ul_HighTimerValue / (250000.0 * (double)b_ClockSelection)) >= (double)((double)ul_RealHighTiming + 0.5)) {
3124										ul_RealHighTiming
3125											=
3126											ul_RealHighTiming
3127											+
3128											1;
3129									}
3130
3131									ul_HighTiming
3132										=
3133										ul_HighTiming
3134										-
3135										1;
3136									ul_HighTimerValue
3137										=
3138										ul_HighTimerValue
3139										-
3140										2;
3141
3142									if (b_ClockSelection != APCI1710_40MHZ) {
3143										ul_HighTimerValue
3144											=
3145											(ULONG)
3146											(
3147											(double)
3148											(ul_HighTimerValue)
3149											*
3150											1.007752288);
3151									}
3152
3153									break;
3154
3155				/******/
3156									/* mn */
3157				/******/
3158
3159								case 4:
3160
3161					/******************/
3162									/* Timer 0 factor */
3163					/******************/
3164
3165									ul_HighTimerValue
3166										=
3167										(ULONG)
3168										(
3169										(ul_HighTiming
3170											*
3171											60)
3172										*
3173										(250000.0
3174											*
3175											b_ClockSelection));
3176
3177					/*******************/
3178									/* Round the value */
3179					/*******************/
3180
3181									if ((double)((double)(ul_HighTiming * 60.0) * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
3182										ul_HighTimerValue
3183											=
3184											ul_HighTimerValue
3185											+
3186											1;
3187									}
3188
3189					/*****************************/
3190									/* Calculate the real timing */
3191					/*****************************/
3192
3193									ul_RealHighTiming
3194										=
3195										(ULONG)
3196										(ul_HighTimerValue
3197										/
3198										(250000.0
3199											*
3200											(double)
3201											b_ClockSelection))
3202										/
3203										60;
3204									d_RealHighTiming
3205										=
3206										(
3207										(double)
3208										ul_HighTimerValue
3209										/
3210										(250000.0
3211											*
3212											(double)
3213											b_ClockSelection))
3214										/
3215										60.0;
3216
3217									if ((double)(((double)ul_HighTimerValue / (250000.0 * (double)b_ClockSelection)) / 60.0) >= (double)((double)ul_RealHighTiming + 0.5)) {
3218										ul_RealHighTiming
3219											=
3220											ul_RealHighTiming
3221											+
3222											1;
3223									}
3224
3225									ul_HighTiming
3226										=
3227										ul_HighTiming
3228										-
3229										1;
3230									ul_HighTimerValue
3231										=
3232										ul_HighTimerValue
3233										-
3234										2;
3235
3236									if (b_ClockSelection != APCI1710_40MHZ) {
3237										ul_HighTimerValue
3238											=
3239											(ULONG)
3240											(
3241											(double)
3242											(ul_HighTimerValue)
3243											*
3244											1.007752288);
3245									}
3246
3247									break;
3248								}
3249
3250								fpu_end();
3251
3252			     /************************/
3253								/* Save the timing unit */
3254			     /************************/
3255
3256								devpriv->
3257									s_ModuleInfo
3258									[b_ModulNbr].
3259									s_PWMModuleInfo.
3260									s_PWMInfo
3261									[b_PWM].
3262									b_TimingUnit
3263									=
3264									b_TimingUnit;
3265
3266			     /****************************/
3267								/* Save the low base timing */
3268			     /****************************/
3269
3270								devpriv->
3271									s_ModuleInfo
3272									[b_ModulNbr].
3273									s_PWMModuleInfo.
3274									s_PWMInfo
3275									[b_PWM].
3276									d_LowTiming
3277									=
3278									d_RealLowTiming;
3279
3280								devpriv->
3281									s_ModuleInfo
3282									[b_ModulNbr].
3283									s_PWMModuleInfo.
3284									s_PWMInfo
3285									[b_PWM].
3286									ul_RealLowTiming
3287									=
3288									ul_RealLowTiming;
3289
3290			     /****************************/
3291								/* Save the high base timing */
3292			     /****************************/
3293
3294								devpriv->
3295									s_ModuleInfo
3296									[b_ModulNbr].
3297									s_PWMModuleInfo.
3298									s_PWMInfo
3299									[b_PWM].
3300									d_HighTiming
3301									=
3302									d_RealHighTiming;
3303
3304								devpriv->
3305									s_ModuleInfo
3306									[b_ModulNbr].
3307									s_PWMModuleInfo.
3308									s_PWMInfo
3309									[b_PWM].
3310									ul_RealHighTiming
3311									=
3312									ul_RealHighTiming;
3313
3314			     /************************/
3315								/* Write the low timing */
3316			     /************************/
3317
3318								outl(ul_LowTimerValue, devpriv->s_BoardInfos.ui_Address + 0 + (20 * b_PWM) + (64 * b_ModulNbr));
3319
3320			     /*************************/
3321								/* Write the high timing */
3322			     /*************************/
3323
3324								outl(ul_HighTimerValue, devpriv->s_BoardInfos.ui_Address + 4 + (20 * b_PWM) + (64 * b_ModulNbr));
3325
3326			     /***************************/
3327								/* Set the clock selection */
3328			     /***************************/
3329
3330								dw_Command =
3331									inl
3332									(devpriv->
3333									s_BoardInfos.
3334									ui_Address
3335									+ 8 +
3336									(20 * b_PWM) + (64 * b_ModulNbr));
3337
3338								dw_Command =
3339									dw_Command
3340									& 0x7F;
3341
3342								if (b_ClockSelection == APCI1710_40MHZ) {
3343									dw_Command
3344										=
3345										dw_Command
3346										|
3347										0x80;
3348								}
3349
3350			     /***************************/
3351								/* Set the clock selection */
3352			     /***************************/
3353
3354								outl(dw_Command,
3355									devpriv->
3356									s_BoardInfos.
3357									ui_Address
3358									+ 8 +
3359									(20 * b_PWM) + (64 * b_ModulNbr));
3360							} else {
3361			     /***************************************/
3362								/* High base timing selection is wrong */
3363			     /***************************************/
3364								DPRINTK("High base timing selection is wrong\n");
3365								i_ReturnValue =
3366									-8;
3367							}
3368						} else {
3369			  /**************************************/
3370							/* Low base timing selection is wrong */
3371			  /**************************************/
3372							DPRINTK("Low base timing selection is wrong\n");
3373							i_ReturnValue = -7;
3374						}
3375					}	// if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
3376					else {
3377		       /**********************************/
3378						/* Timing unit selection is wrong */
3379		       /**********************************/
3380						DPRINTK("Timing unit selection is wrong\n");
3381						i_ReturnValue = -6;
3382					}	// if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
3383				}	// if (dw_Status & 0x10)
3384				else {
3385		    /***********************/
3386					/* PWM not initialised */
3387		    /***********************/
3388					DPRINTK("PWM not initialised\n");
3389					i_ReturnValue = -5;
3390				}	// if (dw_Status & 0x10)
3391			}	// if (b_PWM >= 0 && b_PWM <= 1)
3392			else {
3393		 /******************************/
3394				/* Tor PWM selection is wrong */
3395		 /******************************/
3396				DPRINTK("Tor PWM selection is wrong\n");
3397				i_ReturnValue = -4;
3398			}	// if (b_PWM >= 0 && b_PWM <= 1)
3399		} else {
3400	      /**********************************/
3401			/* The module is not a PWM module */
3402	      /**********************************/
3403			DPRINTK("The module is not a PWM module\n");
3404			i_ReturnValue = -3;
3405		}
3406	} else {
3407	   /***********************/
3408		/* Module number error */
3409	   /***********************/
3410		DPRINTK("Module number error\n");
3411		i_ReturnValue = -2;
3412	}
3413
3414	return (i_ReturnValue);
3415}
3416
3417/*
3418+----------------------------------------------------------------------------+
3419| Function Name     : _INT_ i_APCI1710_GetPWMStatus                          |
3420|                               (BYTE_    b_BoardHandle,                     |
3421|                                BYTE_    b_ModulNbr,                        |
3422|                                BYTE_    b_PWM,                             |
3423|                                PBYTE_  pb_PWMOutputStatus,                 |
3424|                                PBYTE_  pb_ExternGateStatus)                |
3425+----------------------------------------------------------------------------+
3426| Task              : Return the status from selected PWM (b_PWM) from       |
3427|                     selected module (b_ModulNbr).                          |
3428+----------------------------------------------------------------------------+
3429| Input Parameters  : BYTE_  b_BoardHandle : Handle of board APCI-1710       |
3430|                     BYTE_  b_PWM         : Selected PWM (0 or 1)           |
3431|                     BYTE_  b_ModulNbr    : Selected module number (0 to 3)
3432	b_ModulNbr			=(BYTE)  CR_AREF(insn->chanspec);
3433	b_PWM				=(BYTE)  data[0];
3434
3435 |
3436+----------------------------------------------------------------------------+
3437| Output Parameters : PBYTE_  pb_PWMOutputStatus  : Return the PWM output    |
3438|                                                   level status.            |
3439|                                                    0 : The PWM output level|
3440|                                                        is low.             |
3441|                                                    1 : The PWM output level|
3442|                                                        is high.            |
3443|                     PBYTE_  pb_ExternGateStatus : Return the extern gate   |
3444|                                                   level status.            |
3445|                                                    0 : The extern gate is  |
3446|                                                        low.                |
3447|                                                    1 : The extern gate is  |
3448|                                                        high.
3449    pb_PWMOutputStatus	=(PBYTE) data[0];
3450	pb_ExternGateStatus =(PBYTE) data[1];             |
3451+----------------------------------------------------------------------------+
3452| Return Value      :  0: No error                                           |
3453|                     -1: The handle parameter of the board is wrong         |
3454|                     -2: Module selection wrong                             |
3455|                     -3: The module is not a PWM module                     |
3456|                     -4: PWM selection is wrong                             |
3457|                     -5: PWM not initialised see function                   |
3458|                         "i_APCI1710_InitPWM"                               |
3459|                     -6: PWM not enabled see function "i_APCI1710_EnablePWM"|
3460+----------------------------------------------------------------------------+
3461*/
3462
3463INT i_APCI1710_InsnReadGetPWMStatus(comedi_device * dev, comedi_subdevice * s,
3464	comedi_insn * insn, lsampl_t * data)
3465{
3466	INT i_ReturnValue = 0;
3467	DWORD dw_Status;
3468
3469	BYTE b_ModulNbr;
3470	BYTE b_PWM;
3471	PBYTE pb_PWMOutputStatus;
3472	PBYTE pb_ExternGateStatus;
3473
3474	i_ReturnValue = insn->n;
3475	b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
3476	b_PWM = (BYTE) CR_CHAN(insn->chanspec);
3477	pb_PWMOutputStatus = (PBYTE) & data[0];
3478	pb_ExternGateStatus = (PBYTE) & data[1];
3479
3480	/**************************/
3481	/* Test the module number */
3482	/**************************/
3483
3484	if (b_ModulNbr < 4) {
3485	   /***************/
3486		/* Test if PWM */
3487	   /***************/
3488
3489		if ((devpriv->s_BoardInfos.
3490				dw_MolduleConfiguration[b_ModulNbr] &
3491				0xFFFF0000UL) == APCI1710_PWM) {
3492	      /**************************/
3493			/* Test the PWM selection */
3494	      /**************************/
3495
3496			if (b_PWM <= 1) {
3497		 /***************************/
3498				/* Test if PWM initialised */
3499		 /***************************/
3500
3501				dw_Status = inl(devpriv->s_BoardInfos.
3502					ui_Address + 12 + (20 * b_PWM) +
3503					(64 * b_ModulNbr));
3504
3505				if (dw_Status & 0x10) {
3506		    /***********************/
3507					/* Test if PWM enabled */
3508		    /***********************/
3509
3510					if (dw_Status & 0x1) {
3511						*pb_PWMOutputStatus =
3512							(BYTE) ((dw_Status >> 7)
3513							& 1);
3514						*pb_ExternGateStatus =
3515							(BYTE) ((dw_Status >> 6)
3516							& 1);
3517					}	// if (dw_Status & 0x1)
3518					else {
3519		       /*******************/
3520						/* PWM not enabled */
3521		       /*******************/
3522
3523						DPRINTK("PWM not enabled \n");
3524						i_ReturnValue = -6;
3525					}	// if (dw_Status & 0x1)
3526				}	// if (dw_Status & 0x10)
3527				else {
3528		    /***********************/
3529					/* PWM not initialised */
3530		    /***********************/
3531
3532					DPRINTK("PWM not initialised\n");
3533					i_ReturnValue = -5;
3534				}	// if (dw_Status & 0x10)
3535			}	// if (b_PWM >= 0 && b_PWM <= 1)
3536			else {
3537		 /******************************/
3538				/* Tor PWM selection is wrong */
3539		 /******************************/
3540
3541				DPRINTK("Tor PWM selection is wrong\n");
3542				i_ReturnValue = -4;
3543			}	// if (b_PWM >= 0 && b_PWM <= 1)
3544		} else {
3545	      /**********************************/
3546			/* The module is not a PWM module */
3547	      /**********************************/
3548
3549			DPRINTK("The module is not a PWM module\n");
3550			i_ReturnValue = -3;
3551		}
3552	} else {
3553	   /***********************/
3554		/* Module number error */
3555	   /***********************/
3556
3557		DPRINTK("Module number error\n");
3558		i_ReturnValue = -2;
3559	}
3560
3561	return (i_ReturnValue);
3562}
3563
3564INT i_APCI1710_InsnBitsReadPWMInterrupt(comedi_device * dev,
3565	comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
3566{
3567	data[0] = devpriv->s_InterruptParameters.
3568		s_FIFOInterruptParameters[devpriv->
3569		s_InterruptParameters.ui_Read].b_OldModuleMask;
3570	data[1] = devpriv->s_InterruptParameters.
3571		s_FIFOInterruptParameters[devpriv->
3572		s_InterruptParameters.ui_Read].ul_OldInterruptMask;
3573	data[2] = devpriv->s_InterruptParameters.
3574		s_FIFOInterruptParameters[devpriv->
3575		s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
3576
3577			     /**************************/
3578	/* Increment the read FIFO */
3579			     /***************************/
3580
3581	devpriv->
3582		s_InterruptParameters.
3583		ui_Read = (devpriv->
3584		s_InterruptParameters.ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
3585
3586	return insn->n;
3587
3588}
3589