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 : SSI.C | Version : 2.96 | | |
34 | +-------------------------------+---------------------------------------+ | |
35 | | Project manager: Eric Stolz | Date : 02/12/2002 | | |
36 | +-----------------------------------------------------------------------+ | |
37 | | Description : APCI-1710 SSI counter module | | |
38 | | | | |
39 | | | | |
40 | +-----------------------------------------------------------------------+ | |
41 | | UPDATES | | |
42 | +-----------------------------------------------------------------------+ | |
43 | | Date | Author | Description of updates | | |
44 | +----------+-----------+------------------------------------------------+ | |
45 | | 13/05/98 | S. Weber | SSI digital input / output implementation | | |
46 | |----------|-----------|------------------------------------------------| | |
47 | | 22/03/00 | C.Guinot | 0100/0226 -> 0200/0227 | | |
48 | | | | Änderung in InitSSI Funktion | | |
49 | | | | b_SSIProfile >= 2 anstatt b_SSIProfile > 2 | | |
50 | | | | | | |
51 | +-----------------------------------------------------------------------+ | |
52 | | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 | | |
53 | | | | available | | |
54 | +-----------------------------------------------------------------------+ | |
55 | */ | |
56 | ||
57 | /* | |
58 | +----------------------------------------------------------------------------+ | |
59 | | Included files | | |
60 | +----------------------------------------------------------------------------+ | |
61 | */ | |
62 | ||
63 | #include "APCI1710_Ssi.h" | |
64 | ||
65 | /* | |
66 | +----------------------------------------------------------------------------+ | |
67 | | Function Name : _INT_ i_APCI1710_InitSSI | | |
68 | | (BYTE_ b_BoardHandle, | | |
69 | | BYTE_ b_ModulNbr, | | |
70 | | BYTE_ b_SSIProfile, | | |
71 | | BYTE_ b_PositionTurnLength, | | |
72 | | BYTE_ b_TurnCptLength, | | |
73 | | BYTE_ b_PCIInputClock, | | |
74 | | ULONG_ ul_SSIOutputClock, | | |
75 | | BYTE_ b_SSICountingMode) | | |
76 | +----------------------------------------------------------------------------+ | |
77 | | Task : Configure the SSI operating mode from selected module | | |
78 | | (b_ModulNbr). You must calling this function be for you| | |
79 | | call any other function witch access of SSI. | | |
80 | +----------------------------------------------------------------------------+ | |
81 | | Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710| | |
82 | | BYTE_ b_ModulNbr : Module number to | | |
83 | | configure (0 to 3) | | |
84 | | BYTE_ b_SSIProfile : Selection from SSI | | |
85 | | profile length (2 to 32).| | |
86 | | BYTE_ b_PositionTurnLength : Selection from SSI | | |
87 | | position data length | | |
88 | | (1 to 31). | | |
89 | | BYTE_ b_TurnCptLength : Selection from SSI turn | | |
90 | | counter data length | | |
91 | | (1 to 31). | | |
92 | | BYTE b_PCIInputClock : Selection from PCI bus | | |
93 | | clock | | |
94 | | - APCI1710_30MHZ : | | |
95 | | The PC have a PCI bus | | |
96 | | clock from 30 MHz | | |
97 | | - APCI1710_33MHZ : | | |
98 | | The PC have a PCI bus | | |
99 | | clock from 33 MHz | | |
100 | | ULONG_ ul_SSIOutputClock : Selection from SSI output| | |
101 | | clock. | | |
102 | | From 229 to 5 000 000 Hz| | |
103 | | for 30 MHz selection. | | |
104 | | From 252 to 5 000 000 Hz| | |
105 | | for 33 MHz selection. | | |
106 | | BYTE b_SSICountingMode : SSI counting mode | | |
107 | | selection | | |
108 | | - APCI1710_BINARY_MODE : | | |
109 | | Binary counting mode. | | |
110 | | - APCI1710_GRAY_MODE : | | |
111 | | Gray counting mode. | |
112 | ||
113 | b_ModulNbr = CR_AREF(insn->chanspec); | |
114 | b_SSIProfile = (BYTE) data[0]; | |
115 | b_PositionTurnLength= (BYTE) data[1]; | |
116 | b_TurnCptLength = (BYTE) data[2]; | |
117 | b_PCIInputClock = (BYTE) data[3]; | |
118 | ul_SSIOutputClock = (ULONG) data[4]; | |
119 | b_SSICountingMode = (BYTE) data[5]; | | |
120 | +----------------------------------------------------------------------------+ | |
121 | | Output Parameters : - | | |
122 | +----------------------------------------------------------------------------+ | |
123 | | Return Value : 0: No error | | |
124 | | -1: The handle parameter of the board is wrong | | |
125 | | -2: The module parameter is wrong | | |
126 | | -3: The module is not a SSI module | | |
127 | | -4: The selected SSI profile length is wrong | | |
128 | | -5: The selected SSI position data length is wrong | | |
129 | | -6: The selected SSI turn counter data length is wrong | | |
130 | | -7: The selected PCI input clock is wrong | | |
131 | | -8: The selected SSI output clock is wrong | | |
132 | | -9: The selected SSI counting mode parameter is wrong | | |
133 | +----------------------------------------------------------------------------+ | |
134 | */ | |
135 | ||
136 | INT i_APCI1710_InsnConfigInitSSI(comedi_device * dev, comedi_subdevice * s, | |
790c5541 | 137 | comedi_insn * insn, unsigned int * data) |
c995fe94 ADG |
138 | { |
139 | INT i_ReturnValue = 0; | |
140 | UINT ui_TimerValue; | |
141 | BYTE b_ModulNbr, b_SSIProfile, b_PositionTurnLength, b_TurnCptLength, | |
142 | b_PCIInputClock, b_SSICountingMode; | |
143 | ULONG ul_SSIOutputClock; | |
144 | ||
145 | b_ModulNbr = CR_AREF(insn->chanspec); | |
146 | b_SSIProfile = (BYTE) data[0]; | |
147 | b_PositionTurnLength = (BYTE) data[1]; | |
148 | b_TurnCptLength = (BYTE) data[2]; | |
149 | b_PCIInputClock = (BYTE) data[3]; | |
150 | ul_SSIOutputClock = (ULONG) data[4]; | |
151 | b_SSICountingMode = (BYTE) data[5]; | |
152 | ||
153 | i_ReturnValue = insn->n; | |
154 | /**************************/ | |
155 | /* Test the module number */ | |
156 | /**************************/ | |
157 | ||
158 | if (b_ModulNbr < 4) { | |
159 | /***********************/ | |
160 | /* Test if SSI counter */ | |
161 | /***********************/ | |
162 | ||
163 | if ((devpriv->s_BoardInfos. | |
164 | dw_MolduleConfiguration[b_ModulNbr] & | |
165 | 0xFFFF0000UL) == APCI1710_SSI_COUNTER) { | |
166 | /*******************************/ | |
167 | /* Test the SSI profile length */ | |
168 | /*******************************/ | |
169 | ||
170 | // CG 22/03/00 b_SSIProfile >= 2 anstatt b_SSIProfile > 2 | |
171 | if (b_SSIProfile >= 2 && b_SSIProfile < 33) { | |
172 | /*************************************/ | |
173 | /* Test the SSI position data length */ | |
174 | /*************************************/ | |
175 | ||
176 | if (b_PositionTurnLength > 0 | |
177 | && b_PositionTurnLength < 32) { | |
178 | /*****************************************/ | |
179 | /* Test the SSI turn counter data length */ | |
180 | /*****************************************/ | |
181 | ||
182 | if (b_TurnCptLength > 0 | |
183 | && b_TurnCptLength < 32) { | |
184 | /***************************/ | |
185 | /* Test the profile length */ | |
186 | /***************************/ | |
187 | ||
188 | if ((b_TurnCptLength + | |
189 | b_PositionTurnLength) | |
190 | <= b_SSIProfile) { | |
191 | /****************************/ | |
192 | /* Test the PCI input clock */ | |
193 | /****************************/ | |
194 | ||
195 | if (b_PCIInputClock == | |
196 | APCI1710_30MHZ | |
197 | || | |
198 | b_PCIInputClock | |
199 | == | |
200 | APCI1710_33MHZ) | |
201 | { | |
202 | /*************************/ | |
203 | /* Test the output clock */ | |
204 | /*************************/ | |
205 | ||
206 | if ((b_PCIInputClock == APCI1710_30MHZ && (ul_SSIOutputClock > 228 && ul_SSIOutputClock <= 5000000UL)) || (b_PCIInputClock == APCI1710_33MHZ && (ul_SSIOutputClock > 251 && ul_SSIOutputClock <= 5000000UL))) { | |
207 | if (b_SSICountingMode == APCI1710_BINARY_MODE || b_SSICountingMode == APCI1710_GRAY_MODE) { | |
208 | /**********************/ | |
209 | /* Save configuration */ | |
210 | /**********************/ | |
211 | devpriv-> | |
212 | s_ModuleInfo | |
213 | [b_ModulNbr]. | |
214 | s_SSICounterInfo. | |
215 | b_SSIProfile | |
216 | = | |
217 | b_SSIProfile; | |
218 | ||
219 | devpriv-> | |
220 | s_ModuleInfo | |
221 | [b_ModulNbr]. | |
222 | s_SSICounterInfo. | |
223 | b_PositionTurnLength | |
224 | = | |
225 | b_PositionTurnLength; | |
226 | ||
227 | devpriv-> | |
228 | s_ModuleInfo | |
229 | [b_ModulNbr]. | |
230 | s_SSICounterInfo. | |
231 | b_TurnCptLength | |
232 | = | |
233 | b_TurnCptLength; | |
234 | ||
235 | /*********************************/ | |
236 | /* Initialise the profile length */ | |
237 | /*********************************/ | |
238 | ||
239 | if (b_SSICountingMode == APCI1710_BINARY_MODE) { | |
240 | ||
241 | outl(b_SSIProfile + 1, devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr)); | |
242 | } else { | |
243 | ||
244 | outl(b_SSIProfile, devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr)); | |
245 | } | |
246 | ||
247 | /******************************/ | |
248 | /* Calculate the output clock */ | |
249 | /******************************/ | |
250 | ||
251 | ui_TimerValue | |
252 | = | |
253 | (UINT) | |
254 | ( | |
255 | ((ULONG) (b_PCIInputClock) * 500000UL) / ul_SSIOutputClock); | |
256 | ||
257 | /************************/ | |
258 | /* Initialise the timer */ | |
259 | /************************/ | |
260 | ||
261 | outl(ui_TimerValue, devpriv->s_BoardInfos.ui_Address + (64 * b_ModulNbr)); | |
262 | ||
263 | /********************************/ | |
264 | /* Initialise the counting mode */ | |
265 | /********************************/ | |
266 | ||
267 | outl(7 * b_SSICountingMode, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr)); | |
268 | ||
269 | devpriv-> | |
270 | s_ModuleInfo | |
271 | [b_ModulNbr]. | |
272 | s_SSICounterInfo. | |
273 | b_SSIInit | |
274 | = | |
275 | 1; | |
276 | } else { | |
277 | /*****************************************************/ | |
278 | /* The selected SSI counting mode parameter is wrong */ | |
279 | /*****************************************************/ | |
280 | ||
281 | DPRINTK("The selected SSI counting mode parameter is wrong\n"); | |
282 | i_ReturnValue | |
283 | = | |
284 | -9; | |
285 | } | |
286 | } else { | |
287 | /******************************************/ | |
288 | /* The selected SSI output clock is wrong */ | |
289 | /******************************************/ | |
290 | ||
291 | DPRINTK("The selected SSI output clock is wrong\n"); | |
292 | i_ReturnValue | |
293 | = | |
294 | -8; | |
295 | } | |
296 | } else { | |
297 | /*****************************************/ | |
298 | /* The selected PCI input clock is wrong */ | |
299 | /*****************************************/ | |
300 | ||
301 | DPRINTK("The selected PCI input clock is wrong\n"); | |
302 | i_ReturnValue = | |
303 | -7; | |
304 | } | |
305 | } else { | |
306 | /********************************************/ | |
307 | /* The selected SSI profile length is wrong */ | |
308 | /********************************************/ | |
309 | ||
310 | DPRINTK("The selected SSI profile length is wrong\n"); | |
311 | i_ReturnValue = -4; | |
312 | } | |
313 | } else { | |
314 | /******************************************************/ | |
315 | /* The selected SSI turn counter data length is wrong */ | |
316 | /******************************************************/ | |
317 | ||
318 | DPRINTK("The selected SSI turn counter data length is wrong\n"); | |
319 | i_ReturnValue = -6; | |
320 | } | |
321 | } else { | |
322 | /**************************************************/ | |
323 | /* The selected SSI position data length is wrong */ | |
324 | /**************************************************/ | |
325 | ||
326 | DPRINTK("The selected SSI position data length is wrong\n"); | |
327 | i_ReturnValue = -5; | |
328 | } | |
329 | } else { | |
330 | /********************************************/ | |
331 | /* The selected SSI profile length is wrong */ | |
332 | /********************************************/ | |
333 | ||
334 | DPRINTK("The selected SSI profile length is wrong\n"); | |
335 | i_ReturnValue = -4; | |
336 | } | |
337 | } else { | |
338 | /**********************************/ | |
339 | /* The module is not a SSI module */ | |
340 | /**********************************/ | |
341 | ||
342 | DPRINTK("The module is not a SSI module\n"); | |
343 | i_ReturnValue = -3; | |
344 | } | |
345 | } else { | |
346 | /***********************/ | |
347 | /* Module number error */ | |
348 | /***********************/ | |
349 | ||
350 | DPRINTK("Module number error\n"); | |
351 | i_ReturnValue = -2; | |
352 | } | |
353 | ||
354 | return (i_ReturnValue); | |
355 | } | |
356 | ||
357 | /* | |
358 | +----------------------------------------------------------------------------+ | |
359 | | Function Name : _INT_ i_APCI1710_Read1SSIValue | | |
360 | | (BYTE_ b_BoardHandle, | | |
361 | | BYTE_ b_ModulNbr, | | |
362 | | BYTE_ b_SelectedSSI, | | |
363 | | PULONG_ pul_Position, | | |
364 | | PULONG_ pul_TurnCpt) | |
365 | INT i_APCI1710_ReadSSIValue(comedi_device *dev,comedi_subdevice *s, | |
790c5541 | 366 | comedi_insn *insn,unsigned int *data) | |
c995fe94 ADG |
367 | +----------------------------------------------------------------------------+ |
368 | | Task : | |
369 | ||
370 | ||
371 | Read the selected SSI counter (b_SelectedSSI) from | | |
372 | | selected module (b_ModulNbr). | |
373 | or Read all SSI counter (b_SelectedSSI) from | | |
374 | | selected module (b_ModulNbr). | | |
375 | +----------------------------------------------------------------------------+ | |
376 | | Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710| | |
377 | | BYTE_ b_ModulNbr : Module number to | | |
378 | | configure (0 to 3) | | |
379 | | BYTE_ b_SelectedSSI : Selection from SSI | | |
380 | | counter (0 to 2) | |
381 | ||
382 | b_ModulNbr = (BYTE) CR_AREF(insn->chanspec); | |
383 | b_SelectedSSI = (BYTE) CR_CHAN(insn->chanspec); (in case of single ssi) | |
384 | b_ReadType = (BYTE) CR_RANGE(insn->chanspec); | |
385 | | | |
386 | +----------------------------------------------------------------------------+ | |
387 | | Output Parameters : PULONG_ pul_Position : SSI position in the turn | | |
388 | | PULONG_ pul_TurnCpt : Number of turns | |
389 | ||
390 | pul_Position = (PULONG) &data[0]; | |
391 | pul_TurnCpt = (PULONG) &data[1]; | | |
392 | +----------------------------------------------------------------------------+ | |
393 | | Return Value : 0: No error | | |
394 | | -1: The handle parameter of the board is wrong | | |
395 | | -2: The module parameter is wrong | | |
396 | | -3: The module is not a SSI module | | |
397 | | -4: SSI not initialised see function | | |
398 | | "i_APCI1710_InitSSI" | | |
399 | | -5: The selected SSI is wrong | | |
400 | +----------------------------------------------------------------------------+ | |
401 | */ | |
402 | ||
403 | INT i_APCI1710_InsnReadSSIValue(comedi_device * dev, comedi_subdevice * s, | |
790c5541 | 404 | comedi_insn * insn, unsigned int * data) |
c995fe94 ADG |
405 | { |
406 | INT i_ReturnValue = 0; | |
407 | BYTE b_Cpt; | |
408 | BYTE b_Length; | |
409 | BYTE b_Schift; | |
410 | BYTE b_SSICpt; | |
411 | DWORD dw_And; | |
412 | DWORD dw_And1; | |
413 | DWORD dw_And2; | |
414 | DWORD dw_StatusReg; | |
415 | DWORD dw_CounterValue; | |
416 | BYTE b_ModulNbr; | |
417 | BYTE b_SelectedSSI; | |
418 | BYTE b_ReadType; | |
419 | PULONG pul_Position; | |
420 | PULONG pul_TurnCpt; | |
421 | PULONG pul_Position1; | |
422 | PULONG pul_TurnCpt1; | |
423 | ||
424 | i_ReturnValue = insn->n; | |
425 | pul_Position1 = (PULONG) & data[0]; | |
426 | // For Read1 | |
427 | pul_TurnCpt1 = (PULONG) & data[1]; | |
428 | // For Read all | |
429 | pul_Position = (PULONG) & data[0]; //0-2 | |
430 | pul_TurnCpt = (PULONG) & data[3]; //3-5 | |
431 | b_ModulNbr = (BYTE) CR_AREF(insn->chanspec); | |
432 | b_SelectedSSI = (BYTE) CR_CHAN(insn->chanspec); | |
433 | b_ReadType = (BYTE) CR_RANGE(insn->chanspec); | |
434 | ||
435 | /**************************/ | |
436 | /* Test the module number */ | |
437 | /**************************/ | |
438 | ||
439 | if (b_ModulNbr < 4) { | |
440 | /***********************/ | |
441 | /* Test if SSI counter */ | |
442 | /***********************/ | |
443 | ||
444 | if ((devpriv->s_BoardInfos. | |
445 | dw_MolduleConfiguration[b_ModulNbr] & | |
446 | 0xFFFF0000UL) == APCI1710_SSI_COUNTER) { | |
447 | /***************************/ | |
448 | /* Test if SSI initialised */ | |
449 | /***************************/ | |
450 | ||
451 | if (devpriv->s_ModuleInfo[b_ModulNbr]. | |
452 | s_SSICounterInfo.b_SSIInit == 1) { | |
453 | ||
454 | switch (b_ReadType) { | |
455 | ||
456 | case APCI1710_SSI_READ1VALUE: | |
457 | /****************************************/ | |
458 | /* Test the selected SSI counter number */ | |
459 | /****************************************/ | |
460 | ||
461 | if (b_SelectedSSI < 3) { | |
462 | /************************/ | |
463 | /* Start the conversion */ | |
464 | /************************/ | |
465 | ||
466 | outl(0, devpriv->s_BoardInfos. | |
467 | ui_Address + 8 + | |
468 | (64 * b_ModulNbr)); | |
469 | ||
470 | do { | |
471 | /*******************/ | |
472 | /* Read the status */ | |
473 | /*******************/ | |
474 | ||
475 | dw_StatusReg = | |
476 | inl(devpriv-> | |
477 | s_BoardInfos. | |
478 | ui_Address + | |
479 | (64 * b_ModulNbr)); | |
480 | } | |
481 | while ((dw_StatusReg & 0x1) != | |
482 | 0); | |
483 | ||
484 | /******************************/ | |
485 | /* Read the SSI counter value */ | |
486 | /******************************/ | |
487 | ||
488 | dw_CounterValue = | |
489 | inl(devpriv-> | |
490 | s_BoardInfos. | |
491 | ui_Address + 4 + | |
492 | (b_SelectedSSI * 4) + | |
493 | (64 * b_ModulNbr)); | |
494 | ||
495 | b_Length = | |
496 | devpriv-> | |
497 | s_ModuleInfo | |
498 | [b_ModulNbr]. | |
499 | s_SSICounterInfo. | |
500 | b_SSIProfile / 2; | |
501 | ||
502 | if ((b_Length * 2) != | |
503 | devpriv-> | |
504 | s_ModuleInfo | |
505 | [b_ModulNbr]. | |
506 | s_SSICounterInfo. | |
507 | b_SSIProfile) { | |
508 | b_Length++; | |
509 | } | |
510 | ||
511 | b_Schift = | |
512 | b_Length - | |
513 | devpriv-> | |
514 | s_ModuleInfo | |
515 | [b_ModulNbr]. | |
516 | s_SSICounterInfo. | |
517 | b_PositionTurnLength; | |
518 | ||
519 | *pul_Position1 = | |
520 | dw_CounterValue >> | |
521 | b_Schift; | |
522 | ||
523 | dw_And = 1; | |
524 | ||
525 | for (b_Cpt = 0; | |
526 | b_Cpt < | |
527 | devpriv-> | |
528 | s_ModuleInfo | |
529 | [b_ModulNbr]. | |
530 | s_SSICounterInfo. | |
531 | b_PositionTurnLength; | |
532 | b_Cpt++) { | |
533 | dw_And = dw_And * 2; | |
534 | } | |
535 | ||
536 | *pul_Position1 = | |
537 | *pul_Position1 & | |
538 | ((dw_And) - 1); | |
539 | ||
540 | *pul_TurnCpt1 = | |
541 | dw_CounterValue >> | |
542 | b_Length; | |
543 | ||
544 | dw_And = 1; | |
545 | ||
546 | for (b_Cpt = 0; | |
547 | b_Cpt < | |
548 | devpriv-> | |
549 | s_ModuleInfo | |
550 | [b_ModulNbr]. | |
551 | s_SSICounterInfo. | |
552 | b_TurnCptLength; | |
553 | b_Cpt++) { | |
554 | dw_And = dw_And * 2; | |
555 | } | |
556 | ||
557 | *pul_TurnCpt1 = | |
558 | *pul_TurnCpt1 & | |
559 | ((dw_And) - 1); | |
560 | } else { | |
561 | /*****************************/ | |
562 | /* The selected SSI is wrong */ | |
563 | /*****************************/ | |
564 | ||
565 | DPRINTK("The selected SSI is wrong\n"); | |
566 | i_ReturnValue = -5; | |
567 | } | |
568 | break; | |
569 | ||
570 | case APCI1710_SSI_READALLVALUE: | |
571 | dw_And1 = 1; | |
572 | ||
573 | for (b_Cpt = 0; | |
574 | b_Cpt < | |
575 | devpriv-> | |
576 | s_ModuleInfo[b_ModulNbr]. | |
577 | s_SSICounterInfo. | |
578 | b_PositionTurnLength; b_Cpt++) { | |
579 | dw_And1 = dw_And1 * 2; | |
580 | } | |
581 | ||
582 | dw_And2 = 1; | |
583 | ||
584 | for (b_Cpt = 0; | |
585 | b_Cpt < | |
586 | devpriv-> | |
587 | s_ModuleInfo[b_ModulNbr]. | |
588 | s_SSICounterInfo. | |
589 | b_TurnCptLength; b_Cpt++) { | |
590 | dw_And2 = dw_And2 * 2; | |
591 | } | |
592 | ||
593 | /************************/ | |
594 | /* Start the conversion */ | |
595 | /************************/ | |
596 | ||
597 | outl(0, devpriv->s_BoardInfos. | |
598 | ui_Address + 8 + | |
599 | (64 * b_ModulNbr)); | |
600 | ||
601 | do { | |
602 | /*******************/ | |
603 | /* Read the status */ | |
604 | /*******************/ | |
605 | ||
606 | dw_StatusReg = | |
607 | inl(devpriv-> | |
608 | s_BoardInfos. | |
609 | ui_Address + | |
610 | (64 * b_ModulNbr)); | |
611 | } | |
612 | while ((dw_StatusReg & 0x1) != 0); | |
613 | ||
614 | for (b_SSICpt = 0; b_SSICpt < 3; | |
615 | b_SSICpt++) { | |
616 | /******************************/ | |
617 | /* Read the SSI counter value */ | |
618 | /******************************/ | |
619 | ||
620 | dw_CounterValue = | |
621 | inl(devpriv-> | |
622 | s_BoardInfos. | |
623 | ui_Address + 4 + | |
624 | (b_SSICpt * 4) + | |
625 | (64 * b_ModulNbr)); | |
626 | ||
627 | b_Length = | |
628 | devpriv-> | |
629 | s_ModuleInfo | |
630 | [b_ModulNbr]. | |
631 | s_SSICounterInfo. | |
632 | b_SSIProfile / 2; | |
633 | ||
634 | if ((b_Length * 2) != | |
635 | devpriv-> | |
636 | s_ModuleInfo | |
637 | [b_ModulNbr]. | |
638 | s_SSICounterInfo. | |
639 | b_SSIProfile) { | |
640 | b_Length++; | |
641 | } | |
642 | ||
643 | b_Schift = | |
644 | b_Length - | |
645 | devpriv-> | |
646 | s_ModuleInfo | |
647 | [b_ModulNbr]. | |
648 | s_SSICounterInfo. | |
649 | b_PositionTurnLength; | |
650 | ||
651 | pul_Position[b_SSICpt] = | |
652 | dw_CounterValue >> | |
653 | b_Schift; | |
654 | pul_Position[b_SSICpt] = | |
655 | pul_Position[b_SSICpt] & | |
656 | ((dw_And1) - 1); | |
657 | ||
658 | pul_TurnCpt[b_SSICpt] = | |
659 | dw_CounterValue >> | |
660 | b_Length; | |
661 | pul_TurnCpt[b_SSICpt] = | |
662 | pul_TurnCpt[b_SSICpt] & | |
663 | ((dw_And2) - 1); | |
664 | } | |
665 | break; | |
666 | ||
667 | default: | |
668 | printk("Read Type Inputs Wrong\n"); | |
669 | ||
670 | } // switch ending | |
671 | ||
672 | } else { | |
673 | /***********************/ | |
674 | /* SSI not initialised */ | |
675 | /***********************/ | |
676 | ||
677 | DPRINTK("SSI not initialised\n"); | |
678 | i_ReturnValue = -4; | |
679 | } | |
680 | } else { | |
681 | /**********************************/ | |
682 | /* The module is not a SSI module */ | |
683 | /**********************************/ | |
684 | ||
685 | DPRINTK("The module is not a SSI module\n"); | |
686 | i_ReturnValue = -3; | |
687 | ||
688 | } | |
689 | } else { | |
690 | /***********************/ | |
691 | /* Module number error */ | |
692 | /***********************/ | |
693 | ||
694 | DPRINTK("Module number error\n"); | |
695 | i_ReturnValue = -2; | |
696 | } | |
697 | ||
698 | return (i_ReturnValue); | |
699 | } | |
700 | ||
701 | /* | |
702 | +----------------------------------------------------------------------------+ | |
703 | | Function Name : _INT_ i_APCI1710_ReadSSI1DigitalInput | | |
704 | | (BYTE_ b_BoardHandle, | | |
705 | | BYTE_ b_ModulNbr, | | |
706 | | BYTE_ b_InputChannel, | | |
707 | | PBYTE_ pb_ChannelStatus) | | |
708 | +----------------------------------------------------------------------------+ | |
709 | | Task : | |
710 | (0) Set the digital output from selected SSI moule | | |
711 | | (b_ModuleNbr) ON | |
712 | (1) Set the digital output from selected SSI moule | | |
713 | | (b_ModuleNbr) OFF | |
714 | (2)Read the status from selected SSI digital input | | |
715 | | (b_InputChannel) | |
716 | (3)Read the status from all SSI digital inputs from | | |
717 | | selected SSI module (b_ModulNbr) | | |
718 | +----------------------------------------------------------------------------+ | |
719 | | Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710| | |
720 | | BYTE_ b_ModulNbr CR_AREF : Module number to | | |
721 | | configure (0 to 3) | | |
722 | | BYTE_ b_InputChannel CR_CHAN : Selection from digital | | |
723 | | data[0] which IOTYPE input ( 0 to 2) | | |
724 | +----------------------------------------------------------------------------+ | |
725 | | Output Parameters : PBYTE_ pb_ChannelStatus : Digital input channel | | |
726 | | data[0] status | | |
727 | | 0 : Channle is not active| | |
728 | | 1 : Channle is active | | |
729 | +----------------------------------------------------------------------------+ | |
730 | | Return Value : 0: No error | | |
731 | | -1: The handle parameter of the board is wrong | | |
732 | | -2: The module parameter is wrong | | |
733 | | -3: The module is not a SSI module | | |
734 | | -4: The selected SSI digital input is wrong | | |
735 | +----------------------------------------------------------------------------+ | |
736 | */ | |
737 | ||
738 | INT i_APCI1710_InsnBitsSSIDigitalIO(comedi_device * dev, comedi_subdevice * s, | |
790c5541 | 739 | comedi_insn * insn, unsigned int * data) |
c995fe94 ADG |
740 | { |
741 | INT i_ReturnValue = 0; | |
742 | DWORD dw_StatusReg; | |
743 | BYTE b_ModulNbr; | |
744 | BYTE b_InputChannel; | |
745 | PBYTE pb_ChannelStatus; | |
746 | PBYTE pb_InputStatus; | |
747 | BYTE b_IOType; | |
748 | i_ReturnValue = insn->n; | |
749 | b_ModulNbr = (BYTE) CR_AREF(insn->chanspec); | |
750 | b_IOType = (BYTE) data[0]; | |
751 | ||
752 | /**************************/ | |
753 | /* Test the module number */ | |
754 | /**************************/ | |
755 | ||
756 | if (b_ModulNbr < 4) { | |
757 | /***********************/ | |
758 | /* Test if SSI counter */ | |
759 | /***********************/ | |
760 | ||
761 | if ((devpriv->s_BoardInfos. | |
762 | dw_MolduleConfiguration[b_ModulNbr] & | |
763 | 0xFFFF0000UL) == APCI1710_SSI_COUNTER) { | |
764 | switch (b_IOType) { | |
765 | case APCI1710_SSI_SET_CHANNELON: | |
766 | /*****************************/ | |
767 | /* Set the digital output ON */ | |
768 | /*****************************/ | |
769 | ||
770 | outl(1, devpriv->s_BoardInfos.ui_Address + 16 + | |
771 | (64 * b_ModulNbr)); | |
772 | break; | |
773 | ||
774 | case APCI1710_SSI_SET_CHANNELOFF: | |
775 | /******************************/ | |
776 | /* Set the digital output OFF */ | |
777 | /******************************/ | |
778 | ||
779 | outl(0, devpriv->s_BoardInfos.ui_Address + 16 + | |
780 | (64 * b_ModulNbr)); | |
781 | break; | |
782 | ||
783 | case APCI1710_SSI_READ_1CHANNEL: | |
784 | /******************************************/ | |
785 | /* Test the digital imnput channel number */ | |
786 | /******************************************/ | |
787 | ||
788 | b_InputChannel = (BYTE) CR_CHAN(insn->chanspec); | |
789 | pb_ChannelStatus = (PBYTE) & data[0]; | |
790 | ||
791 | if (b_InputChannel <= 2) { | |
792 | /**************************/ | |
793 | /* Read all digital input */ | |
794 | /**************************/ | |
795 | ||
796 | dw_StatusReg = | |
797 | inl(devpriv->s_BoardInfos. | |
798 | ui_Address + (64 * b_ModulNbr)); | |
799 | *pb_ChannelStatus = | |
800 | (BYTE) (((~dw_StatusReg) >> (4 + | |
801 | b_InputChannel)) | |
802 | & 1); | |
803 | } else { | |
804 | /********************************/ | |
805 | /* Selected digital input error */ | |
806 | /********************************/ | |
807 | ||
808 | DPRINTK("Selected digital input error\n"); | |
809 | i_ReturnValue = -4; | |
810 | } | |
811 | break; | |
812 | ||
813 | case APCI1710_SSI_READ_ALLCHANNEL: | |
814 | /**************************/ | |
815 | /* Read all digital input */ | |
816 | /**************************/ | |
817 | pb_InputStatus = (PBYTE) & data[0]; | |
818 | ||
819 | dw_StatusReg = | |
820 | inl(devpriv->s_BoardInfos.ui_Address + | |
821 | (64 * b_ModulNbr)); | |
822 | *pb_InputStatus = | |
823 | (BYTE) (((~dw_StatusReg) >> 4) & 7); | |
824 | break; | |
825 | ||
826 | default: | |
827 | printk("IO type wrong\n"); | |
828 | ||
829 | } //switch end | |
830 | } else { | |
831 | /**********************************/ | |
832 | /* The module is not a SSI module */ | |
833 | /**********************************/ | |
834 | ||
835 | DPRINTK("The module is not a SSI module\n"); | |
836 | i_ReturnValue = -3; | |
837 | } | |
838 | } else { | |
839 | /***********************/ | |
840 | /* Module number error */ | |
841 | /***********************/ | |
842 | ||
843 | DPRINTK("Module number error\n"); | |
844 | i_ReturnValue = -2; | |
845 | } | |
846 | ||
847 | return (i_ReturnValue); | |
848 | } |