Commit | Line | Data |
---|---|---|
c995fe94 | 1 | /* |
75c794f0 GKH |
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 | |
10 | * info@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 | */ | |
c995fe94 | 17 | /* |
75c794f0 | 18 | | Description : APCI-1710 82X54 timer module | |
c995fe94 ADG |
19 | */ |
20 | ||
21 | #include "APCI1710_82x54.h" | |
22 | ||
23 | /* | |
24 | +----------------------------------------------------------------------------+ | |
25 | | Function Name : _INT_ i_APCI1710_InitTimer | | |
26 | | (BYTE_ b_BoardHandle, | | |
27 | | BYTE_ b_ModulNbr, | | |
28 | | BYTE_ b_TimerNbr, | | |
29 | | BYTE_ b_TimerMode, | | |
30 | | ULONG_ ul_ReloadValue, | | |
31 | | BYTE_ b_InputClockSelection, | | |
32 | | BYTE_ b_InputClockLevel, | | |
33 | | BYTE_ b_OutputLevel, | | |
34 | | BYTE_ b_HardwareGateLevel) | |
34c43922 | 35 | INT i_InsnConfig_InitTimer(struct comedi_device *dev,struct comedi_subdevice *s, |
90035c08 | 36 | struct comedi_insn *insn,unsigned int *data) |
c995fe94 ADG |
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 : BYTE_ b_BoardHandle : Handle of board | | |
152 | | APCI-1710 | | |
153 | | BYTE_ b_ModulNbr : Module number to | | |
154 | | configure (0 to 3) | | |
155 | | BYTE_ b_TimerNbr : Timer number to | | |
156 | | configure (0 to 2) | | |
157 | | BYTE_ 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 | | BYTE_ b_InputClockSelection : Selection from input | | |
177 | | timer clock. | | |
178 | | See input clock | | |
179 | | selection table. | | |
180 | | BYTE_ b_InputClockLevel : Selection from input | | |
181 | | clock level. | | |
182 | | 0 : Low active | | |
183 | | (Input inverted) | | |
184 | | 1 : High active | | |
185 | | BYTE_ b_OutputLevel, : Selection from output | | |
186 | | clock level. | | |
187 | | 0 : Low active | | |
188 | | 1 : High active | | |
189 | | (Output inverted) | | |
190 | | BYTE_ 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 = (BYTE) CR_AREF(insn->chanspec); | |
199 | b_TimerNbr = (BYTE) CR_CHAN(insn->chanspec); | |
200 | b_TimerMode = (BYTE) data[0]; | |
201 | ul_ReloadValue = (ULONG) data[1]; | |
202 | b_InputClockSelection =(BYTE) data[2]; | |
203 | b_InputClockLevel =(BYTE) data[3]; | |
204 | b_OutputLevel =(BYTE) data[4]; | |
205 | b_HardwareGateLevel =(BYTE) 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 | ||
34c43922 | 222 | INT i_APCI1710_InsnConfigInitTimer(struct comedi_device * dev, struct comedi_subdevice * s, |
90035c08 | 223 | struct comedi_insn * insn, unsigned int * data) |
c995fe94 ADG |
224 | { |
225 | ||
226 | INT i_ReturnValue = 0; | |
227 | BYTE b_ModulNbr; | |
228 | BYTE b_TimerNbr; | |
229 | BYTE b_TimerMode; | |
230 | ULONG ul_ReloadValue; | |
231 | BYTE b_InputClockSelection; | |
232 | BYTE b_InputClockLevel; | |
233 | BYTE b_OutputLevel; | |
234 | BYTE b_HardwareGateLevel; | |
235 | ||
236 | //BEGIN JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz | |
237 | DWORD 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 = (BYTE) CR_AREF(insn->chanspec); | |
242 | b_TimerNbr = (BYTE) CR_CHAN(insn->chanspec); | |
243 | b_TimerMode = (BYTE) data[0]; | |
244 | ul_ReloadValue = (ULONG) data[1]; | |
245 | b_InputClockSelection = (BYTE) data[2]; | |
246 | b_InputClockLevel = (BYTE) data[3]; | |
247 | b_OutputLevel = (BYTE) data[4]; | |
248 | b_HardwareGateLevel = (BYTE) data[5]; | |
249 | ||
c995fe94 | 250 | /* Test the module number */ |
c995fe94 | 251 | if (b_ModulNbr < 4) { |
c995fe94 | 252 | /* Test if 82X54 timer */ |
75c794f0 | 253 | if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) { |
c995fe94 | 254 | /* Test the timer number */ |
c995fe94 ADG |
255 | |
256 | if (b_TimerNbr <= 2) { | |
c995fe94 | 257 | /* Test the timer mode */ |
c995fe94 ADG |
258 | if (b_TimerMode <= 5) { |
259 | //BEGIN JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz | |
c995fe94 | 260 | /* Test te imput clock selection */ |
c995fe94 ADG |
261 | /* |
262 | if (((b_TimerNbr == 0) && (b_InputClockSelection == 0)) || | |
263 | ((b_TimerNbr != 0) && ((b_InputClockSelection == 0) || (b_InputClockSelection == 1)))) | |
264 | */ | |
265 | ||
75c794f0 GKH |
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)))) { | |
c995fe94 | 274 | //BEGIN JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz |
75c794f0 GKH |
275 | if (((b_InputClockSelection == APCI1710_10MHZ) && |
276 | ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0x0000FFFFUL) >= 0x3131)) || | |
277 | (b_InputClockSelection != APCI1710_10MHZ)) { | |
c995fe94 | 278 | //END JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz |
c995fe94 | 279 | /* Test the input clock level selection */ |
c995fe94 | 280 | |
75c794f0 GKH |
281 | if ((b_InputClockLevel == 0) || |
282 | (b_InputClockLevel == 1)) { | |
283 | /* Test the output clock level selection */ | |
c995fe94 | 284 | if ((b_OutputLevel == 0) || (b_OutputLevel == 1)) { |
c995fe94 | 285 | /* Test the hardware gate level selection */ |
c995fe94 ADG |
286 | if ((b_HardwareGateLevel == 0) || (b_HardwareGateLevel == 1)) { |
287 | //BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz | |
c995fe94 | 288 | /* Test if version > 1.1 and clock selection = 10MHz */ |
c995fe94 | 289 | if ((b_InputClockSelection == APCI1710_10MHZ) && ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0x0000FFFFUL) > 0x3131)) { |
c995fe94 | 290 | /* Test if 40MHz quartz on board */ |
c995fe94 ADG |
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 | ||
c995fe94 | 298 | /* Test if detection OK */ |
c995fe94 ADG |
299 | if (dw_Test == 1) { |
300 | //END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz | |
c995fe94 | 301 | /* Initialisation OK */ |
75c794f0 GKH |
302 | devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init = 1; |
303 | ||
c995fe94 | 304 | /* Save the input clock selection */ |
75c794f0 GKH |
305 | devpriv-> s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_InputClockSelection = b_InputClockSelection; |
306 | ||
c995fe94 | 307 | /* Save the input clock level */ |
75c794f0 GKH |
308 | devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_InputClockLevel = ~b_InputClockLevel & 1; |
309 | ||
c995fe94 | 310 | /* Save the output level */ |
75c794f0 GKH |
311 | devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_OutputLevel = ~b_OutputLevel & 1; |
312 | ||
c995fe94 | 313 | /* Save the gate level */ |
75c794f0 GKH |
314 | devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_HardwareGateLevel = b_HardwareGateLevel; |
315 | ||
c995fe94 | 316 | /* Set the configuration word and disable the timer */ |
c995fe94 ADG |
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 = (DWORD) (((b_HardwareGateLevel << 0) & 0x1) | | |
323 | ((b_InputClockLevel << 1) & 0x2) | | |
324 | (((~b_OutputLevel & 1) << 2) & 0x4) | | |
325 | ((b_InputClockSelection << 4) & 0x10)); | |
326 | */ | |
c995fe94 | 327 | /* Test if 10MHz selected */ |
c995fe94 | 328 | if (b_InputClockSelection == APCI1710_10MHZ) { |
75c794f0 | 329 | b_InputClockSelection = 2; |
c995fe94 ADG |
330 | } |
331 | ||
75c794f0 | 332 | devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord = (DWORD)(((b_HardwareGateLevel << 0) & 0x1) | ((b_InputClockLevel << 1) & 0x2) | (((~b_OutputLevel & 1) << 2) & 0x4) | ((b_InputClockSelection << 4) & 0x30)); |
c995fe94 ADG |
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 | ||
c995fe94 | 336 | /* Initialise the 82X54 Timer */ |
c995fe94 ADG |
337 | outl((DWORD) b_TimerMode, devpriv->s_BoardInfos.ui_Address + 16 + (b_TimerNbr * 4) + (64 * b_ModulNbr)); |
338 | ||
c995fe94 | 339 | /* Write the reload value */ |
c995fe94 ADG |
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 { | |
c995fe94 | 344 | /* Input timer clock selection is wrong */ |
75c794f0 | 345 | i_ReturnValue = -6; |
c995fe94 ADG |
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 { | |
c995fe94 | 350 | /* Selection from hardware gate level is wrong */ |
c995fe94 | 351 | DPRINTK("Selection from hardware gate level is wrong\n"); |
75c794f0 | 352 | i_ReturnValue = -9; |
c995fe94 ADG |
353 | } // if ((b_HardwareGateLevel == 0) || (b_HardwareGateLevel == 1)) |
354 | } // if ((b_OutputLevel == 0) || (b_OutputLevel == 1)) | |
355 | else { | |
c995fe94 | 356 | /* Selection from output clock level is wrong */ |
c995fe94 | 357 | DPRINTK("Selection from output clock level is wrong\n"); |
75c794f0 | 358 | i_ReturnValue = -8; |
c995fe94 ADG |
359 | } // if ((b_OutputLevel == 0) || (b_OutputLevel == 1)) |
360 | } // if ((b_InputClockLevel == 0) || (b_InputClockLevel == 1)) | |
361 | else { | |
c995fe94 | 362 | /* Selection from input clock level is wrong */ |
c995fe94 | 363 | DPRINTK("Selection from input clock level is wrong\n"); |
75c794f0 | 364 | i_ReturnValue = -7; |
c995fe94 ADG |
365 | } // if ((b_InputClockLevel == 0) || (b_InputClockLevel == 1)) |
366 | } else { | |
c995fe94 | 367 | /* Input timer clock selection is wrong */ |
c995fe94 ADG |
368 | DPRINTK("Input timer clock selection is wrong\n"); |
369 | i_ReturnValue = -6; | |
370 | } | |
371 | } else { | |
c995fe94 | 372 | /* Input timer clock selection is wrong */ |
c995fe94 ADG |
373 | DPRINTK("Input timer clock selection is wrong\n"); |
374 | i_ReturnValue = -6; | |
375 | } | |
376 | } // if ((b_TimerMode >= 0) && (b_TimerMode <= 5)) | |
377 | else { | |
c995fe94 | 378 | /* Timer mode selection is wrong */ |
c995fe94 ADG |
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 { | |
c995fe94 | 384 | /* Timer selection wrong */ |
c995fe94 ADG |
385 | DPRINTK("Timer selection wrong\n"); |
386 | i_ReturnValue = -3; | |
387 | } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2)) | |
388 | } else { | |
c995fe94 | 389 | /* The module is not a TIMER module */ |
c995fe94 ADG |
390 | DPRINTK("The module is not a TIMER module\n"); |
391 | i_ReturnValue = -4; | |
392 | } | |
393 | } else { | |
c995fe94 | 394 | /* Module number error */ |
c995fe94 ADG |
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 | | (BYTE_ b_BoardHandle, | | |
406 | | BYTE_ b_ModulNbr, | | |
407 | | BYTE_ b_TimerNbr, | | |
408 | | BYTE_ b_InterruptEnable) | |
34c43922 | 409 | INT i_APCI1710_InsnWriteEnableDisableTimer(struct comedi_device *dev,struct comedi_subdevice *s, |
90035c08 | 410 | struct comedi_insn *insn,unsigned int *data) | |
c995fe94 ADG |
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 : BYTE_ b_BoardHandle : Handle of board | | |
420 | | APCI-1710 | | |
421 | | BYTE_ b_ModulNbr : Selected module number | | |
422 | | (0 to 3) | | |
423 | | BYTE_ b_TimerNbr : Timer number to enable | | |
424 | | (0 to 2) | | |
425 | | BYTE_ 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 = (BYTE) CR_AREF(insn->chanspec); | |
433 | b_TimerNbr = (BYTE) CR_CHAN(insn->chanspec); | |
434 | b_ActionType = (BYTE) 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 | ||
71b5f4f1 | 451 | INT i_APCI1710_InsnWriteEnableDisableTimer(struct comedi_device * dev, |
34c43922 | 452 | struct comedi_subdevice * s, |
90035c08 | 453 | struct comedi_insn * insn, unsigned int * data) |
c995fe94 ADG |
454 | { |
455 | INT i_ReturnValue = 0; | |
456 | DWORD dw_DummyRead; | |
457 | BYTE b_ModulNbr; | |
458 | BYTE b_TimerNbr; | |
459 | BYTE b_ActionType; | |
460 | BYTE b_InterruptEnable; | |
461 | ||
462 | i_ReturnValue = insn->n; | |
463 | b_ModulNbr = (BYTE) CR_AREF(insn->chanspec); | |
464 | b_TimerNbr = (BYTE) CR_CHAN(insn->chanspec); | |
465 | b_ActionType = (BYTE) data[0]; // enable disable | |
c995fe94 | 466 | |
75c794f0 | 467 | /* Test the module number */ |
c995fe94 | 468 | if (b_ModulNbr < 4) { |
c995fe94 | 469 | /* Test if 82X54 timer */ |
75c794f0 | 470 | if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) { |
c995fe94 | 471 | /* Test the timer number */ |
c995fe94 | 472 | if (b_TimerNbr <= 2) { |
c995fe94 | 473 | /* Test if timer initialised */ |
75c794f0 | 474 | if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init == 1) { |
c995fe94 ADG |
475 | |
476 | switch (b_ActionType) { | |
477 | case APCI1710_ENABLE: | |
75c794f0 | 478 | b_InterruptEnable = (BYTE) data[1]; |
c995fe94 | 479 | /* Test the interrupt selection */ |
75c794f0 GKH |
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 | ||
c995fe94 | 486 | /* Enable the interrupt */ |
75c794f0 GKH |
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)); | |
c995fe94 ADG |
490 | devpriv->tsk_Current = current; // Save the current process task structure |
491 | ||
492 | } // if (b_InterruptEnable == APCI1710_ENABLE) | |
493 | else { | |
c995fe94 | 494 | /* Disable the interrupt */ |
75c794f0 GKH |
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 | ||
c995fe94 | 499 | /* Save the interrupt flag */ |
75c794f0 | 500 | devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask & (0xFF - (1 << b_TimerNbr)); |
c995fe94 ADG |
501 | } // if (b_InterruptEnable == APCI1710_ENABLE) |
502 | ||
c995fe94 | 503 | /* Test if error occur */ |
c995fe94 | 504 | if (i_ReturnValue >= 0) { |
c995fe94 | 505 | /* Save the interrupt flag */ |
75c794f0 | 506 | devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask | ((1 & b_InterruptEnable) << b_TimerNbr); |
c995fe94 | 507 | |
75c794f0 | 508 | /* Enable the timer */ |
c995fe94 ADG |
509 | outl(1, devpriv->s_BoardInfos.ui_Address + 44 + (b_TimerNbr * 4) + (64 * b_ModulNbr)); |
510 | } | |
511 | } else { | |
c995fe94 | 512 | /* Interrupt parameter is wrong */ |
c995fe94 ADG |
513 | DPRINTK("\n"); |
514 | i_ReturnValue = -6; | |
515 | } | |
516 | break; | |
517 | case APCI1710_DISABLE: | |
c995fe94 | 518 | /* Test the interrupt flag */ |
75c794f0 | 519 | if (((devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask >> b_TimerNbr) & 1) == 1) { |
c995fe94 | 520 | /* Disable the interrupt */ |
75c794f0 GKH |
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 | ||
c995fe94 | 526 | /* Save the interrupt flag */ |
75c794f0 | 527 | devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask & (0xFF - (1 << b_TimerNbr)); |
c995fe94 ADG |
528 | } |
529 | ||
c995fe94 | 530 | /* Disable the timer */ |
75c794f0 | 531 | outl(0, devpriv->s_BoardInfos.ui_Address + 44 + (b_TimerNbr * 4) + (64 * b_ModulNbr)); |
c995fe94 ADG |
532 | break; |
533 | } // Switch end | |
534 | } else { | |
c995fe94 | 535 | /* Timer not initialised see function */ |
75c794f0 | 536 | DPRINTK ("Timer not initialised see function\n"); |
c995fe94 ADG |
537 | i_ReturnValue = -5; |
538 | } | |
539 | } else { | |
c995fe94 | 540 | /* Timer selection wrong */ |
c995fe94 ADG |
541 | DPRINTK("Timer selection wrong\n"); |
542 | i_ReturnValue = -3; | |
543 | } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2)) | |
544 | } else { | |
c995fe94 | 545 | /* The module is not a TIMER module */ |
c995fe94 ADG |
546 | DPRINTK("The module is not a TIMER module\n"); |
547 | i_ReturnValue = -4; | |
548 | } | |
549 | } else { | |
c995fe94 | 550 | /* Module number error */ |
c995fe94 ADG |
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 | | (BYTE_ b_BoardHandle, | | |
562 | | BYTE_ b_ModulNbr, | | |
563 | | PULONG_ pul_TimerValueArray) | |
34c43922 | 564 | INT i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev,struct comedi_subdevice *s, |
90035c08 | 565 | struct comedi_insn *insn,unsigned int *data) | |
c995fe94 ADG |
566 | +----------------------------------------------------------------------------+ |
567 | | Task : Return the all timer values from selected timer | | |
568 | | module (b_ModulNbr). | | |
569 | +----------------------------------------------------------------------------+ | |
570 | | Input Parameters : BYTE_ b_BoardHandle : Handle of board | | |
571 | | APCI-1710 | | |
572 | | BYTE_ 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 | ||
34c43922 | 593 | INT i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev, struct comedi_subdevice *s, |
90035c08 | 594 | struct comedi_insn *insn, unsigned int *data) |
c995fe94 ADG |
595 | { |
596 | INT i_ReturnValue = 0; | |
597 | BYTE b_ModulNbr, b_ReadType; | |
598 | PULONG pul_TimerValueArray; | |
599 | ||
600 | b_ModulNbr = CR_AREF(insn->chanspec); | |
601 | b_ReadType = CR_CHAN(insn->chanspec); | |
602 | pul_TimerValueArray = (PULONG) data; | |
603 | i_ReturnValue = insn->n; | |
604 | ||
605 | switch (b_ReadType) { | |
606 | case APCI1710_TIMER_READINTERRUPT: | |
607 | ||
75c794f0 GKH |
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; | |
c995fe94 | 611 | |
75c794f0 GKH |
612 | /* Increment the read FIFO */ |
613 | devpriv->s_InterruptParameters.ui_Read = (devpriv->s_InterruptParameters.ui_Read + 1) % APCI1710_SAVE_INTERRUPT; | |
c995fe94 ADG |
614 | |
615 | break; | |
616 | ||
617 | case APCI1710_TIMER_READALLTIMER: | |
c995fe94 | 618 | /* Test the module number */ |
c995fe94 | 619 | if (b_ModulNbr < 4) { |
c995fe94 | 620 | /* Test if 82X54 timer */ |
75c794f0 | 621 | if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) { |
c995fe94 | 622 | /* Test if timer 0 iniutialised */ |
75c794f0 | 623 | if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[0].b_82X54Init == 1) { |
c995fe94 | 624 | /* Test if timer 1 iniutialised */ |
75c794f0 | 625 | if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[1].b_82X54Init == 1) { |
c995fe94 | 626 | /* Test if timer 2 iniutialised */ |
75c794f0 | 627 | if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[2].b_82X54Init == 1) { |
c995fe94 | 628 | /* Latch all counter */ |
75c794f0 | 629 | outl(0x17, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr)); |
c995fe94 | 630 | |
c995fe94 | 631 | /* Read the timer 0 value */ |
75c794f0 | 632 | pul_TimerValueArray[0] = inl(devpriv->s_BoardInfos.ui_Address + 0 + (64 * b_ModulNbr)); |
c995fe94 | 633 | |
c995fe94 | 634 | /* Read the timer 1 value */ |
75c794f0 | 635 | pul_TimerValueArray[1] = inl(devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr)); |
c995fe94 | 636 | |
c995fe94 | 637 | /* Read the timer 2 value */ |
75c794f0 | 638 | pul_TimerValueArray[2] = inl(devpriv->s_BoardInfos.ui_Address + 8 + (64 * b_ModulNbr)); |
c995fe94 | 639 | } else { |
c995fe94 | 640 | /* Timer 2 not initialised see function */ |
c995fe94 ADG |
641 | DPRINTK("Timer 2 not initialised see function\n"); |
642 | i_ReturnValue = -6; | |
643 | } | |
644 | } else { | |
c995fe94 | 645 | /* Timer 1 not initialised see function */ |
c995fe94 ADG |
646 | DPRINTK("Timer 1 not initialised see function\n"); |
647 | i_ReturnValue = -5; | |
648 | } | |
649 | } else { | |
c995fe94 | 650 | /* Timer 0 not initialised see function */ |
c995fe94 ADG |
651 | DPRINTK("Timer 0 not initialised see function\n"); |
652 | i_ReturnValue = -4; | |
653 | } | |
654 | } else { | |
c995fe94 | 655 | /* The module is not a TIMER module */ |
c995fe94 ADG |
656 | DPRINTK("The module is not a TIMER module\n"); |
657 | i_ReturnValue = -3; | |
658 | } | |
659 | } else { | |
c995fe94 | 660 | /* Module number error */ |
c995fe94 ADG |
661 | DPRINTK("Module number error\n"); |
662 | i_ReturnValue = -2; | |
663 | } | |
664 | ||
665 | } // End of Switch | |
666 | return (i_ReturnValue); | |
667 | } | |
668 | ||
669 | /* | |
670 | +----------------------------------------------------------------------------+ | |
71b5f4f1 | 671 | | Function Name :INT i_APCI1710_InsnBitsTimer(struct comedi_device *dev, |
90035c08 | 672 | struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) | |
c995fe94 ADG |
673 | +----------------------------------------------------------------------------+ |
674 | | Task : Read write functions for Timer | | |
675 | +----------------------------------------------------------------------------+ | |
676 | | Input Parameters : | |
677 | +----------------------------------------------------------------------------+ | |
678 | | Output Parameters : - | | |
679 | +----------------------------------------------------------------------------+ | |
680 | | Return Value : | |
681 | +----------------------------------------------------------------------------+ | |
682 | */ | |
683 | ||
34c43922 | 684 | INT i_APCI1710_InsnBitsTimer(struct comedi_device * dev, struct comedi_subdevice * s, |
90035c08 | 685 | struct comedi_insn * insn, unsigned int * data) |
c995fe94 ADG |
686 | { |
687 | BYTE b_BitsType; | |
688 | INT i_ReturnValue = 0; | |
689 | b_BitsType = data[0]; | |
690 | ||
691 | printk("\n82X54"); | |
692 | ||
693 | switch (b_BitsType) { | |
694 | case APCI1710_TIMER_READVALUE: | |
695 | i_ReturnValue = i_APCI1710_ReadTimerValue(dev, | |
75c794f0 GKH |
696 | (BYTE)CR_AREF(insn->chanspec), |
697 | (BYTE)CR_CHAN(insn->chanspec), | |
698 | (PULONG) & data[0]); | |
c995fe94 ADG |
699 | break; |
700 | ||
701 | case APCI1710_TIMER_GETOUTPUTLEVEL: | |
702 | i_ReturnValue = i_APCI1710_GetTimerOutputLevel(dev, | |
75c794f0 GKH |
703 | (BYTE)CR_AREF(insn->chanspec), |
704 | (BYTE)CR_CHAN(insn->chanspec), | |
705 | (PBYTE) &data[0]); | |
c995fe94 ADG |
706 | break; |
707 | ||
708 | case APCI1710_TIMER_GETPROGRESSSTATUS: | |
709 | i_ReturnValue = i_APCI1710_GetTimerProgressStatus(dev, | |
75c794f0 GKH |
710 | (BYTE)CR_AREF(insn->chanspec), |
711 | (BYTE)CR_CHAN(insn->chanspec), | |
712 | (PBYTE)&data[0]); | |
c995fe94 ADG |
713 | break; |
714 | ||
715 | case APCI1710_TIMER_WRITEVALUE: | |
716 | i_ReturnValue = i_APCI1710_WriteTimerValue(dev, | |
75c794f0 GKH |
717 | (BYTE)CR_AREF(insn->chanspec), |
718 | (BYTE)CR_CHAN(insn->chanspec), | |
719 | (ULONG)data[1]); | |
c995fe94 ADG |
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 | | (BYTE_ b_BoardHandle, | | |
737 | | BYTE_ b_ModulNbr, | | |
738 | | BYTE_ 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 : BYTE_ b_BoardHandle : Handle of board | | |
745 | | APCI-1710 | | |
746 | | BYTE_ b_ModulNbr : Selected module number | | |
747 | | (0 to 3) | | |
748 | | BYTE_ 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 | ||
71b5f4f1 | 763 | INT i_APCI1710_ReadTimerValue(struct comedi_device * dev, |
75c794f0 GKH |
764 | BYTE b_ModulNbr, BYTE b_TimerNbr, |
765 | PULONG pul_TimerValue) | |
c995fe94 ADG |
766 | { |
767 | INT i_ReturnValue = 0; | |
768 | ||
c995fe94 | 769 | /* Test the module number */ |
c995fe94 | 770 | if (b_ModulNbr < 4) { |
c995fe94 | 771 | /* Test if 82X54 timer */ |
c995fe94 | 772 | if ((devpriv->s_BoardInfos. |
75c794f0 GKH |
773 | dw_MolduleConfiguration[b_ModulNbr] & |
774 | 0xFFFF0000UL) == APCI1710_82X54_TIMER) { | |
c995fe94 | 775 | /* Test the timer number */ |
c995fe94 | 776 | if (b_TimerNbr <= 2) { |
c995fe94 | 777 | /* Test if timer initialised */ |
c995fe94 | 778 | if (devpriv-> |
75c794f0 GKH |
779 | s_ModuleInfo[b_ModulNbr]. |
780 | s_82X54ModuleInfo. | |
781 | s_82X54TimerInfo[b_TimerNbr]. | |
782 | b_82X54Init == 1) { | |
c995fe94 | 783 | /* Latch the timer value */ |
c995fe94 | 784 | outl((2 << b_TimerNbr) | 0xD0, |
75c794f0 GKH |
785 | devpriv->s_BoardInfos. |
786 | ui_Address + 12 + | |
787 | (64 * b_ModulNbr)); | |
c995fe94 | 788 | |
c995fe94 | 789 | /* Read the counter value */ |
c995fe94 | 790 | *pul_TimerValue = |
75c794f0 | 791 | inl(devpriv->s_BoardInfos. |
c995fe94 ADG |
792 | ui_Address + (b_TimerNbr * 4) + |
793 | (64 * b_ModulNbr)); | |
794 | } else { | |
c995fe94 | 795 | /* Timer not initialised see function */ |
c995fe94 ADG |
796 | DPRINTK("Timer not initialised see function\n"); |
797 | i_ReturnValue = -5; | |
798 | } | |
799 | } else { | |
c995fe94 | 800 | /* Timer selection wrong */ |
c995fe94 ADG |
801 | DPRINTK("Timer selection wrong\n"); |
802 | i_ReturnValue = -3; | |
803 | } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2)) | |
804 | } else { | |
c995fe94 | 805 | /* The module is not a TIMER module */ |
c995fe94 ADG |
806 | DPRINTK("The module is not a TIMER module\n"); |
807 | i_ReturnValue = -4; | |
808 | } | |
809 | } else { | |
c995fe94 | 810 | /* Module number error */ |
c995fe94 ADG |
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 | | (BYTE_ b_BoardHandle, | | |
822 | | BYTE_ b_ModulNbr, | | |
823 | | BYTE_ b_TimerNbr, | | |
824 | | PBYTE_ 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 : BYTE_ b_BoardHandle : Handle of board | | |
831 | | APCI-1710 | | |
832 | | BYTE_ b_ModulNbr : Selected module number | | |
833 | | (0 to 3) | | |
834 | | BYTE_ b_TimerNbr : Timer number to test | | |
835 | | (0 to 2) | | |
836 | +----------------------------------------------------------------------------+ | |
837 | | Output Parameters : PBYTE_ 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 | ||
71b5f4f1 | 851 | INT i_APCI1710_GetTimerOutputLevel(struct comedi_device * dev, |
75c794f0 GKH |
852 | BYTE b_ModulNbr, BYTE b_TimerNbr, |
853 | PBYTE pb_OutputLevel) | |
c995fe94 ADG |
854 | { |
855 | INT i_ReturnValue = 0; | |
856 | DWORD dw_TimerStatus; | |
857 | ||
c995fe94 | 858 | /* Test the module number */ |
c995fe94 | 859 | if (b_ModulNbr < 4) { |
c995fe94 | 860 | /* Test if 82X54 timer */ |
75c794f0 | 861 | if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) { |
c995fe94 | 862 | /* Test the timer number */ |
c995fe94 | 863 | if (b_TimerNbr <= 2) { |
c995fe94 | 864 | /* Test if timer initialised */ |
75c794f0 | 865 | if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init == 1) { |
c995fe94 | 866 | /* Latch the timer value */ |
75c794f0 | 867 | outl((2 << b_TimerNbr) | 0xE0, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr)); |
c995fe94 | 868 | |
c995fe94 | 869 | /* Read the timer status */ |
75c794f0 | 870 | dw_TimerStatus = inl(devpriv->s_BoardInfos.ui_Address + 16 + (b_TimerNbr * 4) + (64 * b_ModulNbr)); |
c995fe94 | 871 | |
75c794f0 | 872 | *pb_OutputLevel = (BYTE) (((dw_TimerStatus >> 7) & 1) ^ devpriv-> s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_OutputLevel); |
c995fe94 | 873 | } else { |
c995fe94 | 874 | /* Timer not initialised see function */ |
c995fe94 ADG |
875 | DPRINTK("Timer not initialised see function\n"); |
876 | i_ReturnValue = -5; | |
877 | } | |
878 | } else { | |
c995fe94 | 879 | /* Timer selection wrong */ |
c995fe94 ADG |
880 | DPRINTK("Timer selection wrong\n"); |
881 | i_ReturnValue = -3; | |
882 | } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2)) | |
883 | } else { | |
c995fe94 | 884 | /* The module is not a TIMER module */ |
c995fe94 ADG |
885 | DPRINTK("The module is not a TIMER module\n"); |
886 | i_ReturnValue = -4; | |
887 | } | |
888 | } else { | |
c995fe94 | 889 | /* Module number error */ |
c995fe94 ADG |
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 | | (BYTE_ b_BoardHandle, | | |
901 | | BYTE_ b_ModulNbr, | | |
902 | | BYTE_ b_TimerNbr, | | |
903 | | PBYTE_ 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 : BYTE_ b_BoardHandle : Handle of board | | |
910 | | APCI-1710 | | |
911 | | BYTE_ b_ModulNbr : Selected module number | | |
912 | | (0 to 3) | | |
913 | | BYTE_ b_TimerNbr : Timer number to test | | |
914 | | (0 to 2) | | |
915 | +----------------------------------------------------------------------------+ | |
916 | | Output Parameters : PBYTE_ 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 | ||
71b5f4f1 | 930 | INT i_APCI1710_GetTimerProgressStatus(struct comedi_device *dev, |
75c794f0 GKH |
931 | BYTE b_ModulNbr, BYTE b_TimerNbr, |
932 | PBYTE pb_TimerStatus) | |
c995fe94 ADG |
933 | { |
934 | INT i_ReturnValue = 0; | |
935 | DWORD dw_TimerStatus; | |
936 | ||
c995fe94 | 937 | /* Test the module number */ |
c995fe94 | 938 | if (b_ModulNbr < 4) { |
c995fe94 | 939 | /* Test if 82X54 timer */ |
c995fe94 | 940 | |
75c794f0 | 941 | if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) { |
c995fe94 | 942 | /* Test the timer number */ |
c995fe94 | 943 | if (b_TimerNbr <= 2) { |
c995fe94 | 944 | /* Test if timer initialised */ |
75c794f0 | 945 | if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init == 1) { |
c995fe94 | 946 | /* Latch the timer value */ |
75c794f0 | 947 | outl((2 << b_TimerNbr) | 0xE0, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr)); |
c995fe94 | 948 | |
c995fe94 | 949 | /* Read the timer status */ |
75c794f0 | 950 | dw_TimerStatus = inl(devpriv->s_BoardInfos.ui_Address + 16 + (b_TimerNbr * 4) + (64 * b_ModulNbr)); |
c995fe94 | 951 | |
75c794f0 GKH |
952 | *pb_TimerStatus = (BYTE) ((dw_TimerStatus) >> 8) & 1; |
953 | printk("ProgressStatus : %d", *pb_TimerStatus); | |
c995fe94 | 954 | } else { |
c995fe94 | 955 | /* Timer not initialised see function */ |
c995fe94 ADG |
956 | i_ReturnValue = -5; |
957 | } | |
958 | } else { | |
c995fe94 | 959 | /* Timer selection wrong */ |
c995fe94 ADG |
960 | i_ReturnValue = -3; |
961 | } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2)) | |
962 | } else { | |
c995fe94 | 963 | /* The module is not a TIMER module */ |
c995fe94 ADG |
964 | |
965 | i_ReturnValue = -4; | |
966 | } | |
967 | } else { | |
c995fe94 | 968 | /* Module number error */ |
c995fe94 ADG |
969 | |
970 | i_ReturnValue = -2; | |
971 | } | |
972 | ||
75c794f0 | 973 | return i_ReturnValue; |
c995fe94 ADG |
974 | } |
975 | ||
976 | /* | |
977 | +----------------------------------------------------------------------------+ | |
978 | | Function Name : _INT_ i_APCI1710_WriteTimerValue | | |
979 | | (BYTE_ b_BoardHandle, | | |
980 | | BYTE_ b_ModulNbr, | | |
981 | | BYTE_ 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 : BYTE_ b_BoardHandle : Handle of board | | |
990 | | APCI-1710 | | |
991 | | BYTE_ b_ModulNbr : Selected module number | | |
992 | | (0 to 3) | | |
993 | | BYTE_ 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 | ||
71b5f4f1 | 1009 | INT i_APCI1710_WriteTimerValue(struct comedi_device * dev, |
75c794f0 GKH |
1010 | BYTE b_ModulNbr, BYTE b_TimerNbr, |
1011 | ULONG ul_WriteValue) | |
c995fe94 ADG |
1012 | { |
1013 | INT i_ReturnValue = 0; | |
1014 | ||
c995fe94 | 1015 | /* Test the module number */ |
c995fe94 | 1016 | if (b_ModulNbr < 4) { |
c995fe94 | 1017 | /* Test if 82X54 timer */ |
75c794f0 | 1018 | if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) { |
c995fe94 | 1019 | /* Test the timer number */ |
c995fe94 | 1020 | if (b_TimerNbr <= 2) { |
c995fe94 | 1021 | /* Test if timer initialised */ |
75c794f0 | 1022 | if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init == 1) { |
c995fe94 | 1023 | /* Write the value */ |
75c794f0 | 1024 | outl(ul_WriteValue, devpriv->s_BoardInfos.ui_Address + (b_TimerNbr * 4) + (64 * b_ModulNbr)); |
c995fe94 | 1025 | } else { |
c995fe94 | 1026 | /* Timer not initialised see function */ |
c995fe94 ADG |
1027 | DPRINTK("Timer not initialised see function\n"); |
1028 | i_ReturnValue = -5; | |
1029 | } | |
1030 | } else { | |
c995fe94 | 1031 | /* Timer selection wrong */ |
c995fe94 ADG |
1032 | DPRINTK("Timer selection wrong\n"); |
1033 | i_ReturnValue = -3; | |
1034 | } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2)) | |
1035 | } else { | |
c995fe94 | 1036 | /* The module is not a TIMER module */ |
c995fe94 ADG |
1037 | DPRINTK("The module is not a TIMER module\n"); |
1038 | i_ReturnValue = -4; | |
1039 | } | |
1040 | } else { | |
c995fe94 | 1041 | /* Module number error */ |
c995fe94 ADG |
1042 | DPRINTK("Module number error\n"); |
1043 | i_ReturnValue = -2; | |
1044 | } | |
1045 | ||
75c794f0 | 1046 | return i_ReturnValue; |
c995fe94 | 1047 | } |