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 ((devpriv->ps_BoardInfo->
145 b_AvailableConvertUnit & (1 << b_TimeBase)) !=
147 /*******************************/
148 /* Test the convert time value */
149 /*******************************/
151 if (dw_ReloadValue <= 65535) {
152 dw_TestReloadValue = dw_ReloadValue;
154 if (b_TimeBase == 1) {
156 dw_TestReloadValue * 1000UL;
158 if (b_TimeBase == 2) {
160 dw_TestReloadValue * 1000000UL;
163 /*******************************/
164 /* Test the convert time value */
165 /*******************************/
167 if (dw_TestReloadValue >=
168 devpriv->s_EeParameters.
169 ui_MinAcquisitiontimeNs) {
170 if ((b_SingleDiff == APCI3XXX_SINGLE)
173 if (((b_SingleDiff == APCI3XXX_SINGLE)
174 && (devpriv->s_EeParameters.i_NbrAiChannel == 0))
175 || ((b_SingleDiff == APCI3XXX_DIFF)
176 && (devpriv->ps_BoardInfo->i_NbrAiChannelDiff == 0))
178 /*******************************/
179 /* Single/Diff selection error */
180 /*******************************/
182 printk("Single/Diff selection error\n");
185 /**********************************/
186 /* Test if conversion not started */
187 /**********************************/
189 if (i_APCI3XXX_TestConversionStarted(dev) == 0) {
191 ui_EocEosConversionTime
196 b_EocEosConversionTimeBase
207 /*******************************/
208 /* Set the convert timing unit */
209 /*******************************/
211 writel((unsigned int)b_TimeBase,
212 devpriv->dw_AiBase + 36);
214 /**************************/
215 /* Set the convert timing */
216 /*************************/
218 writel(dw_ReloadValue, devpriv->dw_AiBase + 32);
220 /**************************/
221 /* Any conversion started */
222 /**************************/
224 printk("Any conversion started\n");
230 /*******************************/
231 /* Single/Diff selection error */
232 /*******************************/
234 printk("Single/Diff selection error\n");
238 /************************/
239 /* Time selection error */
240 /************************/
242 printk("Convert time value selection error\n");
246 /************************/
247 /* Time selection error */
248 /************************/
250 printk("Convert time value selection error\n");
254 /*****************************/
255 /* Time base selection error */
256 /*****************************/
258 printk("Convert time base unity selection error\n");
262 /*******************/
263 /* Data size error */
264 /*******************/
266 printk("Buffer size error\n");
267 i_ReturnValue = -101;
270 return i_ReturnValue;
274 +----------------------------------------------------------------------------+
275 | Function Name : int i_APCI3XXX_InsnConfigAnalogInput |
276 | (struct comedi_device *dev, |
277 | struct comedi_subdevice *s, |
278 | struct comedi_insn *insn, |
279 | unsigned int *data) |
280 +----------------------------------------------------------------------------+
281 | Task Converting mode and convert time selection |
282 +----------------------------------------------------------------------------+
283 | Input Parameters : b_ConvertMode = (unsigned char) data[0]; |
284 | b_TimeBase = (unsigned char) data[1]; (0: ns, 1:micros 2:ms)|
285 | dw_ReloadValue = (unsigned int) data[2]; |
287 +----------------------------------------------------------------------------+
288 | Output Parameters : - |
289 +----------------------------------------------------------------------------+
290 | Return Value :>0: No error |
292 | -100 : Config command error |
293 | -101 : Data size error |
294 +----------------------------------------------------------------------------+
296 static int i_APCI3XXX_InsnConfigAnalogInput(struct comedi_device *dev,
297 struct comedi_subdevice *s,
298 struct comedi_insn *insn,
301 int i_ReturnValue = insn->n;
303 /************************/
304 /* Test the buffer size */
305 /************************/
308 switch ((unsigned char) data[0]) {
309 case APCI3XXX_CONFIGURATION:
311 i_APCI3XXX_AnalogInputConfigOperatingMode(dev,
316 i_ReturnValue = -100;
317 printk("Config command error %d\n", data[0]);
321 /*******************/
322 /* Data size error */
323 /*******************/
325 printk("Buffer size error\n");
326 i_ReturnValue = -101;
329 return i_ReturnValue;
333 +----------------------------------------------------------------------------+
334 | Function Name : int i_APCI3XXX_InsnReadAnalogInput |
335 | (struct comedi_device *dev, |
336 | struct comedi_subdevice *s, |
337 | struct comedi_insn *insn, |
338 | unsigned int *data) |
339 +----------------------------------------------------------------------------+
340 | Task Read 1 analog input |
341 +----------------------------------------------------------------------------+
342 | Input Parameters : b_Range = CR_RANGE(insn->chanspec); |
343 | b_Channel = CR_CHAN(insn->chanspec); |
344 | dw_NbrOfAcquisition = insn->n; |
345 +----------------------------------------------------------------------------+
346 | Output Parameters : - |
347 +----------------------------------------------------------------------------+
348 | Return Value :>0: No error |
349 | -3 : Channel selection error |
350 | -4 : Configuration selelection error |
351 | -10: Any conversion started |
353 | -100 : Config command error |
354 | -101 : Data size error |
355 +----------------------------------------------------------------------------+
357 static int i_APCI3XXX_InsnReadAnalogInput(struct comedi_device *dev,
358 struct comedi_subdevice *s,
359 struct comedi_insn *insn,
362 int i_ReturnValue = insn->n;
363 unsigned char b_Configuration = (unsigned char) CR_RANGE(insn->chanspec);
364 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
365 unsigned int dw_Temp = 0;
366 unsigned int dw_Configuration = 0;
367 unsigned int dw_AcquisitionCpt = 0;
368 unsigned char b_Interrupt = 0;
370 /*************************************/
371 /* Test if operating mode configured */
372 /*************************************/
374 if (devpriv->b_AiInitialisation) {
375 /***************************/
376 /* Test the channel number */
377 /***************************/
379 if (((b_Channel < devpriv->s_EeParameters.i_NbrAiChannel)
380 && (devpriv->b_SingelDiff == APCI3XXX_SINGLE))
381 || ((b_Channel < devpriv->ps_BoardInfo->
383 && (devpriv->b_SingelDiff == APCI3XXX_DIFF))) {
384 /**********************************/
385 /* Test the channel configuration */
386 /**********************************/
388 if (b_Configuration > 7) {
389 /***************************/
390 /* Channel not initialised */
391 /***************************/
394 printk("Channel %d range %d selection error\n",
395 b_Channel, b_Configuration);
398 /***************************/
399 /* Channel selection error */
400 /***************************/
403 printk("Channel %d selection error\n", b_Channel);
406 /**************************/
407 /* Test if no error occur */
408 /**************************/
410 if (i_ReturnValue >= 0) {
411 /************************/
412 /* Test the buffer size */
413 /************************/
415 if ((b_Interrupt != 0) || ((b_Interrupt == 0)
416 && (insn->n >= 1))) {
417 /**********************************/
418 /* Test if conversion not started */
419 /**********************************/
421 if (i_APCI3XXX_TestConversionStarted(dev) == 0) {
426 writel(0x10000UL, devpriv->dw_AiBase + 12);
428 /*******************************/
429 /* Get and save the delay mode */
430 /*******************************/
432 dw_Temp = readl(devpriv->dw_AiBase + 4);
433 dw_Temp = dw_Temp & 0xFFFFFEF0UL;
435 /***********************************/
436 /* Channel configuration selection */
437 /***********************************/
439 writel(dw_Temp, devpriv->dw_AiBase + 4);
441 /**************************/
442 /* Make the configuration */
443 /**************************/
446 (b_Configuration & 3) |
447 ((unsigned int) (b_Configuration >> 2)
448 << 6) | ((unsigned int) devpriv->
451 /***************************/
452 /* Write the configuration */
453 /***************************/
455 writel(dw_Configuration,
456 devpriv->dw_AiBase + 0);
458 /*********************/
459 /* Channel selection */
460 /*********************/
462 writel(dw_Temp | 0x100UL,
463 devpriv->dw_AiBase + 4);
464 writel((unsigned int) b_Channel,
465 devpriv->dw_AiBase + 0);
467 /***********************/
468 /* Restaure delay mode */
469 /***********************/
471 writel(dw_Temp, devpriv->dw_AiBase + 4);
473 /***********************************/
474 /* Set the number of sequence to 1 */
475 /***********************************/
477 writel(1, devpriv->dw_AiBase + 48);
479 /***************************/
480 /* Save the interrupt flag */
481 /***************************/
483 devpriv->b_EocEosInterrupt =
486 /*******************************/
487 /* Save the number of channels */
488 /*******************************/
490 devpriv->ui_AiNbrofChannels = 1;
492 /******************************/
493 /* Test if interrupt not used */
494 /******************************/
496 if (b_Interrupt == 0) {
497 for (dw_AcquisitionCpt = 0;
500 dw_AcquisitionCpt++) {
501 /************************/
502 /* Start the conversion */
503 /************************/
505 writel(0x80000UL, devpriv->dw_AiBase + 8);
512 dw_Temp = readl(devpriv->dw_AiBase + 20);
513 dw_Temp = dw_Temp & 1;
514 } while (dw_Temp != 1);
516 /*************************/
517 /* Read the analog value */
518 /*************************/
520 data[dw_AcquisitionCpt] = (unsigned int)readl(devpriv->dw_AiBase + 28);
523 /************************/
524 /* Start the conversion */
525 /************************/
527 writel(0x180000UL, devpriv->dw_AiBase + 8);
530 /**************************/
531 /* Any conversion started */
532 /**************************/
534 printk("Any conversion started\n");
538 /*******************/
539 /* Data size error */
540 /*******************/
542 printk("Buffer size error\n");
543 i_ReturnValue = -101;
547 /***************************/
548 /* Channel selection error */
549 /***************************/
551 printk("Operating mode not configured\n");
554 return i_ReturnValue;
558 +----------------------------------------------------------------------------+
559 | Function name : void v_APCI3XXX_Interrupt (int irq, |
561 +----------------------------------------------------------------------------+
562 | Task :Interrupt handler for APCI3XXX |
563 | When interrupt occurs this gets called. |
564 | First it finds which interrupt has been generated and |
565 | handles corresponding interrupt |
566 +----------------------------------------------------------------------------+
567 | Input Parameters : - |
568 +----------------------------------------------------------------------------+
570 +----------------------------------------------------------------------------+
573 static void v_APCI3XXX_Interrupt(int irq, void *d)
575 struct comedi_device *dev = d;
576 unsigned char b_CopyCpt = 0;
577 unsigned int dw_Status = 0;
579 /***************************/
580 /* Test if interrupt occur */
581 /***************************/
583 dw_Status = readl(devpriv->dw_AiBase + 16);
584 if ( (dw_Status & 0x2UL) == 0x2UL) {
585 /***********************/
586 /* Reset the interrupt */
587 /***********************/
589 writel(dw_Status, devpriv->dw_AiBase + 16);
591 /*****************************/
592 /* Test if interrupt enabled */
593 /*****************************/
595 if (devpriv->b_EocEosInterrupt == 1) {
596 /********************************/
597 /* Read all analog inputs value */
598 /********************************/
601 b_CopyCpt < devpriv->ui_AiNbrofChannels;
603 devpriv->ui_AiReadData[b_CopyCpt] =
604 (unsigned int)readl(devpriv->dw_AiBase + 28);
607 /**************************/
608 /* Set the interrupt flag */
609 /**************************/
611 devpriv->b_EocEosInterrupt = 2;
613 /**********************************************/
614 /* Send a signal to from kernel to user space */
615 /**********************************************/
617 send_sig(SIGIO, devpriv->tsk_Current, 0);
623 +----------------------------------------------------------------------------+
624 | ANALOG OUTPUT SUBDEVICE |
625 +----------------------------------------------------------------------------+
629 +----------------------------------------------------------------------------+
630 | Function Name : int i_APCI3XXX_InsnWriteAnalogOutput |
631 | (struct comedi_device *dev, |
632 | struct comedi_subdevice *s, |
633 | struct comedi_insn *insn, |
634 | unsigned int *data) |
635 +----------------------------------------------------------------------------+
636 | Task Read 1 analog input |
637 +----------------------------------------------------------------------------+
638 | Input Parameters : b_Range = CR_RANGE(insn->chanspec); |
639 | b_Channel = CR_CHAN(insn->chanspec); |
640 | data[0] = analog value; |
641 +----------------------------------------------------------------------------+
642 | Output Parameters : - |
643 +----------------------------------------------------------------------------+
644 | Return Value :>0: No error |
645 | -3 : Channel selection error |
646 | -4 : Configuration selelection error |
648 | -101 : Data size error |
649 +----------------------------------------------------------------------------+
651 static int i_APCI3XXX_InsnWriteAnalogOutput(struct comedi_device *dev,
652 struct comedi_subdevice *s,
653 struct comedi_insn *insn,
656 unsigned char b_Range = (unsigned char) CR_RANGE(insn->chanspec);
657 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
658 unsigned int dw_Status = 0;
659 int i_ReturnValue = insn->n;
661 /************************/
662 /* Test the buffer size */
663 /************************/
666 /***************************/
667 /* Test the channel number */
668 /***************************/
670 if (b_Channel < devpriv->s_EeParameters.i_NbrAoChannel) {
671 /**********************************/
672 /* Test the channel configuration */
673 /**********************************/
676 /***************************/
677 /* Set the range selection */
678 /***************************/
680 writel(b_Range, devpriv->dw_AiBase + 96);
682 /**************************************************/
683 /* Write the analog value to the selected channel */
684 /**************************************************/
686 writel((data[0] << 8) | b_Channel,
687 devpriv->dw_AiBase + 100);
689 /****************************/
690 /* Wait the end of transfer */
691 /****************************/
694 dw_Status = readl(devpriv->dw_AiBase + 96);
695 } while ((dw_Status & 0x100) != 0x100);
697 /***************************/
698 /* Channel not initialised */
699 /***************************/
702 printk("Channel %d range %d selection error\n",
706 /***************************/
707 /* Channel selection error */
708 /***************************/
711 printk("Channel %d selection error\n", b_Channel);
714 /*******************/
715 /* Data size error */
716 /*******************/
718 printk("Buffer size error\n");
719 i_ReturnValue = -101;
722 return i_ReturnValue;
726 +----------------------------------------------------------------------------+
728 +----------------------------------------------------------------------------+
732 +----------------------------------------------------------------------------+
733 | Function Name : int i_APCI3XXX_InsnConfigInitTTLIO |
734 | (struct comedi_device *dev, |
735 | struct comedi_subdevice *s, |
736 | struct comedi_insn *insn, |
737 | unsigned int *data) |
738 +----------------------------------------------------------------------------+
739 | Task You must calling this function be |
740 | for you call any other function witch access of TTL. |
741 | APCI3XXX_TTL_INIT_DIRECTION_PORT2(user inputs for direction)|
742 +----------------------------------------------------------------------------+
743 | Input Parameters : b_InitType = (unsigned char) data[0]; |
744 | b_Port2Mode = (unsigned char) data[1]; |
745 +----------------------------------------------------------------------------+
746 | Output Parameters : - |
747 +----------------------------------------------------------------------------+
748 | Return Value :>0: No error |
749 | -1: Port 2 mode selection is wrong |
751 | -100 : Config command error |
752 | -101 : Data size error |
753 +----------------------------------------------------------------------------+
755 static int i_APCI3XXX_InsnConfigInitTTLIO(struct comedi_device *dev,
756 struct comedi_subdevice *s,
757 struct comedi_insn *insn,
760 int i_ReturnValue = insn->n;
761 unsigned char b_Command = 0;
763 /************************/
764 /* Test the buffer size */
765 /************************/
768 /*******************/
769 /* Get the command */
770 /* **************** */
772 b_Command = (unsigned char) data[0];
774 /********************/
775 /* Test the command */
776 /********************/
778 if (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2) {
779 /***************************************/
780 /* Test the initialisation buffer size */
781 /***************************************/
783 if ((b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2)
785 /*******************/
786 /* Data size error */
787 /*******************/
789 printk("Buffer size error\n");
790 i_ReturnValue = -101;
793 /************************/
794 /* Config command error */
795 /************************/
797 printk("Command selection error\n");
798 i_ReturnValue = -100;
801 /*******************/
802 /* Data size error */
803 /*******************/
805 printk("Buffer size error\n");
806 i_ReturnValue = -101;
809 /*********************************************************************************/
810 /* Test if no error occur and APCI3XXX_TTL_INIT_DIRECTION_PORT2 command selected */
811 /*********************************************************************************/
813 if ((i_ReturnValue >= 0)
814 && (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2)) {
815 /**********************/
816 /* Test the direction */
817 /**********************/
819 if ((data[1] == 0) || (data[1] == 0xFF)) {
820 /**************************/
821 /* Save the configuration */
822 /**************************/
824 devpriv->ul_TTLPortConfiguration[0] =
825 devpriv->ul_TTLPortConfiguration[0] | data[1];
827 /************************/
828 /* Port direction error */
829 /************************/
831 printk("Port 2 direction selection error\n");
836 /**************************/
837 /* Test if no error occur */
838 /**************************/
840 if (i_ReturnValue >= 0) {
841 /***********************************/
842 /* Test if TTL port initilaisation */
843 /***********************************/
845 if (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2) {
846 /*************************/
847 /* Set the configuration */
848 /*************************/
850 outl(data[1], devpriv->iobase + 224);
854 return i_ReturnValue;
858 +----------------------------------------------------------------------------+
859 | TTL INPUT FUNCTIONS |
860 +----------------------------------------------------------------------------+
864 +----------------------------------------------------------------------------+
865 | Function Name : int i_APCI3XXX_InsnBitsTTLIO |
866 | (struct comedi_device *dev, |
867 | struct comedi_subdevice *s, |
868 | struct comedi_insn *insn, |
869 | unsigned int *data) |
870 +----------------------------------------------------------------------------+
871 | Task : Write the selected output mask and read the status from|
873 +----------------------------------------------------------------------------+
874 | Input Parameters : dw_ChannelMask = data [0]; |
875 | dw_BitMask = data [1]; |
876 +----------------------------------------------------------------------------+
877 | Output Parameters : data[1] : All TTL channles states |
878 +----------------------------------------------------------------------------+
879 | Return Value : >0 : No error |
880 | -4 : Channel mask error |
881 | -101 : Data size error |
882 +----------------------------------------------------------------------------+
884 static int i_APCI3XXX_InsnBitsTTLIO(struct comedi_device *dev,
885 struct comedi_subdevice *s,
886 struct comedi_insn *insn,
889 int i_ReturnValue = insn->n;
890 unsigned char b_ChannelCpt = 0;
891 unsigned int dw_ChannelMask = 0;
892 unsigned int dw_BitMask = 0;
893 unsigned int dw_Status = 0;
895 /************************/
896 /* Test the buffer size */
897 /************************/
900 /*******************************/
901 /* Get the channe and bit mask */
902 /*******************************/
904 dw_ChannelMask = data[0];
905 dw_BitMask = data[1];
907 /*************************/
908 /* Test the channel mask */
909 /*************************/
911 if (((dw_ChannelMask & 0XFF00FF00) == 0) &&
912 (((devpriv->ul_TTLPortConfiguration[0] & 0xFF) == 0xFF)
913 || (((devpriv->ul_TTLPortConfiguration[0] &
915 && ((dw_ChannelMask & 0XFF0000) ==
917 /*********************************/
918 /* Test if set/reset any channel */
919 /*********************************/
921 if (dw_ChannelMask) {
922 /****************************************/
923 /* Test if set/rest any port 0 channels */
924 /****************************************/
926 if (dw_ChannelMask & 0xFF) {
927 /*******************************************/
928 /* Read port 0 (first digital output port) */
929 /*******************************************/
931 dw_Status = inl(devpriv->iobase + 80);
933 for (b_ChannelCpt = 0; b_ChannelCpt < 8;
935 if ((dw_ChannelMask >>
940 (0xFF - (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
944 outl(dw_Status, devpriv->iobase + 80);
947 /****************************************/
948 /* Test if set/rest any port 2 channels */
949 /****************************************/
951 if (dw_ChannelMask & 0xFF0000) {
952 dw_BitMask = dw_BitMask >> 16;
953 dw_ChannelMask = dw_ChannelMask >> 16;
955 /********************************************/
956 /* Read port 2 (second digital output port) */
957 /********************************************/
959 dw_Status = inl(devpriv->iobase + 112);
961 for (b_ChannelCpt = 0; b_ChannelCpt < 8;
963 if ((dw_ChannelMask >>
968 (0xFF - (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
972 outl(dw_Status, devpriv->iobase + 112);
976 /*******************************************/
977 /* Read port 0 (first digital output port) */
978 /*******************************************/
980 data[1] = inl(devpriv->iobase + 80);
982 /******************************************/
983 /* Read port 1 (first digital input port) */
984 /******************************************/
986 data[1] = data[1] | (inl(devpriv->iobase + 64) << 8);
988 /************************/
989 /* Test if port 2 input */
990 /************************/
992 if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF) == 0) {
994 data[1] | (inl(devpriv->iobase +
998 data[1] | (inl(devpriv->iobase +
1002 /************************/
1003 /* Config command error */
1004 /************************/
1006 printk("Channel mask error\n");
1010 /*******************/
1011 /* Data size error */
1012 /*******************/
1014 printk("Buffer size error\n");
1015 i_ReturnValue = -101;
1018 return i_ReturnValue;
1022 +----------------------------------------------------------------------------+
1023 | Function Name : int i_APCI3XXX_InsnReadTTLIO |
1024 | (struct comedi_device *dev, |
1025 | struct comedi_subdevice *s, |
1026 | struct comedi_insn *insn, |
1027 | unsigned int *data) |
1028 +----------------------------------------------------------------------------+
1029 | Task : Read the status from selected channel |
1030 +----------------------------------------------------------------------------+
1031 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
1032 +----------------------------------------------------------------------------+
1033 | Output Parameters : data[0] : Selected TTL channel state |
1034 +----------------------------------------------------------------------------+
1035 | Return Value : 0 : No error |
1036 | -3 : Channel selection error |
1037 | -101 : Data size error |
1038 +----------------------------------------------------------------------------+
1040 static int i_APCI3XXX_InsnReadTTLIO(struct comedi_device *dev,
1041 struct comedi_subdevice *s,
1042 struct comedi_insn *insn,
1045 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
1046 int i_ReturnValue = insn->n;
1047 unsigned int *pls_ReadData = data;
1049 /************************/
1050 /* Test the buffer size */
1051 /************************/
1054 /***********************/
1055 /* Test if read port 0 */
1056 /***********************/
1058 if (b_Channel < 8) {
1059 /*******************************************/
1060 /* Read port 0 (first digital output port) */
1061 /*******************************************/
1063 pls_ReadData[0] = inl(devpriv->iobase + 80);
1064 pls_ReadData[0] = (pls_ReadData[0] >> b_Channel) & 1;
1066 /***********************/
1067 /* Test if read port 1 */
1068 /***********************/
1070 if ((b_Channel > 7) && (b_Channel < 16)) {
1071 /******************************************/
1072 /* Read port 1 (first digital input port) */
1073 /******************************************/
1075 pls_ReadData[0] = inl(devpriv->iobase + 64);
1077 (pls_ReadData[0] >> (b_Channel -
1080 /***********************/
1081 /* Test if read port 2 */
1082 /***********************/
1084 if ((b_Channel > 15) && (b_Channel < 24)) {
1085 /************************/
1086 /* Test if port 2 input */
1087 /************************/
1089 if ((devpriv->ul_TTLPortConfiguration[0]
1092 inl(devpriv->iobase +
1096 (b_Channel - 16)) & 1;
1099 inl(devpriv->iobase +
1103 (b_Channel - 16)) & 1;
1106 /***************************/
1107 /* Channel selection error */
1108 /***************************/
1111 printk("Channel %d selection error\n",
1117 /*******************/
1118 /* Data size error */
1119 /*******************/
1121 printk("Buffer size error\n");
1122 i_ReturnValue = -101;
1125 return i_ReturnValue;
1129 +----------------------------------------------------------------------------+
1130 | TTL OUTPUT FUNCTIONS |
1131 +----------------------------------------------------------------------------+
1135 +----------------------------------------------------------------------------+
1136 | Function Name : int i_APCI3XXX_InsnWriteTTLIO |
1137 | (struct comedi_device *dev, |
1138 | struct comedi_subdevice *s, |
1139 | struct comedi_insn *insn, |
1140 | unsigned int *data) |
1141 +----------------------------------------------------------------------------+
1142 | Task : Set the state from TTL output channel |
1143 +----------------------------------------------------------------------------+
1144 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
1145 | b_State = data [0] |
1146 +----------------------------------------------------------------------------+
1147 | Output Parameters : - |
1148 +----------------------------------------------------------------------------+
1149 | Return Value : 0 : No error |
1150 | -3 : Channel selection error |
1151 | -101 : Data size error |
1152 +----------------------------------------------------------------------------+
1154 static int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device *dev,
1155 struct comedi_subdevice *s,
1156 struct comedi_insn *insn,
1159 int i_ReturnValue = insn->n;
1160 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
1161 unsigned char b_State = 0;
1162 unsigned int dw_Status = 0;
1164 /************************/
1165 /* Test the buffer size */
1166 /************************/
1169 b_State = (unsigned char) data[0];
1171 /***********************/
1172 /* Test if read port 0 */
1173 /***********************/
1175 if (b_Channel < 8) {
1176 /*****************************************************************************/
1177 /* Read port 0 (first digital output port) and set/reset the selected channel */
1178 /*****************************************************************************/
1180 dw_Status = inl(devpriv->iobase + 80);
1182 (dw_Status & (0xFF -
1183 (1 << b_Channel))) | ((b_State & 1) <<
1185 outl(dw_Status, devpriv->iobase + 80);
1187 /***********************/
1188 /* Test if read port 2 */
1189 /***********************/
1191 if ((b_Channel > 15) && (b_Channel < 24)) {
1192 /*************************/
1193 /* Test if port 2 output */
1194 /*************************/
1196 if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF)
1198 /*****************************************************************************/
1199 /* Read port 2 (first digital output port) and set/reset the selected channel */
1200 /*****************************************************************************/
1202 dw_Status = inl(devpriv->iobase + 112);
1204 (dw_Status & (0xFF -
1207 ((b_State & 1) << (b_Channel -
1209 outl(dw_Status, devpriv->iobase + 112);
1211 /***************************/
1212 /* Channel selection error */
1213 /***************************/
1216 printk("Channel %d selection error\n",
1220 /***************************/
1221 /* Channel selection error */
1222 /***************************/
1225 printk("Channel %d selection error\n",
1230 /*******************/
1231 /* Data size error */
1232 /*******************/
1234 printk("Buffer size error\n");
1235 i_ReturnValue = -101;
1238 return i_ReturnValue;
1242 +----------------------------------------------------------------------------+
1243 | DIGITAL INPUT SUBDEVICE |
1244 +----------------------------------------------------------------------------+
1248 +----------------------------------------------------------------------------+
1249 | Function name :int i_APCI3XXX_InsnReadDigitalInput |
1250 | (struct comedi_device *dev, |
1251 | struct comedi_subdevice *s, |
1252 | struct comedi_insn *insn, |
1253 | unsigned int *data) |
1254 +----------------------------------------------------------------------------+
1255 | Task : Reads the value of the specified Digital input channel |
1256 +----------------------------------------------------------------------------+
1257 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) (0 to 3) |
1258 +----------------------------------------------------------------------------+
1259 | Output Parameters : data[0] : Channel value |
1260 +----------------------------------------------------------------------------+
1261 | Return Value : 0 : No error |
1262 | -3 : Channel selection error |
1263 | -101 : Data size error |
1264 +----------------------------------------------------------------------------+
1267 static int i_APCI3XXX_InsnReadDigitalInput(struct comedi_device *dev,
1268 struct comedi_subdevice *s,
1269 struct comedi_insn *insn,
1272 int i_ReturnValue = insn->n;
1273 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
1274 unsigned int dw_Temp = 0;
1276 /***************************/
1277 /* Test the channel number */
1278 /***************************/
1280 if (b_Channel <= devpriv->s_EeParameters.i_NbrDiChannel) {
1281 /************************/
1282 /* Test the buffer size */
1283 /************************/
1286 dw_Temp = inl(devpriv->iobase + 32);
1287 *data = (dw_Temp >> b_Channel) & 1;
1289 /*******************/
1290 /* Data size error */
1291 /*******************/
1293 printk("Buffer size error\n");
1294 i_ReturnValue = -101;
1297 /***************************/
1298 /* Channel selection error */
1299 /***************************/
1301 printk("Channel selection error\n");
1305 return i_ReturnValue;
1309 +----------------------------------------------------------------------------+
1310 | Function name :int i_APCI3XXX_InsnBitsDigitalInput |
1311 | (struct comedi_device *dev, |
1312 | struct comedi_subdevice *s, |
1313 | struct comedi_insn *insn, |
1314 | unsigned int *data) |
1315 +----------------------------------------------------------------------------+
1316 | Task : Reads the value of the Digital input Port i.e.4channels|
1317 +----------------------------------------------------------------------------+
1318 | Input Parameters : - |
1319 +----------------------------------------------------------------------------+
1320 | Output Parameters : data[0] : Port value |
1321 +----------------------------------------------------------------------------+
1322 | Return Value :>0: No error |
1324 | -101 : Data size error |
1325 +----------------------------------------------------------------------------+
1327 static int i_APCI3XXX_InsnBitsDigitalInput(struct comedi_device *dev,
1328 struct comedi_subdevice *s,
1329 struct comedi_insn *insn,
1332 int i_ReturnValue = insn->n;
1333 unsigned int dw_Temp = 0;
1335 /************************/
1336 /* Test the buffer size */
1337 /************************/
1340 dw_Temp = inl(devpriv->iobase + 32);
1341 *data = dw_Temp & 0xf;
1343 /*******************/
1344 /* Data size error */
1345 /*******************/
1347 printk("Buffer size error\n");
1348 i_ReturnValue = -101;
1351 return i_ReturnValue;
1355 +----------------------------------------------------------------------------+
1356 | DIGITAL OUTPUT SUBDEVICE |
1357 +----------------------------------------------------------------------------+
1362 +----------------------------------------------------------------------------+
1363 | Function name :int i_APCI3XXX_InsnBitsDigitalOutput |
1364 | (struct comedi_device *dev, |
1365 | struct comedi_subdevice *s, |
1366 | struct comedi_insn *insn, |
1367 | unsigned int *data) |
1368 +----------------------------------------------------------------------------+
1369 | Task : Write the selected output mask and read the status from|
1370 | all digital output channles |
1371 +----------------------------------------------------------------------------+
1372 | Input Parameters : dw_ChannelMask = data [0]; |
1373 | dw_BitMask = data [1]; |
1374 +----------------------------------------------------------------------------+
1375 | Output Parameters : data[1] : All digital output channles states |
1376 +----------------------------------------------------------------------------+
1377 | Return Value : >0 : No error |
1378 | -4 : Channel mask error |
1379 | -101 : Data size error |
1380 +----------------------------------------------------------------------------+
1382 static int i_APCI3XXX_InsnBitsDigitalOutput(struct comedi_device *dev,
1383 struct comedi_subdevice *s,
1384 struct comedi_insn *insn,
1387 int i_ReturnValue = insn->n;
1388 unsigned char b_ChannelCpt = 0;
1389 unsigned int dw_ChannelMask = 0;
1390 unsigned int dw_BitMask = 0;
1391 unsigned int dw_Status = 0;
1393 /************************/
1394 /* Test the buffer size */
1395 /************************/
1398 /*******************************/
1399 /* Get the channe and bit mask */
1400 /*******************************/
1402 dw_ChannelMask = data[0];
1403 dw_BitMask = data[1];
1405 /*************************/
1406 /* Test the channel mask */
1407 /*************************/
1409 if ((dw_ChannelMask & 0XFFFFFFF0) == 0) {
1410 /*********************************/
1411 /* Test if set/reset any channel */
1412 /*********************************/
1414 if (dw_ChannelMask & 0xF) {
1415 /********************************/
1416 /* Read the digital output port */
1417 /********************************/
1419 dw_Status = inl(devpriv->iobase + 48);
1421 for (b_ChannelCpt = 0; b_ChannelCpt < 4;
1423 if ((dw_ChannelMask >> b_ChannelCpt) &
1427 (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
1431 outl(dw_Status, devpriv->iobase + 48);
1434 /********************************/
1435 /* Read the digital output port */
1436 /********************************/
1438 data[1] = inl(devpriv->iobase + 48);
1440 /************************/
1441 /* Config command error */
1442 /************************/
1444 printk("Channel mask error\n");
1448 /*******************/
1449 /* Data size error */
1450 /*******************/
1452 printk("Buffer size error\n");
1453 i_ReturnValue = -101;
1456 return i_ReturnValue;
1460 +----------------------------------------------------------------------------+
1461 | Function name :int i_APCI3XXX_InsnWriteDigitalOutput |
1462 | (struct comedi_device *dev, |
1463 | struct comedi_subdevice *s, |
1464 | struct comedi_insn *insn, |
1465 | unsigned int *data) |
1466 +----------------------------------------------------------------------------+
1467 | Task : Set the state from digital output channel |
1468 +----------------------------------------------------------------------------+
1469 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
1470 | b_State = data [0] |
1471 +----------------------------------------------------------------------------+
1472 | Output Parameters : - |
1473 +----------------------------------------------------------------------------+
1474 | Return Value : >0 : No error |
1475 | -3 : Channel selection error |
1476 | -101 : Data size error |
1477 +----------------------------------------------------------------------------+
1480 static int i_APCI3XXX_InsnWriteDigitalOutput(struct comedi_device *dev,
1481 struct comedi_subdevice *s,
1482 struct comedi_insn *insn,
1485 int i_ReturnValue = insn->n;
1486 unsigned char b_Channel = CR_CHAN(insn->chanspec);
1487 unsigned char b_State = 0;
1488 unsigned int dw_Status = 0;
1490 /************************/
1491 /* Test the buffer size */
1492 /************************/
1495 /***************************/
1496 /* Test the channel number */
1497 /***************************/
1499 if (b_Channel < devpriv->s_EeParameters.i_NbrDoChannel) {
1500 /*******************/
1501 /* Get the command */
1502 /*******************/
1504 b_State = (unsigned char) data[0];
1506 /********************************/
1507 /* Read the digital output port */
1508 /********************************/
1510 dw_Status = inl(devpriv->iobase + 48);
1514 (1 << b_Channel))) | ((b_State & 1) <<
1516 outl(dw_Status, devpriv->iobase + 48);
1518 /***************************/
1519 /* Channel selection error */
1520 /***************************/
1522 printk("Channel selection error\n");
1526 /*******************/
1527 /* Data size error */
1528 /*******************/
1530 printk("Buffer size error\n");
1531 i_ReturnValue = -101;
1534 return i_ReturnValue;
1538 +----------------------------------------------------------------------------+
1539 | Function name :int i_APCI3XXX_InsnReadDigitalOutput |
1540 | (struct comedi_device *dev, |
1541 | struct comedi_subdevice *s, |
1542 | struct comedi_insn *insn, |
1543 | unsigned int *data) |
1544 +----------------------------------------------------------------------------+
1545 | Task : Read the state from digital output channel |
1546 +----------------------------------------------------------------------------+
1547 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
1548 +----------------------------------------------------------------------------+
1549 | Output Parameters : b_State = data [0] |
1550 +----------------------------------------------------------------------------+
1551 | Return Value : >0 : No error |
1552 | -3 : Channel selection error |
1553 | -101 : Data size error |
1554 +----------------------------------------------------------------------------+
1557 static int i_APCI3XXX_InsnReadDigitalOutput(struct comedi_device *dev,
1558 struct comedi_subdevice *s,
1559 struct comedi_insn *insn,
1562 int i_ReturnValue = insn->n;
1563 unsigned char b_Channel = CR_CHAN(insn->chanspec);
1564 unsigned int dw_Status = 0;
1566 /************************/
1567 /* Test the buffer size */
1568 /************************/
1571 /***************************/
1572 /* Test the channel number */
1573 /***************************/
1575 if (b_Channel < devpriv->s_EeParameters.i_NbrDoChannel) {
1576 /********************************/
1577 /* Read the digital output port */
1578 /********************************/
1580 dw_Status = inl(devpriv->iobase + 48);
1582 dw_Status = (dw_Status >> b_Channel) & 1;
1585 /***************************/
1586 /* Channel selection error */
1587 /***************************/
1589 printk("Channel selection error\n");
1593 /*******************/
1594 /* Data size error */
1595 /*******************/
1597 printk("Buffer size error\n");
1598 i_ReturnValue = -101;
1601 return i_ReturnValue;
1605 +----------------------------------------------------------------------------+
1606 | Function Name : int i_APCI3XXX_Reset(struct comedi_device *dev) | +----------------------------------------------------------------------------+
1607 | Task :resets all the registers |
1608 +----------------------------------------------------------------------------+
1609 | Input Parameters : struct comedi_device *dev |
1610 +----------------------------------------------------------------------------+
1611 | Output Parameters : - |
1612 +----------------------------------------------------------------------------+
1613 | Return Value : - |
1614 +----------------------------------------------------------------------------+
1617 static int i_APCI3XXX_Reset(struct comedi_device *dev)
1619 unsigned char b_Cpt = 0;
1621 /*************************/
1622 /* Disable the interrupt */
1623 /*************************/
1625 disable_irq(dev->irq);
1627 /****************************/
1628 /* Reset the interrupt flag */
1629 /****************************/
1631 devpriv->b_EocEosInterrupt = 0;
1633 /***************************/
1634 /* Clear the start command */
1635 /***************************/
1637 writel(0, devpriv->dw_AiBase + 8);
1639 /*****************************/
1640 /* Reset the interrupt flags */
1641 /*****************************/
1643 writel(readl(devpriv->dw_AiBase + 16), devpriv->dw_AiBase + 16);
1649 readl(devpriv->dw_AiBase + 20);
1651 /******************/
1652 /* Clear the FIFO */
1653 /******************/
1655 for (b_Cpt = 0; b_Cpt < 16; b_Cpt++) {
1656 readl(devpriv->dw_AiBase + 28);
1659 /************************/
1660 /* Enable the interrupt */
1661 /************************/
1663 enable_irq(dev->irq);