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