Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
hwdrv_apci3200.c
Go to the documentation of this file.
1 
24 /*
25 
26  +-----------------------------------------------------------------------+
27  | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
28  +-----------------------------------------------------------------------+
29  | Tel : +49 (0) 7223/9493-0 | email : [email protected] |
30  | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
31  +-------------------------------+---------------------------------------+
32  | Project : APCI-3200 | Compiler : GCC |
33  | Module name : hwdrv_apci3200.c| Version : 2.96 |
34  +-------------------------------+---------------------------------------+
35  | Project manager: Eric Stolz | Date : 02/12/2002 |
36  +-------------------------------+---------------------------------------+
37  | Description : Hardware Layer Access For APCI-3200 |
38  +-----------------------------------------------------------------------+
39  | UPDATES |
40  +----------+-----------+------------------------------------------------+
41  | Date | Author | Description of updates |
42  +----------+-----------+------------------------------------------------+
43  | 02.07.04 | J. Krauth | Modification from the driver in order to |
44  | | | correct some errors when using several boards. |
45  | | | |
46  | | | |
47  +----------+-----------+------------------------------------------------+
48  | 26.10.04 | J. Krauth | - Update for COMEDI 0.7.68 |
49  | | | - Read eeprom value |
50  | | | - Append APCI-3300 |
51  +----------+-----------+------------------------------------------------+
52 */
53 
54 /*
55  +----------------------------------------------------------------------------+
56  | Included files |
57  +----------------------------------------------------------------------------+
58 */
59 #include "hwdrv_apci3200.h"
60 
61 /* #define PRINT_INFO */
62 
63 /* BEGIN JK 06.07.04: Management of sevrals boards */
64 /*
65  int i_CJCAvailable=1;
66  int i_CJCPolarity=0;
67  int i_CJCGain=2;/* changed from 0 to 2 */
71  int i_AutoCalibration=0; /* : auto calibration */
80  int i_Sum=0;
81  int i_Offset;
82  unsigned int ui_Channel_num=0;
83  static int i_Count=0;
85  unsigned int ui_InterruptChannelValue[96]; /* Buffer */
86 */
87 struct str_BoardInfos s_BoardInfos[100]; /* 100 will be the max number of boards to be used */
88 /* END JK 06.07.04: Management of sevrals boards */
89 
90 #define AMCC_OP_REG_MCSR 0x3c
91 #define EEPROM_BUSY 0x80000000
92 #define NVCMD_LOAD_LOW (0x4 << 5) /* nvRam load low command */
93 #define NVCMD_LOAD_HIGH (0x5 << 5) /* nvRam load high command */
94 #define NVCMD_BEGIN_READ (0x7 << 5) /* nvRam begin read command */
95 #define NVCMD_BEGIN_WRITE (0x6 << 5) /* EEPROM begin write command */
96 
97 /*+----------------------------------------------------------------------------+*/
98 /*| Function Name : int i_AddiHeaderRW_ReadEeprom |*/
99 /*| (int i_NbOfWordsToRead, |*/
100 /*| unsigned int dw_PCIBoardEepromAddress, |*/
101 /*| unsigned short w_EepromStartAddress, |*/
102 /*| unsigned short * pw_DataRead) |*/
103 /*+----------------------------------------------------------------------------+*/
104 /*| Task : Read word from the 5920 eeprom. |*/
105 /*+----------------------------------------------------------------------------+*/
106 /*| Input Parameters : int i_NbOfWordsToRead : Nbr. of word to read |*/
107 /*| unsigned int dw_PCIBoardEepromAddress : Address of the eeprom |*/
108 /*| unsigned short w_EepromStartAddress : Eeprom start address |*/
109 /*+----------------------------------------------------------------------------+*/
110 /*| Output Parameters : unsigned short * pw_DataRead : Read data |*/
111 /*+----------------------------------------------------------------------------+*/
112 /*| Return Value : - |*/
113 /*+----------------------------------------------------------------------------+*/
114 
115 int i_AddiHeaderRW_ReadEeprom(int i_NbOfWordsToRead,
116  unsigned int dw_PCIBoardEepromAddress,
117  unsigned short w_EepromStartAddress, unsigned short *pw_DataRead)
118 {
119  unsigned int dw_eeprom_busy = 0;
120  int i_Counter = 0;
121  int i_WordCounter;
122  int i;
123  unsigned char pb_ReadByte[1];
124  unsigned char b_ReadLowByte = 0;
125  unsigned char b_ReadHighByte = 0;
126  unsigned char b_SelectedAddressLow = 0;
127  unsigned char b_SelectedAddressHigh = 0;
128  unsigned short w_ReadWord = 0;
129 
130  for (i_WordCounter = 0; i_WordCounter < i_NbOfWordsToRead;
131  i_WordCounter++) {
132  do {
133  dw_eeprom_busy =
134  inl(dw_PCIBoardEepromAddress +
136  dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
137  } while (dw_eeprom_busy == EEPROM_BUSY);
138 
139  for (i_Counter = 0; i_Counter < 2; i_Counter++) {
140  b_SelectedAddressLow = (w_EepromStartAddress + i_Counter) % 256; /* Read the low 8 bit part */
141  b_SelectedAddressHigh = (w_EepromStartAddress + i_Counter) / 256; /* Read the high 8 bit part */
142 
143  /* Select the load low address mode */
145  dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
146  3);
147 
148  /* Wait on busy */
149  do {
150  dw_eeprom_busy =
151  inl(dw_PCIBoardEepromAddress +
153  dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
154  } while (dw_eeprom_busy == EEPROM_BUSY);
155 
156  /* Load the low address */
157  outb(b_SelectedAddressLow,
158  dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
159  2);
160 
161  /* Wait on busy */
162  do {
163  dw_eeprom_busy =
164  inl(dw_PCIBoardEepromAddress +
166  dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
167  } while (dw_eeprom_busy == EEPROM_BUSY);
168 
169  /* Select the load high address mode */
171  dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
172  3);
173 
174  /* Wait on busy */
175  do {
176  dw_eeprom_busy =
177  inl(dw_PCIBoardEepromAddress +
179  dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
180  } while (dw_eeprom_busy == EEPROM_BUSY);
181 
182  /* Load the high address */
183  outb(b_SelectedAddressHigh,
184  dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
185  2);
186 
187  /* Wait on busy */
188  do {
189  dw_eeprom_busy =
190  inl(dw_PCIBoardEepromAddress +
192  dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
193  } while (dw_eeprom_busy == EEPROM_BUSY);
194 
195  /* Select the READ mode */
197  dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
198  3);
199 
200  /* Wait on busy */
201  do {
202  dw_eeprom_busy =
203  inl(dw_PCIBoardEepromAddress +
205  dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
206  } while (dw_eeprom_busy == EEPROM_BUSY);
207 
208  /* Read data into the EEPROM */
209  *pb_ReadByte =
210  inb(dw_PCIBoardEepromAddress +
211  AMCC_OP_REG_MCSR + 2);
212 
213  /* Wait on busy */
214  do {
215  dw_eeprom_busy =
216  inl(dw_PCIBoardEepromAddress +
218  dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
219  } while (dw_eeprom_busy == EEPROM_BUSY);
220 
221  /* Select the upper address part */
222  if (i_Counter == 0)
223  b_ReadLowByte = pb_ReadByte[0];
224  else
225  b_ReadHighByte = pb_ReadByte[0];
226 
227 
228  /* Sleep */
229  msleep(1);
230 
231  }
232  w_ReadWord =
233  (b_ReadLowByte | (((unsigned short)b_ReadHighByte) *
234  256));
235 
236  pw_DataRead[i_WordCounter] = w_ReadWord;
237 
238  w_EepromStartAddress += 2; /* to read the next word */
239 
240  } /* for (...) i_NbOfWordsToRead */
241  return 0;
242 }
243 
244 /*+----------------------------------------------------------------------------+*/
245 /*| Function Name : void v_GetAPCI3200EepromCalibrationValue (void) |*/
246 /*+----------------------------------------------------------------------------+*/
247 /*| Task : Read calibration value from the APCI-3200 eeprom. |*/
248 /*+----------------------------------------------------------------------------+*/
249 /*| Input Parameters : - |*/
250 /*+----------------------------------------------------------------------------+*/
251 /*| Output Parameters : - |*/
252 /*+----------------------------------------------------------------------------+*/
253 /*| Return Value : - |*/
254 /*+----------------------------------------------------------------------------+*/
255 
256 void v_GetAPCI3200EepromCalibrationValue(unsigned int dw_PCIBoardEepromAddress,
257  struct str_BoardInfos *BoardInformations)
258 {
259  unsigned short w_AnalogInputMainHeaderAddress;
260  unsigned short w_AnalogInputComponentAddress;
261  unsigned short w_NumberOfModuls = 0;
262  unsigned short w_CurrentSources[2];
263  unsigned short w_ModulCounter = 0;
264  unsigned short w_FirstHeaderSize = 0;
265  unsigned short w_NumberOfInputs = 0;
266  unsigned short w_CJCFlag = 0;
267  unsigned short w_NumberOfGainValue = 0;
268  unsigned short w_SingleHeaderAddress = 0;
269  unsigned short w_SingleHeaderSize = 0;
270  unsigned short w_Input = 0;
271  unsigned short w_GainFactorAddress = 0;
272  unsigned short w_GainFactorValue[2];
273  unsigned short w_GainIndex = 0;
274  unsigned short w_GainValue = 0;
275 
276  /*****************************************/
278  /*****************************************/
279  i_AddiHeaderRW_ReadEeprom(1, /* i_NbOfWordsToRead */
280  dw_PCIBoardEepromAddress, 0x116, /* w_EepromStartAddress: Analog input header address */
281  &w_AnalogInputMainHeaderAddress);
282 
283  /*******************************************/
285  /*******************************************/
286  w_AnalogInputMainHeaderAddress = w_AnalogInputMainHeaderAddress + 0x100;
287 
288  /******************************/
290  /******************************/
291  i_AddiHeaderRW_ReadEeprom(1, /* i_NbOfWordsToRead */
292  dw_PCIBoardEepromAddress, w_AnalogInputMainHeaderAddress + 0x02, /* w_EepromStartAddress: Number of conponment */
293  &w_NumberOfModuls);
294 
295  for (w_ModulCounter = 0; w_ModulCounter < w_NumberOfModuls;
296  w_ModulCounter++) {
297  /***********************************/
299  /***********************************/
300  w_AnalogInputComponentAddress =
301  w_AnalogInputMainHeaderAddress +
302  (w_FirstHeaderSize * w_ModulCounter) + 0x04;
303 
304  /****************************/
306  /****************************/
307  i_AddiHeaderRW_ReadEeprom(1, /* i_NbOfWordsToRead */
308  dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress, /* Address of the first header */
309  &w_FirstHeaderSize);
310 
311  w_FirstHeaderSize = w_FirstHeaderSize >> 4;
312 
313  /***************************/
315  /***************************/
316  i_AddiHeaderRW_ReadEeprom(1, /* i_NbOfWordsToRead */
317  dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 0x06, /* Number of inputs for the first modul */
318  &w_NumberOfInputs);
319 
320  w_NumberOfInputs = w_NumberOfInputs >> 4;
321 
322  /***********************/
324  /***********************/
325  i_AddiHeaderRW_ReadEeprom(1, /* i_NbOfWordsToRead */
326  dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 0x08, /* CJC flag */
327  &w_CJCFlag);
328 
329  w_CJCFlag = (w_CJCFlag >> 3) & 0x1; /* Get only the CJC flag */
330 
331  /*******************************/
333  /*******************************/
334  i_AddiHeaderRW_ReadEeprom(1, /* i_NbOfWordsToRead */
335  dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 0x44, /* Number of gain value */
336  &w_NumberOfGainValue);
337 
338  w_NumberOfGainValue = w_NumberOfGainValue & 0xFF;
339 
340  /***********************************/
342  /***********************************/
343  w_SingleHeaderAddress =
344  w_AnalogInputComponentAddress + 0x46 +
345  (((w_NumberOfGainValue / 16) + 1) * 2) +
346  (6 * w_NumberOfGainValue) +
347  (4 * (((w_NumberOfGainValue / 16) + 1) * 2));
348 
349  /********************************************/
351  /********************************************/
352  i_AddiHeaderRW_ReadEeprom(1, /* i_NbOfWordsToRead */
353  dw_PCIBoardEepromAddress, w_SingleHeaderAddress, /* w_EepromStartAddress: Single header address */
354  &w_SingleHeaderSize);
355 
356  w_SingleHeaderSize = w_SingleHeaderSize >> 4;
357 
358  /*************************************/
360  /*************************************/
361  w_GainFactorAddress = w_AnalogInputComponentAddress;
362 
363  for (w_GainIndex = 0; w_GainIndex < w_NumberOfGainValue;
364  w_GainIndex++) {
365  /************************************/
367  /************************************/
368  i_AddiHeaderRW_ReadEeprom(1, /* i_NbOfWordsToRead */
369  dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 70 + (2 * (1 + (w_NumberOfGainValue / 16))) + (0x02 * w_GainIndex), /* Gain value */
370  &w_GainValue);
371 
372  BoardInformations->s_Module[w_ModulCounter].
373  w_GainValue[w_GainIndex] = w_GainValue;
374 
375 # ifdef PRINT_INFO
376  printk("\n Gain value = %d",
377  BoardInformations->s_Module[w_ModulCounter].
378  w_GainValue[w_GainIndex]);
379 # endif
380 
381  /*************************************/
383  /*************************************/
384  i_AddiHeaderRW_ReadEeprom(2, /* i_NbOfWordsToRead */
385  dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 70 + ((2 * w_NumberOfGainValue) + (2 * (1 + (w_NumberOfGainValue / 16)))) + (0x04 * w_GainIndex), /* Gain factor */
386  w_GainFactorValue);
387 
388  BoardInformations->s_Module[w_ModulCounter].
389  ul_GainFactor[w_GainIndex] =
390  (w_GainFactorValue[1] << 16) +
391  w_GainFactorValue[0];
392 
393 # ifdef PRINT_INFO
394  printk("\n w_GainFactorValue [%d] = %lu", w_GainIndex,
395  BoardInformations->s_Module[w_ModulCounter].
396  ul_GainFactor[w_GainIndex]);
397 # endif
398  }
399 
400  /***************************************************************/
402  /***************************************************************/
403  for (w_Input = 0; w_Input < w_NumberOfInputs; w_Input++) {
404  /********************************************/
406  /********************************************/
407  i_AddiHeaderRW_ReadEeprom(2, /* i_NbOfWordsToRead */
408  dw_PCIBoardEepromAddress,
409  (w_Input * w_SingleHeaderSize) +
410  w_SingleHeaderAddress + 0x0C, w_CurrentSources);
411 
412  /************************************/
414  /************************************/
415  BoardInformations->s_Module[w_ModulCounter].
416  ul_CurrentSource[w_Input] =
417  (w_CurrentSources[0] +
418  ((w_CurrentSources[1] & 0xFFF) << 16));
419 
420 # ifdef PRINT_INFO
421  printk("\n Current sources [%d] = %lu", w_Input,
422  BoardInformations->s_Module[w_ModulCounter].
423  ul_CurrentSource[w_Input]);
424 # endif
425  }
426 
427  /***************************************/
429  /***************************************/
430  i_AddiHeaderRW_ReadEeprom(2, /* i_NbOfWordsToRead */
431  dw_PCIBoardEepromAddress,
432  (w_Input * w_SingleHeaderSize) + w_SingleHeaderAddress +
433  0x0C, w_CurrentSources);
434 
435  /************************************/
437  /************************************/
438  BoardInformations->s_Module[w_ModulCounter].
439  ul_CurrentSourceCJC =
440  (w_CurrentSources[0] +
441  ((w_CurrentSources[1] & 0xFFF) << 16));
442 
443 # ifdef PRINT_INFO
444  printk("\n Current sources CJC = %lu",
445  BoardInformations->s_Module[w_ModulCounter].
446  ul_CurrentSourceCJC);
447 # endif
448  }
449 }
450 
452  unsigned int ui_Channel_num, unsigned int *CJCCurrentSource,
453  unsigned int *ChannelCurrentSource, unsigned int *ChannelGainFactor)
454 {
455  int i_DiffChannel = 0;
456  int i_Module = 0;
457 
458 #ifdef PRINT_INFO
459  printk("\n Channel = %u", ui_Channel_num);
460 #endif
461 
462  /* Test if single or differential mode */
463  if (s_BoardInfos[dev->minor].i_ConnectionType == 1) {
464  /* if diff */
465 
466  if (ui_Channel_num <= 1)
467  i_DiffChannel = ui_Channel_num, i_Module = 0;
468  else if ((ui_Channel_num >= 2) && (ui_Channel_num <= 3))
469  i_DiffChannel = ui_Channel_num - 2, i_Module = 1;
470  else if ((ui_Channel_num >= 4) && (ui_Channel_num <= 5))
471  i_DiffChannel = ui_Channel_num - 4, i_Module = 2;
472  else if ((ui_Channel_num >= 6) && (ui_Channel_num <= 7))
473  i_DiffChannel = ui_Channel_num - 6, i_Module = 3;
474 
475  } else {
476  /* if single */
477  if ((ui_Channel_num == 0) || (ui_Channel_num == 1))
478  i_DiffChannel = 0, i_Module = 0;
479  else if ((ui_Channel_num == 2) || (ui_Channel_num == 3))
480  i_DiffChannel = 1, i_Module = 0;
481  else if ((ui_Channel_num == 4) || (ui_Channel_num == 5))
482  i_DiffChannel = 0, i_Module = 1;
483  else if ((ui_Channel_num == 6) || (ui_Channel_num == 7))
484  i_DiffChannel = 1, i_Module = 1;
485  else if ((ui_Channel_num == 8) || (ui_Channel_num == 9))
486  i_DiffChannel = 0, i_Module = 2;
487  else if ((ui_Channel_num == 10) || (ui_Channel_num == 11))
488  i_DiffChannel = 1, i_Module = 2;
489  else if ((ui_Channel_num == 12) || (ui_Channel_num == 13))
490  i_DiffChannel = 0, i_Module = 3;
491  else if ((ui_Channel_num == 14) || (ui_Channel_num == 15))
492  i_DiffChannel = 1, i_Module = 3;
493  }
494 
495  /* Test if thermocouple or RTD mode */
496  *CJCCurrentSource =
497  s_BoardInfos[dev->minor].s_Module[i_Module].ul_CurrentSourceCJC;
498 #ifdef PRINT_INFO
499  printk("\n CJCCurrentSource = %lu", *CJCCurrentSource);
500 #endif
501 
502  *ChannelCurrentSource =
503  s_BoardInfos[dev->minor].s_Module[i_Module].
504  ul_CurrentSource[i_DiffChannel];
505 #ifdef PRINT_INFO
506  printk("\n ChannelCurrentSource = %lu", *ChannelCurrentSource);
507 #endif
508  /* } */
509  /* } */
510 
511  /* Channle gain factor */
512  *ChannelGainFactor =
513  s_BoardInfos[dev->minor].s_Module[i_Module].
514  ul_GainFactor[s_BoardInfos[dev->minor].i_ADDIDATAGain];
515 #ifdef PRINT_INFO
516  printk("\n ChannelGainFactor = %lu", *ChannelGainFactor);
517 #endif
518  /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
519 
520  return 0;
521 }
522 
523 /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
524 
525 /*
526  +----------------------------------------------------------------------------+
527  | Function Name : int i_APCI3200_ReadDigitalInput |
528  | (struct comedi_device *dev,struct comedi_subdevice *s, |
529  | struct comedi_insn *insn,unsigned int *data) |
530  +----------------------------------------------------------------------------+
531  | Task : Read value of the selected channel or port |
532  +----------------------------------------------------------------------------+
533  | Input Parameters : struct comedi_device *dev : Driver handle |
534  | unsigned int ui_NoOfChannels : No Of Channels To read for Port
535  Channel Numberfor single channel
536  | unsigned int data[0] : 0: Read single channel
537  1: Read port value
538  data[1] Port number
539  +----------------------------------------------------------------------------+
540  | Output Parameters : -- data[0] :Read status value
541  +----------------------------------------------------------------------------+
542  | Return Value : TRUE : No error occur |
543  | : FALSE : Error occur. Return the error |
544  | |
545  +----------------------------------------------------------------------------+
546 */
547 
549  struct comedi_insn *insn, unsigned int *data)
550 {
551  unsigned int ui_Temp = 0;
552  unsigned int ui_NoOfChannel = 0;
553  ui_NoOfChannel = CR_CHAN(insn->chanspec);
554  ui_Temp = data[0];
555  *data = inl(devpriv->i_IobaseReserved);
556 
557  if (ui_Temp == 0) {
558  *data = (*data >> ui_NoOfChannel) & 0x1;
559  } /* if (ui_Temp==0) */
560  else {
561  if (ui_Temp == 1) {
562  if (data[1] < 0 || data[1] > 1) {
563  printk("\nThe port number is in error\n");
564  return -EINVAL;
565  } /* if(data[1] < 0 || data[1] >1) */
566  switch (ui_NoOfChannel) {
567 
568  case 2:
569  *data = (*data >> (2 * data[1])) & 0x3;
570  break;
571  case 3:
572  *data = (*data & 15);
573  break;
574  default:
575  comedi_error(dev, " chan spec wrong");
576  return -EINVAL; /* "sorry channel spec wrong " */
577 
578  } /* switch(ui_NoOfChannels) */
579  } /* if (ui_Temp==1) */
580  else {
581  printk("\nSpecified channel not supported \n");
582  } /* elseif (ui_Temp==1) */
583  }
584  return insn->n;
585 }
586 
587 /*
588  +----------------------------------------------------------------------------+
589  | Function Name : int i_APCI3200_ConfigDigitalOutput |
590  | (struct comedi_device *dev,struct comedi_subdevice *s, |
591  | struct comedi_insn *insn,unsigned int *data) |
592  +----------------------------------------------------------------------------+
593  | Task : Configures The Digital Output Subdevice. |
594  +----------------------------------------------------------------------------+
595  | Input Parameters : struct comedi_device *dev : Driver handle |
596  | data[0] :1 Memory enable
597  0 Memory Disable
598  +----------------------------------------------------------------------------+
599  | Output Parameters : -- |
600  +----------------------------------------------------------------------------+
601  | Return Value : TRUE : No error occur |
602  | : FALSE : Error occur. Return the error |
603  | |
604  +----------------------------------------------------------------------------+
605 */
607  struct comedi_insn *insn, unsigned int *data)
608 {
609 
610  if ((data[0] != 0) && (data[0] != 1)) {
611  comedi_error(dev,
612  "Not a valid Data !!! ,Data should be 1 or 0\n");
613  return -EINVAL;
614  } /* if ( (data[0]!=0) && (data[0]!=1) ) */
615  if (data[0]) {
616  devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
617  } /* if (data[0]) */
618  else {
619  devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
620  } /* else if (data[0]) */
621  return insn->n;
622 }
623 
624 /*
625  +----------------------------------------------------------------------------+
626  | Function Name : int i_APCI3200_WriteDigitalOutput |
627  | (struct comedi_device *dev,struct comedi_subdevice *s, |
628  | struct comedi_insn *insn,unsigned int *data) |
629  +----------------------------------------------------------------------------+
630  | Task : writes To the digital Output Subdevice |
631  +----------------------------------------------------------------------------+
632  | Input Parameters : struct comedi_device *dev : Driver handle |
633  | struct comedi_subdevice *s : Subdevice Pointer |
634  | struct comedi_insn *insn : Insn Structure Pointer |
635  | unsigned int *data : Data Pointer contains |
636  | configuration parameters as below |
637  | data[0] :Value to output
638  data[1] : 0 o/p single channel
639  1 o/p port
640  data[2] : port no
641  data[3] :0 set the digital o/p on
642  1 set the digital o/p off
643  +----------------------------------------------------------------------------+
644  | Output Parameters : -- |
645  +----------------------------------------------------------------------------+
646  | Return Value : TRUE : No error occur |
647  | : FALSE : Error occur. Return the error |
648  | |
649  +----------------------------------------------------------------------------+
650 */
652  struct comedi_insn *insn, unsigned int *data)
653 {
654  unsigned int ui_Temp = 0, ui_Temp1 = 0;
655  unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */
656  if (devpriv->b_OutputMemoryStatus) {
657  ui_Temp = inl(devpriv->i_IobaseAddon);
658 
659  } /* if(devpriv->b_OutputMemoryStatus ) */
660  else {
661  ui_Temp = 0;
662  } /* if(devpriv->b_OutputMemoryStatus ) */
663  if (data[3] == 0) {
664  if (data[1] == 0) {
665  data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
666  outl(data[0], devpriv->i_IobaseAddon);
667  } /* if(data[1]==0) */
668  else {
669  if (data[1] == 1) {
670  switch (ui_NoOfChannel) {
671 
672  case 2:
673  data[0] =
674  (data[0] << (2 *
675  data[2])) | ui_Temp;
676  break;
677  case 3:
678  data[0] = (data[0] | ui_Temp);
679  break;
680  } /* switch(ui_NoOfChannels) */
681 
682  outl(data[0], devpriv->i_IobaseAddon);
683  } /* if(data[1]==1) */
684  else {
685  printk("\nSpecified channel not supported\n");
686  } /* else if(data[1]==1) */
687  } /* elseif(data[1]==0) */
688  } /* if(data[3]==0) */
689  else {
690  if (data[3] == 1) {
691  if (data[1] == 0) {
692  data[0] = ~data[0] & 0x1;
693  ui_Temp1 = 1;
694  ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
695  ui_Temp = ui_Temp | ui_Temp1;
696  data[0] = (data[0] << ui_NoOfChannel) ^ 0xf;
697  data[0] = data[0] & ui_Temp;
698  outl(data[0], devpriv->i_IobaseAddon);
699  } /* if(data[1]==0) */
700  else {
701  if (data[1] == 1) {
702  switch (ui_NoOfChannel) {
703 
704  case 2:
705  data[0] = ~data[0] & 0x3;
706  ui_Temp1 = 3;
707  ui_Temp1 =
708  ui_Temp1 << 2 * data[2];
709  ui_Temp = ui_Temp | ui_Temp1;
710  data[0] =
711  ((data[0] << (2 *
712  data
713  [2])) ^
714  0xf) & ui_Temp;
715 
716  break;
717  case 3:
718  break;
719 
720  default:
721  comedi_error(dev,
722  " chan spec wrong");
723  return -EINVAL; /* "sorry channel spec wrong " */
724  } /* switch(ui_NoOfChannels) */
725 
726  outl(data[0], devpriv->i_IobaseAddon);
727  } /* if(data[1]==1) */
728  else {
729  printk("\nSpecified channel not supported\n");
730  } /* else if(data[1]==1) */
731  } /* elseif(data[1]==0) */
732  } /* if(data[3]==1); */
733  else {
734  printk("\nSpecified functionality does not exist\n");
735  return -EINVAL;
736  } /* if else data[3]==1) */
737  } /* if else data[3]==0) */
738  return insn->n;
739 }
740 
741 /*
742  +----------------------------------------------------------------------------+
743  | Function Name : int i_APCI3200_ReadDigitalOutput |
744  | (struct comedi_device *dev,struct comedi_subdevice *s, |
745  | struct comedi_insn *insn,unsigned int *data) |
746  +----------------------------------------------------------------------------+
747  | Task : Read value of the selected channel or port |
748  +----------------------------------------------------------------------------+
749  | Input Parameters : struct comedi_device *dev : Driver handle |
750  | unsigned int ui_NoOfChannels : No Of Channels To read |
751  | unsigned int *data : Data Pointer to read status |
752  data[0] :0 read single channel
753  1 read port value
754  data[1] port no
755 
756  +----------------------------------------------------------------------------+
757  | Output Parameters : -- |
758  +----------------------------------------------------------------------------+
759  | Return Value : TRUE : No error occur |
760  | : FALSE : Error occur. Return the error |
761  | |
762  +----------------------------------------------------------------------------+
763 */
765  struct comedi_insn *insn, unsigned int *data)
766 {
767  unsigned int ui_Temp;
768  unsigned int ui_NoOfChannel;
769  ui_NoOfChannel = CR_CHAN(insn->chanspec);
770  ui_Temp = data[0];
771  *data = inl(devpriv->i_IobaseAddon);
772  if (ui_Temp == 0) {
773  *data = (*data >> ui_NoOfChannel) & 0x1;
774  } /* if (ui_Temp==0) */
775  else {
776  if (ui_Temp == 1) {
777  if (data[1] < 0 || data[1] > 1) {
778  printk("\nThe port selection is in error\n");
779  return -EINVAL;
780  } /* if(data[1] <0 ||data[1] >1) */
781  switch (ui_NoOfChannel) {
782  case 2:
783  *data = (*data >> (2 * data[1])) & 3;
784  break;
785 
786  case 3:
787  break;
788 
789  default:
790  comedi_error(dev, " chan spec wrong");
791  return -EINVAL; /* "sorry channel spec wrong " */
792  break;
793  } /* switch(ui_NoOfChannels) */
794  } /* if (ui_Temp==1) */
795  else {
796  printk("\nSpecified channel not supported \n");
797  } /* else if (ui_Temp==1) */
798  } /* else if (ui_Temp==0) */
799  return insn->n;
800 }
801 
802 /*
803  +----------------------------------------------------------------------------+
804  | Function Name : int i_APCI3200_ConfigAnalogInput |
805  | (struct comedi_device *dev,struct comedi_subdevice *s, |
806  | struct comedi_insn *insn,unsigned int *data) |
807  +----------------------------------------------------------------------------+
808  | Task : Configures The Analog Input Subdevice |
809  +----------------------------------------------------------------------------+
810  | Input Parameters : struct comedi_device *dev : Driver handle |
811  | struct comedi_subdevice *s : Subdevice Pointer |
812  | struct comedi_insn *insn : Insn Structure Pointer |
813  | unsigned int *data : Data Pointer contains |
814  | configuration parameters as below |
815  | |
816  | data[0]
817  | 0:Normal AI |
818  | 1:RTD |
819  | 2:THERMOCOUPLE |
820  | data[1] : Gain To Use |
821  | |
822  | data[2] : Polarity
823  | 0:Bipolar |
824  | 1:Unipolar |
825  | |
826  | data[3] : Offset Range
827  | |
828  | data[4] : Coupling
829  | 0:DC Coupling |
830  | 1:AC Coupling |
831  | |
832  | data[5] :Differential/Single
833  | 0:Single |
834  | 1:Differential |
835  | |
836  | data[6] :TimerReloadValue
837  | |
838  | data[7] :ConvertingTimeUnit
839  | |
840  | data[8] :0 Analog voltage measurement
841  1 Resistance measurement
842  2 Temperature measurement
843  | data[9] :Interrupt
844  | 0:Disable
845  | 1:Enable
846  data[10] :Type of Thermocouple
847  | data[11] : 0: single channel
848  Module Number
849  |
850  | data[12]
851  | 0:Single Read
852  | 1:Read more channel
853  2:Single scan
854  | 3:Continuous Scan
855  data[13] :Number of channels to read
856  | data[14] :RTD connection type
857  :0:RTD not used
858  1:RTD 2 wire connection
859  2:RTD 3 wire connection
860  3:RTD 4 wire connection
861  | |
862  | |
863  | |
864  +----------------------------------------------------------------------------+
865  | Output Parameters : -- |
866  +----------------------------------------------------------------------------+
867  | Return Value : TRUE : No error occur |
868  | : FALSE : Error occur. Return the error |
869  | |
870  +----------------------------------------------------------------------------+
871 */
873  struct comedi_insn *insn, unsigned int *data)
874 {
875 
876  unsigned int ul_Config = 0, ul_Temp = 0;
877  unsigned int ui_ChannelNo = 0;
878  unsigned int ui_Dummy = 0;
879  int i_err = 0;
880 
881  /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
882 
883 #ifdef PRINT_INFO
884  int i = 0, i2 = 0;
885 #endif
886  /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
887 
888  /* BEGIN JK 06.07.04: Management of sevrals boards */
889  /* Initialize the structure */
890  if (s_BoardInfos[dev->minor].b_StructInitialized != 1) {
891  s_BoardInfos[dev->minor].i_CJCAvailable = 1;
892  s_BoardInfos[dev->minor].i_CJCPolarity = 0;
893  s_BoardInfos[dev->minor].i_CJCGain = 2; /* changed from 0 to 2 */
894  s_BoardInfos[dev->minor].i_InterruptFlag = 0;
895  s_BoardInfos[dev->minor].i_AutoCalibration = 0; /* : auto calibration */
896  s_BoardInfos[dev->minor].i_ChannelCount = 0;
897  s_BoardInfos[dev->minor].i_Sum = 0;
898  s_BoardInfos[dev->minor].ui_Channel_num = 0;
899  s_BoardInfos[dev->minor].i_Count = 0;
900  s_BoardInfos[dev->minor].i_Initialised = 0;
901  s_BoardInfos[dev->minor].b_StructInitialized = 1;
902 
903  /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
904  s_BoardInfos[dev->minor].i_ConnectionType = 0;
905  /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
906 
907  /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
908  memset(s_BoardInfos[dev->minor].s_Module, 0,
909  sizeof(s_BoardInfos[dev->minor].s_Module[MAX_MODULE]));
910 
912  &s_BoardInfos[dev->minor]);
913 
914 #ifdef PRINT_INFO
915  for (i = 0; i < MAX_MODULE; i++) {
916  printk("\n s_Module[%i].ul_CurrentSourceCJC = %lu", i,
917  s_BoardInfos[dev->minor].s_Module[i].
918  ul_CurrentSourceCJC);
919 
920  for (i2 = 0; i2 < 5; i2++) {
921  printk("\n s_Module[%i].ul_CurrentSource [%i] = %lu", i, i2, s_BoardInfos[dev->minor].s_Module[i].ul_CurrentSource[i2]);
922  }
923 
924  for (i2 = 0; i2 < 8; i2++) {
925  printk("\n s_Module[%i].ul_GainFactor [%i] = %lu", i, i2, s_BoardInfos[dev->minor].s_Module[i].ul_GainFactor[i2]);
926  }
927 
928  for (i2 = 0; i2 < 8; i2++) {
929  printk("\n s_Module[%i].w_GainValue [%i] = %u",
930  i, i2,
931  s_BoardInfos[dev->minor].s_Module[i].
932  w_GainValue[i2]);
933  }
934  }
935 #endif
936  /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
937  }
938 
939  if (data[0] != 0 && data[0] != 1 && data[0] != 2) {
940  printk("\nThe selection of acquisition type is in error\n");
941  i_err++;
942  } /* if(data[0]!=0 && data[0]!=1 && data[0]!=2) */
943  if (data[0] == 1) {
944  if (data[14] != 0 && data[14] != 1 && data[14] != 2
945  && data[14] != 4) {
946  printk("\n Error in selection of RTD connection type\n");
947  i_err++;
948  } /* if(data[14]!=0 && data[14]!=1 && data[14]!=2 && data[14]!=4) */
949  } /* if(data[0]==1 ) */
950  if (data[1] < 0 || data[1] > 7) {
951  printk("\nThe selection of gain is in error\n");
952  i_err++;
953  } /* if(data[1]<0 || data[1]>7) */
954  if (data[2] != 0 && data[2] != 1) {
955  printk("\nThe selection of polarity is in error\n");
956  i_err++;
957  } /* if(data[2]!=0 && data[2]!=1) */
958  if (data[3] != 0) {
959  printk("\nThe selection of offset range is in error\n");
960  i_err++;
961  } /* if(data[3]!=0) */
962  if (data[4] != 0 && data[4] != 1) {
963  printk("\nThe selection of coupling is in error\n");
964  i_err++;
965  } /* if(data[4]!=0 && data[4]!=1) */
966  if (data[5] != 0 && data[5] != 1) {
967  printk("\nThe selection of single/differential mode is in error\n");
968  i_err++;
969  } /* if(data[5]!=0 && data[5]!=1) */
970  if (data[8] != 0 && data[8] != 1 && data[2] != 2) {
971  printk("\nError in selection of functionality\n");
972  } /* if(data[8]!=0 && data[8]!=1 && data[2]!=2) */
973  if (data[12] == 0 || data[12] == 1) {
974  if (data[6] != 20 && data[6] != 40 && data[6] != 80
975  && data[6] != 160) {
976  printk("\nThe selection of conversion time reload value is in error\n");
977  i_err++;
978  } /* if (data[6]!=20 && data[6]!=40 && data[6]!=80 && data[6]!=160 ) */
979  if (data[7] != 2) {
980  printk("\nThe selection of conversion time unit is in error\n");
981  i_err++;
982  } /* if(data[7]!=2) */
983  }
984  if (data[9] != 0 && data[9] != 1) {
985  printk("\nThe selection of interrupt enable is in error\n");
986  i_err++;
987  } /* if(data[9]!=0 && data[9]!=1) */
988  if (data[11] < 0 || data[11] > 4) {
989  printk("\nThe selection of module is in error\n");
990  i_err++;
991  } /* if(data[11] <0 || data[11]>1) */
992  if (data[12] < 0 || data[12] > 3) {
993  printk("\nThe selection of singlechannel/scan selection is in error\n");
994  i_err++;
995  } /* if(data[12] < 0 || data[12]> 3) */
996  if (data[13] < 0 || data[13] > 16) {
997  printk("\nThe selection of number of channels is in error\n");
998  i_err++;
999  } /* if(data[13] <0 ||data[13] >15) */
1000 
1001  /* BEGIN JK 06.07.04: Management of sevrals boards */
1002  /*
1003  i_ChannelCount=data[13];
1004  i_ScanType=data[12];
1005  i_ADDIDATAPolarity = data[2];
1006  i_ADDIDATAGain=data[1];
1007  i_ADDIDATAConversionTime=data[6];
1008  i_ADDIDATAConversionTimeUnit=data[7];
1009  i_ADDIDATAType=data[0];
1010  */
1011 
1012  /* Save acquisition configuration for the actual board */
1013  s_BoardInfos[dev->minor].i_ChannelCount = data[13];
1014  s_BoardInfos[dev->minor].i_ScanType = data[12];
1015  s_BoardInfos[dev->minor].i_ADDIDATAPolarity = data[2];
1016  s_BoardInfos[dev->minor].i_ADDIDATAGain = data[1];
1017  s_BoardInfos[dev->minor].i_ADDIDATAConversionTime = data[6];
1018  s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit = data[7];
1019  s_BoardInfos[dev->minor].i_ADDIDATAType = data[0];
1020  /* Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
1021  s_BoardInfos[dev->minor].i_ConnectionType = data[5];
1022  /* End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
1023  /* END JK 06.07.04: Management of sevrals boards */
1024 
1025  /* Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
1026  memset(s_BoardInfos[dev->minor].ui_ScanValueArray, 0, (7 + 12) * sizeof(unsigned int)); /* 7 is the maximal number of channels */
1027  /* End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
1028 
1029  /* BEGIN JK 02.07.04 : This while can't be do, it block the process when using severals boards */
1030  /* while(i_InterruptFlag==1) */
1031  while (s_BoardInfos[dev->minor].i_InterruptFlag == 1) {
1032 #ifndef MSXBOX
1033  udelay(1);
1034 #else
1035  /* In the case where the driver is compiled for the MSX-Box */
1036  /* we used a printk to have a little delay because udelay */
1037  /* seems to be broken under the MSX-Box. */
1038  /* This solution hat to be studied. */
1039  printk("");
1040 #endif
1041  }
1042  /* END JK 02.07.04 : This while can't be do, it block the process when using severals boards */
1043 
1044  ui_ChannelNo = CR_CHAN(insn->chanspec); /* get the channel */
1045  /* BEGIN JK 06.07.04: Management of sevrals boards */
1046  /* i_ChannelNo=ui_ChannelNo; */
1047  /* ui_Channel_num =ui_ChannelNo; */
1048 
1049  s_BoardInfos[dev->minor].i_ChannelNo = ui_ChannelNo;
1050  s_BoardInfos[dev->minor].ui_Channel_num = ui_ChannelNo;
1051 
1052  /* END JK 06.07.04: Management of sevrals boards */
1053 
1054  if (data[5] == 0) {
1055  if (ui_ChannelNo < 0 || ui_ChannelNo > 15) {
1056  printk("\nThe Selection of the channel is in error\n");
1057  i_err++;
1058  } /* if(ui_ChannelNo<0 || ui_ChannelNo>15) */
1059  } /* if(data[5]==0) */
1060  else {
1061  if (data[14] == 2) {
1062  if (ui_ChannelNo < 0 || ui_ChannelNo > 3) {
1063  printk("\nThe Selection of the channel is in error\n");
1064  i_err++;
1065  } /* if(ui_ChannelNo<0 || ui_ChannelNo>3) */
1066  } /* if(data[14]==2) */
1067  else {
1068  if (ui_ChannelNo < 0 || ui_ChannelNo > 7) {
1069  printk("\nThe Selection of the channel is in error\n");
1070  i_err++;
1071  } /* if(ui_ChannelNo<0 || ui_ChannelNo>7) */
1072  } /* elseif(data[14]==2) */
1073  } /* elseif(data[5]==0) */
1074  if (data[12] == 0 || data[12] == 1) {
1075  switch (data[5]) {
1076  case 0:
1077  if (ui_ChannelNo >= 0 && ui_ChannelNo <= 3) {
1078  /* BEGIN JK 06.07.04: Management of sevrals boards */
1079  /* i_Offset=0; */
1080  s_BoardInfos[dev->minor].i_Offset = 0;
1081  /* END JK 06.07.04: Management of sevrals boards */
1082  } /* if(ui_ChannelNo >=0 && ui_ChannelNo <=3) */
1083  if (ui_ChannelNo >= 4 && ui_ChannelNo <= 7) {
1084  /* BEGIN JK 06.07.04: Management of sevrals boards */
1085  /* i_Offset=64; */
1086  s_BoardInfos[dev->minor].i_Offset = 64;
1087  /* END JK 06.07.04: Management of sevrals boards */
1088  } /* if(ui_ChannelNo >=4 && ui_ChannelNo <=7) */
1089  if (ui_ChannelNo >= 8 && ui_ChannelNo <= 11) {
1090  /* BEGIN JK 06.07.04: Management of sevrals boards */
1091  /* i_Offset=128; */
1092  s_BoardInfos[dev->minor].i_Offset = 128;
1093  /* END JK 06.07.04: Management of sevrals boards */
1094  } /* if(ui_ChannelNo >=8 && ui_ChannelNo <=11) */
1095  if (ui_ChannelNo >= 12 && ui_ChannelNo <= 15) {
1096  /* BEGIN JK 06.07.04: Management of sevrals boards */
1097  /* i_Offset=192; */
1098  s_BoardInfos[dev->minor].i_Offset = 192;
1099  /* END JK 06.07.04: Management of sevrals boards */
1100  } /* if(ui_ChannelNo >=12 && ui_ChannelNo <=15) */
1101  break;
1102  case 1:
1103  if (data[14] == 2) {
1104  if (ui_ChannelNo == 0) {
1105  /* BEGIN JK 06.07.04: Management of sevrals boards */
1106  /* i_Offset=0; */
1107  s_BoardInfos[dev->minor].i_Offset = 0;
1108  /* END JK 06.07.04: Management of sevrals boards */
1109  } /* if(ui_ChannelNo ==0 ) */
1110  if (ui_ChannelNo == 1) {
1111  /* BEGIN JK 06.07.04: Management of sevrals boards */
1112  /* i_Offset=0; */
1113  s_BoardInfos[dev->minor].i_Offset = 64;
1114  /* END JK 06.07.04: Management of sevrals boards */
1115  } /* if(ui_ChannelNo ==1) */
1116  if (ui_ChannelNo == 2) {
1117  /* BEGIN JK 06.07.04: Management of sevrals boards */
1118  /* i_Offset=128; */
1119  s_BoardInfos[dev->minor].i_Offset = 128;
1120  /* END JK 06.07.04: Management of sevrals boards */
1121  } /* if(ui_ChannelNo ==2 ) */
1122  if (ui_ChannelNo == 3) {
1123  /* BEGIN JK 06.07.04: Management of sevrals boards */
1124  /* i_Offset=192; */
1125  s_BoardInfos[dev->minor].i_Offset = 192;
1126  /* END JK 06.07.04: Management of sevrals boards */
1127  } /* if(ui_ChannelNo ==3) */
1128 
1129  /* BEGIN JK 06.07.04: Management of sevrals boards */
1130  /* i_ChannelNo=0; */
1131  s_BoardInfos[dev->minor].i_ChannelNo = 0;
1132  /* END JK 06.07.04: Management of sevrals boards */
1133  ui_ChannelNo = 0;
1134  break;
1135  } /* if(data[14]==2) */
1136  if (ui_ChannelNo >= 0 && ui_ChannelNo <= 1) {
1137  /* BEGIN JK 06.07.04: Management of sevrals boards */
1138  /* i_Offset=0; */
1139  s_BoardInfos[dev->minor].i_Offset = 0;
1140  /* END JK 06.07.04: Management of sevrals boards */
1141  } /* if(ui_ChannelNo >=0 && ui_ChannelNo <=1) */
1142  if (ui_ChannelNo >= 2 && ui_ChannelNo <= 3) {
1143  /* BEGIN JK 06.07.04: Management of sevrals boards */
1144  /* i_ChannelNo=i_ChannelNo-2; */
1145  /* i_Offset=64; */
1146  s_BoardInfos[dev->minor].i_ChannelNo =
1147  s_BoardInfos[dev->minor].i_ChannelNo -
1148  2;
1149  s_BoardInfos[dev->minor].i_Offset = 64;
1150  /* END JK 06.07.04: Management of sevrals boards */
1151  ui_ChannelNo = ui_ChannelNo - 2;
1152  } /* if(ui_ChannelNo >=2 && ui_ChannelNo <=3) */
1153  if (ui_ChannelNo >= 4 && ui_ChannelNo <= 5) {
1154  /* BEGIN JK 06.07.04: Management of sevrals boards */
1155  /* i_ChannelNo=i_ChannelNo-4; */
1156  /* i_Offset=128; */
1157  s_BoardInfos[dev->minor].i_ChannelNo =
1158  s_BoardInfos[dev->minor].i_ChannelNo -
1159  4;
1160  s_BoardInfos[dev->minor].i_Offset = 128;
1161  /* END JK 06.07.04: Management of sevrals boards */
1162  ui_ChannelNo = ui_ChannelNo - 4;
1163  } /* if(ui_ChannelNo >=4 && ui_ChannelNo <=5) */
1164  if (ui_ChannelNo >= 6 && ui_ChannelNo <= 7) {
1165  /* BEGIN JK 06.07.04: Management of sevrals boards */
1166  /* i_ChannelNo=i_ChannelNo-6; */
1167  /* i_Offset=192; */
1168  s_BoardInfos[dev->minor].i_ChannelNo =
1169  s_BoardInfos[dev->minor].i_ChannelNo -
1170  6;
1171  s_BoardInfos[dev->minor].i_Offset = 192;
1172  /* END JK 06.07.04: Management of sevrals boards */
1173  ui_ChannelNo = ui_ChannelNo - 6;
1174  } /* if(ui_ChannelNo >=6 && ui_ChannelNo <=7) */
1175  break;
1176 
1177  default:
1178  printk("\n This selection of polarity does not exist\n");
1179  i_err++;
1180  } /* switch(data[2]) */
1181  } /* if(data[12]==0 || data[12]==1) */
1182  else {
1183  switch (data[11]) {
1184  case 1:
1185  /* BEGIN JK 06.07.04: Management of sevrals boards */
1186  /* i_Offset=0; */
1187  s_BoardInfos[dev->minor].i_Offset = 0;
1188  /* END JK 06.07.04: Management of sevrals boards */
1189  break;
1190  case 2:
1191  /* BEGIN JK 06.07.04: Management of sevrals boards */
1192  /* i_Offset=64; */
1193  s_BoardInfos[dev->minor].i_Offset = 64;
1194  /* END JK 06.07.04: Management of sevrals boards */
1195  break;
1196  case 3:
1197  /* BEGIN JK 06.07.04: Management of sevrals boards */
1198  /* i_Offset=128; */
1199  s_BoardInfos[dev->minor].i_Offset = 128;
1200  /* END JK 06.07.04: Management of sevrals boards */
1201  break;
1202  case 4:
1203  /* BEGIN JK 06.07.04: Management of sevrals boards */
1204  /* i_Offset=192; */
1205  s_BoardInfos[dev->minor].i_Offset = 192;
1206  /* END JK 06.07.04: Management of sevrals boards */
1207  break;
1208  default:
1209  printk("\nError in module selection\n");
1210  i_err++;
1211  } /* switch(data[11]) */
1212  } /* elseif(data[12]==0 || data[12]==1) */
1213  if (i_err) {
1214  i_APCI3200_Reset(dev);
1215  return -EINVAL;
1216  }
1217  /* if(i_ScanType!=1) */
1218  if (s_BoardInfos[dev->minor].i_ScanType != 1) {
1219  /* BEGIN JK 06.07.04: Management of sevrals boards */
1220  /* i_Count=0; */
1221  /* i_Sum=0; */
1222  s_BoardInfos[dev->minor].i_Count = 0;
1223  s_BoardInfos[dev->minor].i_Sum = 0;
1224  /* END JK 06.07.04: Management of sevrals boards */
1225  } /* if(i_ScanType!=1) */
1226 
1227  ul_Config =
1228  data[1] | (data[2] << 6) | (data[5] << 7) | (data[3] << 8) |
1229  (data[4] << 9);
1230  /* BEGIN JK 06.07.04: Management of sevrals boards */
1231  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1232  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1233  12) >> 19) & 1) != 1) ;
1234  /* END JK 06.07.04: Management of sevrals boards */
1235  /*********************************/
1236  /* Write the channel to configure */
1237  /*********************************/
1238  /* BEGIN JK 06.07.04: Management of sevrals boards */
1239  /* outl(0 | ui_ChannelNo , devpriv->iobase+i_Offset + 0x4); */
1240  outl(0 | ui_ChannelNo,
1241  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x4);
1242  /* END JK 06.07.04: Management of sevrals boards */
1243 
1244  /* BEGIN JK 06.07.04: Management of sevrals boards */
1245  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1246  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1247  12) >> 19) & 1) != 1) ;
1248  /* END JK 06.07.04: Management of sevrals boards */
1249  /**************************/
1250  /* Reset the configuration */
1251  /**************************/
1252  /* BEGIN JK 06.07.04: Management of sevrals boards */
1253  /* outl(0 , devpriv->iobase+i_Offset + 0x0); */
1254  outl(0, devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x0);
1255  /* END JK 06.07.04: Management of sevrals boards */
1256 
1257  /* BEGIN JK 06.07.04: Management of sevrals boards */
1258  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1259  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1260  12) >> 19) & 1) != 1) ;
1261  /* END JK 06.07.04: Management of sevrals boards */
1262 
1263  /***************************/
1264  /* Write the configuration */
1265  /***************************/
1266  /* BEGIN JK 06.07.04: Management of sevrals boards */
1267  /* outl(ul_Config , devpriv->iobase+i_Offset + 0x0); */
1268  outl(ul_Config,
1269  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x0);
1270  /* END JK 06.07.04: Management of sevrals boards */
1271 
1272  /***************************/
1273  /*Reset the calibration bit */
1274  /***************************/
1275  /* BEGIN JK 06.07.04: Management of sevrals boards */
1276  /* ul_Temp = inl(devpriv->iobase+i_Offset + 12); */
1277  ul_Temp = inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
1278  /* END JK 06.07.04: Management of sevrals boards */
1279 
1280  /* BEGIN JK 06.07.04: Management of sevrals boards */
1281  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1282  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1283  12) >> 19) & 1) != 1) ;
1284  /* END JK 06.07.04: Management of sevrals boards */
1285 
1286  /* BEGIN JK 06.07.04: Management of sevrals boards */
1287  /* outl((ul_Temp & 0xFFF9FFFF) , devpriv->iobase+.i_Offset + 12); */
1288  outl((ul_Temp & 0xFFF9FFFF),
1289  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
1290  /* END JK 06.07.04: Management of sevrals boards */
1291 
1292  if (data[9] == 1) {
1293  devpriv->tsk_Current = current;
1294  /* BEGIN JK 06.07.04: Management of sevrals boards */
1295  /* i_InterruptFlag=1; */
1296  s_BoardInfos[dev->minor].i_InterruptFlag = 1;
1297  /* END JK 06.07.04: Management of sevrals boards */
1298  } /* if(data[9]==1) */
1299  else {
1300  /* BEGIN JK 06.07.04: Management of sevrals boards */
1301  /* i_InterruptFlag=0; */
1302  s_BoardInfos[dev->minor].i_InterruptFlag = 0;
1303  /* END JK 06.07.04: Management of sevrals boards */
1304  } /* else if(data[9]==1) */
1305 
1306  /* BEGIN JK 06.07.04: Management of sevrals boards */
1307  /* i_Initialised=1; */
1308  s_BoardInfos[dev->minor].i_Initialised = 1;
1309  /* END JK 06.07.04: Management of sevrals boards */
1310 
1311  /* BEGIN JK 06.07.04: Management of sevrals boards */
1312  /* if(i_ScanType==1) */
1313  if (s_BoardInfos[dev->minor].i_ScanType == 1)
1314  /* END JK 06.07.04: Management of sevrals boards */
1315  {
1316  /* BEGIN JK 06.07.04: Management of sevrals boards */
1317  /* i_Sum=i_Sum+1; */
1318  s_BoardInfos[dev->minor].i_Sum =
1319  s_BoardInfos[dev->minor].i_Sum + 1;
1320  /* END JK 06.07.04: Management of sevrals boards */
1321 
1322  insn->unused[0] = 0;
1323  i_APCI3200_ReadAnalogInput(dev, s, insn, &ui_Dummy);
1324  }
1325 
1326  return insn->n;
1327 }
1328 
1329 /*
1330  +----------------------------------------------------------------------------+
1331  | Function Name : int i_APCI3200_ReadAnalogInput |
1332  | (struct comedi_device *dev,struct comedi_subdevice *s, |
1333  | struct comedi_insn *insn,unsigned int *data) |
1334  +----------------------------------------------------------------------------+
1335  | Task : Read value of the selected channel |
1336  +----------------------------------------------------------------------------+
1337  | Input Parameters : struct comedi_device *dev : Driver handle |
1338  | unsigned int ui_NoOfChannels : No Of Channels To read |
1339  | unsigned int *data : Data Pointer to read status |
1340  +----------------------------------------------------------------------------+
1341  | Output Parameters : -- |
1342  | data[0] : Digital Value Of Input |
1343  | data[1] : Calibration Offset Value |
1344  | data[2] : Calibration Gain Value
1345  | data[3] : CJC value
1346  | data[4] : CJC offset value
1347  | data[5] : CJC gain value
1348  | Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
1349  | data[6] : CJC current source from eeprom
1350  | data[7] : Channel current source from eeprom
1351  | data[8] : Channle gain factor from eeprom
1352  | End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
1353  +----------------------------------------------------------------------------+
1354  | Return Value : TRUE : No error occur |
1355  | : FALSE : Error occur. Return the error |
1356  | |
1357  +----------------------------------------------------------------------------+
1358 */
1360  struct comedi_insn *insn, unsigned int *data)
1361 {
1362  unsigned int ui_DummyValue = 0;
1363  int i_ConvertCJCCalibration;
1364  int i = 0;
1365 
1366  /* BEGIN JK 06.07.04: Management of sevrals boards */
1367  /* if(i_Initialised==0) */
1368  if (s_BoardInfos[dev->minor].i_Initialised == 0)
1369  /* END JK 06.07.04: Management of sevrals boards */
1370  {
1371  i_APCI3200_Reset(dev);
1372  return -EINVAL;
1373  } /* if(i_Initialised==0); */
1374 
1375 #ifdef PRINT_INFO
1376  printk("\n insn->unused[0] = %i", insn->unused[0]);
1377 #endif
1378 
1379  switch (insn->unused[0]) {
1380  case 0:
1381 
1383  &ui_DummyValue);
1384  /* BEGIN JK 06.07.04: Management of sevrals boards */
1385  /* ui_InterruptChannelValue[i_Count+0]=ui_DummyValue; */
1386  s_BoardInfos[dev->minor].
1388  i_Count + 0] = ui_DummyValue;
1389  /* END JK 06.07.04: Management of sevrals boards */
1390 
1391  /* Begin JK 25.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
1393  s_BoardInfos[dev->minor].ui_Channel_num,
1394  &s_BoardInfos[dev->minor].
1395  ui_InterruptChannelValue[s_BoardInfos[dev->minor].
1396  i_Count + 6],
1397  &s_BoardInfos[dev->minor].
1398  ui_InterruptChannelValue[s_BoardInfos[dev->minor].
1399  i_Count + 7],
1400  &s_BoardInfos[dev->minor].
1401  ui_InterruptChannelValue[s_BoardInfos[dev->minor].
1402  i_Count + 8]);
1403 
1404 #ifdef PRINT_INFO
1405  printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+6] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 6]);
1406 
1407  printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+7] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 7]);
1408 
1409  printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+8] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 8]);
1410 #endif
1411 
1412  /* End JK 25.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
1413 
1414  /* BEGIN JK 06.07.04: Management of sevrals boards */
1415  /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE) && (i_CJCAvailable==1)) */
1416  if ((s_BoardInfos[dev->minor].i_ADDIDATAType == 2)
1417  && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE)
1418  && (s_BoardInfos[dev->minor].i_CJCAvailable == 1))
1419  /* END JK 06.07.04: Management of sevrals boards */
1420  {
1421  i_APCI3200_ReadCJCValue(dev, &ui_DummyValue);
1422  /* BEGIN JK 06.07.04: Management of sevrals boards */
1423  /* ui_InterruptChannelValue[i_Count + 3]=ui_DummyValue; */
1424  s_BoardInfos[dev->minor].
1425  ui_InterruptChannelValue[s_BoardInfos[dev->
1426  minor].i_Count + 3] = ui_DummyValue;
1427  /* END JK 06.07.04: Management of sevrals boards */
1428  } /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)) */
1429  else {
1430  /* BEGIN JK 06.07.04: Management of sevrals boards */
1431  /* ui_InterruptChannelValue[i_Count + 3]=0; */
1432  s_BoardInfos[dev->minor].
1433  ui_InterruptChannelValue[s_BoardInfos[dev->
1434  minor].i_Count + 3] = 0;
1435  /* END JK 06.07.04: Management of sevrals boards */
1436  } /* elseif((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE) && (i_CJCAvailable==1)) */
1437 
1438  /* BEGIN JK 06.07.04: Management of sevrals boards */
1439  /* if (( i_AutoCalibration == FALSE) && (i_InterruptFlag == FALSE)) */
1440  if ((s_BoardInfos[dev->minor].i_AutoCalibration == FALSE)
1441  && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE))
1442  /* END JK 06.07.04: Management of sevrals boards */
1443  {
1445  &ui_DummyValue);
1446  /* BEGIN JK 06.07.04: Management of sevrals boards */
1447  /* ui_InterruptChannelValue[i_Count + 1]=ui_DummyValue; */
1448  s_BoardInfos[dev->minor].
1449  ui_InterruptChannelValue[s_BoardInfos[dev->
1450  minor].i_Count + 1] = ui_DummyValue;
1451  /* END JK 06.07.04: Management of sevrals boards */
1453  &ui_DummyValue);
1454  /* BEGIN JK 06.07.04: Management of sevrals boards */
1455  /* ui_InterruptChannelValue[i_Count + 2]=ui_DummyValue; */
1456  s_BoardInfos[dev->minor].
1457  ui_InterruptChannelValue[s_BoardInfos[dev->
1458  minor].i_Count + 2] = ui_DummyValue;
1459  /* END JK 06.07.04: Management of sevrals boards */
1460  } /* if (( i_AutoCalibration == FALSE) && (i_InterruptFlag == FALSE)) */
1461 
1462  /* BEGIN JK 06.07.04: Management of sevrals boards */
1463  /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)&& (i_CJCAvailable==1)) */
1464  if ((s_BoardInfos[dev->minor].i_ADDIDATAType == 2)
1465  && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE)
1466  && (s_BoardInfos[dev->minor].i_CJCAvailable == 1))
1467  /* END JK 06.07.04: Management of sevrals boards */
1468  {
1469  /**********************************************************/
1470  /*Test if the Calibration channel must be read for the CJC */
1471  /**********************************************************/
1472  /**********************************/
1473  /*Test if the polarity is the same */
1474  /**********************************/
1475  /* BEGIN JK 06.07.04: Management of sevrals boards */
1476  /* if(i_CJCPolarity!=i_ADDIDATAPolarity) */
1477  if (s_BoardInfos[dev->minor].i_CJCPolarity !=
1478  s_BoardInfos[dev->minor].i_ADDIDATAPolarity)
1479  /* END JK 06.07.04: Management of sevrals boards */
1480  {
1481  i_ConvertCJCCalibration = 1;
1482  } /* if(i_CJCPolarity!=i_ADDIDATAPolarity) */
1483  else {
1484  /* BEGIN JK 06.07.04: Management of sevrals boards */
1485  /* if(i_CJCGain==i_ADDIDATAGain) */
1486  if (s_BoardInfos[dev->minor].i_CJCGain ==
1487  s_BoardInfos[dev->minor].i_ADDIDATAGain)
1488  /* END JK 06.07.04: Management of sevrals boards */
1489  {
1490  i_ConvertCJCCalibration = 0;
1491  } /* if(i_CJCGain==i_ADDIDATAGain) */
1492  else {
1493  i_ConvertCJCCalibration = 1;
1494  } /* elseif(i_CJCGain==i_ADDIDATAGain) */
1495  } /* elseif(i_CJCPolarity!=i_ADDIDATAPolarity) */
1496  if (i_ConvertCJCCalibration == 1) {
1498  &ui_DummyValue);
1499  /* BEGIN JK 06.07.04: Management of sevrals boards */
1500  /* ui_InterruptChannelValue[i_Count+4]=ui_DummyValue; */
1501  s_BoardInfos[dev->minor].
1502  ui_InterruptChannelValue[s_BoardInfos
1503  [dev->minor].i_Count + 4] =
1504  ui_DummyValue;
1505  /* END JK 06.07.04: Management of sevrals boards */
1506 
1507  i_APCI3200_ReadCJCCalGain(dev, &ui_DummyValue);
1508 
1509  /* BEGIN JK 06.07.04: Management of sevrals boards */
1510  /* ui_InterruptChannelValue[i_Count+5]=ui_DummyValue; */
1511  s_BoardInfos[dev->minor].
1512  ui_InterruptChannelValue[s_BoardInfos
1513  [dev->minor].i_Count + 5] =
1514  ui_DummyValue;
1515  /* END JK 06.07.04: Management of sevrals boards */
1516  } /* if(i_ConvertCJCCalibration==1) */
1517  else {
1518  /* BEGIN JK 06.07.04: Management of sevrals boards */
1519  /* ui_InterruptChannelValue[i_Count+4]=0; */
1520  /* ui_InterruptChannelValue[i_Count+5]=0; */
1521 
1522  s_BoardInfos[dev->minor].
1523  ui_InterruptChannelValue[s_BoardInfos
1524  [dev->minor].i_Count + 4] = 0;
1525  s_BoardInfos[dev->minor].
1526  ui_InterruptChannelValue[s_BoardInfos
1527  [dev->minor].i_Count + 5] = 0;
1528  /* END JK 06.07.04: Management of sevrals boards */
1529  } /* elseif(i_ConvertCJCCalibration==1) */
1530  } /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)) */
1531 
1532  /* BEGIN JK 06.07.04: Management of sevrals boards */
1533  /* if(i_ScanType!=1) */
1534  if (s_BoardInfos[dev->minor].i_ScanType != 1) {
1535  /* i_Count=0; */
1536  s_BoardInfos[dev->minor].i_Count = 0;
1537  } /* if(i_ScanType!=1) */
1538  else {
1539  /* i_Count=i_Count +6; */
1540  /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
1541  /* s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count +6; */
1542  s_BoardInfos[dev->minor].i_Count =
1543  s_BoardInfos[dev->minor].i_Count + 9;
1544  /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
1545  } /* else if(i_ScanType!=1) */
1546 
1547  /* if((i_ScanType==1) &&(i_InterruptFlag==1)) */
1548  if ((s_BoardInfos[dev->minor].i_ScanType == 1)
1549  && (s_BoardInfos[dev->minor].i_InterruptFlag == 1)) {
1550  /* i_Count=i_Count-6; */
1551  /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
1552  /* s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count-6; */
1553  s_BoardInfos[dev->minor].i_Count =
1554  s_BoardInfos[dev->minor].i_Count - 9;
1555  /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
1556  }
1557  /* if(i_ScanType==0) */
1558  if (s_BoardInfos[dev->minor].i_ScanType == 0) {
1559  /*
1560  data[0]= ui_InterruptChannelValue[0];
1561  data[1]= ui_InterruptChannelValue[1];
1562  data[2]= ui_InterruptChannelValue[2];
1563  data[3]= ui_InterruptChannelValue[3];
1564  data[4]= ui_InterruptChannelValue[4];
1565  data[5]= ui_InterruptChannelValue[5];
1566  */
1567 #ifdef PRINT_INFO
1568  printk("\n data[0]= s_BoardInfos [dev->minor].ui_InterruptChannelValue[0];");
1569 #endif
1570  data[0] =
1571  s_BoardInfos[dev->minor].
1573  data[1] =
1574  s_BoardInfos[dev->minor].
1576  data[2] =
1577  s_BoardInfos[dev->minor].
1579  data[3] =
1580  s_BoardInfos[dev->minor].
1582  data[4] =
1583  s_BoardInfos[dev->minor].
1585  data[5] =
1586  s_BoardInfos[dev->minor].
1588 
1589  /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
1590  /* printk("\n 0 - i_APCI3200_GetChannelCalibrationValue data [6] = %lu, data [7] = %lu, data [8] = %lu", data [6], data [7], data [8]); */
1592  s_BoardInfos[dev->minor].ui_Channel_num,
1593  &data[6], &data[7], &data[8]);
1594  /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
1595  }
1596  break;
1597  case 1:
1598 
1599  for (i = 0; i < insn->n; i++) {
1600  /* data[i]=ui_InterruptChannelValue[i]; */
1601  data[i] =
1602  s_BoardInfos[dev->minor].
1604  }
1605 
1606  /* i_Count=0; */
1607  /* i_Sum=0; */
1608  /* if(i_ScanType==1) */
1609  s_BoardInfos[dev->minor].i_Count = 0;
1610  s_BoardInfos[dev->minor].i_Sum = 0;
1611  if (s_BoardInfos[dev->minor].i_ScanType == 1) {
1612  /* i_Initialised=0; */
1613  /* i_InterruptFlag=0; */
1614  s_BoardInfos[dev->minor].i_Initialised = 0;
1615  s_BoardInfos[dev->minor].i_InterruptFlag = 0;
1616  /* END JK 06.07.04: Management of sevrals boards */
1617  }
1618  break;
1619  default:
1620  printk("\nThe parameters passed are in error\n");
1621  i_APCI3200_Reset(dev);
1622  return -EINVAL;
1623  } /* switch(insn->unused[0]) */
1624 
1625  return insn->n;
1626 }
1627 
1628 /*
1629  +----------------------------------------------------------------------------+
1630  | Function Name : int i_APCI3200_Read1AnalogInputChannel |
1631  | (struct comedi_device *dev,struct comedi_subdevice *s, |
1632  | struct comedi_insn *insn,unsigned int *data) |
1633  +----------------------------------------------------------------------------+
1634  | Task : Read value of the selected channel |
1635  +----------------------------------------------------------------------------+
1636  | Input Parameters : struct comedi_device *dev : Driver handle |
1637  | unsigned int ui_NoOfChannel : Channel No to read |
1638  | unsigned int *data : Data Pointer to read status |
1639  +----------------------------------------------------------------------------+
1640  | Output Parameters : -- |
1641  | data[0] : Digital Value read |
1642  |
1643  +----------------------------------------------------------------------------+
1644  | Return Value : TRUE : No error occur |
1645  | : FALSE : Error occur. Return the error |
1646  | |
1647  +----------------------------------------------------------------------------+
1648 */
1650  struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
1651 {
1652  unsigned int ui_EOC = 0;
1653  unsigned int ui_ChannelNo = 0;
1654  unsigned int ui_CommandRegister = 0;
1655 
1656  /* BEGIN JK 06.07.04: Management of sevrals boards */
1657  /* ui_ChannelNo=i_ChannelNo; */
1658  ui_ChannelNo = s_BoardInfos[dev->minor].i_ChannelNo;
1659 
1660  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1661  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1662  12) >> 19) & 1) != 1) ;
1663  /*********************************/
1664  /* Write the channel to configure */
1665  /*********************************/
1666  /* Begin JK 20.10.2004: Bad channel value is used when using differential mode */
1667  /* outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4); */
1668  /* outl(0 | s_BoardInfos [dev->minor].ui_Channel_num , devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 0x4); */
1669  outl(0 | s_BoardInfos[dev->minor].i_ChannelNo,
1670  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x4);
1671  /* End JK 20.10.2004: Bad channel value is used when using differential mode */
1672 
1673  /*******************************/
1674  /* Set the convert timing unit */
1675  /*******************************/
1676  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1677  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1678  12) >> 19) & 1) != 1) ;
1679 
1680  /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */
1681  outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
1682  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
1683 
1684  /**************************/
1685  /* Set the convert timing */
1686  /**************************/
1687  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1688  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1689  12) >> 19) & 1) != 1) ;
1690 
1691  /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */
1692  outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
1693  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
1694 
1695  /**************************************************************************/
1696  /* Set the start end stop index to the selected channel and set the start */
1697  /**************************************************************************/
1698 
1699  ui_CommandRegister = ui_ChannelNo | (ui_ChannelNo << 8) | 0x80000;
1700 
1701  /*********************************/
1702  /*Test if the interrupt is enable */
1703  /*********************************/
1704 
1705  /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
1706  if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
1707  /************************/
1708  /* Enable the interrupt */
1709  /************************/
1710  ui_CommandRegister = ui_CommandRegister | 0x00100000;
1711  } /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
1712 
1713  /******************************/
1714  /* Write the command register */
1715  /******************************/
1716  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1717  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1718  12) >> 19) & 1) != 1) ;
1719 
1720  /* outl(ui_CommandRegister, devpriv->iobase+i_Offset + 8); */
1721  outl(ui_CommandRegister,
1722  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
1723 
1724  /*****************************/
1725  /*Test if interrupt is enable */
1726  /*****************************/
1727  /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
1728  if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
1729  do {
1730  /*************************/
1731  /*Read the EOC Status bit */
1732  /*************************/
1733 
1734  /* ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1; */
1735  ui_EOC = inl(devpriv->iobase +
1736  s_BoardInfos[dev->minor].i_Offset + 20) & 1;
1737 
1738  } while (ui_EOC != 1);
1739 
1740  /***************************************/
1741  /* Read the digital value of the input */
1742  /***************************************/
1743 
1744  /* data[0] = inl (devpriv->iobase+i_Offset + 28); */
1745  data[0] =
1746  inl(devpriv->iobase +
1747  s_BoardInfos[dev->minor].i_Offset + 28);
1748  /* END JK 06.07.04: Management of sevrals boards */
1749 
1750  } /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
1751  return 0;
1752 }
1753 
1754 /*
1755  +----------------------------------------------------------------------------+
1756  | Function Name : int i_APCI3200_ReadCalibrationOffsetValue |
1757  | (struct comedi_device *dev,struct comedi_subdevice *s, |
1758  | struct comedi_insn *insn,unsigned int *data) |
1759  +----------------------------------------------------------------------------+
1760  | Task : Read calibration offset value of the selected channel|
1761  +----------------------------------------------------------------------------+
1762  | Input Parameters : struct comedi_device *dev : Driver handle |
1763  | unsigned int *data : Data Pointer to read status |
1764  +----------------------------------------------------------------------------+
1765  | Output Parameters : -- |
1766  | data[0] : Calibration offset Value |
1767  |
1768  +----------------------------------------------------------------------------+
1769  | Return Value : TRUE : No error occur |
1770  | : FALSE : Error occur. Return the error |
1771  | |
1772  +----------------------------------------------------------------------------+
1773 */
1775 {
1776  unsigned int ui_Temp = 0, ui_EOC = 0;
1777  unsigned int ui_CommandRegister = 0;
1778 
1779  /* BEGIN JK 06.07.04: Management of sevrals boards */
1780  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1781  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1782  12) >> 19) & 1) != 1) ;
1783  /*********************************/
1784  /* Write the channel to configure */
1785  /*********************************/
1786  /* Begin JK 20.10.2004: This seems not necessary ! */
1787  /* outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4); */
1788  /* outl(0 | s_BoardInfos [dev->minor].ui_Channel_num , devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 0x4); */
1789  /* End JK 20.10.2004: This seems not necessary ! */
1790 
1791  /*******************************/
1792  /* Set the convert timing unit */
1793  /*******************************/
1794  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1795  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1796  12) >> 19) & 1) != 1) ;
1797  /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */
1798  outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
1799  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
1800  /**************************/
1801  /* Set the convert timing */
1802  /**************************/
1803  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1804  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1805  12) >> 19) & 1) != 1) ;
1806  /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */
1807  outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
1808  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
1809  /*****************************/
1810  /*Read the calibration offset */
1811  /*****************************/
1812  /* ui_Temp = inl(devpriv->iobase+i_Offset + 12); */
1813  ui_Temp = inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
1814 
1815  /*********************************/
1816  /*Configure the Offset Conversion */
1817  /*********************************/
1818  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1819  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1820  12) >> 19) & 1) != 1) ;
1821  /* outl((ui_Temp | 0x00020000), devpriv->iobase+i_Offset + 12); */
1822  outl((ui_Temp | 0x00020000),
1823  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
1824  /*******************************/
1825  /*Initialise ui_CommandRegister */
1826  /*******************************/
1827 
1828  ui_CommandRegister = 0;
1829 
1830  /*********************************/
1831  /*Test if the interrupt is enable */
1832  /*********************************/
1833 
1834  /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
1835  if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
1836 
1837  /**********************/
1838  /*Enable the interrupt */
1839  /**********************/
1840 
1841  ui_CommandRegister = ui_CommandRegister | 0x00100000;
1842 
1843  } /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
1844 
1845  /**********************/
1846  /*Start the conversion */
1847  /**********************/
1848  ui_CommandRegister = ui_CommandRegister | 0x00080000;
1849 
1850  /***************************/
1851  /*Write the command regiter */
1852  /***************************/
1853  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1854  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1855  12) >> 19) & 1) != 1) ;
1856  /* outl(ui_CommandRegister, devpriv->iobase+i_Offset + 8); */
1857  outl(ui_CommandRegister,
1858  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
1859 
1860  /*****************************/
1861  /*Test if interrupt is enable */
1862  /*****************************/
1863 
1864  /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
1865  if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
1866 
1867  do {
1868  /*******************/
1869  /*Read the EOC flag */
1870  /*******************/
1871 
1872  /* ui_EOC = inl (devpriv->iobase+i_Offset + 20) & 1; */
1873  ui_EOC = inl(devpriv->iobase +
1874  s_BoardInfos[dev->minor].i_Offset + 20) & 1;
1875 
1876  } while (ui_EOC != 1);
1877 
1878  /**************************************************/
1879  /*Read the digital value of the calibration Offset */
1880  /**************************************************/
1881 
1882  /* data[0] = inl(devpriv->iobase+i_Offset+ 28); */
1883  data[0] =
1884  inl(devpriv->iobase +
1885  s_BoardInfos[dev->minor].i_Offset + 28);
1886  } /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
1887  return 0;
1888 }
1889 
1890 /*
1891  +----------------------------------------------------------------------------+
1892  | Function Name : int i_APCI3200_ReadCalibrationGainValue |
1893  | (struct comedi_device *dev,struct comedi_subdevice *s, |
1894  | struct comedi_insn *insn,unsigned int *data) |
1895  +----------------------------------------------------------------------------+
1896  | Task : Read calibration gain value of the selected channel |
1897  +----------------------------------------------------------------------------+
1898  | Input Parameters : struct comedi_device *dev : Driver handle |
1899  | unsigned int *data : Data Pointer to read status |
1900  +----------------------------------------------------------------------------+
1901  | Output Parameters : -- |
1902  | data[0] : Calibration gain Value Of Input |
1903  |
1904  +----------------------------------------------------------------------------+
1905  | Return Value : TRUE : No error occur |
1906  | : FALSE : Error occur. Return the error |
1907  | |
1908  +----------------------------------------------------------------------------+
1909 */
1911 {
1912  unsigned int ui_EOC = 0;
1913  int ui_CommandRegister = 0;
1914 
1915  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1916  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1917  12) >> 19) & 1) != 1) ;
1918  /*********************************/
1919  /* Write the channel to configure */
1920  /*********************************/
1921  /* Begin JK 20.10.2004: This seems not necessary ! */
1922  /* outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4); */
1923  /* outl(0 | s_BoardInfos [dev->minor].ui_Channel_num , devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 0x4); */
1924  /* End JK 20.10.2004: This seems not necessary ! */
1925 
1926  /***************************/
1927  /*Read the calibration gain */
1928  /***************************/
1929  /*******************************/
1930  /* Set the convert timing unit */
1931  /*******************************/
1932  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1933  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1934  12) >> 19) & 1) != 1) ;
1935  /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */
1936  outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
1937  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
1938  /**************************/
1939  /* Set the convert timing */
1940  /**************************/
1941  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1942  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1943  12) >> 19) & 1) != 1) ;
1944  /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */
1945  outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
1946  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
1947  /*******************************/
1948  /*Configure the Gain Conversion */
1949  /*******************************/
1950  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1951  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1952  12) >> 19) & 1) != 1) ;
1953  /* outl(0x00040000 , devpriv->iobase+i_Offset + 12); */
1954  outl(0x00040000,
1955  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
1956 
1957  /*******************************/
1958  /*Initialise ui_CommandRegister */
1959  /*******************************/
1960 
1961  ui_CommandRegister = 0;
1962 
1963  /*********************************/
1964  /*Test if the interrupt is enable */
1965  /*********************************/
1966 
1967  /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
1968  if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
1969 
1970  /**********************/
1971  /*Enable the interrupt */
1972  /**********************/
1973 
1974  ui_CommandRegister = ui_CommandRegister | 0x00100000;
1975 
1976  } /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
1977 
1978  /**********************/
1979  /*Start the conversion */
1980  /**********************/
1981 
1982  ui_CommandRegister = ui_CommandRegister | 0x00080000;
1983  /***************************/
1984  /*Write the command regiter */
1985  /***************************/
1986  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1987  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1988  12) >> 19) & 1) != 1) ;
1989  /* outl(ui_CommandRegister , devpriv->iobase+i_Offset + 8); */
1990  outl(ui_CommandRegister,
1991  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
1992 
1993  /*****************************/
1994  /*Test if interrupt is enable */
1995  /*****************************/
1996 
1997  /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
1998  if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
1999 
2000  do {
2001 
2002  /*******************/
2003  /*Read the EOC flag */
2004  /*******************/
2005 
2006  /* ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1; */
2007  ui_EOC = inl(devpriv->iobase +
2008  s_BoardInfos[dev->minor].i_Offset + 20) & 1;
2009 
2010  } while (ui_EOC != 1);
2011 
2012  /************************************************/
2013  /*Read the digital value of the calibration Gain */
2014  /************************************************/
2015 
2016  /* data[0] = inl(devpriv->iobase+i_Offset + 28); */
2017  data[0] =
2018  inl(devpriv->iobase +
2019  s_BoardInfos[dev->minor].i_Offset + 28);
2020 
2021  } /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
2022  return 0;
2023 }
2024 
2025 /*
2026  +----------------------------------------------------------------------------+
2027  | Function Name : int i_APCI3200_ReadCJCValue |
2028  | (struct comedi_device *dev,struct comedi_subdevice *s, |
2029  | struct comedi_insn *insn,unsigned int *data) |
2030  +----------------------------------------------------------------------------+
2031  | Task : Read CJC value of the selected channel |
2032  +----------------------------------------------------------------------------+
2033  | Input Parameters : struct comedi_device *dev : Driver handle |
2034  | unsigned int *data : Data Pointer to read status |
2035  +----------------------------------------------------------------------------+
2036  | Output Parameters : -- |
2037  | data[0] : CJC Value |
2038  |
2039  +----------------------------------------------------------------------------+
2040  | Return Value : TRUE : No error occur |
2041  | : FALSE : Error occur. Return the error |
2042  | |
2043  +----------------------------------------------------------------------------+
2044 */
2045 
2046 int i_APCI3200_ReadCJCValue(struct comedi_device *dev, unsigned int *data)
2047 {
2048  unsigned int ui_EOC = 0;
2049  int ui_CommandRegister = 0;
2050 
2051  /******************************/
2052  /*Set the converting time unit */
2053  /******************************/
2054 
2055  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2056  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2057  12) >> 19) & 1) != 1) ;
2058 
2059  /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */
2060  outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
2061  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
2062  /**************************/
2063  /* Set the convert timing */
2064  /**************************/
2065  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2066  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2067  12) >> 19) & 1) != 1) ;
2068 
2069  /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */
2070  outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
2071  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
2072 
2073  /******************************/
2074  /*Configure the CJC Conversion */
2075  /******************************/
2076  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2077  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2078  12) >> 19) & 1) != 1) ;
2079 
2080  /* outl( 0x00000400 , devpriv->iobase+i_Offset + 4); */
2081  outl(0x00000400,
2082  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4);
2083  /*******************************/
2084  /*Initialise dw_CommandRegister */
2085  /*******************************/
2086  ui_CommandRegister = 0;
2087  /*********************************/
2088  /*Test if the interrupt is enable */
2089  /*********************************/
2090  /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
2091  if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
2092  /**********************/
2093  /*Enable the interrupt */
2094  /**********************/
2095  ui_CommandRegister = ui_CommandRegister | 0x00100000;
2096  }
2097 
2098  /**********************/
2099  /*Start the conversion */
2100  /**********************/
2101 
2102  ui_CommandRegister = ui_CommandRegister | 0x00080000;
2103 
2104  /***************************/
2105  /*Write the command regiter */
2106  /***************************/
2107  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2108  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2109  12) >> 19) & 1) != 1) ;
2110  /* outl(ui_CommandRegister , devpriv->iobase+i_Offset + 8); */
2111  outl(ui_CommandRegister,
2112  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
2113 
2114  /*****************************/
2115  /*Test if interrupt is enable */
2116  /*****************************/
2117 
2118  /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
2119  if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
2120  do {
2121 
2122  /*******************/
2123  /*Read the EOC flag */
2124  /*******************/
2125 
2126  /* ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1; */
2127  ui_EOC = inl(devpriv->iobase +
2128  s_BoardInfos[dev->minor].i_Offset + 20) & 1;
2129 
2130  } while (ui_EOC != 1);
2131 
2132  /***********************************/
2133  /*Read the digital value of the CJC */
2134  /***********************************/
2135 
2136  /* data[0] = inl(devpriv->iobase+i_Offset + 28); */
2137  data[0] =
2138  inl(devpriv->iobase +
2139  s_BoardInfos[dev->minor].i_Offset + 28);
2140 
2141  } /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
2142  return 0;
2143 }
2144 
2145 /*
2146  +----------------------------------------------------------------------------+
2147  | Function Name : int i_APCI3200_ReadCJCCalOffset |
2148  | (struct comedi_device *dev,struct comedi_subdevice *s, |
2149  | struct comedi_insn *insn,unsigned int *data) |
2150  +----------------------------------------------------------------------------+
2151  | Task : Read CJC calibration offset value of the selected channel
2152  +----------------------------------------------------------------------------+
2153  | Input Parameters : struct comedi_device *dev : Driver handle |
2154  | unsigned int *data : Data Pointer to read status |
2155  +----------------------------------------------------------------------------+
2156  | Output Parameters : -- |
2157  | data[0] : CJC calibration offset Value
2158  |
2159  +----------------------------------------------------------------------------+
2160  | Return Value : TRUE : No error occur |
2161  | : FALSE : Error occur. Return the error |
2162  | |
2163  +----------------------------------------------------------------------------+
2164 */
2166 {
2167  unsigned int ui_EOC = 0;
2168  int ui_CommandRegister = 0;
2169  /*******************************************/
2170  /*Read calibration offset value for the CJC */
2171  /*******************************************/
2172  /*******************************/
2173  /* Set the convert timing unit */
2174  /*******************************/
2175  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2176  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2177  12) >> 19) & 1) != 1) ;
2178  /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */
2179  outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
2180  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
2181  /**************************/
2182  /* Set the convert timing */
2183  /**************************/
2184  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2185  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2186  12) >> 19) & 1) != 1) ;
2187  /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */
2188  outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
2189  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
2190  /******************************/
2191  /*Configure the CJC Conversion */
2192  /******************************/
2193  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2194  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2195  12) >> 19) & 1) != 1) ;
2196  /* outl(0x00000400 , devpriv->iobase+i_Offset + 4); */
2197  outl(0x00000400,
2198  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4);
2199  /*********************************/
2200  /*Configure the Offset Conversion */
2201  /*********************************/
2202  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2203  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2204  12) >> 19) & 1) != 1) ;
2205  /* outl(0x00020000, devpriv->iobase+i_Offset + 12); */
2206  outl(0x00020000,
2207  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
2208  /*******************************/
2209  /*Initialise ui_CommandRegister */
2210  /*******************************/
2211  ui_CommandRegister = 0;
2212  /*********************************/
2213  /*Test if the interrupt is enable */
2214  /*********************************/
2215 
2216  /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
2217  if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
2218  /**********************/
2219  /*Enable the interrupt */
2220  /**********************/
2221  ui_CommandRegister = ui_CommandRegister | 0x00100000;
2222 
2223  }
2224 
2225  /**********************/
2226  /*Start the conversion */
2227  /**********************/
2228  ui_CommandRegister = ui_CommandRegister | 0x00080000;
2229  /***************************/
2230  /*Write the command regiter */
2231  /***************************/
2232  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2233  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2234  12) >> 19) & 1) != 1) ;
2235  /* outl(ui_CommandRegister,devpriv->iobase+i_Offset + 8); */
2236  outl(ui_CommandRegister,
2237  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
2238  /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
2239  if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
2240  do {
2241  /*******************/
2242  /*Read the EOC flag */
2243  /*******************/
2244  /* ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1; */
2245  ui_EOC = inl(devpriv->iobase +
2246  s_BoardInfos[dev->minor].i_Offset + 20) & 1;
2247  } while (ui_EOC != 1);
2248 
2249  /**************************************************/
2250  /*Read the digital value of the calibration Offset */
2251  /**************************************************/
2252  /* data[0] = inl(devpriv->iobase+i_Offset + 28); */
2253  data[0] =
2254  inl(devpriv->iobase +
2255  s_BoardInfos[dev->minor].i_Offset + 28);
2256  } /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
2257  return 0;
2258 }
2259 
2260 /*
2261  +----------------------------------------------------------------------------+
2262  | Function Name : int i_APCI3200_ReadCJCGainValue |
2263  | (struct comedi_device *dev,struct comedi_subdevice *s, |
2264  | struct comedi_insn *insn,unsigned int *data) |
2265  +----------------------------------------------------------------------------+
2266  | Task : Read CJC calibration gain value
2267  +----------------------------------------------------------------------------+
2268  | Input Parameters : struct comedi_device *dev : Driver handle |
2269  | unsigned int ui_NoOfChannels : No Of Channels To read |
2270  | unsigned int *data : Data Pointer to read status |
2271  +----------------------------------------------------------------------------+
2272  | Output Parameters : -- |
2273  | data[0] : CJC calibration gain value
2274  |
2275  +----------------------------------------------------------------------------+
2276  | Return Value : TRUE : No error occur |
2277  | : FALSE : Error occur. Return the error |
2278  | |
2279  +----------------------------------------------------------------------------+
2280 */
2282 {
2283  unsigned int ui_EOC = 0;
2284  int ui_CommandRegister = 0;
2285  /*******************************/
2286  /* Set the convert timing unit */
2287  /*******************************/
2288  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2289  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2290  12) >> 19) & 1) != 1) ;
2291  /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */
2292  outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
2293  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
2294  /**************************/
2295  /* Set the convert timing */
2296  /**************************/
2297  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2298  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2299  12) >> 19) & 1) != 1) ;
2300  /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */
2301  outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
2302  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
2303  /******************************/
2304  /*Configure the CJC Conversion */
2305  /******************************/
2306  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2307  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2308  12) >> 19) & 1) != 1) ;
2309  /* outl(0x00000400,devpriv->iobase+i_Offset + 4); */
2310  outl(0x00000400,
2311  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4);
2312  /*******************************/
2313  /*Configure the Gain Conversion */
2314  /*******************************/
2315  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2316  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2317  12) >> 19) & 1) != 1) ;
2318  /* outl(0x00040000,devpriv->iobase+i_Offset + 12); */
2319  outl(0x00040000,
2320  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
2321 
2322  /*******************************/
2323  /*Initialise dw_CommandRegister */
2324  /*******************************/
2325  ui_CommandRegister = 0;
2326  /*********************************/
2327  /*Test if the interrupt is enable */
2328  /*********************************/
2329  /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
2330  if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
2331  /**********************/
2332  /*Enable the interrupt */
2333  /**********************/
2334  ui_CommandRegister = ui_CommandRegister | 0x00100000;
2335  }
2336  /**********************/
2337  /*Start the conversion */
2338  /**********************/
2339  ui_CommandRegister = ui_CommandRegister | 0x00080000;
2340  /***************************/
2341  /*Write the command regiter */
2342  /***************************/
2343  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2344  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2345  12) >> 19) & 1) != 1) ;
2346  /* outl(ui_CommandRegister ,devpriv->iobase+i_Offset + 8); */
2347  outl(ui_CommandRegister,
2348  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
2349  /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
2350  if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
2351  do {
2352  /*******************/
2353  /*Read the EOC flag */
2354  /*******************/
2355  /* ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1; */
2356  ui_EOC = inl(devpriv->iobase +
2357  s_BoardInfos[dev->minor].i_Offset + 20) & 1;
2358  } while (ui_EOC != 1);
2359  /************************************************/
2360  /*Read the digital value of the calibration Gain */
2361  /************************************************/
2362  /* data[0] = inl (devpriv->iobase+i_Offset + 28); */
2363  data[0] =
2364  inl(devpriv->iobase +
2365  s_BoardInfos[dev->minor].i_Offset + 28);
2366  } /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
2367  return 0;
2368 }
2369 
2370 /*
2371  +----------------------------------------------------------------------------+
2372  | Function Name : int i_APCI3200_InsnBits_AnalogInput_Test |
2373  | (struct comedi_device *dev,struct comedi_subdevice *s, |
2374  | struct comedi_insn *insn,unsigned int *data) |
2375  +----------------------------------------------------------------------------+
2376  | Task : Tests the Selected Anlog Input Channel |
2377  +----------------------------------------------------------------------------+
2378  | Input Parameters : struct comedi_device *dev : Driver handle |
2379  | struct comedi_subdevice *s : Subdevice Pointer |
2380  | struct comedi_insn *insn : Insn Structure Pointer |
2381  | unsigned int *data : Data Pointer contains |
2382  | configuration parameters as below |
2383  |
2384  |
2385  | data[0] : 0 TestAnalogInputShortCircuit
2386  | 1 TestAnalogInputConnection |
2387 
2388  +----------------------------------------------------------------------------+
2389  | Output Parameters : -- |
2390  | data[0] : Digital value obtained |
2391  | data[1] : calibration offset |
2392  | data[2] : calibration gain |
2393  | |
2394  | |
2395  +----------------------------------------------------------------------------+
2396  | Return Value : TRUE : No error occur |
2397  | : FALSE : Error occur. Return the error |
2398  | |
2399  +----------------------------------------------------------------------------+
2400 */
2401 
2403  struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
2404 {
2405  unsigned int ui_Configuration = 0;
2406  int i_Temp; /* ,i_TimeUnit; */
2407  /* if(i_Initialised==0) */
2408 
2409  if (s_BoardInfos[dev->minor].i_Initialised == 0) {
2410  i_APCI3200_Reset(dev);
2411  return -EINVAL;
2412  } /* if(i_Initialised==0); */
2413  if (data[0] != 0 && data[0] != 1) {
2414  printk("\nError in selection of functionality\n");
2415  i_APCI3200_Reset(dev);
2416  return -EINVAL;
2417  } /* if(data[0]!=0 && data[0]!=1) */
2418 
2419  if (data[0] == 1) /* Perform Short Circuit TEST */
2420  {
2421  /**************************/
2422  /*Set the short-cicuit bit */
2423  /**************************/
2424  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2425  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].
2426  i_Offset + 12) >> 19) & 1) !=
2427  1) ;
2428  /* outl((0x00001000 |i_ChannelNo) , devpriv->iobase+i_Offset + 4); */
2429  outl((0x00001000 | s_BoardInfos[dev->minor].i_ChannelNo),
2430  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2431  4);
2432  /*************************/
2433  /*Set the time unit to ns */
2434  /*************************/
2435  /* i_TimeUnit= i_ADDIDATAConversionTimeUnit;
2436  i_ADDIDATAConversionTimeUnit= 1; */
2437  /* i_Temp= i_InterruptFlag ; */
2438  i_Temp = s_BoardInfos[dev->minor].i_InterruptFlag;
2439  /* i_InterruptFlag = ADDIDATA_DISABLE; */
2440  s_BoardInfos[dev->minor].i_InterruptFlag = ADDIDATA_DISABLE;
2441  i_APCI3200_Read1AnalogInputChannel(dev, s, insn, data);
2442  /* if(i_AutoCalibration == FALSE) */
2443  if (s_BoardInfos[dev->minor].i_AutoCalibration == FALSE) {
2444  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2445  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].
2446  i_Offset +
2447  12) >> 19) & 1) != 1) ;
2448 
2449  /* outl((0x00001000 |i_ChannelNo) , devpriv->iobase+i_Offset + 4); */
2450  outl((0x00001000 | s_BoardInfos[dev->minor].
2451  i_ChannelNo),
2452  devpriv->iobase +
2453  s_BoardInfos[dev->minor].i_Offset + 4);
2454  data++;
2456  data++;
2458  }
2459  } else {
2460  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2461  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].
2462  i_Offset + 12) >> 19) & 1) !=
2463  1) ;
2464  /* outl((0x00000800|i_ChannelNo) , devpriv->iobase+i_Offset + 4); */
2465  outl((0x00000800 | s_BoardInfos[dev->minor].i_ChannelNo),
2466  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2467  4);
2468  /* ui_Configuration = inl(devpriv->iobase+i_Offset + 0); */
2469  ui_Configuration =
2470  inl(devpriv->iobase +
2471  s_BoardInfos[dev->minor].i_Offset + 0);
2472  /*************************/
2473  /*Set the time unit to ns */
2474  /*************************/
2475  /* i_TimeUnit= i_ADDIDATAConversionTimeUnit;
2476  i_ADDIDATAConversionTimeUnit= 1; */
2477  /* i_Temp= i_InterruptFlag ; */
2478  i_Temp = s_BoardInfos[dev->minor].i_InterruptFlag;
2479  /* i_InterruptFlag = ADDIDATA_DISABLE; */
2480  s_BoardInfos[dev->minor].i_InterruptFlag = ADDIDATA_DISABLE;
2481  i_APCI3200_Read1AnalogInputChannel(dev, s, insn, data);
2482  /* if(i_AutoCalibration == FALSE) */
2483  if (s_BoardInfos[dev->minor].i_AutoCalibration == FALSE) {
2484  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2485  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].
2486  i_Offset +
2487  12) >> 19) & 1) != 1) ;
2488  /* outl((0x00000800|i_ChannelNo) , devpriv->iobase+i_Offset + 4); */
2489  outl((0x00000800 | s_BoardInfos[dev->minor].
2490  i_ChannelNo),
2491  devpriv->iobase +
2492  s_BoardInfos[dev->minor].i_Offset + 4);
2493  data++;
2495  data++;
2497  }
2498  }
2499  /* i_InterruptFlag=i_Temp ; */
2500  s_BoardInfos[dev->minor].i_InterruptFlag = i_Temp;
2501  /* printk("\ni_InterruptFlag=%d\n",i_InterruptFlag); */
2502  return insn->n;
2503 }
2504 
2505 /*
2506  +----------------------------------------------------------------------------+
2507  | Function Name : int i_APCI3200_InsnWriteReleaseAnalogInput |
2508  | (struct comedi_device *dev,struct comedi_subdevice *s, |
2509  | struct comedi_insn *insn,unsigned int *data) |
2510  +----------------------------------------------------------------------------+
2511  | Task : Resets the channels |
2512  +----------------------------------------------------------------------------+
2513  | Input Parameters : struct comedi_device *dev : Driver handle |
2514  | struct comedi_subdevice *s : Subdevice Pointer |
2515  | struct comedi_insn *insn : Insn Structure Pointer |
2516  | unsigned int *data : Data Pointer
2517  +----------------------------------------------------------------------------+
2518  | Output Parameters : -- |
2519 
2520  +----------------------------------------------------------------------------+
2521  | Return Value : TRUE : No error occur |
2522  | : FALSE : Error occur. Return the error |
2523  | |
2524  +----------------------------------------------------------------------------+
2525 */
2526 
2528  struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
2529 {
2530  i_APCI3200_Reset(dev);
2531  return insn->n;
2532 }
2533 
2534 /*
2535  +----------------------------------------------------------------------------+
2536  | Function name :int i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev|
2537  | ,struct comedi_subdevice *s,struct comedi_cmd *cmd) |
2538  | |
2539  +----------------------------------------------------------------------------+
2540  | Task : Test validity for a command for cyclic anlog input |
2541  | acquisition |
2542  | |
2543  +----------------------------------------------------------------------------+
2544  | Input Parameters : struct comedi_device *dev |
2545  | struct comedi_subdevice *s |
2546  | struct comedi_cmd *cmd |
2547  | |
2548  |
2549  | |
2550  | |
2551  | |
2552  +----------------------------------------------------------------------------+
2553  | Return Value :0 |
2554  | |
2555  +----------------------------------------------------------------------------+
2556 */
2557 
2559  struct comedi_cmd *cmd)
2560 {
2561 
2562  int err = 0;
2563  unsigned int ui_ConvertTime = 0;
2564  unsigned int ui_ConvertTimeBase = 0;
2565  unsigned int ui_DelayTime = 0;
2566  unsigned int ui_DelayTimeBase = 0;
2567  int i_Triggermode = 0;
2568  int i_TriggerEdge = 0;
2569  int i_NbrOfChannel = 0;
2570  int i_Cpt = 0;
2571  double d_ConversionTimeForAllChannels = 0.0;
2572  double d_SCANTimeNewUnit = 0.0;
2573 
2574  /* Step 1 : check if triggers are trivially valid */
2575 
2576  err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
2577  err |= cfc_check_trigger_src(&cmd->scan_begin_src,
2579  err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER);
2580  err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
2581  err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
2582 
2583  if (s_BoardInfos[dev->minor].i_InterruptFlag == 0)
2584  err |= -EINVAL;
2585 
2586  if (err) {
2587  i_APCI3200_Reset(dev);
2588  return 1;
2589  }
2590 
2591  /* Step 2a : make sure trigger sources are unique */
2592 
2593  err |= cfc_check_trigger_is_unique(&cmd->start_src);
2594  err |= cfc_check_trigger_is_unique(&cmd->scan_begin_src);
2595  err |= cfc_check_trigger_is_unique(&cmd->stop_src);
2596 
2597  /* Step 2b : and mutually compatible */
2598 
2599  if (cmd->start_src == TRIG_EXT) {
2600  i_TriggerEdge = cmd->start_arg & 0xFFFF;
2601  i_Triggermode = cmd->start_arg >> 16;
2602  if (i_TriggerEdge < 1 || i_TriggerEdge > 3) {
2603  err++;
2604  printk("\nThe trigger edge selection is in error\n");
2605  }
2606  if (i_Triggermode != 2) {
2607  err++;
2608  printk("\nThe trigger mode selection is in error\n");
2609  }
2610  }
2611 
2612  if (err) {
2613  i_APCI3200_Reset(dev);
2614  return 2;
2615  }
2616  /* i_FirstChannel=cmd->chanlist[0]; */
2617  s_BoardInfos[dev->minor].i_FirstChannel = cmd->chanlist[0];
2618  /* i_LastChannel=cmd->chanlist[1]; */
2619  s_BoardInfos[dev->minor].i_LastChannel = cmd->chanlist[1];
2620 
2621  if (cmd->convert_src == TRIG_TIMER) {
2622  ui_ConvertTime = cmd->convert_arg & 0xFFFF;
2623  ui_ConvertTimeBase = cmd->convert_arg >> 16;
2624  if (ui_ConvertTime != 20 && ui_ConvertTime != 40
2625  && ui_ConvertTime != 80 && ui_ConvertTime != 160)
2626  {
2627  printk("\nThe selection of conversion time reload value is in error\n");
2628  err++;
2629  } /* if (ui_ConvertTime!=20 && ui_ConvertTime!=40 && ui_ConvertTime!=80 && ui_ConvertTime!=160 ) */
2630  if (ui_ConvertTimeBase != 2) {
2631  printk("\nThe selection of conversion time unit is in error\n");
2632  err++;
2633  } /* if(ui_ConvertTimeBase!=2) */
2634  } else {
2635  ui_ConvertTime = 0;
2636  ui_ConvertTimeBase = 0;
2637  }
2638  if (cmd->scan_begin_src == TRIG_FOLLOW) {
2639  ui_DelayTime = 0;
2640  ui_DelayTimeBase = 0;
2641  } /* if(cmd->scan_begin_src==TRIG_FOLLOW) */
2642  else {
2643  ui_DelayTime = cmd->scan_begin_arg & 0xFFFF;
2644  ui_DelayTimeBase = cmd->scan_begin_arg >> 16;
2645  if (ui_DelayTimeBase != 2 && ui_DelayTimeBase != 3) {
2646  err++;
2647  printk("\nThe Delay time base selection is in error\n");
2648  }
2649  if (ui_DelayTime < 1 || ui_DelayTime > 1023) {
2650  err++;
2651  printk("\nThe Delay time value is in error\n");
2652  }
2653  if (err) {
2654  i_APCI3200_Reset(dev);
2655  return 3;
2656  }
2657  fpu_begin();
2658  d_SCANTimeNewUnit = (double)ui_DelayTime;
2659  /* i_NbrOfChannel= i_LastChannel-i_FirstChannel + 4; */
2660  i_NbrOfChannel =
2661  s_BoardInfos[dev->minor].i_LastChannel -
2662  s_BoardInfos[dev->minor].i_FirstChannel + 4;
2663  /**********************************************************/
2664  /*calculate the total conversion time for all the channels */
2665  /**********************************************************/
2666  d_ConversionTimeForAllChannels =
2667  (double)((double)ui_ConvertTime /
2668  (double)i_NbrOfChannel);
2669 
2670  /*******************************/
2671  /*Convert the frequence in time */
2672  /*******************************/
2673  d_ConversionTimeForAllChannels =
2674  (double)1.0 / d_ConversionTimeForAllChannels;
2675  ui_ConvertTimeBase = 3;
2676  /***********************************/
2677  /*Test if the time unit is the same */
2678  /***********************************/
2679 
2680  if (ui_DelayTimeBase <= ui_ConvertTimeBase) {
2681 
2682  for (i_Cpt = 0;
2683  i_Cpt < (ui_ConvertTimeBase - ui_DelayTimeBase);
2684  i_Cpt++) {
2685 
2686  d_ConversionTimeForAllChannels =
2687  d_ConversionTimeForAllChannels * 1000;
2688  d_ConversionTimeForAllChannels =
2689  d_ConversionTimeForAllChannels + 1;
2690  }
2691  } else {
2692  for (i_Cpt = 0;
2693  i_Cpt < (ui_DelayTimeBase - ui_ConvertTimeBase);
2694  i_Cpt++) {
2695  d_SCANTimeNewUnit = d_SCANTimeNewUnit * 1000;
2696 
2697  }
2698  }
2699 
2700  if (d_ConversionTimeForAllChannels >= d_SCANTimeNewUnit) {
2701 
2702  printk("\nSCAN Delay value cannot be used\n");
2703  /*********************************/
2704  /*SCAN Delay value cannot be used */
2705  /*********************************/
2706  err++;
2707  }
2708  fpu_end();
2709  } /* else if(cmd->scan_begin_src==TRIG_FOLLOW) */
2710 
2711  if (err) {
2712  i_APCI3200_Reset(dev);
2713  return 4;
2714  }
2715 
2716  return 0;
2717 }
2718 
2719 /*
2720  +----------------------------------------------------------------------------+
2721  | Function name :int i_APCI3200_StopCyclicAcquisition(struct comedi_device *dev,|
2722  | struct comedi_subdevice *s)|
2723  | |
2724  +----------------------------------------------------------------------------+
2725  | Task : Stop the acquisition |
2726  | |
2727  +----------------------------------------------------------------------------+
2728  | Input Parameters : struct comedi_device *dev |
2729  | struct comedi_subdevice *s |
2730  | |
2731  +----------------------------------------------------------------------------+
2732  | Return Value :0 |
2733  | |
2734  +----------------------------------------------------------------------------+
2735 */
2736 
2738 {
2739  unsigned int ui_Configuration = 0;
2740  /* i_InterruptFlag=0; */
2741  /* i_Initialised=0; */
2742  /* i_Count=0; */
2743  /* i_Sum=0; */
2744  s_BoardInfos[dev->minor].i_InterruptFlag = 0;
2745  s_BoardInfos[dev->minor].i_Initialised = 0;
2746  s_BoardInfos[dev->minor].i_Count = 0;
2747  s_BoardInfos[dev->minor].i_Sum = 0;
2748 
2749  /*******************/
2750  /*Read the register */
2751  /*******************/
2752  /* ui_Configuration = inl(devpriv->iobase+i_Offset + 8); */
2753  ui_Configuration =
2754  inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
2755  /*****************************/
2756  /*Reset the START and IRQ bit */
2757  /*****************************/
2758  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2759  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2760  12) >> 19) & 1) != 1) ;
2761  /* outl((ui_Configuration & 0xFFE7FFFF),devpriv->iobase+i_Offset + 8); */
2762  outl((ui_Configuration & 0xFFE7FFFF),
2763  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
2764  return 0;
2765 }
2766 
2767 /*
2768  +----------------------------------------------------------------------------+
2769  | Function name : int i_APCI3200_CommandAnalogInput(struct comedi_device *dev, |
2770  | struct comedi_subdevice *s) |
2771  | |
2772  +----------------------------------------------------------------------------+
2773  | Task : Does asynchronous acquisition |
2774  | Determines the mode 1 or 2. |
2775  | |
2776  +----------------------------------------------------------------------------+
2777  | Input Parameters : struct comedi_device *dev |
2778  | struct comedi_subdevice *s |
2779  | |
2780  | |
2781  +----------------------------------------------------------------------------+
2782  | Return Value : |
2783  | |
2784  +----------------------------------------------------------------------------+
2785 */
2786 
2788 {
2789  struct comedi_cmd *cmd = &s->async->cmd;
2790  unsigned int ui_Configuration = 0;
2791  /* INT i_CurrentSource = 0; */
2792  unsigned int ui_Trigger = 0;
2793  unsigned int ui_TriggerEdge = 0;
2794  unsigned int ui_Triggermode = 0;
2795  unsigned int ui_ScanMode = 0;
2796  unsigned int ui_ConvertTime = 0;
2797  unsigned int ui_ConvertTimeBase = 0;
2798  unsigned int ui_DelayTime = 0;
2799  unsigned int ui_DelayTimeBase = 0;
2800  unsigned int ui_DelayMode = 0;
2801  /* i_FirstChannel=cmd->chanlist[0]; */
2802  /* i_LastChannel=cmd->chanlist[1]; */
2803  s_BoardInfos[dev->minor].i_FirstChannel = cmd->chanlist[0];
2804  s_BoardInfos[dev->minor].i_LastChannel = cmd->chanlist[1];
2805  if (cmd->start_src == TRIG_EXT) {
2806  ui_Trigger = 1;
2807  ui_TriggerEdge = cmd->start_arg & 0xFFFF;
2808  ui_Triggermode = cmd->start_arg >> 16;
2809  } /* if(cmd->start_src==TRIG_EXT) */
2810  else {
2811  ui_Trigger = 0;
2812  } /* elseif(cmd->start_src==TRIG_EXT) */
2813 
2814  if (cmd->stop_src == TRIG_COUNT) {
2815  ui_ScanMode = 0;
2816  } /* if (cmd->stop_src==TRIG_COUNT) */
2817  else {
2818  ui_ScanMode = 2;
2819  } /* else if (cmd->stop_src==TRIG_COUNT) */
2820 
2821  if (cmd->scan_begin_src == TRIG_FOLLOW) {
2822  ui_DelayTime = 0;
2823  ui_DelayTimeBase = 0;
2824  ui_DelayMode = 0;
2825  } /* if(cmd->scan_begin_src==TRIG_FOLLOW) */
2826  else {
2827  ui_DelayTime = cmd->scan_begin_arg & 0xFFFF;
2828  ui_DelayTimeBase = cmd->scan_begin_arg >> 16;
2829  ui_DelayMode = 1;
2830  } /* else if(cmd->scan_begin_src==TRIG_FOLLOW) */
2831  /* printk("\nui_DelayTime=%u\n",ui_DelayTime); */
2832  /* printk("\nui_DelayTimeBase=%u\n",ui_DelayTimeBase); */
2833  if (cmd->convert_src == TRIG_TIMER) {
2834  ui_ConvertTime = cmd->convert_arg & 0xFFFF;
2835  ui_ConvertTimeBase = cmd->convert_arg >> 16;
2836  } else {
2837  ui_ConvertTime = 0;
2838  ui_ConvertTimeBase = 0;
2839  }
2840 
2841  /* if(i_ADDIDATAType ==1 || ((i_ADDIDATAType==2))) */
2842  /* { */
2843  /**************************************************/
2844  /*Read the old configuration of the current source */
2845  /**************************************************/
2846  /* ui_Configuration = inl(devpriv->iobase+i_Offset + 12); */
2847  ui_Configuration =
2848  inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
2849  /***********************************************/
2850  /*Write the configuration of the current source */
2851  /***********************************************/
2852  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2853  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2854  12) >> 19) & 1) != 1) ;
2855  /* outl((ui_Configuration & 0xFFC00000 ), devpriv->iobase+i_Offset +12); */
2856  outl((ui_Configuration & 0xFFC00000),
2857  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
2858  /* } */
2859  ui_Configuration = 0;
2860  /* printk("\nfirstchannel=%u\n",i_FirstChannel); */
2861  /* printk("\nlastchannel=%u\n",i_LastChannel); */
2862  /* printk("\nui_Trigger=%u\n",ui_Trigger); */
2863  /* printk("\nui_TriggerEdge=%u\n",ui_TriggerEdge); */
2864  /* printk("\nui_Triggermode=%u\n",ui_Triggermode); */
2865  /* printk("\nui_DelayMode=%u\n",ui_DelayMode); */
2866  /* printk("\nui_ScanMode=%u\n",ui_ScanMode); */
2867 
2868  /* ui_Configuration = i_FirstChannel |(i_LastChannel << 8)| 0x00100000 | */
2869  ui_Configuration =
2870  s_BoardInfos[dev->minor].i_FirstChannel | (s_BoardInfos[dev->
2871  minor].
2872  i_LastChannel << 8) | 0x00100000 | (ui_Trigger << 24) |
2873  (ui_TriggerEdge << 25) | (ui_Triggermode << 27) | (ui_DelayMode
2874  << 18) | (ui_ScanMode << 16);
2875 
2876  /*************************/
2877  /*Write the Configuration */
2878  /*************************/
2879  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2880  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2881  12) >> 19) & 1) != 1) ;
2882  /* outl( ui_Configuration, devpriv->iobase+i_Offset + 0x8); */
2883  outl(ui_Configuration,
2884  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x8);
2885  /***********************/
2886  /*Write the Delay Value */
2887  /***********************/
2888  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2889  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2890  12) >> 19) & 1) != 1) ;
2891  /* outl(ui_DelayTime,devpriv->iobase+i_Offset + 40); */
2892  outl(ui_DelayTime,
2893  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 40);
2894  /***************************/
2895  /*Write the Delay time base */
2896  /***************************/
2897  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2898  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2899  12) >> 19) & 1) != 1) ;
2900  /* outl(ui_DelayTimeBase,devpriv->iobase+i_Offset + 44); */
2901  outl(ui_DelayTimeBase,
2902  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 44);
2903  /*********************************/
2904  /*Write the conversion time value */
2905  /*********************************/
2906  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2907  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2908  12) >> 19) & 1) != 1) ;
2909  /* outl(ui_ConvertTime,devpriv->iobase+i_Offset + 32); */
2910  outl(ui_ConvertTime,
2911  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
2912 
2913  /********************************/
2914  /*Write the conversion time base */
2915  /********************************/
2916  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2917  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2918  12) >> 19) & 1) != 1) ;
2919  /* outl(ui_ConvertTimeBase,devpriv->iobase+i_Offset + 36); */
2920  outl(ui_ConvertTimeBase,
2921  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
2922  /*******************/
2923  /*Read the register */
2924  /*******************/
2925  /* ui_Configuration = inl(devpriv->iobase+i_Offset + 4); */
2926  ui_Configuration =
2927  inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4);
2928  /******************/
2929  /*Set the SCAN bit */
2930  /******************/
2931  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2932  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2933  12) >> 19) & 1) != 1) ;
2934 
2935  /* outl(((ui_Configuration & 0x1E0FF) | 0x00002000),devpriv->iobase+i_Offset + 4); */
2936  outl(((ui_Configuration & 0x1E0FF) | 0x00002000),
2937  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4);
2938  /*******************/
2939  /*Read the register */
2940  /*******************/
2941  ui_Configuration = 0;
2942  /* ui_Configuration = inl(devpriv->iobase+i_Offset + 8); */
2943  ui_Configuration =
2944  inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
2945 
2946  /*******************/
2947  /*Set the START bit */
2948  /*******************/
2949  /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2950  while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2951  12) >> 19) & 1) != 1) ;
2952  /* outl((ui_Configuration | 0x00080000),devpriv->iobase+i_Offset + 8); */
2953  outl((ui_Configuration | 0x00080000),
2954  devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
2955  return 0;
2956 }
2957 
2958 /*
2959  +----------------------------------------------------------------------------+
2960  | Function Name : int i_APCI3200_Reset(struct comedi_device *dev) |
2961  | |
2962  +----------------------------------------------------------------------------+
2963  | Task :Resets the registers of the card |
2964  +----------------------------------------------------------------------------+
2965  | Input Parameters : |
2966  +----------------------------------------------------------------------------+
2967  | Output Parameters : -- |
2968  +----------------------------------------------------------------------------+
2969  | Return Value : |
2970  | |
2971  +----------------------------------------------------------------------------+
2972 */
2973 
2975 {
2976  int i_Temp;
2977  unsigned int dw_Dummy;
2978  /* i_InterruptFlag=0; */
2979  /* i_Initialised==0; */
2980  /* i_Count=0; */
2981  /* i_Sum=0; */
2982 
2983  s_BoardInfos[dev->minor].i_InterruptFlag = 0;
2984  s_BoardInfos[dev->minor].i_Initialised = 0;
2985  s_BoardInfos[dev->minor].i_Count = 0;
2986  s_BoardInfos[dev->minor].i_Sum = 0;
2987  s_BoardInfos[dev->minor].b_StructInitialized = 0;
2988 
2989  outl(0x83838383, devpriv->i_IobaseAmcc + 0x60);
2990 
2991  /* Enable the interrupt for the controller */
2992  dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38);
2993  outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38);
2994  outl(0, devpriv->i_IobaseAddon); /* Resets the output */
2995  /***************/
2996  /*Empty the buffer */
2997  /**************/
2998  for (i_Temp = 0; i_Temp <= 95; i_Temp++) {
2999  /* ui_InterruptChannelValue[i_Temp]=0; */
3000  s_BoardInfos[dev->minor].ui_InterruptChannelValue[i_Temp] = 0;
3001  } /* for(i_Temp=0;i_Temp<=95;i_Temp++) */
3002  /*****************************/
3003  /*Reset the START and IRQ bit */
3004  /*****************************/
3005  for (i_Temp = 0; i_Temp <= 192;) {
3006  while (((inl(devpriv->iobase + i_Temp + 12) >> 19) & 1) != 1) ;
3007  outl(0, devpriv->iobase + i_Temp + 8);
3008  i_Temp = i_Temp + 64;
3009  } /* for(i_Temp=0;i_Temp<=192;i_Temp+64) */
3010  return 0;
3011 }
3012 
3013 /*
3014  +----------------------------------------------------------------------------+
3015  | Function Name : static void v_APCI3200_Interrupt |
3016  | (int irq , void *d) |
3017  +----------------------------------------------------------------------------+
3018  | Task : Interrupt processing Routine |
3019  +----------------------------------------------------------------------------+
3020  | Input Parameters : int irq : irq number |
3021  | void *d : void pointer |
3022  +----------------------------------------------------------------------------+
3023  | Output Parameters : -- |
3024  +----------------------------------------------------------------------------+
3025  | Return Value : TRUE : No error occur |
3026  | : FALSE : Error occur. Return the error |
3027  | |
3028  +----------------------------------------------------------------------------+
3029 */
3030 void v_APCI3200_Interrupt(int irq, void *d)
3031 {
3032  struct comedi_device *dev = d;
3033  unsigned int ui_StatusRegister = 0;
3034  unsigned int ui_ChannelNumber = 0;
3035  int i_CalibrationFlag = 0;
3036  int i_CJCFlag = 0;
3037  unsigned int ui_DummyValue = 0;
3038  unsigned int ui_DigitalTemperature = 0;
3039  unsigned int ui_DigitalInput = 0;
3040  int i_ConvertCJCCalibration;
3041 
3042  /* BEGIN JK TEST */
3043  int i_ReturnValue = 0;
3044  /* END JK TEST */
3045 
3046  /* printk ("\n i_ScanType = %i i_ADDIDATAType = %i", s_BoardInfos [dev->minor].i_ScanType, s_BoardInfos [dev->minor].i_ADDIDATAType); */
3047 
3048  /* switch(i_ScanType) */
3049  switch (s_BoardInfos[dev->minor].i_ScanType) {
3050  case 0:
3051  case 1:
3052  /* switch(i_ADDIDATAType) */
3053  switch (s_BoardInfos[dev->minor].i_ADDIDATAType) {
3054  case 0:
3055  case 1:
3056 
3057  /************************************/
3058  /*Read the interrupt status register */
3059  /************************************/
3060  /* ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16); */
3061  ui_StatusRegister =
3062  inl(devpriv->iobase +
3063  s_BoardInfos[dev->minor].i_Offset + 16);
3064  if ((ui_StatusRegister & 0x2) == 0x2) {
3065  /* i_CalibrationFlag = ((inl(devpriv->iobase+i_Offset + 12) & 0x00060000) >> 17); */
3066  i_CalibrationFlag =
3067  ((inl(devpriv->iobase +
3068  s_BoardInfos[dev->
3069  minor].
3070  i_Offset +
3071  12) & 0x00060000) >>
3072  17);
3073  /*************************/
3074  /*Read the channel number */
3075  /*************************/
3076  /* ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24); */
3077 
3078  /*************************************/
3079  /*Read the digital analog input value */
3080  /*************************************/
3081  /* ui_DigitalInput = inl(devpriv->iobase+i_Offset + 28); */
3082  ui_DigitalInput =
3083  inl(devpriv->iobase +
3084  s_BoardInfos[dev->minor].i_Offset + 28);
3085 
3086  /***********************************************/
3087  /* Test if the value read is the channel value */
3088  /***********************************************/
3089  if (i_CalibrationFlag == 0) {
3090  /* ui_InterruptChannelValue[i_Count + 0] = ui_DigitalInput; */
3091  s_BoardInfos[dev->minor].
3093  [s_BoardInfos[dev->minor].
3094  i_Count + 0] = ui_DigitalInput;
3095 
3096  /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
3097  /*
3098  printk("\n 1 - i_APCI3200_GetChannelCalibrationValue (dev, s_BoardInfos %i", ui_ChannelNumber);
3099  i_APCI3200_GetChannelCalibrationValue (dev, s_BoardInfos [dev->minor].ui_Channel_num,
3100  &s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count + 6],
3101  &s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count + 7],
3102  &s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count + 8]);
3103  */
3104  /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
3105 
3106  /******************************************************/
3107  /*Start the conversion of the calibration offset value */
3108  /******************************************************/
3110  (dev, &ui_DummyValue);
3111  } /* if (i_CalibrationFlag == 0) */
3112  /**********************************************************/
3113  /* Test if the value read is the calibration offset value */
3114  /**********************************************************/
3115 
3116  if (i_CalibrationFlag == 1) {
3117 
3118  /******************/
3119  /* Save the value */
3120  /******************/
3121 
3122  /* ui_InterruptChannelValue[i_Count + 1] = ui_DigitalInput; */
3123  s_BoardInfos[dev->minor].
3125  [s_BoardInfos[dev->minor].
3126  i_Count + 1] = ui_DigitalInput;
3127 
3128  /******************************************************/
3129  /* Start the conversion of the calibration gain value */
3130  /******************************************************/
3132  &ui_DummyValue);
3133  } /* if (i_CalibrationFlag == 1) */
3134  /******************************************************/
3135  /*Test if the value read is the calibration gain value */
3136  /******************************************************/
3137 
3138  if (i_CalibrationFlag == 2) {
3139 
3140  /****************/
3141  /*Save the value */
3142  /****************/
3143  /* ui_InterruptChannelValue[i_Count + 2] = ui_DigitalInput; */
3144  s_BoardInfos[dev->minor].
3146  [s_BoardInfos[dev->minor].
3147  i_Count + 2] = ui_DigitalInput;
3148  /* if(i_ScanType==1) */
3149  if (s_BoardInfos[dev->minor].
3150  i_ScanType == 1) {
3151 
3152  /* i_InterruptFlag=0; */
3153  s_BoardInfos[dev->minor].
3154  i_InterruptFlag = 0;
3155  /* i_Count=i_Count + 6; */
3156  /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
3157  /* s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count + 6; */
3158  s_BoardInfos[dev->minor].
3159  i_Count =
3160  s_BoardInfos[dev->
3161  minor].i_Count + 9;
3162  /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
3163  } /* if(i_ScanType==1) */
3164  else {
3165  /* i_Count=0; */
3166  s_BoardInfos[dev->minor].
3167  i_Count = 0;
3168  } /* elseif(i_ScanType==1) */
3169  /* if(i_ScanType!=1) */
3170  if (s_BoardInfos[dev->minor].
3171  i_ScanType != 1) {
3172  i_ReturnValue = send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */
3173  } /* if(i_ScanType!=1) */
3174  else {
3175  /* if(i_ChannelCount==i_Sum) */
3176  if (s_BoardInfos[dev->minor].
3177  i_ChannelCount ==
3178  s_BoardInfos[dev->
3179  minor].i_Sum) {
3180  send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */
3181  }
3182  } /* if(i_ScanType!=1) */
3183  } /* if (i_CalibrationFlag == 2) */
3184  } /* if ((ui_StatusRegister & 0x2) == 0x2) */
3185 
3186  break;
3187 
3188  case 2:
3189  /************************************/
3190  /*Read the interrupt status register */
3191  /************************************/
3192 
3193  /* ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16); */
3194  ui_StatusRegister =
3195  inl(devpriv->iobase +
3196  s_BoardInfos[dev->minor].i_Offset + 16);
3197  /*************************/
3198  /*Test if interrupt occur */
3199  /*************************/
3200 
3201  if ((ui_StatusRegister & 0x2) == 0x2) {
3202 
3203  /* i_CJCFlag = ((inl(devpriv->iobase+i_Offset + 4) & 0x00000400) >> 10); */
3204  i_CJCFlag =
3205  ((inl(devpriv->iobase +
3206  s_BoardInfos[dev->
3207  minor].
3208  i_Offset +
3209  4) & 0x00000400) >> 10);
3210 
3211  /* i_CalibrationFlag = ((inl(devpriv->iobase+i_Offset + 12) & 0x00060000) >> 17); */
3212  i_CalibrationFlag =
3213  ((inl(devpriv->iobase +
3214  s_BoardInfos[dev->
3215  minor].
3216  i_Offset +
3217  12) & 0x00060000) >>
3218  17);
3219 
3220  /*************************/
3221  /*Read the channel number */
3222  /*************************/
3223 
3224  /* ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24); */
3225  ui_ChannelNumber =
3226  inl(devpriv->iobase +
3227  s_BoardInfos[dev->minor].i_Offset + 24);
3228  /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
3229  s_BoardInfos[dev->minor].ui_Channel_num =
3230  ui_ChannelNumber;
3231  /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
3232 
3233  /************************************/
3234  /*Read the digital temperature value */
3235  /************************************/
3236  /* ui_DigitalTemperature = inl(devpriv->iobase+i_Offset + 28); */
3237  ui_DigitalTemperature =
3238  inl(devpriv->iobase +
3239  s_BoardInfos[dev->minor].i_Offset + 28);
3240 
3241  /*********************************************/
3242  /*Test if the value read is the channel value */
3243  /*********************************************/
3244 
3245  if ((i_CalibrationFlag == 0)
3246  && (i_CJCFlag == 0)) {
3247  /* ui_InterruptChannelValue[i_Count + 0]=ui_DigitalTemperature; */
3248  s_BoardInfos[dev->minor].
3250  [s_BoardInfos[dev->minor].
3251  i_Count + 0] =
3252  ui_DigitalTemperature;
3253 
3254  /*********************************/
3255  /*Start the conversion of the CJC */
3256  /*********************************/
3258  &ui_DummyValue);
3259 
3260  } /* if ((i_CalibrationFlag == 0) && (i_CJCFlag == 0)) */
3261 
3262  /*****************************************/
3263  /*Test if the value read is the CJC value */
3264  /*****************************************/
3265 
3266  if ((i_CJCFlag == 1)
3267  && (i_CalibrationFlag == 0)) {
3268  /* ui_InterruptChannelValue[i_Count + 3]=ui_DigitalTemperature; */
3269  s_BoardInfos[dev->minor].
3271  [s_BoardInfos[dev->minor].
3272  i_Count + 3] =
3273  ui_DigitalTemperature;
3274 
3275  /******************************************************/
3276  /*Start the conversion of the calibration offset value */
3277  /******************************************************/
3279  (dev, &ui_DummyValue);
3280  } /* if ((i_CJCFlag == 1) && (i_CalibrationFlag == 0)) */
3281 
3282  /********************************************************/
3283  /*Test if the value read is the calibration offset value */
3284  /********************************************************/
3285 
3286  if ((i_CalibrationFlag == 1)
3287  && (i_CJCFlag == 0)) {
3288  /* ui_InterruptChannelValue[i_Count + 1]=ui_DigitalTemperature; */
3289  s_BoardInfos[dev->minor].
3291  [s_BoardInfos[dev->minor].
3292  i_Count + 1] =
3293  ui_DigitalTemperature;
3294 
3295  /****************************************************/
3296  /*Start the conversion of the calibration gain value */
3297  /****************************************************/
3299  &ui_DummyValue);
3300 
3301  } /* if ((i_CalibrationFlag == 1) && (i_CJCFlag == 0)) */
3302 
3303  /******************************************************/
3304  /*Test if the value read is the calibration gain value */
3305  /******************************************************/
3306 
3307  if ((i_CalibrationFlag == 2)
3308  && (i_CJCFlag == 0)) {
3309  /* ui_InterruptChannelValue[i_Count + 2]=ui_DigitalTemperature; */
3310  s_BoardInfos[dev->minor].
3312  [s_BoardInfos[dev->minor].
3313  i_Count + 2] =
3314  ui_DigitalTemperature;
3315 
3316  /**********************************************************/
3317  /*Test if the Calibration channel must be read for the CJC */
3318  /**********************************************************/
3319 
3320  /*Test if the polarity is the same */
3321  /**********************************/
3322  /* if(i_CJCPolarity!=i_ADDIDATAPolarity) */
3323  if (s_BoardInfos[dev->minor].
3324  i_CJCPolarity !=
3325  s_BoardInfos[dev->minor].
3327  i_ConvertCJCCalibration = 1;
3328  } /* if(i_CJCPolarity!=i_ADDIDATAPolarity) */
3329  else {
3330  /* if(i_CJCGain==i_ADDIDATAGain) */
3331  if (s_BoardInfos[dev->minor].
3332  i_CJCGain ==
3333  s_BoardInfos[dev->
3334  minor].
3335  i_ADDIDATAGain) {
3336  i_ConvertCJCCalibration
3337  = 0;
3338  } /* if(i_CJCGain==i_ADDIDATAGain) */
3339  else {
3340  i_ConvertCJCCalibration
3341  = 1;
3342  } /* elseif(i_CJCGain==i_ADDIDATAGain) */
3343  } /* elseif(i_CJCPolarity!=i_ADDIDATAPolarity) */
3344  if (i_ConvertCJCCalibration == 1) {
3345  /****************************************************************/
3346  /*Start the conversion of the calibration gain value for the CJC */
3347  /****************************************************************/
3349  &ui_DummyValue);
3350 
3351  } /* if(i_ConvertCJCCalibration==1) */
3352  else {
3353  /* ui_InterruptChannelValue[i_Count + 4]=0; */
3354  /* ui_InterruptChannelValue[i_Count + 5]=0; */
3355  s_BoardInfos[dev->minor].
3357  [s_BoardInfos[dev->
3358  minor].i_Count +
3359  4] = 0;
3360  s_BoardInfos[dev->minor].
3362  [s_BoardInfos[dev->
3363  minor].i_Count +
3364  5] = 0;
3365  } /* elseif(i_ConvertCJCCalibration==1) */
3366  } /* else if ((i_CalibrationFlag == 2) && (i_CJCFlag == 0)) */
3367 
3368  /********************************************************************/
3369  /*Test if the value read is the calibration offset value for the CJC */
3370  /********************************************************************/
3371 
3372  if ((i_CalibrationFlag == 1)
3373  && (i_CJCFlag == 1)) {
3374  /* ui_InterruptChannelValue[i_Count + 4]=ui_DigitalTemperature; */
3375  s_BoardInfos[dev->minor].
3377  [s_BoardInfos[dev->minor].
3378  i_Count + 4] =
3379  ui_DigitalTemperature;
3380 
3381  /****************************************************************/
3382  /*Start the conversion of the calibration gain value for the CJC */
3383  /****************************************************************/
3385  &ui_DummyValue);
3386 
3387  } /* if ((i_CalibrationFlag == 1) && (i_CJCFlag == 1)) */
3388 
3389  /******************************************************************/
3390  /*Test if the value read is the calibration gain value for the CJC */
3391  /******************************************************************/
3392 
3393  if ((i_CalibrationFlag == 2)
3394  && (i_CJCFlag == 1)) {
3395  /* ui_InterruptChannelValue[i_Count + 5]=ui_DigitalTemperature; */
3396  s_BoardInfos[dev->minor].
3398  [s_BoardInfos[dev->minor].
3399  i_Count + 5] =
3400  ui_DigitalTemperature;
3401 
3402  /* if(i_ScanType==1) */
3403  if (s_BoardInfos[dev->minor].
3404  i_ScanType == 1) {
3405 
3406  /* i_InterruptFlag=0; */
3407  s_BoardInfos[dev->minor].
3408  i_InterruptFlag = 0;
3409  /* i_Count=i_Count + 6; */
3410  /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
3411  /* s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count + 6; */
3412  s_BoardInfos[dev->minor].
3413  i_Count =
3414  s_BoardInfos[dev->
3415  minor].i_Count + 9;
3416  /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
3417  } /* if(i_ScanType==1) */
3418  else {
3419  /* i_Count=0; */
3420  s_BoardInfos[dev->minor].
3421  i_Count = 0;
3422  } /* elseif(i_ScanType==1) */
3423 
3424  /* if(i_ScanType!=1) */
3425  if (s_BoardInfos[dev->minor].
3426  i_ScanType != 1) {
3427  send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */
3428  } /* if(i_ScanType!=1) */
3429  else {
3430  /* if(i_ChannelCount==i_Sum) */
3431  if (s_BoardInfos[dev->minor].
3432  i_ChannelCount ==
3433  s_BoardInfos[dev->
3434  minor].i_Sum) {
3435  send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */
3436 
3437  } /* if(i_ChannelCount==i_Sum) */
3438  } /* else if(i_ScanType!=1) */
3439  } /* if ((i_CalibrationFlag == 2) && (i_CJCFlag == 1)) */
3440 
3441  } /* else if ((ui_StatusRegister & 0x2) == 0x2) */
3442  break;
3443  } /* switch(i_ADDIDATAType) */
3444  break;
3445  case 2:
3446  case 3:
3448  break;
3449  } /* switch(i_ScanType) */
3450  return;
3451 }
3452 
3453 /*
3454  +----------------------------------------------------------------------------+
3455  | Function name :int i_APCI3200_InterruptHandleEos(struct comedi_device *dev) |
3456  | |
3457  | |
3458  +----------------------------------------------------------------------------+
3459  | Task : . |
3460  | This function copies the acquired data(from FIFO) |
3461  | to Comedi buffer. |
3462  | |
3463  +----------------------------------------------------------------------------+
3464  | Input Parameters : struct comedi_device *dev |
3465  | |
3466  | |
3467  +----------------------------------------------------------------------------+
3468  | Return Value : 0 |
3469  | |
3470  +----------------------------------------------------------------------------+
3471 */
3473 {
3474  unsigned int ui_StatusRegister = 0;
3475  struct comedi_subdevice *s = &dev->subdevices[0];
3476 
3477  /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
3478  /* comedi_async *async = s->async; */
3479  /* UINT *data; */
3480  /* data=async->data+async->buf_int_ptr;//new samples added from here onwards */
3481  int n = 0, i = 0;
3482  /* END JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
3483 
3484  /************************************/
3485  /*Read the interrupt status register */
3486  /************************************/
3487  /* ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16); */
3488  ui_StatusRegister =
3489  inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 16);
3490 
3491  /*************************/
3492  /*Test if interrupt occur */
3493  /*************************/
3494 
3495  if ((ui_StatusRegister & 0x2) == 0x2) {
3496  /*************************/
3497  /*Read the channel number */
3498  /*************************/
3499  /* ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24); */
3500  /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
3501  /* This value is not used */
3502  /* ui_ChannelNumber = inl(devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 24); */
3503  s->async->events = 0;
3504  /* END JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
3505 
3506  /*************************************/
3507  /*Read the digital Analog Input value */
3508  /*************************************/
3509 
3510  /* data[i_Count] = inl(devpriv->iobase+i_Offset + 28); */
3511  /* Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
3512  /* data[s_BoardInfos [dev->minor].i_Count] = inl(devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 28); */
3513  s_BoardInfos[dev->minor].ui_ScanValueArray[s_BoardInfos[dev->
3514  minor].i_Count] =
3515  inl(devpriv->iobase +
3516  s_BoardInfos[dev->minor].i_Offset + 28);
3517  /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
3518 
3519  /* if((i_Count == (i_LastChannel-i_FirstChannel+3))) */
3520  if ((s_BoardInfos[dev->minor].i_Count ==
3521  (s_BoardInfos[dev->minor].i_LastChannel -
3522  s_BoardInfos[dev->minor].
3523  i_FirstChannel + 3))) {
3524 
3525  /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
3526  s_BoardInfos[dev->minor].i_Count++;
3527 
3528  for (i = s_BoardInfos[dev->minor].i_FirstChannel;
3529  i <= s_BoardInfos[dev->minor].i_LastChannel;
3530  i++) {
3532  &s_BoardInfos[dev->minor].
3533  ui_ScanValueArray[s_BoardInfos[dev->
3534  minor].i_Count + ((i -
3535  s_BoardInfos
3536  [dev->minor].
3538  * 3)],
3539  &s_BoardInfos[dev->minor].
3540  ui_ScanValueArray[s_BoardInfos[dev->
3541  minor].i_Count + ((i -
3542  s_BoardInfos
3543  [dev->minor].
3544  i_FirstChannel)
3545  * 3) + 1],
3546  &s_BoardInfos[dev->minor].
3547  ui_ScanValueArray[s_BoardInfos[dev->
3548  minor].i_Count + ((i -
3549  s_BoardInfos
3550  [dev->minor].
3551  i_FirstChannel)
3552  * 3) + 2]);
3553  }
3554 
3555  /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
3556 
3557  /* i_Count=-1; */
3558 
3559  s_BoardInfos[dev->minor].i_Count = -1;
3560 
3561  /* async->buf_int_count+=(i_LastChannel-i_FirstChannel+4)*sizeof(unsigned int); */
3562  /* Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
3563  /* async->buf_int_count+=(s_BoardInfos [dev->minor].i_LastChannel-s_BoardInfos [dev->minor].i_FirstChannel+4)*sizeof(unsigned int); */
3564  /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
3565  /* async->buf_int_ptr+=(i_LastChannel-i_FirstChannel+4)*sizeof(unsigned int); */
3566  /* Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
3567  /* async->buf_int_ptr+=(s_BoardInfos [dev->minor].i_LastChannel-s_BoardInfos [dev->minor].i_FirstChannel+4)*sizeof(unsigned int); */
3568  /* comedi_eos(dev,s); */
3569 
3570  /* Set the event type (Comedi Buffer End Of Scan) */
3571  s->async->events |= COMEDI_CB_EOS;
3572 
3573  /* Test if enougth memory is available and allocate it for 7 values */
3574  /* n = comedi_buf_write_alloc(s->async, 7*sizeof(unsigned int)); */
3576  (7 + 12) * sizeof(unsigned int));
3577 
3578  /* If not enough memory available, event is set to Comedi Buffer Error */
3579  if (n > ((7 + 12) * sizeof(unsigned int))) {
3580  printk("\ncomedi_buf_write_alloc n = %i", n);
3581  s->async->events |= COMEDI_CB_ERROR;
3582  }
3583  /* Write all 7 scan values in the comedi buffer */
3585  (unsigned int *) s_BoardInfos[dev->minor].
3586  ui_ScanValueArray, (7 + 12) * sizeof(unsigned int));
3587 
3588  /* Update comedi buffer pinters indexes */
3590  (7 + 12) * sizeof(unsigned int));
3591 
3592  /* Send events */
3593  comedi_event(dev, s);
3594  /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
3595 
3596  /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
3597  /* */
3598  /* if (s->async->buf_int_ptr>=s->async->data_len) // for buffer rool over */
3599  /* { */
3600  /* /* buffer rollover */ */
3601  /* s->async->buf_int_ptr=0; */
3602  /* comedi_eobuf(dev,s); */
3603  /* } */
3604  /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
3605  }
3606  /* i_Count++; */
3607  s_BoardInfos[dev->minor].i_Count++;
3608  }
3609  /* i_InterruptFlag=0; */
3610  s_BoardInfos[dev->minor].i_InterruptFlag = 0;
3611  return 0;
3612 }