4 Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
10 Fax: +49(0)7223/9493-92
11 http://www.addi-data.com
14 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
16 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 You should also find the complete GPL in the COPYING file accompanying this source code.
25 +-----------------------------------------------------------------------+
26 | (C) ADDI-DATA GmbH Dieselstrasse 3 D-77833 Ottersweier |
27 +-----------------------------------------------------------------------+
28 | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
29 | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
30 +-----------------------------------------------------------------------+
31 | Project : APCI-3XXX | Compiler : GCC |
32 | Module name : hwdrv_apci3xxx.c| Version : 2.96 |
33 +-------------------------------+---------------------------------------+
34 | Project manager: S. Weber | Date : 15/09/2005 |
35 +-----------------------------------------------------------------------+
36 | Description :APCI3XXX Module. Hardware abstraction Layer for APCI3XXX|
37 +-----------------------------------------------------------------------+
39 +-----------------------------------------------------------------------+
40 | Date | Author | Description of updates |
41 +----------+-----------+------------------------------------------------+
44 +----------+-----------+------------------------------------------------+
47 #include "hwdrv_apci3xxx.h"
50 +----------------------------------------------------------------------------+
51 | ANALOG INPUT FUNCTIONS |
52 +----------------------------------------------------------------------------+
56 +----------------------------------------------------------------------------+
57 | Function Name : int i_APCI3XXX_TestConversionStarted |
58 | (struct comedi_device *dev) |
59 +----------------------------------------------------------------------------+
60 | Task Test if any conversion started |
61 +----------------------------------------------------------------------------+
62 | Input Parameters : - |
63 +----------------------------------------------------------------------------+
64 | Output Parameters : - |
65 +----------------------------------------------------------------------------+
66 | Return Value : 0 : Conversion not started |
67 | 1 : Conversion started |
68 +----------------------------------------------------------------------------+
70 static int i_APCI3XXX_TestConversionStarted(struct comedi_device *dev)
72 if ((readl(devpriv->dw_AiBase + 8) & 0x80000UL) == 0x80000UL)
80 +----------------------------------------------------------------------------+
81 | Function Name : int i_APCI3XXX_AnalogInputConfigOperatingMode |
82 | (struct comedi_device *dev, |
83 | struct comedi_subdevice *s, |
84 | struct comedi_insn *insn, |
85 | unsigned int *data) |
86 +----------------------------------------------------------------------------+
87 | Task Converting mode and convert time selection |
88 +----------------------------------------------------------------------------+
89 | Input Parameters : b_SingleDiff = (unsigned char) data[1]; |
90 | b_TimeBase = (unsigned char) data[2]; (0: ns, 1:micros 2:ms)|
91 | dw_ReloadValue = (unsigned int) data[3]; |
93 +----------------------------------------------------------------------------+
94 | Output Parameters : - |
95 +----------------------------------------------------------------------------+
96 | Return Value :>0 : No error |
97 | -1 : Single/Diff selection error |
98 | -2 : Convert time base unity selection error |
99 | -3 : Convert time value selection error |
100 | -10: Any conversion started |
102 | -100 : Config command error |
103 | -101 : Data size error |
104 +----------------------------------------------------------------------------+
106 static int i_APCI3XXX_AnalogInputConfigOperatingMode(struct comedi_device *dev,
107 struct comedi_subdevice *s,
108 struct comedi_insn *insn,
111 int i_ReturnValue = insn->n;
112 unsigned char b_TimeBase = 0;
113 unsigned char b_SingleDiff = 0;
114 unsigned int dw_ReloadValue = 0;
115 unsigned int dw_TestReloadValue = 0;
117 /************************/
118 /* Test the buffer size */
119 /************************/
122 /****************************/
123 /* Get the Singel/Diff flag */
124 /****************************/
126 b_SingleDiff = (unsigned char) data[1];
128 /****************************/
129 /* Get the time base unitiy */
130 /****************************/
132 b_TimeBase = (unsigned char) data[2];
134 /*************************************/
135 /* Get the convert time reload value */
136 /*************************************/
138 dw_ReloadValue = (unsigned int) data[3];
140 /**********************/
141 /* Test the time base */
142 /**********************/
144 if ((this_board->b_AvailableConvertUnit & (1 << b_TimeBase)) !=
146 /*******************************/
147 /* Test the convert time value */
148 /*******************************/
150 if (dw_ReloadValue <= 65535) {
151 dw_TestReloadValue = dw_ReloadValue;
153 if (b_TimeBase == 1) {
155 dw_TestReloadValue * 1000UL;
157 if (b_TimeBase == 2) {
159 dw_TestReloadValue * 1000000UL;
162 /*******************************/
163 /* Test the convert time value */
164 /*******************************/
166 if (dw_TestReloadValue >=
167 devpriv->s_EeParameters.
168 ui_MinAcquisitiontimeNs) {
169 if ((b_SingleDiff == APCI3XXX_SINGLE)
172 if (((b_SingleDiff == APCI3XXX_SINGLE)
173 && (devpriv->s_EeParameters.i_NbrAiChannel == 0))
174 || ((b_SingleDiff == APCI3XXX_DIFF)
175 && (this_board->i_NbrAiChannelDiff == 0))
177 /*******************************/
178 /* Single/Diff selection error */
179 /*******************************/
181 printk("Single/Diff selection error\n");
184 /**********************************/
185 /* Test if conversion not started */
186 /**********************************/
188 if (i_APCI3XXX_TestConversionStarted(dev) == 0) {
190 ui_EocEosConversionTime
195 b_EocEosConversionTimeBase
206 /*******************************/
207 /* Set the convert timing unit */
208 /*******************************/
210 writel((unsigned int)b_TimeBase,
211 devpriv->dw_AiBase + 36);
213 /**************************/
214 /* Set the convert timing */
215 /*************************/
217 writel(dw_ReloadValue, devpriv->dw_AiBase + 32);
219 /**************************/
220 /* Any conversion started */
221 /**************************/
223 printk("Any conversion started\n");
229 /*******************************/
230 /* Single/Diff selection error */
231 /*******************************/
233 printk("Single/Diff selection error\n");
237 /************************/
238 /* Time selection error */
239 /************************/
241 printk("Convert time value selection error\n");
245 /************************/
246 /* Time selection error */
247 /************************/
249 printk("Convert time value selection error\n");
253 /*****************************/
254 /* Time base selection error */
255 /*****************************/
257 printk("Convert time base unity selection error\n");
261 /*******************/
262 /* Data size error */
263 /*******************/
265 printk("Buffer size error\n");
266 i_ReturnValue = -101;
269 return i_ReturnValue;
273 +----------------------------------------------------------------------------+
274 | Function Name : int i_APCI3XXX_InsnConfigAnalogInput |
275 | (struct comedi_device *dev, |
276 | struct comedi_subdevice *s, |
277 | struct comedi_insn *insn, |
278 | unsigned int *data) |
279 +----------------------------------------------------------------------------+
280 | Task Converting mode and convert time selection |
281 +----------------------------------------------------------------------------+
282 | Input Parameters : b_ConvertMode = (unsigned char) data[0]; |
283 | b_TimeBase = (unsigned char) data[1]; (0: ns, 1:micros 2:ms)|
284 | dw_ReloadValue = (unsigned int) data[2]; |
286 +----------------------------------------------------------------------------+
287 | Output Parameters : - |
288 +----------------------------------------------------------------------------+
289 | Return Value :>0: No error |
291 | -100 : Config command error |
292 | -101 : Data size error |
293 +----------------------------------------------------------------------------+
295 static int i_APCI3XXX_InsnConfigAnalogInput(struct comedi_device *dev,
296 struct comedi_subdevice *s,
297 struct comedi_insn *insn,
300 int i_ReturnValue = insn->n;
302 /************************/
303 /* Test the buffer size */
304 /************************/
307 switch ((unsigned char) data[0]) {
308 case APCI3XXX_CONFIGURATION:
310 i_APCI3XXX_AnalogInputConfigOperatingMode(dev,
315 i_ReturnValue = -100;
316 printk("Config command error %d\n", data[0]);
320 /*******************/
321 /* Data size error */
322 /*******************/
324 printk("Buffer size error\n");
325 i_ReturnValue = -101;
328 return i_ReturnValue;
332 +----------------------------------------------------------------------------+
333 | Function Name : int i_APCI3XXX_InsnReadAnalogInput |
334 | (struct comedi_device *dev, |
335 | struct comedi_subdevice *s, |
336 | struct comedi_insn *insn, |
337 | unsigned int *data) |
338 +----------------------------------------------------------------------------+
339 | Task Read 1 analog input |
340 +----------------------------------------------------------------------------+
341 | Input Parameters : b_Range = CR_RANGE(insn->chanspec); |
342 | b_Channel = CR_CHAN(insn->chanspec); |
343 | dw_NbrOfAcquisition = insn->n; |
344 +----------------------------------------------------------------------------+
345 | Output Parameters : - |
346 +----------------------------------------------------------------------------+
347 | Return Value :>0: No error |
348 | -3 : Channel selection error |
349 | -4 : Configuration selelection error |
350 | -10: Any conversion started |
352 | -100 : Config command error |
353 | -101 : Data size error |
354 +----------------------------------------------------------------------------+
356 static int i_APCI3XXX_InsnReadAnalogInput(struct comedi_device *dev,
357 struct comedi_subdevice *s,
358 struct comedi_insn *insn,
361 int i_ReturnValue = insn->n;
362 unsigned char b_Configuration = (unsigned char) CR_RANGE(insn->chanspec);
363 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
364 unsigned int dw_Temp = 0;
365 unsigned int dw_Configuration = 0;
366 unsigned int dw_AcquisitionCpt = 0;
367 unsigned char b_Interrupt = 0;
369 /*************************************/
370 /* Test if operating mode configured */
371 /*************************************/
373 if (devpriv->b_AiInitialisation) {
374 /***************************/
375 /* Test the channel number */
376 /***************************/
378 if (((b_Channel < devpriv->s_EeParameters.i_NbrAiChannel)
379 && (devpriv->b_SingelDiff == APCI3XXX_SINGLE))
380 || ((b_Channel < this_board->i_NbrAiChannelDiff)
381 && (devpriv->b_SingelDiff == APCI3XXX_DIFF))) {
382 /**********************************/
383 /* Test the channel configuration */
384 /**********************************/
386 if (b_Configuration > 7) {
387 /***************************/
388 /* Channel not initialised */
389 /***************************/
392 printk("Channel %d range %d selection error\n",
393 b_Channel, b_Configuration);
396 /***************************/
397 /* Channel selection error */
398 /***************************/
401 printk("Channel %d selection error\n", b_Channel);
404 /**************************/
405 /* Test if no error occur */
406 /**************************/
408 if (i_ReturnValue >= 0) {
409 /************************/
410 /* Test the buffer size */
411 /************************/
413 if ((b_Interrupt != 0) || ((b_Interrupt == 0)
414 && (insn->n >= 1))) {
415 /**********************************/
416 /* Test if conversion not started */
417 /**********************************/
419 if (i_APCI3XXX_TestConversionStarted(dev) == 0) {
424 writel(0x10000UL, devpriv->dw_AiBase + 12);
426 /*******************************/
427 /* Get and save the delay mode */
428 /*******************************/
430 dw_Temp = readl(devpriv->dw_AiBase + 4);
431 dw_Temp = dw_Temp & 0xFFFFFEF0UL;
433 /***********************************/
434 /* Channel configuration selection */
435 /***********************************/
437 writel(dw_Temp, devpriv->dw_AiBase + 4);
439 /**************************/
440 /* Make the configuration */
441 /**************************/
444 (b_Configuration & 3) |
445 ((unsigned int) (b_Configuration >> 2)
446 << 6) | ((unsigned int) devpriv->
449 /***************************/
450 /* Write the configuration */
451 /***************************/
453 writel(dw_Configuration,
454 devpriv->dw_AiBase + 0);
456 /*********************/
457 /* Channel selection */
458 /*********************/
460 writel(dw_Temp | 0x100UL,
461 devpriv->dw_AiBase + 4);
462 writel((unsigned int) b_Channel,
463 devpriv->dw_AiBase + 0);
465 /***********************/
466 /* Restaure delay mode */
467 /***********************/
469 writel(dw_Temp, devpriv->dw_AiBase + 4);
471 /***********************************/
472 /* Set the number of sequence to 1 */
473 /***********************************/
475 writel(1, devpriv->dw_AiBase + 48);
477 /***************************/
478 /* Save the interrupt flag */
479 /***************************/
481 devpriv->b_EocEosInterrupt =
484 /*******************************/
485 /* Save the number of channels */
486 /*******************************/
488 devpriv->ui_AiNbrofChannels = 1;
490 /******************************/
491 /* Test if interrupt not used */
492 /******************************/
494 if (b_Interrupt == 0) {
495 for (dw_AcquisitionCpt = 0;
498 dw_AcquisitionCpt++) {
499 /************************/
500 /* Start the conversion */
501 /************************/
503 writel(0x80000UL, devpriv->dw_AiBase + 8);
510 dw_Temp = readl(devpriv->dw_AiBase + 20);
511 dw_Temp = dw_Temp & 1;
512 } while (dw_Temp != 1);
514 /*************************/
515 /* Read the analog value */
516 /*************************/
518 data[dw_AcquisitionCpt] = (unsigned int)readl(devpriv->dw_AiBase + 28);
521 /************************/
522 /* Start the conversion */
523 /************************/
525 writel(0x180000UL, devpriv->dw_AiBase + 8);
528 /**************************/
529 /* Any conversion started */
530 /**************************/
532 printk("Any conversion started\n");
536 /*******************/
537 /* Data size error */
538 /*******************/
540 printk("Buffer size error\n");
541 i_ReturnValue = -101;
545 /***************************/
546 /* Channel selection error */
547 /***************************/
549 printk("Operating mode not configured\n");
552 return i_ReturnValue;
556 +----------------------------------------------------------------------------+
557 | Function name : void v_APCI3XXX_Interrupt (int irq, |
559 +----------------------------------------------------------------------------+
560 | Task :Interrupt handler for APCI3XXX |
561 | When interrupt occurs this gets called. |
562 | First it finds which interrupt has been generated and |
563 | handles corresponding interrupt |
564 +----------------------------------------------------------------------------+
565 | Input Parameters : - |
566 +----------------------------------------------------------------------------+
568 +----------------------------------------------------------------------------+
571 static void v_APCI3XXX_Interrupt(int irq, void *d)
573 struct comedi_device *dev = d;
574 unsigned char b_CopyCpt = 0;
575 unsigned int dw_Status = 0;
577 /***************************/
578 /* Test if interrupt occur */
579 /***************************/
581 dw_Status = readl(devpriv->dw_AiBase + 16);
582 if ( (dw_Status & 0x2UL) == 0x2UL) {
583 /***********************/
584 /* Reset the interrupt */
585 /***********************/
587 writel(dw_Status, devpriv->dw_AiBase + 16);
589 /*****************************/
590 /* Test if interrupt enabled */
591 /*****************************/
593 if (devpriv->b_EocEosInterrupt == 1) {
594 /********************************/
595 /* Read all analog inputs value */
596 /********************************/
599 b_CopyCpt < devpriv->ui_AiNbrofChannels;
601 devpriv->ui_AiReadData[b_CopyCpt] =
602 (unsigned int)readl(devpriv->dw_AiBase + 28);
605 /**************************/
606 /* Set the interrupt flag */
607 /**************************/
609 devpriv->b_EocEosInterrupt = 2;
611 /**********************************************/
612 /* Send a signal to from kernel to user space */
613 /**********************************************/
615 send_sig(SIGIO, devpriv->tsk_Current, 0);
621 +----------------------------------------------------------------------------+
622 | ANALOG OUTPUT SUBDEVICE |
623 +----------------------------------------------------------------------------+
627 +----------------------------------------------------------------------------+
628 | Function Name : int i_APCI3XXX_InsnWriteAnalogOutput |
629 | (struct comedi_device *dev, |
630 | struct comedi_subdevice *s, |
631 | struct comedi_insn *insn, |
632 | unsigned int *data) |
633 +----------------------------------------------------------------------------+
634 | Task Read 1 analog input |
635 +----------------------------------------------------------------------------+
636 | Input Parameters : b_Range = CR_RANGE(insn->chanspec); |
637 | b_Channel = CR_CHAN(insn->chanspec); |
638 | data[0] = analog value; |
639 +----------------------------------------------------------------------------+
640 | Output Parameters : - |
641 +----------------------------------------------------------------------------+
642 | Return Value :>0: No error |
643 | -3 : Channel selection error |
644 | -4 : Configuration selelection error |
646 | -101 : Data size error |
647 +----------------------------------------------------------------------------+
649 static int i_APCI3XXX_InsnWriteAnalogOutput(struct comedi_device *dev,
650 struct comedi_subdevice *s,
651 struct comedi_insn *insn,
654 unsigned char b_Range = (unsigned char) CR_RANGE(insn->chanspec);
655 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
656 unsigned int dw_Status = 0;
657 int i_ReturnValue = insn->n;
659 /************************/
660 /* Test the buffer size */
661 /************************/
664 /***************************/
665 /* Test the channel number */
666 /***************************/
668 if (b_Channel < devpriv->s_EeParameters.i_NbrAoChannel) {
669 /**********************************/
670 /* Test the channel configuration */
671 /**********************************/
674 /***************************/
675 /* Set the range selection */
676 /***************************/
678 writel(b_Range, devpriv->dw_AiBase + 96);
680 /**************************************************/
681 /* Write the analog value to the selected channel */
682 /**************************************************/
684 writel((data[0] << 8) | b_Channel,
685 devpriv->dw_AiBase + 100);
687 /****************************/
688 /* Wait the end of transfer */
689 /****************************/
692 dw_Status = readl(devpriv->dw_AiBase + 96);
693 } while ((dw_Status & 0x100) != 0x100);
695 /***************************/
696 /* Channel not initialised */
697 /***************************/
700 printk("Channel %d range %d selection error\n",
704 /***************************/
705 /* Channel selection error */
706 /***************************/
709 printk("Channel %d selection error\n", b_Channel);
712 /*******************/
713 /* Data size error */
714 /*******************/
716 printk("Buffer size error\n");
717 i_ReturnValue = -101;
720 return i_ReturnValue;
724 +----------------------------------------------------------------------------+
726 +----------------------------------------------------------------------------+
730 +----------------------------------------------------------------------------+
731 | Function Name : int i_APCI3XXX_InsnConfigInitTTLIO |
732 | (struct comedi_device *dev, |
733 | struct comedi_subdevice *s, |
734 | struct comedi_insn *insn, |
735 | unsigned int *data) |
736 +----------------------------------------------------------------------------+
737 | Task You must calling this function be |
738 | for you call any other function witch access of TTL. |
739 | APCI3XXX_TTL_INIT_DIRECTION_PORT2(user inputs for direction)|
740 +----------------------------------------------------------------------------+
741 | Input Parameters : b_InitType = (unsigned char) data[0]; |
742 | b_Port2Mode = (unsigned char) data[1]; |
743 +----------------------------------------------------------------------------+
744 | Output Parameters : - |
745 +----------------------------------------------------------------------------+
746 | Return Value :>0: No error |
747 | -1: Port 2 mode selection is wrong |
749 | -100 : Config command error |
750 | -101 : Data size error |
751 +----------------------------------------------------------------------------+
753 static int i_APCI3XXX_InsnConfigInitTTLIO(struct comedi_device *dev,
754 struct comedi_subdevice *s,
755 struct comedi_insn *insn,
758 int i_ReturnValue = insn->n;
759 unsigned char b_Command = 0;
761 /************************/
762 /* Test the buffer size */
763 /************************/
766 /*******************/
767 /* Get the command */
768 /* **************** */
770 b_Command = (unsigned char) data[0];
772 /********************/
773 /* Test the command */
774 /********************/
776 if (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2) {
777 /***************************************/
778 /* Test the initialisation buffer size */
779 /***************************************/
781 if ((b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2)
783 /*******************/
784 /* Data size error */
785 /*******************/
787 printk("Buffer size error\n");
788 i_ReturnValue = -101;
791 /************************/
792 /* Config command error */
793 /************************/
795 printk("Command selection error\n");
796 i_ReturnValue = -100;
799 /*******************/
800 /* Data size error */
801 /*******************/
803 printk("Buffer size error\n");
804 i_ReturnValue = -101;
807 /*********************************************************************************/
808 /* Test if no error occur and APCI3XXX_TTL_INIT_DIRECTION_PORT2 command selected */
809 /*********************************************************************************/
811 if ((i_ReturnValue >= 0)
812 && (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2)) {
813 /**********************/
814 /* Test the direction */
815 /**********************/
817 if ((data[1] == 0) || (data[1] == 0xFF)) {
818 /**************************/
819 /* Save the configuration */
820 /**************************/
822 devpriv->ul_TTLPortConfiguration[0] =
823 devpriv->ul_TTLPortConfiguration[0] | data[1];
825 /************************/
826 /* Port direction error */
827 /************************/
829 printk("Port 2 direction selection error\n");
834 /**************************/
835 /* Test if no error occur */
836 /**************************/
838 if (i_ReturnValue >= 0) {
839 /***********************************/
840 /* Test if TTL port initilaisation */
841 /***********************************/
843 if (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2) {
844 /*************************/
845 /* Set the configuration */
846 /*************************/
848 outl(data[1], devpriv->iobase + 224);
852 return i_ReturnValue;
856 +----------------------------------------------------------------------------+
857 | TTL INPUT FUNCTIONS |
858 +----------------------------------------------------------------------------+
862 +----------------------------------------------------------------------------+
863 | Function Name : int i_APCI3XXX_InsnBitsTTLIO |
864 | (struct comedi_device *dev, |
865 | struct comedi_subdevice *s, |
866 | struct comedi_insn *insn, |
867 | unsigned int *data) |
868 +----------------------------------------------------------------------------+
869 | Task : Write the selected output mask and read the status from|
871 +----------------------------------------------------------------------------+
872 | Input Parameters : dw_ChannelMask = data [0]; |
873 | dw_BitMask = data [1]; |
874 +----------------------------------------------------------------------------+
875 | Output Parameters : data[1] : All TTL channles states |
876 +----------------------------------------------------------------------------+
877 | Return Value : >0 : No error |
878 | -4 : Channel mask error |
879 | -101 : Data size error |
880 +----------------------------------------------------------------------------+
882 static int i_APCI3XXX_InsnBitsTTLIO(struct comedi_device *dev,
883 struct comedi_subdevice *s,
884 struct comedi_insn *insn,
887 int i_ReturnValue = insn->n;
888 unsigned char b_ChannelCpt = 0;
889 unsigned int dw_ChannelMask = 0;
890 unsigned int dw_BitMask = 0;
891 unsigned int dw_Status = 0;
893 /************************/
894 /* Test the buffer size */
895 /************************/
898 /*******************************/
899 /* Get the channe and bit mask */
900 /*******************************/
902 dw_ChannelMask = data[0];
903 dw_BitMask = data[1];
905 /*************************/
906 /* Test the channel mask */
907 /*************************/
909 if (((dw_ChannelMask & 0XFF00FF00) == 0) &&
910 (((devpriv->ul_TTLPortConfiguration[0] & 0xFF) == 0xFF)
911 || (((devpriv->ul_TTLPortConfiguration[0] &
913 && ((dw_ChannelMask & 0XFF0000) ==
915 /*********************************/
916 /* Test if set/reset any channel */
917 /*********************************/
919 if (dw_ChannelMask) {
920 /****************************************/
921 /* Test if set/rest any port 0 channels */
922 /****************************************/
924 if (dw_ChannelMask & 0xFF) {
925 /*******************************************/
926 /* Read port 0 (first digital output port) */
927 /*******************************************/
929 dw_Status = inl(devpriv->iobase + 80);
931 for (b_ChannelCpt = 0; b_ChannelCpt < 8;
933 if ((dw_ChannelMask >>
938 (0xFF - (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
942 outl(dw_Status, devpriv->iobase + 80);
945 /****************************************/
946 /* Test if set/rest any port 2 channels */
947 /****************************************/
949 if (dw_ChannelMask & 0xFF0000) {
950 dw_BitMask = dw_BitMask >> 16;
951 dw_ChannelMask = dw_ChannelMask >> 16;
953 /********************************************/
954 /* Read port 2 (second digital output port) */
955 /********************************************/
957 dw_Status = inl(devpriv->iobase + 112);
959 for (b_ChannelCpt = 0; b_ChannelCpt < 8;
961 if ((dw_ChannelMask >>
966 (0xFF - (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
970 outl(dw_Status, devpriv->iobase + 112);
974 /*******************************************/
975 /* Read port 0 (first digital output port) */
976 /*******************************************/
978 data[1] = inl(devpriv->iobase + 80);
980 /******************************************/
981 /* Read port 1 (first digital input port) */
982 /******************************************/
984 data[1] = data[1] | (inl(devpriv->iobase + 64) << 8);
986 /************************/
987 /* Test if port 2 input */
988 /************************/
990 if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF) == 0) {
992 data[1] | (inl(devpriv->iobase +
996 data[1] | (inl(devpriv->iobase +
1000 /************************/
1001 /* Config command error */
1002 /************************/
1004 printk("Channel mask error\n");
1008 /*******************/
1009 /* Data size error */
1010 /*******************/
1012 printk("Buffer size error\n");
1013 i_ReturnValue = -101;
1016 return i_ReturnValue;
1020 +----------------------------------------------------------------------------+
1021 | Function Name : int i_APCI3XXX_InsnReadTTLIO |
1022 | (struct comedi_device *dev, |
1023 | struct comedi_subdevice *s, |
1024 | struct comedi_insn *insn, |
1025 | unsigned int *data) |
1026 +----------------------------------------------------------------------------+
1027 | Task : Read the status from selected channel |
1028 +----------------------------------------------------------------------------+
1029 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
1030 +----------------------------------------------------------------------------+
1031 | Output Parameters : data[0] : Selected TTL channel state |
1032 +----------------------------------------------------------------------------+
1033 | Return Value : 0 : No error |
1034 | -3 : Channel selection error |
1035 | -101 : Data size error |
1036 +----------------------------------------------------------------------------+
1038 static int i_APCI3XXX_InsnReadTTLIO(struct comedi_device *dev,
1039 struct comedi_subdevice *s,
1040 struct comedi_insn *insn,
1043 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
1044 int i_ReturnValue = insn->n;
1045 unsigned int *pls_ReadData = data;
1047 /************************/
1048 /* Test the buffer size */
1049 /************************/
1052 /***********************/
1053 /* Test if read port 0 */
1054 /***********************/
1056 if (b_Channel < 8) {
1057 /*******************************************/
1058 /* Read port 0 (first digital output port) */
1059 /*******************************************/
1061 pls_ReadData[0] = inl(devpriv->iobase + 80);
1062 pls_ReadData[0] = (pls_ReadData[0] >> b_Channel) & 1;
1064 /***********************/
1065 /* Test if read port 1 */
1066 /***********************/
1068 if ((b_Channel > 7) && (b_Channel < 16)) {
1069 /******************************************/
1070 /* Read port 1 (first digital input port) */
1071 /******************************************/
1073 pls_ReadData[0] = inl(devpriv->iobase + 64);
1075 (pls_ReadData[0] >> (b_Channel -
1078 /***********************/
1079 /* Test if read port 2 */
1080 /***********************/
1082 if ((b_Channel > 15) && (b_Channel < 24)) {
1083 /************************/
1084 /* Test if port 2 input */
1085 /************************/
1087 if ((devpriv->ul_TTLPortConfiguration[0]
1090 inl(devpriv->iobase +
1094 (b_Channel - 16)) & 1;
1097 inl(devpriv->iobase +
1101 (b_Channel - 16)) & 1;
1104 /***************************/
1105 /* Channel selection error */
1106 /***************************/
1109 printk("Channel %d selection error\n",
1115 /*******************/
1116 /* Data size error */
1117 /*******************/
1119 printk("Buffer size error\n");
1120 i_ReturnValue = -101;
1123 return i_ReturnValue;
1127 +----------------------------------------------------------------------------+
1128 | TTL OUTPUT FUNCTIONS |
1129 +----------------------------------------------------------------------------+
1133 +----------------------------------------------------------------------------+
1134 | Function Name : int i_APCI3XXX_InsnWriteTTLIO |
1135 | (struct comedi_device *dev, |
1136 | struct comedi_subdevice *s, |
1137 | struct comedi_insn *insn, |
1138 | unsigned int *data) |
1139 +----------------------------------------------------------------------------+
1140 | Task : Set the state from TTL output channel |
1141 +----------------------------------------------------------------------------+
1142 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
1143 | b_State = data [0] |
1144 +----------------------------------------------------------------------------+
1145 | Output Parameters : - |
1146 +----------------------------------------------------------------------------+
1147 | Return Value : 0 : No error |
1148 | -3 : Channel selection error |
1149 | -101 : Data size error |
1150 +----------------------------------------------------------------------------+
1152 static int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device *dev,
1153 struct comedi_subdevice *s,
1154 struct comedi_insn *insn,
1157 int i_ReturnValue = insn->n;
1158 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
1159 unsigned char b_State = 0;
1160 unsigned int dw_Status = 0;
1162 /************************/
1163 /* Test the buffer size */
1164 /************************/
1167 b_State = (unsigned char) data[0];
1169 /***********************/
1170 /* Test if read port 0 */
1171 /***********************/
1173 if (b_Channel < 8) {
1174 /*****************************************************************************/
1175 /* Read port 0 (first digital output port) and set/reset the selected channel */
1176 /*****************************************************************************/
1178 dw_Status = inl(devpriv->iobase + 80);
1180 (dw_Status & (0xFF -
1181 (1 << b_Channel))) | ((b_State & 1) <<
1183 outl(dw_Status, devpriv->iobase + 80);
1185 /***********************/
1186 /* Test if read port 2 */
1187 /***********************/
1189 if ((b_Channel > 15) && (b_Channel < 24)) {
1190 /*************************/
1191 /* Test if port 2 output */
1192 /*************************/
1194 if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF)
1196 /*****************************************************************************/
1197 /* Read port 2 (first digital output port) and set/reset the selected channel */
1198 /*****************************************************************************/
1200 dw_Status = inl(devpriv->iobase + 112);
1202 (dw_Status & (0xFF -
1205 ((b_State & 1) << (b_Channel -
1207 outl(dw_Status, devpriv->iobase + 112);
1209 /***************************/
1210 /* Channel selection error */
1211 /***************************/
1214 printk("Channel %d selection error\n",
1218 /***************************/
1219 /* Channel selection error */
1220 /***************************/
1223 printk("Channel %d selection error\n",
1228 /*******************/
1229 /* Data size error */
1230 /*******************/
1232 printk("Buffer size error\n");
1233 i_ReturnValue = -101;
1236 return i_ReturnValue;
1240 +----------------------------------------------------------------------------+
1241 | DIGITAL INPUT SUBDEVICE |
1242 +----------------------------------------------------------------------------+
1246 +----------------------------------------------------------------------------+
1247 | Function name :int i_APCI3XXX_InsnReadDigitalInput |
1248 | (struct comedi_device *dev, |
1249 | struct comedi_subdevice *s, |
1250 | struct comedi_insn *insn, |
1251 | unsigned int *data) |
1252 +----------------------------------------------------------------------------+
1253 | Task : Reads the value of the specified Digital input channel |
1254 +----------------------------------------------------------------------------+
1255 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) (0 to 3) |
1256 +----------------------------------------------------------------------------+
1257 | Output Parameters : data[0] : Channel value |
1258 +----------------------------------------------------------------------------+
1259 | Return Value : 0 : No error |
1260 | -3 : Channel selection error |
1261 | -101 : Data size error |
1262 +----------------------------------------------------------------------------+
1265 static int i_APCI3XXX_InsnReadDigitalInput(struct comedi_device *dev,
1266 struct comedi_subdevice *s,
1267 struct comedi_insn *insn,
1270 int i_ReturnValue = insn->n;
1271 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
1272 unsigned int dw_Temp = 0;
1274 /***************************/
1275 /* Test the channel number */
1276 /***************************/
1278 if (b_Channel <= devpriv->s_EeParameters.i_NbrDiChannel) {
1279 /************************/
1280 /* Test the buffer size */
1281 /************************/
1284 dw_Temp = inl(devpriv->iobase + 32);
1285 *data = (dw_Temp >> b_Channel) & 1;
1287 /*******************/
1288 /* Data size error */
1289 /*******************/
1291 printk("Buffer size error\n");
1292 i_ReturnValue = -101;
1295 /***************************/
1296 /* Channel selection error */
1297 /***************************/
1299 printk("Channel selection error\n");
1303 return i_ReturnValue;
1307 +----------------------------------------------------------------------------+
1308 | Function name :int i_APCI3XXX_InsnBitsDigitalInput |
1309 | (struct comedi_device *dev, |
1310 | struct comedi_subdevice *s, |
1311 | struct comedi_insn *insn, |
1312 | unsigned int *data) |
1313 +----------------------------------------------------------------------------+
1314 | Task : Reads the value of the Digital input Port i.e.4channels|
1315 +----------------------------------------------------------------------------+
1316 | Input Parameters : - |
1317 +----------------------------------------------------------------------------+
1318 | Output Parameters : data[0] : Port value |
1319 +----------------------------------------------------------------------------+
1320 | Return Value :>0: No error |
1322 | -101 : Data size error |
1323 +----------------------------------------------------------------------------+
1325 static int i_APCI3XXX_InsnBitsDigitalInput(struct comedi_device *dev,
1326 struct comedi_subdevice *s,
1327 struct comedi_insn *insn,
1330 int i_ReturnValue = insn->n;
1331 unsigned int dw_Temp = 0;
1333 /************************/
1334 /* Test the buffer size */
1335 /************************/
1338 dw_Temp = inl(devpriv->iobase + 32);
1339 *data = dw_Temp & 0xf;
1341 /*******************/
1342 /* Data size error */
1343 /*******************/
1345 printk("Buffer size error\n");
1346 i_ReturnValue = -101;
1349 return i_ReturnValue;
1353 +----------------------------------------------------------------------------+
1354 | DIGITAL OUTPUT SUBDEVICE |
1355 +----------------------------------------------------------------------------+
1360 +----------------------------------------------------------------------------+
1361 | Function name :int i_APCI3XXX_InsnBitsDigitalOutput |
1362 | (struct comedi_device *dev, |
1363 | struct comedi_subdevice *s, |
1364 | struct comedi_insn *insn, |
1365 | unsigned int *data) |
1366 +----------------------------------------------------------------------------+
1367 | Task : Write the selected output mask and read the status from|
1368 | all digital output channles |
1369 +----------------------------------------------------------------------------+
1370 | Input Parameters : dw_ChannelMask = data [0]; |
1371 | dw_BitMask = data [1]; |
1372 +----------------------------------------------------------------------------+
1373 | Output Parameters : data[1] : All digital output channles states |
1374 +----------------------------------------------------------------------------+
1375 | Return Value : >0 : No error |
1376 | -4 : Channel mask error |
1377 | -101 : Data size error |
1378 +----------------------------------------------------------------------------+
1380 static int i_APCI3XXX_InsnBitsDigitalOutput(struct comedi_device *dev,
1381 struct comedi_subdevice *s,
1382 struct comedi_insn *insn,
1385 int i_ReturnValue = insn->n;
1386 unsigned char b_ChannelCpt = 0;
1387 unsigned int dw_ChannelMask = 0;
1388 unsigned int dw_BitMask = 0;
1389 unsigned int dw_Status = 0;
1391 /************************/
1392 /* Test the buffer size */
1393 /************************/
1396 /*******************************/
1397 /* Get the channe and bit mask */
1398 /*******************************/
1400 dw_ChannelMask = data[0];
1401 dw_BitMask = data[1];
1403 /*************************/
1404 /* Test the channel mask */
1405 /*************************/
1407 if ((dw_ChannelMask & 0XFFFFFFF0) == 0) {
1408 /*********************************/
1409 /* Test if set/reset any channel */
1410 /*********************************/
1412 if (dw_ChannelMask & 0xF) {
1413 /********************************/
1414 /* Read the digital output port */
1415 /********************************/
1417 dw_Status = inl(devpriv->iobase + 48);
1419 for (b_ChannelCpt = 0; b_ChannelCpt < 4;
1421 if ((dw_ChannelMask >> b_ChannelCpt) &
1425 (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
1429 outl(dw_Status, devpriv->iobase + 48);
1432 /********************************/
1433 /* Read the digital output port */
1434 /********************************/
1436 data[1] = inl(devpriv->iobase + 48);
1438 /************************/
1439 /* Config command error */
1440 /************************/
1442 printk("Channel mask error\n");
1446 /*******************/
1447 /* Data size error */
1448 /*******************/
1450 printk("Buffer size error\n");
1451 i_ReturnValue = -101;
1454 return i_ReturnValue;
1458 +----------------------------------------------------------------------------+
1459 | Function name :int i_APCI3XXX_InsnWriteDigitalOutput |
1460 | (struct comedi_device *dev, |
1461 | struct comedi_subdevice *s, |
1462 | struct comedi_insn *insn, |
1463 | unsigned int *data) |
1464 +----------------------------------------------------------------------------+
1465 | Task : Set the state from digital output channel |
1466 +----------------------------------------------------------------------------+
1467 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
1468 | b_State = data [0] |
1469 +----------------------------------------------------------------------------+
1470 | Output Parameters : - |
1471 +----------------------------------------------------------------------------+
1472 | Return Value : >0 : No error |
1473 | -3 : Channel selection error |
1474 | -101 : Data size error |
1475 +----------------------------------------------------------------------------+
1478 static int i_APCI3XXX_InsnWriteDigitalOutput(struct comedi_device *dev,
1479 struct comedi_subdevice *s,
1480 struct comedi_insn *insn,
1483 int i_ReturnValue = insn->n;
1484 unsigned char b_Channel = CR_CHAN(insn->chanspec);
1485 unsigned char b_State = 0;
1486 unsigned int dw_Status = 0;
1488 /************************/
1489 /* Test the buffer size */
1490 /************************/
1493 /***************************/
1494 /* Test the channel number */
1495 /***************************/
1497 if (b_Channel < devpriv->s_EeParameters.i_NbrDoChannel) {
1498 /*******************/
1499 /* Get the command */
1500 /*******************/
1502 b_State = (unsigned char) data[0];
1504 /********************************/
1505 /* Read the digital output port */
1506 /********************************/
1508 dw_Status = inl(devpriv->iobase + 48);
1512 (1 << b_Channel))) | ((b_State & 1) <<
1514 outl(dw_Status, devpriv->iobase + 48);
1516 /***************************/
1517 /* Channel selection error */
1518 /***************************/
1520 printk("Channel selection error\n");
1524 /*******************/
1525 /* Data size error */
1526 /*******************/
1528 printk("Buffer size error\n");
1529 i_ReturnValue = -101;
1532 return i_ReturnValue;
1536 +----------------------------------------------------------------------------+
1537 | Function name :int i_APCI3XXX_InsnReadDigitalOutput |
1538 | (struct comedi_device *dev, |
1539 | struct comedi_subdevice *s, |
1540 | struct comedi_insn *insn, |
1541 | unsigned int *data) |
1542 +----------------------------------------------------------------------------+
1543 | Task : Read the state from digital output channel |
1544 +----------------------------------------------------------------------------+
1545 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
1546 +----------------------------------------------------------------------------+
1547 | Output Parameters : b_State = data [0] |
1548 +----------------------------------------------------------------------------+
1549 | Return Value : >0 : No error |
1550 | -3 : Channel selection error |
1551 | -101 : Data size error |
1552 +----------------------------------------------------------------------------+
1555 static int i_APCI3XXX_InsnReadDigitalOutput(struct comedi_device *dev,
1556 struct comedi_subdevice *s,
1557 struct comedi_insn *insn,
1560 int i_ReturnValue = insn->n;
1561 unsigned char b_Channel = CR_CHAN(insn->chanspec);
1562 unsigned int dw_Status = 0;
1564 /************************/
1565 /* Test the buffer size */
1566 /************************/
1569 /***************************/
1570 /* Test the channel number */
1571 /***************************/
1573 if (b_Channel < devpriv->s_EeParameters.i_NbrDoChannel) {
1574 /********************************/
1575 /* Read the digital output port */
1576 /********************************/
1578 dw_Status = inl(devpriv->iobase + 48);
1580 dw_Status = (dw_Status >> b_Channel) & 1;
1583 /***************************/
1584 /* Channel selection error */
1585 /***************************/
1587 printk("Channel selection error\n");
1591 /*******************/
1592 /* Data size error */
1593 /*******************/
1595 printk("Buffer size error\n");
1596 i_ReturnValue = -101;
1599 return i_ReturnValue;
1603 +----------------------------------------------------------------------------+
1604 | Function Name : int i_APCI3XXX_Reset(struct comedi_device *dev) | +----------------------------------------------------------------------------+
1605 | Task :resets all the registers |
1606 +----------------------------------------------------------------------------+
1607 | Input Parameters : struct comedi_device *dev |
1608 +----------------------------------------------------------------------------+
1609 | Output Parameters : - |
1610 +----------------------------------------------------------------------------+
1611 | Return Value : - |
1612 +----------------------------------------------------------------------------+
1615 static int i_APCI3XXX_Reset(struct comedi_device *dev)
1617 unsigned char b_Cpt = 0;
1619 /*************************/
1620 /* Disable the interrupt */
1621 /*************************/
1623 disable_irq(dev->irq);
1625 /****************************/
1626 /* Reset the interrupt flag */
1627 /****************************/
1629 devpriv->b_EocEosInterrupt = 0;
1631 /***************************/
1632 /* Clear the start command */
1633 /***************************/
1635 writel(0, devpriv->dw_AiBase + 8);
1637 /*****************************/
1638 /* Reset the interrupt flags */
1639 /*****************************/
1641 writel(readl(devpriv->dw_AiBase + 16), devpriv->dw_AiBase + 16);
1647 readl(devpriv->dw_AiBase + 20);
1649 /******************/
1650 /* Clear the FIFO */
1651 /******************/
1653 for (b_Cpt = 0; b_Cpt < 16; b_Cpt++) {
1654 readl(devpriv->dw_AiBase + 28);
1657 /************************/
1658 /* Enable the interrupt */
1659 /************************/
1661 enable_irq(dev->irq);