APCI1710_Pwm.c revision dae0dc30be7fa21b15a9d9534589286c6c3e68a3
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(struct comedi_device *dev,
61struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *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(struct comedi_device *dev, struct comedi_subdevice *s,
74	struct comedi_insn *insn, unsigned int *data)
75{
76	unsigned char 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, (unsigned char) CR_AREF(insn->chanspec),	/*   b_ModulNbr */
83			(unsigned char) data[0],	/* b_PWM */
84			(unsigned char) data[1],	/*  b_ClockSelection */
85			(unsigned char) data[2],	/*  b_TimingUnit */
86			(unsigned int) data[3],	/* ul_LowTiming */
87			(unsigned int) data[4],	/* ul_HighTiming */
88			(unsigned int *) & data[0],	/* pul_RealLowTiming */
89			(unsigned int *) & data[1]	/* pul_RealHighTiming */
90			);
91		break;
92
93	case APCI1710_PWM_GETINITDATA:
94		i_ReturnValue = i_APCI1710_GetPWMInitialisation(dev, (unsigned char) CR_AREF(insn->chanspec),	/*  b_ModulNbr */
95			(unsigned char) data[0],	/* b_PWM */
96			(unsigned char *) & data[0],	/* pb_TimingUnit */
97			(unsigned int *) & data[1],	/* pul_LowTiming */
98			(unsigned int *) & data[2],	/* pul_HighTiming */
99			(unsigned char *) & data[3],	/*  pb_StartLevel */
100			(unsigned char *) & data[4],	/*  pb_StopMode */
101			(unsigned char *) & data[5],	/*  pb_StopLevel */
102			(unsigned char *) & data[6],	/*  pb_ExternGate */
103			(unsigned char *) & data[7],	/*  pb_InterruptEnable */
104			(unsigned char *) & 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|                                       (unsigned char_     b_BoardHandle,            |
121|                                        unsigned char_     b_ModulNbr,               |
122|                                        unsigned char_     b_PWM,                    |
123|                                        unsigned char_     b_ClockSelection,         |
124|                                        unsigned char_     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  : unsigned char_     b_BoardHandle    : Handle of board APCI-1710 |
139|                     unsigned char_     b_ModulNbr       : Module number to configure|
140|                                                  (0 to 3)                  |
141|                     unsigned char_     b_PWM            : Selected PWM (0 or 1).    |
142|                     unsigned char_     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|                     unsigned char_     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(struct comedi_device *dev,
183	unsigned char b_ModulNbr,
184	unsigned char b_PWM,
185	unsigned char b_ClockSelection,
186	unsigned char b_TimingUnit,
187	unsigned int ul_LowTiming,
188	unsigned int ul_HighTiming,
189	unsigned int *pul_RealLowTiming, unsigned int *pul_RealHighTiming)
190{
191	int i_ReturnValue = 0;
192	unsigned int ul_LowTimerValue = 0;
193	unsigned int ul_HighTimerValue = 0;
194	unsigned int 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											(unsigned int)
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											(unsigned int)
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												(unsigned int)
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											(unsigned int)
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											(unsigned int)
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												(unsigned int)
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											(unsigned int)
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												(unsigned int)
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											(unsigned int)
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											(unsigned int)
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												(unsigned int)
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											(unsigned int)
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											(unsigned int)
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												(unsigned int)
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											(unsigned int)
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											(unsigned int)
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												(unsigned int)
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											(unsigned int)
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											(unsigned int)
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												(unsigned int)
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											(unsigned int)
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												(unsigned int)
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											(unsigned int)
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											(unsigned int)
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												(unsigned int)
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											(unsigned int)
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											(unsigned int)
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												(unsigned int)
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|                                       (unsigned char_     b_BoardHandle,            |
1446|                                        unsigned char_     b_ModulNbr,               |
1447|                                        unsigned char_     b_PWM,                    |
1448|                                        unsigned char *_   pb_TimingUnit,             |
1449|                                        PULONG_ pul_LowTiming,              |
1450|                                        PULONG_ pul_HighTiming,             |
1451|                                        unsigned char *_   pb_StartLevel,             |
1452|                                        unsigned char *_   pb_StopMode,               |
1453|                                        unsigned char *_   pb_StopLevel,              |
1454|                                        unsigned char *_   pb_ExternGate,             |
1455|                                        unsigned char *_   pb_InterruptEnable,        |
1456|                                        unsigned char *_   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  : unsigned char_ b_BoardHandle : Handle of board APCI-1710        |
1464|                     unsigned char_ b_ModulNbr    : Selected module number (0 to 3)  |
1465|                     unsigned char_ b_PWM         : Selected PWM (0 or 1)            |
1466+----------------------------------------------------------------------------+
1467| Output Parameters : unsigned char *_  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|                     unsigned char *_  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|                     unsigned char *_  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|                     unsigned char *_  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|                     unsigned char *_  pb_ExternGate      : Extern gate action        |
1508|                                                  selection                 |
1509|                                                   0 : Extern gate signal   |
1510|                                                       not used.            |
1511|                                                   1 : Extern gate signal   |
1512|                                                       used.                |
1513|                     unsigned char *_  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|                     unsigned char *_  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(struct comedi_device *dev,
1538	unsigned char b_ModulNbr,
1539	unsigned char b_PWM,
1540	unsigned char *pb_TimingUnit,
1541	unsigned int *pul_LowTiming,
1542	unsigned int *pul_HighTiming,
1543	unsigned char *pb_StartLevel,
1544	unsigned char *pb_StopMode,
1545	unsigned char *pb_StopLevel,
1546	unsigned char *pb_ExternGate, unsigned char *pb_InterruptEnable, unsigned char *pb_Enable)
1547{
1548	int i_ReturnValue = 0;
1549	unsigned int dw_Status;
1550	unsigned int 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						(unsigned char) ((dw_Command >> 5) & 1);
1606					*pb_StopMode =
1607						(unsigned char) ((dw_Command >> 0) & 1);
1608					*pb_StopLevel =
1609						(unsigned char) ((dw_Command >> 1) & 1);
1610					*pb_ExternGate =
1611						(unsigned char) ((dw_Command >> 4) & 1);
1612					*pb_InterruptEnable =
1613						(unsigned char) ((dw_Command >> 3) & 1);
1614
1615					if (*pb_StopLevel) {
1616						*pb_StopLevel =
1617							*pb_StopLevel +
1618							(unsigned char) ((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						(unsigned char) ((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(struct comedi_device *dev,
1674struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *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(struct comedi_device *dev, struct comedi_subdevice *s,
1687	struct comedi_insn *insn, unsigned int *data)
1688{
1689	unsigned char 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			(unsigned char) CR_AREF(insn->chanspec),
1697			(unsigned char) data[0],
1698			(unsigned char) data[1],
1699			(unsigned char) data[2],
1700			(unsigned char) data[3], (unsigned char) data[4], (unsigned char) data[5]);
1701		break;
1702
1703	case APCI1710_PWM_DISABLE:
1704		i_ReturnValue = i_APCI1710_DisablePWM(dev,
1705			(unsigned char) CR_AREF(insn->chanspec), (unsigned char) data[0]);
1706		break;
1707
1708	case APCI1710_PWM_NEWTIMING:
1709		i_ReturnValue = i_APCI1710_SetNewPWMTiming(dev,
1710			(unsigned char) CR_AREF(insn->chanspec),
1711			(unsigned char) data[0],
1712			(unsigned char) data[1], (unsigned int) data[2], (unsigned int) 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|                                       (unsigned char_  b_BoardHandle,               |
1728|                                        unsigned char_  b_ModulNbr,                  |
1729|                                        unsigned char_  b_PWM,                       |
1730|                                        unsigned char_  b_StartLevel,                |
1731|                                        unsigned char_  b_StopMode,                  |
1732|                                        unsigned char_  b_StopLevel,                 |
1733|                                        unsigned char_  b_ExternGate,                |
1734|                                        unsigned char_  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  : unsigned char_ b_BoardHandle     : Handle of board APCI-1710    |
1745|                     unsigned char_ b_ModulNbr        : Selected module number       |
1746|                                               (0 to 3)                     |
1747|                     unsigned char_ b_PWM             : Selected PWM (0 or 1)        |
1748|                     unsigned char_ 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|                     unsigned char_ 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|                     unsigned char_ 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|                     unsigned char_ b_ExternGate      : Extern gate action selection |
1778|                                                0 : Extern gate signal not  |
1779|                                                    used.                   |
1780|                                                1 : Extern gate signal used.|
1781|                     unsigned char_ 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(struct comedi_device *dev,
1810	unsigned char b_ModulNbr,
1811	unsigned char b_PWM,
1812	unsigned char b_StartLevel,
1813	unsigned char b_StopMode,
1814	unsigned char b_StopLevel, unsigned char b_ExternGate, unsigned char b_InterruptEnable)
1815{
1816	int i_ReturnValue = 0;
1817	unsigned int dw_Status;
1818	unsigned int 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 (unsigned char_  b_BoardHandle,     |
2038|                                                  unsigned char_  b_ModulNbr,        |
2039|                                                  unsigned char_  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|                    unsigned char_ b_ModulNbr    : Selected module number (0 to 3)   |
2049|                    unsigned char_ 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(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char b_PWM)
2066{
2067	int i_ReturnValue = 0;
2068	unsigned int 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|                                       (unsigned char_     b_BoardHandle,            |
2154|                                        unsigned char_     b_ModulNbr,               |
2155|                                        unsigned char_     b_PWM,                    |
2156|                                        unsigned char_     b_ClockSelection,         |
2157|                                        unsigned char_     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  : unsigned char_     b_BoardHandle    : Handle of board APCI-1710 |
2166|                     unsigned char_     b_ModulNbr       : Module number to configure|
2167|                                                  (0 to 3)                  |
2168|                     unsigned char_     b_PWM            : Selected PWM (0 or 1).    |
2169|                     unsigned char_     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(struct comedi_device *dev,
2193	unsigned char b_ModulNbr,
2194	unsigned char b_PWM, unsigned char b_TimingUnit, unsigned int ul_LowTiming, unsigned int ul_HighTiming)
2195{
2196	unsigned char b_ClockSelection;
2197	int i_ReturnValue = 0;
2198	unsigned int ul_LowTimerValue = 0;
2199	unsigned int ul_HighTimerValue = 0;
2200	unsigned int ul_RealLowTiming = 0;
2201	unsigned int ul_RealHighTiming = 0;
2202	unsigned int dw_Status;
2203	unsigned int 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										(unsigned int)
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										(unsigned int)
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											(unsigned int)
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										(unsigned int)
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										(unsigned int)
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											(unsigned int)
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										(unsigned int)
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											(unsigned int)
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										(unsigned int)
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										(unsigned int)
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											(unsigned int)
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										(unsigned int)
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										(unsigned int)
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											(unsigned int)
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										(unsigned int)
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										(unsigned int)
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											(unsigned int)
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										(unsigned int)
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										(unsigned int)
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											(unsigned int)
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										(unsigned int)
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											(unsigned int)
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										(unsigned int)
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										(unsigned int)
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											(unsigned int)
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										(unsigned int)
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										(unsigned int)
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											(unsigned int)
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|                               (unsigned char_    b_BoardHandle,                     |
3421|                                unsigned char_    b_ModulNbr,                        |
3422|                                unsigned char_    b_PWM,                             |
3423|                                unsigned char *_  pb_PWMOutputStatus,                 |
3424|                                unsigned char *_  pb_ExternGateStatus)                |
3425+----------------------------------------------------------------------------+
3426| Task              : Return the status from selected PWM (b_PWM) from       |
3427|                     selected module (b_ModulNbr).                          |
3428+----------------------------------------------------------------------------+
3429| Input Parameters  : unsigned char_  b_BoardHandle : Handle of board APCI-1710       |
3430|                     unsigned char_  b_PWM         : Selected PWM (0 or 1)           |
3431|                     unsigned char_  b_ModulNbr    : Selected module number (0 to 3)
3432	b_ModulNbr			=(unsigned char)  CR_AREF(insn->chanspec);
3433	b_PWM				=(unsigned char)  data[0];
3434
3435 |
3436+----------------------------------------------------------------------------+
3437| Output Parameters : unsigned char *_  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|                     unsigned char *_  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	=(unsigned char *) data[0];
3450	pb_ExternGateStatus =(unsigned char *) 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(struct comedi_device *dev, struct comedi_subdevice *s,
3464	struct comedi_insn *insn, unsigned int *data)
3465{
3466	int i_ReturnValue = 0;
3467	unsigned int dw_Status;
3468
3469	unsigned char b_ModulNbr;
3470	unsigned char b_PWM;
3471	unsigned char *pb_PWMOutputStatus;
3472	unsigned char *pb_ExternGateStatus;
3473
3474	i_ReturnValue = insn->n;
3475	b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
3476	b_PWM = (unsigned char) CR_CHAN(insn->chanspec);
3477	pb_PWMOutputStatus = (unsigned char *) & data[0];
3478	pb_ExternGateStatus = (unsigned char *) & 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							(unsigned char) ((dw_Status >> 7)
3513							& 1);
3514						*pb_ExternGateStatus =
3515							(unsigned char) ((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(struct comedi_device *dev,
3565	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *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