Commit | Line | Data |
---|---|---|
c995fe94 ADG |
1 | /** |
2 | @verbatim | |
3 | ||
4 | Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. | |
5 | ||
6 | ADDI-DATA GmbH | |
7 | Dieselstrasse 3 | |
8 | D-77833 Ottersweier | |
9 | Tel: +19(0)7223/9493-0 | |
10 | Fax: +49(0)7223/9493-92 | |
11 | http://www.addi-data-com | |
12 | info@addi-data.com | |
13 | ||
14 | This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. | |
15 | ||
16 | This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 | ||
20 | You shoud also find the complete GPL in the COPYING file accompanying this source code. | |
21 | ||
22 | @endverbatim | |
23 | */ | |
24 | /* | |
25 | ||
26 | +-----------------------------------------------------------------------+ | |
27 | | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier | | |
28 | +-----------------------------------------------------------------------+ | |
29 | | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com | | |
30 | | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com | | |
31 | +-----------------------------------------------------------------------+ | |
32 | | Project : API APCI1710 | Compiler : gcc | | |
33 | | Module name : Inp_CPT.C | Version : 2.96 | | |
34 | +-------------------------------+---------------------------------------+ | |
35 | | Project manager: Eric Stolz | Date : 02/12/2002 | | |
36 | +-----------------------------------------------------------------------+ | |
37 | | Description : APCI-1710 pulse encoder module | | |
38 | | | | |
39 | | | | |
40 | +-----------------------------------------------------------------------+ | |
41 | | UPDATES | | |
42 | +-----------------------------------------------------------------------+ | |
43 | | Date | Author | Description of updates | | |
44 | +----------+-----------+------------------------------------------------+ | |
45 | | | | | | |
46 | |----------|-----------|------------------------------------------------| | |
47 | | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 | | |
48 | | | | available | | |
49 | +-----------------------------------------------------------------------+ | |
50 | */ | |
51 | ||
52 | /* | |
53 | +----------------------------------------------------------------------------+ | |
54 | | Included files | | |
55 | +----------------------------------------------------------------------------+ | |
56 | */ | |
57 | ||
58 | #include "APCI1710_Inp_cpt.h" | |
59 | ||
60 | /* | |
61 | +----------------------------------------------------------------------------+ | |
62 | | Function Name : _INT_ i_APCI1710_InitPulseEncoder | | |
63 | | (BYTE_ b_BoardHandle, | | |
64 | | BYTE_ b_ModulNbr, | | |
65 | | BYTE_ b_PulseEncoderNbr, | | |
66 | | BYTE_ b_InputLevelSelection, | | |
67 | | BYTE_ b_TriggerOutputAction, | | |
68 | | ULONG_ ul_StartValue) | | |
69 | +----------------------------------------------------------------------------+ | |
70 | | Task : Configure the pulse encoder operating mode selected via| | |
71 | | b_ModulNbr and b_PulseEncoderNbr. The pulse encoder | | |
72 | | after each pulse decrement the counter value from 1. | | |
73 | | | | |
74 | | You must calling this function be for you call any | | |
75 | | other function witch access of pulse encoders. | | |
76 | +----------------------------------------------------------------------------+ | |
77 | | Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710| | |
78 | | BYTE_ b_ModulNbr : Module number to | | |
79 | | configure (0 to 3) | | |
80 | | BYTE_ b_PulseEncoderNbr : Pulse encoder selection | | |
81 | | (0 to 3) | | |
82 | | BYTE_ b_InputLevelSelection : Input level selection | | |
83 | | (0 or 1) | | |
84 | | 0 : Set pulse encoder| | |
85 | | count the the low| | |
86 | | level pulse. | | |
87 | | 1 : Set pulse encoder| | |
88 | | count the the | | |
89 | | high level pulse.| | |
90 | | BYTE_ b_TriggerOutputAction : Digital TRIGGER output | | |
91 | | action | | |
92 | | 0 : No action | | |
93 | | 1 : Set the trigger | | |
94 | | output to "1" | | |
95 | | (high) after the | | |
96 | | passage from 1 to| | |
97 | | 0 from pulse | | |
98 | | encoder. | | |
99 | | 2 : Set the trigger | | |
100 | | output to "0" | | |
101 | | (low) after the | | |
102 | | passage from 1 to| | |
103 | | 0 from pulse | | |
104 | | encoder | | |
105 | | ULONG_ ul_StartValue : Pulse encoder start value| | |
106 | | (1 to 4294967295) | |
107 | b_ModulNbr =(BYTE) CR_AREF(insn->chanspec); | |
108 | b_PulseEncoderNbr =(BYTE) data[0]; | |
109 | b_InputLevelSelection =(BYTE) data[1]; | |
110 | b_TriggerOutputAction =(BYTE) data[2]; | |
111 | ul_StartValue =(ULONG) data[3]; | |
112 | | | |
113 | +----------------------------------------------------------------------------+ | |
114 | | Output Parameters : - | | |
115 | +----------------------------------------------------------------------------+ | |
116 | | Return Value : 0: No error | | |
117 | | -1: The handle parameter of the board is wrong | | |
118 | | -2: The module is not a pulse encoder module | | |
119 | | -3: Pulse encoder selection is wrong | | |
120 | | -4: Input level selection is wrong | | |
121 | | -5: Digital TRIGGER output action selection is wrong | | |
122 | | -6: Pulse encoder start value is wrong | | |
123 | +----------------------------------------------------------------------------+ | |
124 | */ | |
125 | ||
126 | INT i_APCI1710_InsnConfigInitPulseEncoder(comedi_device * dev, | |
790c5541 | 127 | comedi_subdevice * s, comedi_insn * insn, unsigned int * data) |
c995fe94 ADG |
128 | { |
129 | INT i_ReturnValue = 0; | |
130 | DWORD dw_IntRegister; | |
131 | ||
132 | BYTE b_ModulNbr; | |
133 | BYTE b_PulseEncoderNbr; | |
134 | BYTE b_InputLevelSelection; | |
135 | BYTE b_TriggerOutputAction; | |
136 | ULONG ul_StartValue; | |
137 | ||
138 | b_ModulNbr = (BYTE) CR_AREF(insn->chanspec); | |
139 | b_PulseEncoderNbr = (BYTE) data[0]; | |
140 | b_InputLevelSelection = (BYTE) data[1]; | |
141 | b_TriggerOutputAction = (BYTE) data[2]; | |
142 | ul_StartValue = (ULONG) data[3]; | |
143 | ||
144 | i_ReturnValue = insn->n; | |
145 | ||
146 | /***********************************/ | |
147 | /* Test the selected module number */ | |
148 | /***********************************/ | |
149 | ||
150 | if (b_ModulNbr <= 3) { | |
151 | /*************************/ | |
152 | /* Test if pulse encoder */ | |
153 | /*************************/ | |
154 | ||
155 | if ((devpriv->s_BoardInfos. | |
156 | dw_MolduleConfiguration[b_ModulNbr] & | |
157 | APCI1710_PULSE_ENCODER) == | |
158 | APCI1710_PULSE_ENCODER) { | |
159 | /******************************************/ | |
160 | /* Test the selected pulse encoder number */ | |
161 | /******************************************/ | |
162 | ||
163 | if (b_PulseEncoderNbr <= 3) { | |
164 | /************************/ | |
165 | /* Test the input level */ | |
166 | /************************/ | |
167 | ||
168 | if ((b_InputLevelSelection == 0) | |
169 | || (b_InputLevelSelection == 1)) { | |
170 | /*******************************************/ | |
171 | /* Test the ouput TRIGGER action selection */ | |
172 | /*******************************************/ | |
173 | ||
174 | if ((b_TriggerOutputAction <= 2) | |
175 | || (b_PulseEncoderNbr > 0)) { | |
176 | if (ul_StartValue > 1) { | |
177 | ||
178 | dw_IntRegister = | |
179 | inl(devpriv-> | |
180 | s_BoardInfos. | |
181 | ui_Address + | |
182 | 20 + | |
183 | (64 * b_ModulNbr)); | |
184 | ||
185 | /***********************/ | |
186 | /* Set the start value */ | |
187 | /***********************/ | |
188 | ||
189 | outl(ul_StartValue, | |
190 | devpriv-> | |
191 | s_BoardInfos. | |
192 | ui_Address + | |
193 | (b_PulseEncoderNbr | |
194 | * 4) + | |
195 | (64 * b_ModulNbr)); | |
196 | ||
197 | /***********************/ | |
198 | /* Set the input level */ | |
199 | /***********************/ | |
200 | devpriv-> | |
201 | s_ModuleInfo | |
202 | [b_ModulNbr]. | |
203 | s_PulseEncoderModuleInfo. | |
204 | dw_SetRegister = | |
205 | (devpriv-> | |
206 | s_ModuleInfo | |
207 | [b_ModulNbr]. | |
208 | s_PulseEncoderModuleInfo. | |
209 | dw_SetRegister & | |
210 | (0xFFFFFFFFUL - | |
211 | (1UL << (8 + b_PulseEncoderNbr)))) | ((1UL & (~b_InputLevelSelection)) << (8 + b_PulseEncoderNbr)); | |
212 | ||
213 | /*******************************/ | |
214 | /* Test if output trigger used */ | |
215 | /*******************************/ | |
216 | ||
217 | if ((b_TriggerOutputAction > 0) && (b_PulseEncoderNbr > 1)) { | |
218 | /****************************/ | |
219 | /* Enable the output action */ | |
220 | /****************************/ | |
221 | ||
222 | devpriv-> | |
223 | s_ModuleInfo | |
224 | [b_ModulNbr]. | |
225 | s_PulseEncoderModuleInfo. | |
226 | dw_SetRegister | |
227 | = | |
228 | devpriv-> | |
229 | s_ModuleInfo | |
230 | [b_ModulNbr]. | |
231 | s_PulseEncoderModuleInfo. | |
232 | dw_SetRegister | |
233 | | (1UL | |
234 | << (4 + b_PulseEncoderNbr)); | |
235 | ||
236 | /*********************************/ | |
237 | /* Set the output TRIGGER action */ | |
238 | /*********************************/ | |
239 | ||
240 | devpriv-> | |
241 | s_ModuleInfo | |
242 | [b_ModulNbr]. | |
243 | s_PulseEncoderModuleInfo. | |
244 | dw_SetRegister | |
245 | = | |
246 | (devpriv-> | |
247 | s_ModuleInfo | |
248 | [b_ModulNbr]. | |
249 | s_PulseEncoderModuleInfo. | |
250 | dw_SetRegister | |
251 | & | |
252 | (0xFFFFFFFFUL | |
253 | - | |
254 | (1UL << (12 + b_PulseEncoderNbr)))) | ((1UL & (b_TriggerOutputAction - 1)) << (12 + b_PulseEncoderNbr)); | |
255 | } else { | |
256 | /*****************************/ | |
257 | /* Disable the output action */ | |
258 | /*****************************/ | |
259 | ||
260 | devpriv-> | |
261 | s_ModuleInfo | |
262 | [b_ModulNbr]. | |
263 | s_PulseEncoderModuleInfo. | |
264 | dw_SetRegister | |
265 | = | |
266 | devpriv-> | |
267 | s_ModuleInfo | |
268 | [b_ModulNbr]. | |
269 | s_PulseEncoderModuleInfo. | |
270 | dw_SetRegister | |
271 | & | |
272 | (0xFFFFFFFFUL | |
273 | - | |
274 | (1UL << (4 + b_PulseEncoderNbr))); | |
275 | } | |
276 | ||
277 | /*************************/ | |
278 | /* Set the configuration */ | |
279 | /*************************/ | |
280 | ||
281 | outl(devpriv-> | |
282 | s_ModuleInfo | |
283 | [b_ModulNbr]. | |
284 | s_PulseEncoderModuleInfo. | |
285 | dw_SetRegister, | |
286 | devpriv-> | |
287 | s_BoardInfos. | |
288 | ui_Address + | |
289 | 20 + | |
290 | (64 * b_ModulNbr)); | |
291 | ||
292 | devpriv-> | |
293 | s_ModuleInfo | |
294 | [b_ModulNbr]. | |
295 | s_PulseEncoderModuleInfo. | |
296 | s_PulseEncoderInfo | |
297 | [b_PulseEncoderNbr]. | |
298 | b_PulseEncoderInit | |
299 | = 1; | |
300 | } else { | |
301 | /**************************************/ | |
302 | /* Pulse encoder start value is wrong */ | |
303 | /**************************************/ | |
304 | ||
305 | DPRINTK("Pulse encoder start value is wrong\n"); | |
306 | i_ReturnValue = -6; | |
307 | } | |
308 | } else { | |
309 | /****************************************************/ | |
310 | /* Digital TRIGGER output action selection is wrong */ | |
311 | /****************************************************/ | |
312 | ||
313 | DPRINTK("Digital TRIGGER output action selection is wrong\n"); | |
314 | i_ReturnValue = -5; | |
315 | } | |
316 | } else { | |
317 | /**********************************/ | |
318 | /* Input level selection is wrong */ | |
319 | /**********************************/ | |
320 | ||
321 | DPRINTK("Input level selection is wrong\n"); | |
322 | i_ReturnValue = -4; | |
323 | } | |
324 | } else { | |
325 | /************************************/ | |
326 | /* Pulse encoder selection is wrong */ | |
327 | /************************************/ | |
328 | ||
329 | DPRINTK("Pulse encoder selection is wrong\n"); | |
330 | i_ReturnValue = -3; | |
331 | } | |
332 | } else { | |
333 | /********************************************/ | |
334 | /* The module is not a pulse encoder module */ | |
335 | /********************************************/ | |
336 | ||
337 | DPRINTK("The module is not a pulse encoder module\n"); | |
338 | i_ReturnValue = -2; | |
339 | } | |
340 | } else { | |
341 | /********************************************/ | |
342 | /* The module is not a pulse encoder module */ | |
343 | /********************************************/ | |
344 | ||
345 | DPRINTK("The module is not a pulse encoder module\n"); | |
346 | i_ReturnValue = -2; | |
347 | } | |
348 | ||
349 | return (i_ReturnValue); | |
350 | } | |
351 | ||
352 | /* | |
353 | +----------------------------------------------------------------------------+ | |
354 | | Function Name : _INT_ i_APCI1710_EnablePulseEncoder | | |
355 | | (BYTE_ b_BoardHandle, | | |
356 | | BYTE_ b_ModulNbr, | | |
357 | | BYTE_ b_PulseEncoderNbr, | | |
358 | | BYTE_ b_CycleSelection, | | |
359 | | BYTE_ b_InterruptHandling) | | |
360 | +----------------------------------------------------------------------------+ | |
361 | | Task : Enableor disable the selected pulse encoder (b_PulseEncoderNbr) | | |
362 | | from selected module (b_ModulNbr). Each input pulse | | |
363 | | decrement the pulse encoder counter value from 1. | | |
364 | | If you enabled the interrupt (b_InterruptHandling), a | | |
365 | | interrupt is generated when the pulse encoder has run | | |
366 | | down. | | |
367 | +----------------------------------------------------------------------------+ | |
368 | | Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710| | |
369 | | BYTE_ b_ModulNbr : Module number to | | |
370 | | configure (0 to 3) | | |
371 | | BYTE_ b_PulseEncoderNbr : Pulse encoder selection | | |
372 | | (0 to 3) | | |
373 | | BYTE_ b_CycleSelection : APCI1710_CONTINUOUS: | | |
374 | | Each time the | | |
375 | | counting value is set| | |
376 | | on "0", the pulse | | |
377 | | encoder load the | | |
378 | | start value after | | |
379 | | the next pulse. | | |
380 | | APCI1710_SINGLE: | | |
381 | | If the counter is set| | |
382 | | on "0", the pulse | | |
383 | | encoder is stopped. | | |
384 | | BYTE_ b_InterruptHandling : Interrupts can be | | |
385 | | generated, when the pulse| | |
386 | | encoder has run down. | | |
387 | | With this parameter the | | |
388 | | user decides if | | |
389 | | interrupts are used or | | |
390 | | not. | | |
391 | | APCI1710_ENABLE: | | |
392 | | Interrupts are enabled | | |
393 | | APCI1710_DISABLE: | | |
394 | | Interrupts are disabled | |
395 | ||
396 | b_ModulNbr =(BYTE) CR_AREF(insn->chanspec); | |
397 | b_Action =(BYTE) data[0]; | |
398 | b_PulseEncoderNbr =(BYTE) data[1]; | |
399 | b_CycleSelection =(BYTE) data[2]; | |
400 | b_InterruptHandling =(BYTE) data[3];| | |
401 | +----------------------------------------------------------------------------+ | |
402 | | Output Parameters : - | | |
403 | +----------------------------------------------------------------------------+ | |
404 | | Return Value : 0: No error | | |
405 | | -1: The handle parameter of the board is wrong | | |
406 | | -2: Module selection is wrong | | |
407 | | -3: Pulse encoder selection is wrong | | |
408 | | -4: Pulse encoder not initialised. | | |
409 | | See function "i_APCI1710_InitPulseEncoder" | | |
410 | | -5: Cycle selection mode is wrong | | |
411 | | -6: Interrupt handling mode is wrong | | |
412 | | -7: Interrupt routine not installed. | | |
413 | | See function "i_APCI1710_SetBoardIntRoutineX" | | |
414 | +----------------------------------------------------------------------------+ | |
415 | */ | |
416 | ||
417 | INT i_APCI1710_InsnWriteEnableDisablePulseEncoder(comedi_device * dev, | |
790c5541 | 418 | comedi_subdevice * s, comedi_insn * insn, unsigned int * data) |
c995fe94 ADG |
419 | { |
420 | INT i_ReturnValue = 0; | |
421 | BYTE b_ModulNbr; | |
422 | BYTE b_PulseEncoderNbr; | |
423 | BYTE b_CycleSelection; | |
424 | BYTE b_InterruptHandling; | |
425 | BYTE b_Action; | |
426 | ||
427 | i_ReturnValue = insn->n; | |
428 | b_ModulNbr = (BYTE) CR_AREF(insn->chanspec); | |
429 | b_Action = (BYTE) data[0]; | |
430 | b_PulseEncoderNbr = (BYTE) data[1]; | |
431 | b_CycleSelection = (BYTE) data[2]; | |
432 | b_InterruptHandling = (BYTE) data[3]; | |
433 | ||
434 | /***********************************/ | |
435 | /* Test the selected module number */ | |
436 | /***********************************/ | |
437 | ||
438 | if (b_ModulNbr <= 3) { | |
439 | /******************************************/ | |
440 | /* Test the selected pulse encoder number */ | |
441 | /******************************************/ | |
442 | ||
443 | if (b_PulseEncoderNbr <= 3) { | |
444 | /*************************************/ | |
445 | /* Test if pulse encoder initialised */ | |
446 | /*************************************/ | |
447 | ||
448 | if (devpriv->s_ModuleInfo[b_ModulNbr]. | |
449 | s_PulseEncoderModuleInfo. | |
450 | s_PulseEncoderInfo[b_PulseEncoderNbr]. | |
451 | b_PulseEncoderInit == 1) { | |
452 | switch (b_Action) { | |
453 | ||
454 | case APCI1710_ENABLE: | |
455 | /****************************/ | |
456 | /* Test the cycle selection */ | |
457 | /****************************/ | |
458 | ||
459 | if (b_CycleSelection == | |
460 | APCI1710_CONTINUOUS | |
461 | || b_CycleSelection == | |
462 | APCI1710_SINGLE) { | |
463 | /*******************************/ | |
464 | /* Test the interrupt handling */ | |
465 | /*******************************/ | |
466 | ||
467 | if (b_InterruptHandling == | |
468 | APCI1710_ENABLE | |
469 | || b_InterruptHandling | |
470 | == APCI1710_DISABLE) { | |
471 | /******************************/ | |
472 | /* Test if interrupt not used */ | |
473 | /******************************/ | |
474 | ||
475 | if (b_InterruptHandling | |
476 | == | |
477 | APCI1710_DISABLE) | |
478 | { | |
479 | /*************************/ | |
480 | /* Disable the interrupt */ | |
481 | /*************************/ | |
482 | ||
483 | devpriv-> | |
484 | s_ModuleInfo | |
485 | [b_ModulNbr]. | |
486 | s_PulseEncoderModuleInfo. | |
487 | dw_SetRegister | |
488 | = | |
489 | devpriv-> | |
490 | s_ModuleInfo | |
491 | [b_ModulNbr]. | |
492 | s_PulseEncoderModuleInfo. | |
493 | dw_SetRegister | |
494 | & | |
495 | (0xFFFFFFFFUL | |
496 | - | |
497 | (1UL << b_PulseEncoderNbr)); | |
498 | } else { | |
499 | ||
500 | /************************/ | |
501 | /* Enable the interrupt */ | |
502 | /************************/ | |
503 | ||
504 | devpriv-> | |
505 | s_ModuleInfo | |
506 | [b_ModulNbr]. | |
507 | s_PulseEncoderModuleInfo. | |
508 | dw_SetRegister | |
509 | = | |
510 | devpriv-> | |
511 | s_ModuleInfo | |
512 | [b_ModulNbr]. | |
513 | s_PulseEncoderModuleInfo. | |
514 | dw_SetRegister | |
515 | | (1UL | |
516 | << | |
517 | b_PulseEncoderNbr); | |
518 | devpriv->tsk_Current = current; // Save the current process task structure | |
519 | ||
520 | } | |
521 | ||
522 | if (i_ReturnValue >= 0) { | |
523 | /***********************************/ | |
524 | /* Enable or disable the interrupt */ | |
525 | /***********************************/ | |
526 | ||
527 | outl(devpriv-> | |
528 | s_ModuleInfo | |
529 | [b_ModulNbr]. | |
530 | s_PulseEncoderModuleInfo. | |
531 | dw_SetRegister, | |
532 | devpriv-> | |
533 | s_BoardInfos. | |
534 | ui_Address | |
535 | + 20 + | |
536 | (64 * b_ModulNbr)); | |
537 | ||
538 | /****************************/ | |
539 | /* Enable the pulse encoder */ | |
540 | /****************************/ | |
541 | devpriv-> | |
542 | s_ModuleInfo | |
543 | [b_ModulNbr]. | |
544 | s_PulseEncoderModuleInfo. | |
545 | dw_ControlRegister | |
546 | = | |
547 | devpriv-> | |
548 | s_ModuleInfo | |
549 | [b_ModulNbr]. | |
550 | s_PulseEncoderModuleInfo. | |
551 | dw_ControlRegister | |
552 | | (1UL | |
553 | << | |
554 | b_PulseEncoderNbr); | |
555 | ||
556 | /**********************/ | |
557 | /* Set the cycle mode */ | |
558 | /**********************/ | |
559 | ||
560 | devpriv-> | |
561 | s_ModuleInfo | |
562 | [b_ModulNbr]. | |
563 | s_PulseEncoderModuleInfo. | |
564 | dw_ControlRegister | |
565 | = | |
566 | (devpriv-> | |
567 | s_ModuleInfo | |
568 | [b_ModulNbr]. | |
569 | s_PulseEncoderModuleInfo. | |
570 | dw_ControlRegister | |
571 | & | |
572 | (0xFFFFFFFFUL | |
573 | - | |
574 | (1 << (b_PulseEncoderNbr + 4)))) | ((b_CycleSelection & 1UL) << (4 + b_PulseEncoderNbr)); | |
575 | ||
576 | /****************************/ | |
577 | /* Enable the pulse encoder */ | |
578 | /****************************/ | |
579 | ||
580 | outl(devpriv-> | |
581 | s_ModuleInfo | |
582 | [b_ModulNbr]. | |
583 | s_PulseEncoderModuleInfo. | |
584 | dw_ControlRegister, | |
585 | devpriv-> | |
586 | s_BoardInfos. | |
587 | ui_Address | |
588 | + 16 + | |
589 | (64 * b_ModulNbr)); | |
590 | } | |
591 | } else { | |
592 | /************************************/ | |
593 | /* Interrupt handling mode is wrong */ | |
594 | /************************************/ | |
595 | ||
596 | DPRINTK("Interrupt handling mode is wrong\n"); | |
597 | i_ReturnValue = -6; | |
598 | } | |
599 | } else { | |
600 | /*********************************/ | |
601 | /* Cycle selection mode is wrong */ | |
602 | /*********************************/ | |
603 | ||
604 | DPRINTK("Cycle selection mode is wrong\n"); | |
605 | i_ReturnValue = -5; | |
606 | } | |
607 | break; | |
608 | ||
609 | case APCI1710_DISABLE: | |
610 | devpriv->s_ModuleInfo[b_ModulNbr]. | |
611 | s_PulseEncoderModuleInfo. | |
612 | dw_ControlRegister = | |
613 | devpriv-> | |
614 | s_ModuleInfo[b_ModulNbr]. | |
615 | s_PulseEncoderModuleInfo. | |
616 | dw_ControlRegister & | |
617 | (0xFFFFFFFFUL - | |
618 | (1UL << b_PulseEncoderNbr)); | |
619 | ||
620 | /*****************************/ | |
621 | /* Disable the pulse encoder */ | |
622 | /*****************************/ | |
623 | ||
624 | outl(devpriv->s_ModuleInfo[b_ModulNbr]. | |
625 | s_PulseEncoderModuleInfo. | |
626 | dw_ControlRegister, | |
627 | devpriv->s_BoardInfos. | |
628 | ui_Address + 16 + | |
629 | (64 * b_ModulNbr)); | |
630 | ||
631 | break; | |
632 | } // switch End | |
633 | ||
634 | } else { | |
635 | /*********************************/ | |
636 | /* Pulse encoder not initialised */ | |
637 | /*********************************/ | |
638 | ||
639 | DPRINTK("Pulse encoder not initialised\n"); | |
640 | i_ReturnValue = -4; | |
641 | } | |
642 | } else { | |
643 | /************************************/ | |
644 | /* Pulse encoder selection is wrong */ | |
645 | /************************************/ | |
646 | ||
647 | DPRINTK("Pulse encoder selection is wrong\n"); | |
648 | i_ReturnValue = -3; | |
649 | } | |
650 | } else { | |
651 | /*****************************/ | |
652 | /* Module selection is wrong */ | |
653 | /*****************************/ | |
654 | ||
655 | DPRINTK("Module selection is wrong\n"); | |
656 | i_ReturnValue = -2; | |
657 | } | |
658 | ||
659 | return (i_ReturnValue); | |
660 | } | |
661 | ||
662 | /* | |
663 | +----------------------------------------------------------------------------+ | |
664 | | Function Name : _INT_ i_APCI1710_ReadPulseEncoderStatus | | |
665 | | (BYTE_ b_BoardHandle, | | |
666 | | BYTE_ b_ModulNbr, | | |
667 | | BYTE_ b_PulseEncoderNbr, | | |
668 | | PBYTE_ pb_Status) | | |
669 | +----------------------------------------------------------------------------+ | |
670 | | Task APCI1710_PULSEENCODER_READ : Reads the pulse encoder status | |
671 | and valuefrom selected pulse | | |
672 | | encoder (b_PulseEncoderNbr) from selected module | | |
673 | | (b_ModulNbr). | | |
674 | +----------------------------------------------------------------------------+ | |
675 | BYTE b_Type; data[0] | |
676 | APCI1710_PULSEENCODER_WRITE | |
677 | Writes a 32-bit value (ul_WriteValue) into the selected| | |
678 | | pulse encoder (b_PulseEncoderNbr) from selected module | | |
679 | | (b_ModulNbr). This operation set the new start pulse | | |
680 | | encoder value. | |
681 | APCI1710_PULSEENCODER_READ | |
682 | | Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710| | |
683 | | CRAREF() BYTE_ b_ModulNbr : Module number to | | |
684 | | configure (0 to 3) | | |
685 | | data[1] BYTE_ b_PulseEncoderNbr : Pulse encoder selection | | |
686 | | (0 to 3) | |
687 | APCI1710_PULSEENCODER_WRITE | |
688 | data[2] ULONG_ ul_WriteValue : 32-bit value to be | | |
689 | | written | | |
690 | +----------------------------------------------------------------------------+ | |
691 | | Output Parameters : PBYTE_ pb_Status : Pulse encoder status. | | |
692 | | 0 : No overflow occur| | |
693 | | 1 : Overflow occur | |
694 | PULONG_ pul_ReadValue : Pulse encoder value | | | |
695 | +----------------------------------------------------------------------------+ | |
696 | | Return Value : 0: No error | | |
697 | | -1: The handle parameter of the board is wrong | | |
698 | | -2: Module selection is wrong | | |
699 | | -3: Pulse encoder selection is wrong | | |
700 | | -4: Pulse encoder not initialised. | | |
701 | | See function "i_APCI1710_InitPulseEncoder" | | |
702 | +----------------------------------------------------------------------------+ | |
703 | */ | |
704 | ||
705 | /*_INT_ i_APCI1710_ReadPulseEncoderStatus (BYTE_ b_BoardHandle, | |
706 | BYTE_ b_ModulNbr, | |
707 | BYTE_ b_PulseEncoderNbr, | |
708 | ||
709 | PBYTE_ pb_Status) | |
710 | */ | |
711 | INT i_APCI1710_InsnBitsReadWritePulseEncoder(comedi_device * dev, | |
790c5541 | 712 | comedi_subdevice * s, comedi_insn * insn, unsigned int * data) |
c995fe94 ADG |
713 | { |
714 | INT i_ReturnValue = 0; | |
715 | DWORD dw_StatusRegister; | |
716 | BYTE b_ModulNbr; | |
717 | BYTE b_PulseEncoderNbr; | |
718 | PBYTE pb_Status; | |
719 | BYTE b_Type; | |
720 | PULONG pul_ReadValue; | |
721 | ULONG ul_WriteValue; | |
722 | ||
723 | i_ReturnValue = insn->n; | |
724 | b_ModulNbr = (BYTE) CR_AREF(insn->chanspec); | |
725 | b_Type = (BYTE) data[0]; | |
726 | b_PulseEncoderNbr = (BYTE) data[1]; | |
727 | pb_Status = (PBYTE) & data[0]; | |
728 | pul_ReadValue = (PULONG) & data[1]; | |
729 | ||
730 | /***********************************/ | |
731 | /* Test the selected module number */ | |
732 | /***********************************/ | |
733 | ||
734 | if (b_ModulNbr <= 3) { | |
735 | /******************************************/ | |
736 | /* Test the selected pulse encoder number */ | |
737 | /******************************************/ | |
738 | ||
739 | if (b_PulseEncoderNbr <= 3) { | |
740 | /*************************************/ | |
741 | /* Test if pulse encoder initialised */ | |
742 | /*************************************/ | |
743 | ||
744 | if (devpriv->s_ModuleInfo[b_ModulNbr]. | |
745 | s_PulseEncoderModuleInfo. | |
746 | s_PulseEncoderInfo[b_PulseEncoderNbr]. | |
747 | b_PulseEncoderInit == 1) { | |
748 | ||
749 | switch (b_Type) { | |
750 | case APCI1710_PULSEENCODER_READ: | |
751 | /****************************/ | |
752 | /* Read the status register */ | |
753 | /****************************/ | |
754 | ||
755 | dw_StatusRegister = | |
756 | inl(devpriv->s_BoardInfos. | |
757 | ui_Address + 16 + | |
758 | (64 * b_ModulNbr)); | |
759 | ||
760 | devpriv->s_ModuleInfo[b_ModulNbr]. | |
761 | s_PulseEncoderModuleInfo. | |
762 | dw_StatusRegister = devpriv-> | |
763 | s_ModuleInfo[b_ModulNbr]. | |
764 | s_PulseEncoderModuleInfo. | |
765 | dw_StatusRegister | | |
766 | dw_StatusRegister; | |
767 | ||
768 | *pb_Status = | |
769 | (BYTE) (devpriv-> | |
770 | s_ModuleInfo[b_ModulNbr]. | |
771 | s_PulseEncoderModuleInfo. | |
772 | dw_StatusRegister >> (1 + | |
773 | b_PulseEncoderNbr)) & 1; | |
774 | ||
775 | devpriv->s_ModuleInfo[b_ModulNbr]. | |
776 | s_PulseEncoderModuleInfo. | |
777 | dw_StatusRegister = | |
778 | devpriv-> | |
779 | s_ModuleInfo[b_ModulNbr]. | |
780 | s_PulseEncoderModuleInfo. | |
781 | dw_StatusRegister & | |
782 | (0xFFFFFFFFUL - (1 << (1 + | |
783 | b_PulseEncoderNbr))); | |
784 | ||
785 | /******************/ | |
786 | /* Read the value */ | |
787 | /******************/ | |
788 | ||
789 | *pul_ReadValue = | |
790 | inl(devpriv->s_BoardInfos. | |
791 | ui_Address + | |
792 | (4 * b_PulseEncoderNbr) + | |
793 | (64 * b_ModulNbr)); | |
794 | break; | |
795 | ||
796 | case APCI1710_PULSEENCODER_WRITE: | |
797 | ul_WriteValue = (ULONG) data[2]; | |
798 | /*******************/ | |
799 | /* Write the value */ | |
800 | /*******************/ | |
801 | ||
802 | outl(ul_WriteValue, | |
803 | devpriv->s_BoardInfos. | |
804 | ui_Address + | |
805 | (4 * b_PulseEncoderNbr) + | |
806 | (64 * b_ModulNbr)); | |
807 | ||
808 | } //end of switch | |
809 | } else { | |
810 | /*********************************/ | |
811 | /* Pulse encoder not initialised */ | |
812 | /*********************************/ | |
813 | ||
814 | DPRINTK("Pulse encoder not initialised\n"); | |
815 | i_ReturnValue = -4; | |
816 | } | |
817 | } else { | |
818 | /************************************/ | |
819 | /* Pulse encoder selection is wrong */ | |
820 | /************************************/ | |
821 | ||
822 | DPRINTK("Pulse encoder selection is wrong\n"); | |
823 | i_ReturnValue = -3; | |
824 | } | |
825 | } else { | |
826 | /*****************************/ | |
827 | /* Module selection is wrong */ | |
828 | /*****************************/ | |
829 | ||
830 | DPRINTK("Module selection is wrong\n"); | |
831 | i_ReturnValue = -2; | |
832 | } | |
833 | ||
834 | return (i_ReturnValue); | |
835 | } | |
836 | ||
837 | INT i_APCI1710_InsnReadInterruptPulseEncoder(comedi_device * dev, | |
790c5541 | 838 | comedi_subdevice * s, comedi_insn * insn, unsigned int * data) |
c995fe94 ADG |
839 | { |
840 | ||
841 | data[0] = devpriv->s_InterruptParameters. | |
842 | s_FIFOInterruptParameters[devpriv-> | |
843 | s_InterruptParameters.ui_Read].b_OldModuleMask; | |
844 | data[1] = devpriv->s_InterruptParameters. | |
845 | s_FIFOInterruptParameters[devpriv-> | |
846 | s_InterruptParameters.ui_Read].ul_OldInterruptMask; | |
847 | data[2] = devpriv->s_InterruptParameters. | |
848 | s_FIFOInterruptParameters[devpriv-> | |
849 | s_InterruptParameters.ui_Read].ul_OldCounterLatchValue; | |
850 | ||
851 | /***************************/ | |
852 | /* Increment the read FIFO */ | |
853 | /***************************/ | |
854 | ||
855 | devpriv->s_InterruptParameters. | |
856 | ui_Read = (devpriv-> | |
857 | s_InterruptParameters.ui_Read + 1) % APCI1710_SAVE_INTERRUPT; | |
858 | ||
859 | return insn->n; | |
860 | ||
861 | } |