Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
APCI1710_82x54.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
3  *
4  * ADDI-DATA GmbH
5  * Dieselstrasse 3
6  * D-77833 Ottersweier
7  * Tel: +19(0)7223/9493-0
8  * Fax: +49(0)7223/9493-92
9  * http://www.addi-data.com
11  *
12  * This program is free software; you can redistribute it and/or modify it
13  * under the terms of the GNU General Public License as published by the Free
14  * Software Foundation; either version 2 of the License, or (at your option)
15  * any later version.
16  */
17 /*
18  | Description : APCI-1710 82X54 timer module |
19 */
20 
21 #include "APCI1710_82x54.h"
22 
23 /*
24 +----------------------------------------------------------------------------+
25 | Function Name : _INT_ i_APCI1710_InitTimer |
26 | (unsigned char_ b_BoardHandle, |
27 | unsigned char_ b_ModulNbr, |
28 | unsigned char_ b_TimerNbr, |
29 | unsigned char_ b_TimerMode, |
30 | ULONG_ ul_ReloadValue, |
31 | unsigned char_ b_InputClockSelection, |
32 | unsigned char_ b_InputClockLevel, |
33 | unsigned char_ b_OutputLevel, |
34 | unsigned char_ b_HardwareGateLevel)
35 int i_InsnConfig_InitTimer(struct comedi_device *dev,struct comedi_subdevice *s,
36  struct comedi_insn *insn,unsigned int *data)
37 |
38 +----------------------------------------------------------------------------+
39 | Task : Configure the Timer (b_TimerNbr) operating mode |
40 | (b_TimerMode) from selected module (b_ModulNbr). |
41 | You must calling this function be for you call any |
42 | other function witch access of the timer. |
43 | |
44 | |
45 | Timer mode description table |
46 | |
47 |+--------+-----------------------------+--------------+--------------------+|
48 ||Selected+ Mode description +u_ReloadValue | Hardware gate input||
49 || mode | | description | action ||
50 |+--------+-----------------------------+--------------+--------------------+|
51 || |Mode 0 is typically used | | ||
52 || |for event counting. After | | ||
53 || |the initialisation, OUT | | ||
54 || |is initially low, and | | ||
55 || 0 |will remain low until the |Start counting| Hardware gate ||
56 || |counter reaches zero. | value | ||
57 || |OUT then goes high and | | ||
58 || |remains high until a new | | ||
59 || |count is written. See | | ||
60 || |"i_APCI1710_WriteTimerValue" | | ||
61 || |function. | | ||
62 |+--------+-----------------------------+--------------+--------------------+|
63 || |Mode 1 is similar to mode 0 | | ||
64 || |except for the gate input | | ||
65 || 1 |action. The gate input is not|Start counting| Hardware trigger ||
66 || |used for enabled or disabled | value | ||
67 || |the timer. | | ||
68 || |The gate input is used for | | ||
69 || |triggered the timer. | | ||
70 |+--------+-----------------------------+--------------+--------------------+|
71 || |This mode functions like a | | ||
72 || |divide-by-ul_ReloadValue | | ||
73 || |counter. It is typically used| | ||
74 || |to generate a real time clock| | ||
75 || |interrupt. OUT will initially| | ||
76 || 2 |be high after the | Division | Hardware gate ||
77 || |initialisation. When the | factor | ||
78 || |initial count has decremented| | ||
79 || |to 1, OUT goes low for one | | ||
80 || |CLK pule. OUT then goes high | | ||
81 || |again, the counter reloads | | ||
82 || |the initial count | | ||
83 || |(ul_ReloadValue) and the | | ||
84 || |process is repeated. | | ||
85 || |This action can generated a | | ||
86 || |interrupt. See function | | ||
87 || |"i_APCI1710_SetBoardInt- | | ||
88 || |RoutineX" | | ||
89 || |and "i_APCI1710_EnableTimer" | | ||
90 |+--------+-----------------------------+--------------+--------------------+|
91 || |Mode 3 is typically used for | | ||
92 || |baud rate generation. This | | ||
93 || |mode is similar to mode 2 | | ||
94 || |except for the duty cycle of | | ||
95 || 3 |OUT. OUT will initially be | Division | Hardware gate ||
96 || |high after the initialisation| factor | ||
97 || |When half the initial count | | ||
98 || |(ul_ReloadValue) has expired,| | ||
99 || |OUT goes low for the | | ||
100 || |remainder of the count. The | | ||
101 || |mode is periodic; the | | ||
102 || |sequence above is repeated | | ||
103 || |indefinitely. | | ||
104 |+--------+-----------------------------+--------------+--------------------+|
105 || |OUT will be initially high | | ||
106 || |after the initialisation. | | ||
107 || |When the initial count | | ||
108 || 4 |expires OUT will go low for |Start counting| Hardware gate ||
109 || |one CLK pulse and then go | value | ||
110 || |high again. | | ||
111 || |The counting sequences is | | ||
112 || |triggered by writing a new | | ||
113 || |value. See | | ||
114 || |"i_APCI1710_WriteTimerValue" | | ||
115 || |function. If a new count is | | ||
116 || |written during counting, | | ||
117 || |it will be loaded on the | | ||
118 || |next CLK pulse | | ||
119 |+--------+-----------------------------+--------------+--------------------+|
120 || |Mode 5 is similar to mode 4 | | ||
121 || |except for the gate input | | ||
122 || |action. The gate input is not| | ||
123 || 5 |used for enabled or disabled |Start counting| Hardware trigger ||
124 || |the timer. The gate input is | value | ||
125 || |used for triggered the timer.| | ||
126 |+--------+-----------------------------+--------------+--------------------+|
127 | |
128 | |
129 | |
130 | Input clock selection table |
131 | |
132 | +--------------------------------+------------------------------------+ |
133 | | b_InputClockSelection | Description | |
134 | | parameter | | |
135 | +--------------------------------+------------------------------------+ |
136 | | APCI1710_PCI_BUS_CLOCK | For the timer input clock, the PCI | |
137 | | | bus clock / 4 is used. This PCI bus| |
138 | | | clock can be 30MHz or 33MHz. For | |
139 | | | Timer 0 only this selection are | |
140 | | | available. | |
141 | +--------------------------------+------------------------------------+ |
142 | | APCI1710_ FRONT_CONNECTOR_INPUT| Of the front connector you have the| |
143 | | | possibility to inject a input clock| |
144 | | | for Timer 1 or Timer 2. The source | |
145 | | | from this clock can eat the output | |
146 | | | clock from Timer 0 or any other | |
147 | | | clock source. | |
148 | +--------------------------------+------------------------------------+ |
149 | |
150 +----------------------------------------------------------------------------+
151 | Input Parameters : unsigned char_ b_BoardHandle : Handle of board |
152 | APCI-1710 |
153 | unsigned char_ b_ModulNbr : Module number to |
154 | configure (0 to 3) |
155 | unsigned char_ b_TimerNbr : Timer number to |
156 | configure (0 to 2) |
157 | unsigned char_ b_TimerMode : Timer mode selection |
158 | (0 to 5) |
159 | 0: Interrupt on terminal|
160 | count |
161 | 1: Hardware |
162 | retriggerable one- |
163 | shot |
164 | 2: Rate generator |
165 | 3: Square wave mode |
166 | 4: Software triggered |
167 | strobe |
168 | 5: Hardware triggered |
169 | strobe |
170 | See timer mode |
171 | description table. |
172 | ULONG_ ul_ReloadValue : Start counting value |
173 | or division factor |
174 | See timer mode |
175 | description table. |
176 | unsigned char_ b_InputClockSelection : Selection from input |
177 | timer clock. |
178 | See input clock |
179 | selection table. |
180 | unsigned char_ b_InputClockLevel : Selection from input |
181 | clock level. |
182 | 0 : Low active |
183 | (Input inverted) |
184 | 1 : High active |
185 | unsigned char_ b_OutputLevel, : Selection from output |
186 | clock level. |
187 | 0 : Low active |
188 | 1 : High active |
189 | (Output inverted) |
190 | unsigned char_ b_HardwareGateLevel : Selection from |
191 | hardware gate level. |
192 | 0 : Low active |
193 | (Input inverted) |
194 | 1 : High active |
195 | If you will not used |
196 | the hardware gate set |
197 | this value to 0.
198 |b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
199  b_TimerNbr = (unsigned char) CR_CHAN(insn->chanspec);
200  b_TimerMode = (unsigned char) data[0];
201  ul_ReloadValue = (unsigned int) data[1];
202  b_InputClockSelection =(unsigned char) data[2];
203  b_InputClockLevel =(unsigned char) data[3];
204  b_OutputLevel =(unsigned char) data[4];
205  b_HardwareGateLevel =(unsigned char) data[5];
206 +----------------------------------------------------------------------------+
207 | Output Parameters : - |
208 +----------------------------------------------------------------------------+
209 | Return Value : 0: No error |
210 | -1: The handle parameter of the board is wrong |
211 | -2: Module selection wrong |
212 | -3: Timer selection wrong |
213 | -4: The module is not a TIMER module |
214 | -5: Timer mode selection is wrong |
215 | -6: Input timer clock selection is wrong |
216 | -7: Selection from input clock level is wrong |
217 | -8: Selection from output clock level is wrong |
218 | -9: Selection from hardware gate level is wrong |
219 +----------------------------------------------------------------------------+
220 */
221 
223  struct comedi_insn *insn, unsigned int *data)
224 {
225 
226  int i_ReturnValue = 0;
227  unsigned char b_ModulNbr;
228  unsigned char b_TimerNbr;
229  unsigned char b_TimerMode;
230  unsigned int ul_ReloadValue;
231  unsigned char b_InputClockSelection;
232  unsigned char b_InputClockLevel;
233  unsigned char b_OutputLevel;
234  unsigned char b_HardwareGateLevel;
235 
236  /* BEGIN JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz */
237  unsigned int dw_Test = 0;
238  /* END JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz */
239 
240  i_ReturnValue = insn->n;
241  b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
242  b_TimerNbr = (unsigned char) CR_CHAN(insn->chanspec);
243  b_TimerMode = (unsigned char) data[0];
244  ul_ReloadValue = (unsigned int) data[1];
245  b_InputClockSelection = (unsigned char) data[2];
246  b_InputClockLevel = (unsigned char) data[3];
247  b_OutputLevel = (unsigned char) data[4];
248  b_HardwareGateLevel = (unsigned char) data[5];
249 
250  /* Test the module number */
251  if (b_ModulNbr < 4) {
252  /* Test if 82X54 timer */
253  if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
254  /* Test the timer number */
255 
256  if (b_TimerNbr <= 2) {
257  /* Test the timer mode */
258  if (b_TimerMode <= 5) {
259  /* BEGIN JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz */
260  /* Test te imput clock selection */
261  /*
262  if (((b_TimerNbr == 0) && (b_InputClockSelection == 0)) ||
263  ((b_TimerNbr != 0) && ((b_InputClockSelection == 0) || (b_InputClockSelection == 1))))
264  */
265 
266  if (((b_TimerNbr == 0) &&
267  (b_InputClockSelection == APCI1710_PCI_BUS_CLOCK)) ||
268  ((b_TimerNbr == 0) &&
269  (b_InputClockSelection == APCI1710_10MHZ)) ||
270  ((b_TimerNbr != 0) &&
271  ((b_InputClockSelection == APCI1710_PCI_BUS_CLOCK) ||
272  (b_InputClockSelection == APCI1710_FRONT_CONNECTOR_INPUT) ||
273  (b_InputClockSelection == APCI1710_10MHZ)))) {
274  /* BEGIN JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz */
275  if (((b_InputClockSelection == APCI1710_10MHZ) &&
276  ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0x0000FFFFUL) >= 0x3131)) ||
277  (b_InputClockSelection != APCI1710_10MHZ)) {
278  /* END JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz */
279  /* Test the input clock level selection */
280 
281  if ((b_InputClockLevel == 0) ||
282  (b_InputClockLevel == 1)) {
283  /* Test the output clock level selection */
284  if ((b_OutputLevel == 0) || (b_OutputLevel == 1)) {
285  /* Test the hardware gate level selection */
286  if ((b_HardwareGateLevel == 0) || (b_HardwareGateLevel == 1)) {
287  /* BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz */
288  /* Test if version > 1.1 and clock selection = 10MHz */
289  if ((b_InputClockSelection == APCI1710_10MHZ) && ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0x0000FFFFUL) > 0x3131)) {
290  /* Test if 40MHz quartz on board */
291  dw_Test = inl(devpriv->s_BoardInfos.ui_Address + (16 + (b_TimerNbr * 4) + (64 * b_ModulNbr)));
292 
293  dw_Test = (dw_Test >> 16) & 1;
294  } else {
295  dw_Test = 1;
296  }
297 
298  /* Test if detection OK */
299  if (dw_Test == 1) {
300  /* END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz */
301  /* Initialisation OK */
302  devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init = 1;
303 
304  /* Save the input clock selection */
305  devpriv-> s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_InputClockSelection = b_InputClockSelection;
306 
307  /* Save the input clock level */
308  devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_InputClockLevel = ~b_InputClockLevel & 1;
309 
310  /* Save the output level */
311  devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_OutputLevel = ~b_OutputLevel & 1;
312 
313  /* Save the gate level */
314  devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_HardwareGateLevel = b_HardwareGateLevel;
315 
316  /* Set the configuration word and disable the timer */
317  /* BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz */
318  /*
319  devpriv->s_ModuleInfo [b_ModulNbr].
320  s_82X54ModuleInfo.
321  s_82X54TimerInfo [b_TimerNbr].
322  dw_ConfigurationWord = (unsigned int) (((b_HardwareGateLevel << 0) & 0x1) |
323  ((b_InputClockLevel << 1) & 0x2) |
324  (((~b_OutputLevel & 1) << 2) & 0x4) |
325  ((b_InputClockSelection << 4) & 0x10));
326  */
327  /* Test if 10MHz selected */
328  if (b_InputClockSelection == APCI1710_10MHZ) {
329  b_InputClockSelection = 2;
330  }
331 
332  devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord = (unsigned int)(((b_HardwareGateLevel << 0) & 0x1) | ((b_InputClockLevel << 1) & 0x2) | (((~b_OutputLevel & 1) << 2) & 0x4) | ((b_InputClockSelection << 4) & 0x30));
333  /* END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz */
334  outl(devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord, devpriv->s_BoardInfos.ui_Address + 32 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
335 
336  /* Initialise the 82X54 Timer */
337  outl((unsigned int) b_TimerMode, devpriv->s_BoardInfos.ui_Address + 16 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
338 
339  /* Write the reload value */
340  outl(ul_ReloadValue, devpriv->s_BoardInfos.ui_Address + 0 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
341  /* BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz */
342  } /* if (dw_Test == 1) */
343  else {
344  /* Input timer clock selection is wrong */
345  i_ReturnValue = -6;
346  } /* if (dw_Test == 1) */
347  /* END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz */
348  } /* if ((b_HardwareGateLevel == 0) || (b_HardwareGateLevel == 1)) */
349  else {
350  /* Selection from hardware gate level is wrong */
351  DPRINTK("Selection from hardware gate level is wrong\n");
352  i_ReturnValue = -9;
353  } /* if ((b_HardwareGateLevel == 0) || (b_HardwareGateLevel == 1)) */
354  } /* if ((b_OutputLevel == 0) || (b_OutputLevel == 1)) */
355  else {
356  /* Selection from output clock level is wrong */
357  DPRINTK("Selection from output clock level is wrong\n");
358  i_ReturnValue = -8;
359  } /* if ((b_OutputLevel == 0) || (b_OutputLevel == 1)) */
360  } /* if ((b_InputClockLevel == 0) || (b_InputClockLevel == 1)) */
361  else {
362  /* Selection from input clock level is wrong */
363  DPRINTK("Selection from input clock level is wrong\n");
364  i_ReturnValue = -7;
365  } /* if ((b_InputClockLevel == 0) || (b_InputClockLevel == 1)) */
366  } else {
367  /* Input timer clock selection is wrong */
368  DPRINTK("Input timer clock selection is wrong\n");
369  i_ReturnValue = -6;
370  }
371  } else {
372  /* Input timer clock selection is wrong */
373  DPRINTK("Input timer clock selection is wrong\n");
374  i_ReturnValue = -6;
375  }
376  } /* if ((b_TimerMode >= 0) && (b_TimerMode <= 5)) */
377  else {
378  /* Timer mode selection is wrong */
379  DPRINTK("Timer mode selection is wrong\n");
380  i_ReturnValue = -5;
381  } /* if ((b_TimerMode >= 0) && (b_TimerMode <= 5)) */
382  } /* if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2)) */
383  else {
384  /* Timer selection wrong */
385  DPRINTK("Timer selection wrong\n");
386  i_ReturnValue = -3;
387  } /* if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2)) */
388  } else {
389  /* The module is not a TIMER module */
390  DPRINTK("The module is not a TIMER module\n");
391  i_ReturnValue = -4;
392  }
393  } else {
394  /* Module number error */
395  DPRINTK("Module number error\n");
396  i_ReturnValue = -2;
397  }
398 
399  return i_ReturnValue;
400 }
401 
402 /*
403 +----------------------------------------------------------------------------+
404 | Function Name : _INT_ i_APCI1710_EnableTimer |
405 | (unsigned char_ b_BoardHandle, |
406 | unsigned char_ b_ModulNbr, |
407 | unsigned char_ b_TimerNbr, |
408 | unsigned char_ b_InterruptEnable)
409 int i_APCI1710_InsnWriteEnableDisableTimer(struct comedi_device *dev,struct comedi_subdevice *s,
410  struct comedi_insn *insn,unsigned int *data) |
411 +----------------------------------------------------------------------------+
412 | Task : Enable OR Disable the Timer (b_TimerNbr) from selected module |
413 | (b_ModulNbr). You must calling the |
414 | "i_APCI1710_InitTimer" function be for you call this |
415 | function. If you enable the timer interrupt, the timer |
416 | generate a interrupt after the timer value reach |
417 | the zero. See function "i_APCI1710_SetBoardIntRoutineX"|
418 +----------------------------------------------------------------------------+
419 | Input Parameters : unsigned char_ b_BoardHandle : Handle of board |
420 | APCI-1710 |
421 | unsigned char_ b_ModulNbr : Selected module number |
422 | (0 to 3) |
423 | unsigned char_ b_TimerNbr : Timer number to enable |
424 | (0 to 2) |
425 | unsigned char_ b_InterruptEnable : Enable or disable the |
426 | timer interrupt. |
427 | APCI1710_ENABLE : |
428 | Enable the timer interrupt |
429 | APCI1710_DISABLE : |
430 | Disable the timer interrupt|
431 i_ReturnValue=insn->n;
432  b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
433  b_TimerNbr = (unsigned char) CR_CHAN(insn->chanspec);
434  b_ActionType = (unsigned char) data[0]; /* enable disable */
435 +----------------------------------------------------------------------------+
436 | Output Parameters : - |
437 +----------------------------------------------------------------------------+
438 | Return Value : 0: No error |
439 | -1: The handle parameter of the board is wrong |
440 | -2: Module selection wrong |
441 | -3: Timer selection wrong |
442 | -4: The module is not a TIMER module |
443 | -5: Timer not initialised see function |
444 | "i_APCI1710_InitTimer" |
445 | -6: Interrupt parameter is wrong |
446 | -7: Interrupt function not initialised. |
447 | See function "i_APCI1710_SetBoardIntRoutineX" |
448 +----------------------------------------------------------------------------+
449 */
450 
453  struct comedi_insn *insn, unsigned int *data)
454 {
455  int i_ReturnValue = 0;
456  unsigned int dw_DummyRead;
457  unsigned char b_ModulNbr;
458  unsigned char b_TimerNbr;
459  unsigned char b_ActionType;
460  unsigned char b_InterruptEnable;
461 
462  i_ReturnValue = insn->n;
463  b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
464  b_TimerNbr = (unsigned char) CR_CHAN(insn->chanspec);
465  b_ActionType = (unsigned char) data[0]; /* enable disable */
466 
467  /* Test the module number */
468  if (b_ModulNbr < 4) {
469  /* Test if 82X54 timer */
470  if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
471  /* Test the timer number */
472  if (b_TimerNbr <= 2) {
473  /* Test if timer initialised */
474  if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init == 1) {
475 
476  switch (b_ActionType) {
477  case APCI1710_ENABLE:
478  b_InterruptEnable = (unsigned char) data[1];
479  /* Test the interrupt selection */
480  if ((b_InterruptEnable == APCI1710_ENABLE) ||
481  (b_InterruptEnable == APCI1710_DISABLE)) {
482  if (b_InterruptEnable == APCI1710_ENABLE) {
483 
484  dw_DummyRead = inl(devpriv->s_BoardInfos.ui_Address + 12 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
485 
486  /* Enable the interrupt */
487  devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord | 0x8;
488 
489  outl(devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord, devpriv->s_BoardInfos.ui_Address + 32 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
490  devpriv->tsk_Current = current; /* Save the current process task structure */
491 
492  } /* if (b_InterruptEnable == APCI1710_ENABLE) */
493  else {
494  /* Disable the interrupt */
495  devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord & 0xF7;
496 
497  outl(devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord, devpriv->s_BoardInfos.ui_Address + 32 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
498 
499  /* Save the interrupt flag */
500  devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask & (0xFF - (1 << b_TimerNbr));
501  } /* if (b_InterruptEnable == APCI1710_ENABLE) */
502 
503  /* Test if error occur */
504  if (i_ReturnValue >= 0) {
505  /* Save the interrupt flag */
506  devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask | ((1 & b_InterruptEnable) << b_TimerNbr);
507 
508  /* Enable the timer */
509  outl(1, devpriv->s_BoardInfos.ui_Address + 44 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
510  }
511  } else {
512  /* Interrupt parameter is wrong */
513  DPRINTK("\n");
514  i_ReturnValue = -6;
515  }
516  break;
517  case APCI1710_DISABLE:
518  /* Test the interrupt flag */
519  if (((devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask >> b_TimerNbr) & 1) == 1) {
520  /* Disable the interrupt */
521 
522  devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr]. dw_ConfigurationWord = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord & 0xF7;
523 
524  outl(devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord, devpriv->s_BoardInfos.ui_Address + 32 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
525 
526  /* Save the interrupt flag */
527  devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask & (0xFF - (1 << b_TimerNbr));
528  }
529 
530  /* Disable the timer */
531  outl(0, devpriv->s_BoardInfos.ui_Address + 44 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
532  break;
533  } /* Switch end */
534  } else {
535  /* Timer not initialised see function */
536  DPRINTK ("Timer not initialised see function\n");
537  i_ReturnValue = -5;
538  }
539  } else {
540  /* Timer selection wrong */
541  DPRINTK("Timer selection wrong\n");
542  i_ReturnValue = -3;
543  } /* if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2)) */
544  } else {
545  /* The module is not a TIMER module */
546  DPRINTK("The module is not a TIMER module\n");
547  i_ReturnValue = -4;
548  }
549  } else {
550  /* Module number error */
551  DPRINTK("Module number error\n");
552  i_ReturnValue = -2;
553  }
554 
555  return i_ReturnValue;
556 }
557 
558 /*
559 +----------------------------------------------------------------------------+
560 | Function Name : _INT_ i_APCI1710_ReadAllTimerValue |
561 | (unsigned char_ b_BoardHandle, |
562 | unsigned char_ b_ModulNbr, |
563 | PULONG_ pul_TimerValueArray)
564 int i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev,struct comedi_subdevice *s,
565  struct comedi_insn *insn,unsigned int *data) |
566 +----------------------------------------------------------------------------+
567 | Task : Return the all timer values from selected timer |
568 | module (b_ModulNbr). |
569 +----------------------------------------------------------------------------+
570 | Input Parameters : unsigned char_ b_BoardHandle : Handle of board |
571 | APCI-1710 |
572 | unsigned char_ b_ModulNbr : Selected module number |
573 | (0 to 3) |
574 +----------------------------------------------------------------------------+
575 | Output Parameters : PULONG_ pul_TimerValueArray : Timer value array. |
576 | Element 0 contain the timer 0 value. |
577 | Element 1 contain the timer 1 value. |
578 | Element 2 contain the timer 2 value. |
579 +----------------------------------------------------------------------------+
580 | Return Value : 0: No error |
581 | -1: The handle parameter of the board is wrong |
582 | -2: Module selection wrong |
583 | -3: The module is not a TIMER module |
584 | -4: Timer 0 not initialised see function |
585 | "i_APCI1710_InitTimer" |
586 | -5: Timer 1 not initialised see function |
587 | "i_APCI1710_InitTimer" |
588 | -6: Timer 2 not initialised see function |
589 | "i_APCI1710_InitTimer" |
590 +----------------------------------------------------------------------------+
591 */
592 
594  struct comedi_insn *insn, unsigned int *data)
595 {
596  int i_ReturnValue = 0;
597  unsigned char b_ModulNbr, b_ReadType;
598  unsigned int *pul_TimerValueArray;
599 
600  b_ModulNbr = CR_AREF(insn->chanspec);
601  b_ReadType = CR_CHAN(insn->chanspec);
602  pul_TimerValueArray = (unsigned int *) data;
603  i_ReturnValue = insn->n;
604 
605  switch (b_ReadType) {
607 
608  data[0] = devpriv->s_InterruptParameters.s_FIFOInterruptParameters[devpriv->s_InterruptParameters.ui_Read].b_OldModuleMask;
609  data[1] = devpriv->s_InterruptParameters.s_FIFOInterruptParameters[devpriv->s_InterruptParameters.ui_Read].ul_OldInterruptMask;
610  data[2] = devpriv->s_InterruptParameters.s_FIFOInterruptParameters[devpriv->s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
611 
612  /* Increment the read FIFO */
613  devpriv->s_InterruptParameters.ui_Read = (devpriv->s_InterruptParameters.ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
614 
615  break;
616 
618  /* Test the module number */
619  if (b_ModulNbr < 4) {
620  /* Test if 82X54 timer */
621  if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
622  /* Test if timer 0 iniutialised */
623  if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[0].b_82X54Init == 1) {
624  /* Test if timer 1 iniutialised */
625  if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[1].b_82X54Init == 1) {
626  /* Test if timer 2 iniutialised */
627  if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[2].b_82X54Init == 1) {
628  /* Latch all counter */
629  outl(0x17, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr));
630 
631  /* Read the timer 0 value */
632  pul_TimerValueArray[0] = inl(devpriv->s_BoardInfos.ui_Address + 0 + (64 * b_ModulNbr));
633 
634  /* Read the timer 1 value */
635  pul_TimerValueArray[1] = inl(devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr));
636 
637  /* Read the timer 2 value */
638  pul_TimerValueArray[2] = inl(devpriv->s_BoardInfos.ui_Address + 8 + (64 * b_ModulNbr));
639  } else {
640  /* Timer 2 not initialised see function */
641  DPRINTK("Timer 2 not initialised see function\n");
642  i_ReturnValue = -6;
643  }
644  } else {
645  /* Timer 1 not initialised see function */
646  DPRINTK("Timer 1 not initialised see function\n");
647  i_ReturnValue = -5;
648  }
649  } else {
650  /* Timer 0 not initialised see function */
651  DPRINTK("Timer 0 not initialised see function\n");
652  i_ReturnValue = -4;
653  }
654  } else {
655  /* The module is not a TIMER module */
656  DPRINTK("The module is not a TIMER module\n");
657  i_ReturnValue = -3;
658  }
659  } else {
660  /* Module number error */
661  DPRINTK("Module number error\n");
662  i_ReturnValue = -2;
663  }
664 
665  } /* End of Switch */
666  return i_ReturnValue;
667 }
668 
669 /*
670 +----------------------------------------------------------------------------+
671 | Function Name :INT i_APCI1710_InsnBitsTimer(struct comedi_device *dev,
672 struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
673 +----------------------------------------------------------------------------+
674 | Task : Read write functions for Timer |
675 +----------------------------------------------------------------------------+
676 | Input Parameters :
677 +----------------------------------------------------------------------------+
678 | Output Parameters : - |
679 +----------------------------------------------------------------------------+
680 | Return Value :
681 +----------------------------------------------------------------------------+
682 */
683 
685  struct comedi_insn *insn, unsigned int *data)
686 {
687  unsigned char b_BitsType;
688  int i_ReturnValue = 0;
689  b_BitsType = data[0];
690 
691  printk("\n82X54");
692 
693  switch (b_BitsType) {
695  i_ReturnValue = i_APCI1710_ReadTimerValue(dev,
696  (unsigned char)CR_AREF(insn->chanspec),
697  (unsigned char)CR_CHAN(insn->chanspec),
698  (unsigned int *) &data[0]);
699  break;
700 
702  i_ReturnValue = i_APCI1710_GetTimerOutputLevel(dev,
703  (unsigned char)CR_AREF(insn->chanspec),
704  (unsigned char)CR_CHAN(insn->chanspec),
705  (unsigned char *) &data[0]);
706  break;
707 
709  i_ReturnValue = i_APCI1710_GetTimerProgressStatus(dev,
710  (unsigned char)CR_AREF(insn->chanspec),
711  (unsigned char)CR_CHAN(insn->chanspec),
712  (unsigned char *)&data[0]);
713  break;
714 
716  i_ReturnValue = i_APCI1710_WriteTimerValue(dev,
717  (unsigned char)CR_AREF(insn->chanspec),
718  (unsigned char)CR_CHAN(insn->chanspec),
719  (unsigned int)data[1]);
720 
721  break;
722 
723  default:
724  printk("Bits Config Parameter Wrong\n");
725  i_ReturnValue = -1;
726  }
727 
728  if (i_ReturnValue >= 0)
729  i_ReturnValue = insn->n;
730  return i_ReturnValue;
731 }
732 
733 /*
734 +----------------------------------------------------------------------------+
735 | Function Name : _INT_ i_APCI1710_ReadTimerValue |
736 | (unsigned char_ b_BoardHandle, |
737 | unsigned char_ b_ModulNbr, |
738 | unsigned char_ b_TimerNbr, |
739 | PULONG_ pul_TimerValue) |
740 +----------------------------------------------------------------------------+
741 | Task : Return the timer value from selected digital timer |
742 | (b_TimerNbr) from selected timer module (b_ModulNbr). |
743 +----------------------------------------------------------------------------+
744 | Input Parameters : unsigned char_ b_BoardHandle : Handle of board |
745 | APCI-1710 |
746 | unsigned char_ b_ModulNbr : Selected module number |
747 | (0 to 3) |
748 | unsigned char_ b_TimerNbr : Timer number to read |
749 | (0 to 2) |
750 +----------------------------------------------------------------------------+
751 | Output Parameters : PULONG_ pul_TimerValue : Timer value |
752 +----------------------------------------------------------------------------+
753 | Return Value : 0: No error |
754 | -1: The handle parameter of the board is wrong |
755 | -2: Module selection wrong |
756 | -3: Timer selection wrong |
757 | -4: The module is not a TIMER module |
758 | -5: Timer not initialised see function |
759 | "i_APCI1710_InitTimer" |
760 +----------------------------------------------------------------------------+
761 */
762 
764  unsigned char b_ModulNbr, unsigned char b_TimerNbr,
765  unsigned int *pul_TimerValue)
766 {
767  int i_ReturnValue = 0;
768 
769  /* Test the module number */
770  if (b_ModulNbr < 4) {
771  /* Test if 82X54 timer */
772  if ((devpriv->s_BoardInfos.
773  dw_MolduleConfiguration[b_ModulNbr] &
774  0xFFFF0000UL) == APCI1710_82X54_TIMER) {
775  /* Test the timer number */
776  if (b_TimerNbr <= 2) {
777  /* Test if timer initialised */
778  if (devpriv->
779  s_ModuleInfo[b_ModulNbr].
780  s_82X54ModuleInfo.
781  s_82X54TimerInfo[b_TimerNbr].
782  b_82X54Init == 1) {
783  /* Latch the timer value */
784  outl((2 << b_TimerNbr) | 0xD0,
785  devpriv->s_BoardInfos.
786  ui_Address + 12 +
787  (64 * b_ModulNbr));
788 
789  /* Read the counter value */
790  *pul_TimerValue =
791  inl(devpriv->s_BoardInfos.
792  ui_Address + (b_TimerNbr * 4) +
793  (64 * b_ModulNbr));
794  } else {
795  /* Timer not initialised see function */
796  DPRINTK("Timer not initialised see function\n");
797  i_ReturnValue = -5;
798  }
799  } else {
800  /* Timer selection wrong */
801  DPRINTK("Timer selection wrong\n");
802  i_ReturnValue = -3;
803  } /* if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2)) */
804  } else {
805  /* The module is not a TIMER module */
806  DPRINTK("The module is not a TIMER module\n");
807  i_ReturnValue = -4;
808  }
809  } else {
810  /* Module number error */
811  DPRINTK("Module number error\n");
812  i_ReturnValue = -2;
813  }
814 
815  return i_ReturnValue;
816 }
817 
818  /*
819  +----------------------------------------------------------------------------+
820  | Function Name : _INT_ i_APCI1710_GetTimerOutputLevel |
821  | (unsigned char_ b_BoardHandle, |
822  | unsigned char_ b_ModulNbr, |
823  | unsigned char_ b_TimerNbr, |
824  | unsigned char *_ pb_OutputLevel) |
825  +----------------------------------------------------------------------------+
826  | Task : Return the output signal level (pb_OutputLevel) from |
827  | selected digital timer (b_TimerNbr) from selected timer|
828  | module (b_ModulNbr). |
829  +----------------------------------------------------------------------------+
830  | Input Parameters : unsigned char_ b_BoardHandle : Handle of board |
831  | APCI-1710 |
832  | unsigned char_ b_ModulNbr : Selected module number |
833  | (0 to 3) |
834  | unsigned char_ b_TimerNbr : Timer number to test |
835  | (0 to 2) |
836  +----------------------------------------------------------------------------+
837  | Output Parameters : unsigned char *_ pb_OutputLevel : Output signal level |
838  | 0 : The output is low |
839  | 1 : The output is high |
840  +----------------------------------------------------------------------------+
841  | Return Value : 0: No error |
842  | -1: The handle parameter of the board is wrong |
843  | -2: Module selection wrong |
844  | -3: Timer selection wrong |
845  | -4: The module is not a TIMER module |
846  | -5: Timer not initialised see function |
847  | "i_APCI1710_InitTimer" |
848  +----------------------------------------------------------------------------+
849  */
850 
852  unsigned char b_ModulNbr, unsigned char b_TimerNbr,
853  unsigned char *pb_OutputLevel)
854 {
855  int i_ReturnValue = 0;
856  unsigned int dw_TimerStatus;
857 
858  /* Test the module number */
859  if (b_ModulNbr < 4) {
860  /* Test if 82X54 timer */
861  if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
862  /* Test the timer number */
863  if (b_TimerNbr <= 2) {
864  /* Test if timer initialised */
865  if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init == 1) {
866  /* Latch the timer value */
867  outl((2 << b_TimerNbr) | 0xE0, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr));
868 
869  /* Read the timer status */
870  dw_TimerStatus = inl(devpriv->s_BoardInfos.ui_Address + 16 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
871 
872  *pb_OutputLevel = (unsigned char) (((dw_TimerStatus >> 7) & 1) ^ devpriv-> s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_OutputLevel);
873  } else {
874  /* Timer not initialised see function */
875  DPRINTK("Timer not initialised see function\n");
876  i_ReturnValue = -5;
877  }
878  } else {
879  /* Timer selection wrong */
880  DPRINTK("Timer selection wrong\n");
881  i_ReturnValue = -3;
882  } /* if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2)) */
883  } else {
884  /* The module is not a TIMER module */
885  DPRINTK("The module is not a TIMER module\n");
886  i_ReturnValue = -4;
887  }
888  } else {
889  /* Module number error */
890  DPRINTK("Module number error\n");
891  i_ReturnValue = -2;
892  }
893 
894  return i_ReturnValue;
895 }
896 
897 /*
898 +----------------------------------------------------------------------------+
899 | Function Name : _INT_ i_APCI1710_GetTimerProgressStatus |
900 | (unsigned char_ b_BoardHandle, |
901 | unsigned char_ b_ModulNbr, |
902 | unsigned char_ b_TimerNbr, |
903 | unsigned char *_ pb_TimerStatus) |
904 +----------------------------------------------------------------------------+
905 | Task : Return the progress status (pb_TimerStatus) from |
906 | selected digital timer (b_TimerNbr) from selected timer|
907 | module (b_ModulNbr). |
908 +----------------------------------------------------------------------------+
909 | Input Parameters : unsigned char_ b_BoardHandle : Handle of board |
910 | APCI-1710 |
911 | unsigned char_ b_ModulNbr : Selected module number |
912 | (0 to 3) |
913 | unsigned char_ b_TimerNbr : Timer number to test |
914 | (0 to 2) |
915 +----------------------------------------------------------------------------+
916 | Output Parameters : unsigned char *_ pb_TimerStatus : Output signal level |
917 | 0 : Timer not in progress |
918 | 1 : Timer in progress |
919 +----------------------------------------------------------------------------+
920 | Return Value : 0: No error |
921 | -1: The handle parameter of the board is wrong |
922 | -2: Module selection wrong |
923 | -3: Timer selection wrong |
924 | -4: The module is not a TIMER module |
925 | -5: Timer not initialised see function |
926 | "i_APCI1710_InitTimer" |
927 +----------------------------------------------------------------------------+
928 */
929 
931  unsigned char b_ModulNbr, unsigned char b_TimerNbr,
932  unsigned char *pb_TimerStatus)
933 {
934  int i_ReturnValue = 0;
935  unsigned int dw_TimerStatus;
936 
937  /* Test the module number */
938  if (b_ModulNbr < 4) {
939  /* Test if 82X54 timer */
940 
941  if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
942  /* Test the timer number */
943  if (b_TimerNbr <= 2) {
944  /* Test if timer initialised */
945  if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init == 1) {
946  /* Latch the timer value */
947  outl((2 << b_TimerNbr) | 0xE0, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr));
948 
949  /* Read the timer status */
950  dw_TimerStatus = inl(devpriv->s_BoardInfos.ui_Address + 16 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
951 
952  *pb_TimerStatus = (unsigned char) ((dw_TimerStatus) >> 8) & 1;
953  printk("ProgressStatus : %d", *pb_TimerStatus);
954  } else {
955  /* Timer not initialised see function */
956  i_ReturnValue = -5;
957  }
958  } else {
959  /* Timer selection wrong */
960  i_ReturnValue = -3;
961  } /* if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2)) */
962  } else {
963  /* The module is not a TIMER module */
964 
965  i_ReturnValue = -4;
966  }
967  } else {
968  /* Module number error */
969 
970  i_ReturnValue = -2;
971  }
972 
973  return i_ReturnValue;
974 }
975 
976 /*
977 +----------------------------------------------------------------------------+
978 | Function Name : _INT_ i_APCI1710_WriteTimerValue |
979 | (unsigned char_ b_BoardHandle, |
980 | unsigned char_ b_ModulNbr, |
981 | unsigned char_ b_TimerNbr, |
982 | ULONG_ ul_WriteValue) |
983 +----------------------------------------------------------------------------+
984 | Task : Write the value (ul_WriteValue) into the selected timer|
985 | (b_TimerNbr) from selected timer module (b_ModulNbr). |
986 | The action in depend of the time mode selection. |
987 | See timer mode description table. |
988 +----------------------------------------------------------------------------+
989 | Input Parameters : unsigned char_ b_BoardHandle : Handle of board |
990 | APCI-1710 |
991 | unsigned char_ b_ModulNbr : Selected module number |
992 | (0 to 3) |
993 | unsigned char_ b_TimerNbr : Timer number to write |
994 | (0 to 2) |
995 | ULONG_ ul_WriteValue : Value to write |
996 +----------------------------------------------------------------------------+
997 | Output Parameters : - |
998 +----------------------------------------------------------------------------+
999 | Return Value : 0: No error |
1000 | -1: The handle parameter of the board is wrong |
1001 | -2: Module selection wrong |
1002 | -3: Timer selection wrong |
1003 | -4: The module is not a TIMER module |
1004 | -5: Timer not initialised see function |
1005 | "i_APCI1710_InitTimer" |
1006 +----------------------------------------------------------------------------+
1007 */
1008 
1010  unsigned char b_ModulNbr, unsigned char b_TimerNbr,
1011  unsigned int ul_WriteValue)
1012 {
1013  int i_ReturnValue = 0;
1014 
1015  /* Test the module number */
1016  if (b_ModulNbr < 4) {
1017  /* Test if 82X54 timer */
1018  if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
1019  /* Test the timer number */
1020  if (b_TimerNbr <= 2) {
1021  /* Test if timer initialised */
1022  if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init == 1) {
1023  /* Write the value */
1024  outl(ul_WriteValue, devpriv->s_BoardInfos.ui_Address + (b_TimerNbr * 4) + (64 * b_ModulNbr));
1025  } else {
1026  /* Timer not initialised see function */
1027  DPRINTK("Timer not initialised see function\n");
1028  i_ReturnValue = -5;
1029  }
1030  } else {
1031  /* Timer selection wrong */
1032  DPRINTK("Timer selection wrong\n");
1033  i_ReturnValue = -3;
1034  } /* if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2)) */
1035  } else {
1036  /* The module is not a TIMER module */
1037  DPRINTK("The module is not a TIMER module\n");
1038  i_ReturnValue = -4;
1039  }
1040  } else {
1041  /* Module number error */
1042  DPRINTK("Module number error\n");
1043  i_ReturnValue = -2;
1044  }
1045 
1046  return i_ReturnValue;
1047 }