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->ps_BoardInfo->
169 ui_MinAcquisitiontimeNs) {
170 if ((b_SingleDiff == APCI3XXX_SINGLE)
173 if (((b_SingleDiff == APCI3XXX_SINGLE) && (devpriv->ps_BoardInfo->i_NbrAiChannel == 0)) || ((b_SingleDiff == APCI3XXX_DIFF) && (devpriv->ps_BoardInfo->i_NbrAiChannelDiff == 0))) {
174 /*******************************/
175 /* Single/Diff selection error */
176 /*******************************/
178 printk("Single/Diff selection error\n");
181 /**********************************/
182 /* Test if conversion not started */
183 /**********************************/
185 if (i_APCI3XXX_TestConversionStarted(dev) == 0) {
187 ui_EocEosConversionTime
192 b_EocEosConversionTimeBase
203 /*******************************/
204 /* Set the convert timing unit */
205 /*******************************/
207 writel((unsigned int)b_TimeBase,
208 devpriv->dw_AiBase + 36);
210 /**************************/
211 /* Set the convert timing */
212 /*************************/
214 writel(dw_ReloadValue, devpriv->dw_AiBase + 32);
216 /**************************/
217 /* Any conversion started */
218 /**************************/
220 printk("Any conversion started\n");
226 /*******************************/
227 /* Single/Diff selection error */
228 /*******************************/
230 printk("Single/Diff selection error\n");
234 /************************/
235 /* Time selection error */
236 /************************/
238 printk("Convert time value selection error\n");
242 /************************/
243 /* Time selection error */
244 /************************/
246 printk("Convert time value selection error\n");
250 /*****************************/
251 /* Time base selection error */
252 /*****************************/
254 printk("Convert time base unity selection error\n");
258 /*******************/
259 /* Data size error */
260 /*******************/
262 printk("Buffer size error\n");
263 i_ReturnValue = -101;
266 return i_ReturnValue;
270 +----------------------------------------------------------------------------+
271 | Function Name : int i_APCI3XXX_InsnConfigAnalogInput |
272 | (struct comedi_device *dev, |
273 | struct comedi_subdevice *s, |
274 | struct comedi_insn *insn, |
275 | unsigned int *data) |
276 +----------------------------------------------------------------------------+
277 | Task Converting mode and convert time selection |
278 +----------------------------------------------------------------------------+
279 | Input Parameters : b_ConvertMode = (unsigned char) data[0]; |
280 | b_TimeBase = (unsigned char) data[1]; (0: ns, 1:micros 2:ms)|
281 | dw_ReloadValue = (unsigned int) data[2]; |
283 +----------------------------------------------------------------------------+
284 | Output Parameters : - |
285 +----------------------------------------------------------------------------+
286 | Return Value :>0: No error |
288 | -100 : Config command error |
289 | -101 : Data size error |
290 +----------------------------------------------------------------------------+
292 static int i_APCI3XXX_InsnConfigAnalogInput(struct comedi_device *dev,
293 struct comedi_subdevice *s,
294 struct comedi_insn *insn,
297 int i_ReturnValue = insn->n;
299 /************************/
300 /* Test the buffer size */
301 /************************/
304 switch ((unsigned char) data[0]) {
305 case APCI3XXX_CONFIGURATION:
307 i_APCI3XXX_AnalogInputConfigOperatingMode(dev,
312 i_ReturnValue = -100;
313 printk("Config command error %d\n", data[0]);
317 /*******************/
318 /* Data size error */
319 /*******************/
321 printk("Buffer size error\n");
322 i_ReturnValue = -101;
325 return i_ReturnValue;
329 +----------------------------------------------------------------------------+
330 | Function Name : int i_APCI3XXX_InsnReadAnalogInput |
331 | (struct comedi_device *dev, |
332 | struct comedi_subdevice *s, |
333 | struct comedi_insn *insn, |
334 | unsigned int *data) |
335 +----------------------------------------------------------------------------+
336 | Task Read 1 analog input |
337 +----------------------------------------------------------------------------+
338 | Input Parameters : b_Range = CR_RANGE(insn->chanspec); |
339 | b_Channel = CR_CHAN(insn->chanspec); |
340 | dw_NbrOfAcquisition = insn->n; |
341 +----------------------------------------------------------------------------+
342 | Output Parameters : - |
343 +----------------------------------------------------------------------------+
344 | Return Value :>0: No error |
345 | -3 : Channel selection error |
346 | -4 : Configuration selelection error |
347 | -10: Any conversion started |
349 | -100 : Config command error |
350 | -101 : Data size error |
351 +----------------------------------------------------------------------------+
353 static int i_APCI3XXX_InsnReadAnalogInput(struct comedi_device *dev,
354 struct comedi_subdevice *s,
355 struct comedi_insn *insn,
358 int i_ReturnValue = insn->n;
359 unsigned char b_Configuration = (unsigned char) CR_RANGE(insn->chanspec);
360 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
361 unsigned int dw_Temp = 0;
362 unsigned int dw_Configuration = 0;
363 unsigned int dw_AcquisitionCpt = 0;
364 unsigned char b_Interrupt = 0;
366 /*************************************/
367 /* Test if operating mode configured */
368 /*************************************/
370 if (devpriv->b_AiInitialisation) {
371 /***************************/
372 /* Test the channel number */
373 /***************************/
375 if (((b_Channel < devpriv->ps_BoardInfo->i_NbrAiChannel)
376 && (devpriv->b_SingelDiff == APCI3XXX_SINGLE))
377 || ((b_Channel < devpriv->ps_BoardInfo->
379 && (devpriv->b_SingelDiff == APCI3XXX_DIFF))) {
380 /**********************************/
381 /* Test the channel configuration */
382 /**********************************/
384 if (b_Configuration > 7) {
385 /***************************/
386 /* Channel not initialised */
387 /***************************/
390 printk("Channel %d range %d selection error\n",
391 b_Channel, b_Configuration);
394 /***************************/
395 /* Channel selection error */
396 /***************************/
399 printk("Channel %d selection error\n", b_Channel);
402 /**************************/
403 /* Test if no error occur */
404 /**************************/
406 if (i_ReturnValue >= 0) {
407 /************************/
408 /* Test the buffer size */
409 /************************/
411 if ((b_Interrupt != 0) || ((b_Interrupt == 0)
412 && (insn->n >= 1))) {
413 /**********************************/
414 /* Test if conversion not started */
415 /**********************************/
417 if (i_APCI3XXX_TestConversionStarted(dev) == 0) {
422 writel(0x10000UL, devpriv->dw_AiBase + 12);
424 /*******************************/
425 /* Get and save the delay mode */
426 /*******************************/
428 dw_Temp = readl(devpriv->dw_AiBase + 4);
429 dw_Temp = dw_Temp & 0xFFFFFEF0UL;
431 /***********************************/
432 /* Channel configuration selection */
433 /***********************************/
435 writel(dw_Temp, devpriv->dw_AiBase + 4);
437 /**************************/
438 /* Make the configuration */
439 /**************************/
442 (b_Configuration & 3) |
443 ((unsigned int) (b_Configuration >> 2)
444 << 6) | ((unsigned int) devpriv->
447 /***************************/
448 /* Write the configuration */
449 /***************************/
451 writel(dw_Configuration,
452 devpriv->dw_AiBase + 0);
454 /*********************/
455 /* Channel selection */
456 /*********************/
458 writel(dw_Temp | 0x100UL,
459 devpriv->dw_AiBase + 4);
460 writel((unsigned int) b_Channel,
461 devpriv->dw_AiBase + 0);
463 /***********************/
464 /* Restaure delay mode */
465 /***********************/
467 writel(dw_Temp, devpriv->dw_AiBase + 4);
469 /***********************************/
470 /* Set the number of sequence to 1 */
471 /***********************************/
473 writel(1, devpriv->dw_AiBase + 48);
475 /***************************/
476 /* Save the interrupt flag */
477 /***************************/
479 devpriv->b_EocEosInterrupt =
482 /*******************************/
483 /* Save the number of channels */
484 /*******************************/
486 devpriv->ui_AiNbrofChannels = 1;
488 /******************************/
489 /* Test if interrupt not used */
490 /******************************/
492 if (b_Interrupt == 0) {
493 for (dw_AcquisitionCpt = 0;
496 dw_AcquisitionCpt++) {
497 /************************/
498 /* Start the conversion */
499 /************************/
501 writel(0x80000UL, devpriv->dw_AiBase + 8);
508 dw_Temp = readl(devpriv->dw_AiBase + 20);
509 dw_Temp = dw_Temp & 1;
510 } while (dw_Temp != 1);
512 /*************************/
513 /* Read the analog value */
514 /*************************/
516 data[dw_AcquisitionCpt] = (unsigned int)readl(devpriv->dw_AiBase + 28);
519 /************************/
520 /* Start the conversion */
521 /************************/
523 writel(0x180000UL, devpriv->dw_AiBase + 8);
526 /**************************/
527 /* Any conversion started */
528 /**************************/
530 printk("Any conversion started\n");
534 /*******************/
535 /* Data size error */
536 /*******************/
538 printk("Buffer size error\n");
539 i_ReturnValue = -101;
543 /***************************/
544 /* Channel selection error */
545 /***************************/
547 printk("Operating mode not configured\n");
550 return i_ReturnValue;
554 +----------------------------------------------------------------------------+
555 | Function name : void v_APCI3XXX_Interrupt (int irq, |
557 +----------------------------------------------------------------------------+
558 | Task :Interrupt handler for APCI3XXX |
559 | When interrupt occurs this gets called. |
560 | First it finds which interrupt has been generated and |
561 | handles corresponding interrupt |
562 +----------------------------------------------------------------------------+
563 | Input Parameters : - |
564 +----------------------------------------------------------------------------+
566 +----------------------------------------------------------------------------+
569 static void v_APCI3XXX_Interrupt(int irq, void *d)
571 struct comedi_device *dev = d;
572 unsigned char b_CopyCpt = 0;
573 unsigned int dw_Status = 0;
575 /***************************/
576 /* Test if interrupt occur */
577 /***************************/
579 dw_Status = readl(devpriv->dw_AiBase + 16);
580 if ( (dw_Status & 0x2UL) == 0x2UL) {
581 /***********************/
582 /* Reset the interrupt */
583 /***********************/
585 writel(dw_Status, devpriv->dw_AiBase + 16);
587 /*****************************/
588 /* Test if interrupt enabled */
589 /*****************************/
591 if (devpriv->b_EocEosInterrupt == 1) {
592 /********************************/
593 /* Read all analog inputs value */
594 /********************************/
597 b_CopyCpt < devpriv->ui_AiNbrofChannels;
599 devpriv->ui_AiReadData[b_CopyCpt] =
600 (unsigned int)readl(devpriv->dw_AiBase + 28);
603 /**************************/
604 /* Set the interrupt flag */
605 /**************************/
607 devpriv->b_EocEosInterrupt = 2;
609 /**********************************************/
610 /* Send a signal to from kernel to user space */
611 /**********************************************/
613 send_sig(SIGIO, devpriv->tsk_Current, 0);
619 +----------------------------------------------------------------------------+
620 | ANALOG OUTPUT SUBDEVICE |
621 +----------------------------------------------------------------------------+
625 +----------------------------------------------------------------------------+
626 | Function Name : int i_APCI3XXX_InsnWriteAnalogOutput |
627 | (struct comedi_device *dev, |
628 | struct comedi_subdevice *s, |
629 | struct comedi_insn *insn, |
630 | unsigned int *data) |
631 +----------------------------------------------------------------------------+
632 | Task Read 1 analog input |
633 +----------------------------------------------------------------------------+
634 | Input Parameters : b_Range = CR_RANGE(insn->chanspec); |
635 | b_Channel = CR_CHAN(insn->chanspec); |
636 | data[0] = analog value; |
637 +----------------------------------------------------------------------------+
638 | Output Parameters : - |
639 +----------------------------------------------------------------------------+
640 | Return Value :>0: No error |
641 | -3 : Channel selection error |
642 | -4 : Configuration selelection error |
644 | -101 : Data size error |
645 +----------------------------------------------------------------------------+
647 static int i_APCI3XXX_InsnWriteAnalogOutput(struct comedi_device *dev,
648 struct comedi_subdevice *s,
649 struct comedi_insn *insn,
652 unsigned char b_Range = (unsigned char) CR_RANGE(insn->chanspec);
653 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
654 unsigned int dw_Status = 0;
655 int i_ReturnValue = insn->n;
657 /************************/
658 /* Test the buffer size */
659 /************************/
662 /***************************/
663 /* Test the channel number */
664 /***************************/
666 if (b_Channel < devpriv->ps_BoardInfo->i_NbrAoChannel) {
667 /**********************************/
668 /* Test the channel configuration */
669 /**********************************/
672 /***************************/
673 /* Set the range selection */
674 /***************************/
676 writel(b_Range, devpriv->dw_AiBase + 96);
678 /**************************************************/
679 /* Write the analog value to the selected channel */
680 /**************************************************/
682 writel((data[0] << 8) | b_Channel,
683 devpriv->dw_AiBase + 100);
685 /****************************/
686 /* Wait the end of transfer */
687 /****************************/
690 dw_Status = readl(devpriv->dw_AiBase + 96);
691 } while ((dw_Status & 0x100) != 0x100);
693 /***************************/
694 /* Channel not initialised */
695 /***************************/
698 printk("Channel %d range %d selection error\n",
702 /***************************/
703 /* Channel selection error */
704 /***************************/
707 printk("Channel %d selection error\n", b_Channel);
710 /*******************/
711 /* Data size error */
712 /*******************/
714 printk("Buffer size error\n");
715 i_ReturnValue = -101;
718 return i_ReturnValue;
722 +----------------------------------------------------------------------------+
724 +----------------------------------------------------------------------------+
728 +----------------------------------------------------------------------------+
729 | Function Name : int i_APCI3XXX_InsnConfigInitTTLIO |
730 | (struct comedi_device *dev, |
731 | struct comedi_subdevice *s, |
732 | struct comedi_insn *insn, |
733 | unsigned int *data) |
734 +----------------------------------------------------------------------------+
735 | Task You must calling this function be |
736 | for you call any other function witch access of TTL. |
737 | APCI3XXX_TTL_INIT_DIRECTION_PORT2(user inputs for direction)|
738 +----------------------------------------------------------------------------+
739 | Input Parameters : b_InitType = (unsigned char) data[0]; |
740 | b_Port2Mode = (unsigned char) data[1]; |
741 +----------------------------------------------------------------------------+
742 | Output Parameters : - |
743 +----------------------------------------------------------------------------+
744 | Return Value :>0: No error |
745 | -1: Port 2 mode selection is wrong |
747 | -100 : Config command error |
748 | -101 : Data size error |
749 +----------------------------------------------------------------------------+
751 static int i_APCI3XXX_InsnConfigInitTTLIO(struct comedi_device *dev,
752 struct comedi_subdevice *s,
753 struct comedi_insn *insn,
756 int i_ReturnValue = insn->n;
757 unsigned char b_Command = 0;
759 /************************/
760 /* Test the buffer size */
761 /************************/
764 /*******************/
765 /* Get the command */
766 /* **************** */
768 b_Command = (unsigned char) data[0];
770 /********************/
771 /* Test the command */
772 /********************/
774 if (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2) {
775 /***************************************/
776 /* Test the initialisation buffer size */
777 /***************************************/
779 if ((b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2)
781 /*******************/
782 /* Data size error */
783 /*******************/
785 printk("Buffer size error\n");
786 i_ReturnValue = -101;
789 /************************/
790 /* Config command error */
791 /************************/
793 printk("Command selection error\n");
794 i_ReturnValue = -100;
797 /*******************/
798 /* Data size error */
799 /*******************/
801 printk("Buffer size error\n");
802 i_ReturnValue = -101;
805 /*********************************************************************************/
806 /* Test if no error occur and APCI3XXX_TTL_INIT_DIRECTION_PORT2 command selected */
807 /*********************************************************************************/
809 if ((i_ReturnValue >= 0)
810 && (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2)) {
811 /**********************/
812 /* Test the direction */
813 /**********************/
815 if ((data[1] == 0) || (data[1] == 0xFF)) {
816 /**************************/
817 /* Save the configuration */
818 /**************************/
820 devpriv->ul_TTLPortConfiguration[0] =
821 devpriv->ul_TTLPortConfiguration[0] | data[1];
823 /************************/
824 /* Port direction error */
825 /************************/
827 printk("Port 2 direction selection error\n");
832 /**************************/
833 /* Test if no error occur */
834 /**************************/
836 if (i_ReturnValue >= 0) {
837 /***********************************/
838 /* Test if TTL port initilaisation */
839 /***********************************/
841 if (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2) {
842 /*************************/
843 /* Set the configuration */
844 /*************************/
846 outl(data[1], devpriv->iobase + 224);
850 return i_ReturnValue;
854 +----------------------------------------------------------------------------+
855 | TTL INPUT FUNCTIONS |
856 +----------------------------------------------------------------------------+
860 +----------------------------------------------------------------------------+
861 | Function Name : int i_APCI3XXX_InsnBitsTTLIO |
862 | (struct comedi_device *dev, |
863 | struct comedi_subdevice *s, |
864 | struct comedi_insn *insn, |
865 | unsigned int *data) |
866 +----------------------------------------------------------------------------+
867 | Task : Write the selected output mask and read the status from|
869 +----------------------------------------------------------------------------+
870 | Input Parameters : dw_ChannelMask = data [0]; |
871 | dw_BitMask = data [1]; |
872 +----------------------------------------------------------------------------+
873 | Output Parameters : data[1] : All TTL channles states |
874 +----------------------------------------------------------------------------+
875 | Return Value : >0 : No error |
876 | -4 : Channel mask error |
877 | -101 : Data size error |
878 +----------------------------------------------------------------------------+
880 static int i_APCI3XXX_InsnBitsTTLIO(struct comedi_device *dev,
881 struct comedi_subdevice *s,
882 struct comedi_insn *insn,
885 int i_ReturnValue = insn->n;
886 unsigned char b_ChannelCpt = 0;
887 unsigned int dw_ChannelMask = 0;
888 unsigned int dw_BitMask = 0;
889 unsigned int dw_Status = 0;
891 /************************/
892 /* Test the buffer size */
893 /************************/
896 /*******************************/
897 /* Get the channe and bit mask */
898 /*******************************/
900 dw_ChannelMask = data[0];
901 dw_BitMask = data[1];
903 /*************************/
904 /* Test the channel mask */
905 /*************************/
907 if (((dw_ChannelMask & 0XFF00FF00) == 0) &&
908 (((devpriv->ul_TTLPortConfiguration[0] & 0xFF) == 0xFF)
909 || (((devpriv->ul_TTLPortConfiguration[0] &
911 && ((dw_ChannelMask & 0XFF0000) ==
913 /*********************************/
914 /* Test if set/reset any channel */
915 /*********************************/
917 if (dw_ChannelMask) {
918 /****************************************/
919 /* Test if set/rest any port 0 channels */
920 /****************************************/
922 if (dw_ChannelMask & 0xFF) {
923 /*******************************************/
924 /* Read port 0 (first digital output port) */
925 /*******************************************/
927 dw_Status = inl(devpriv->iobase + 80);
929 for (b_ChannelCpt = 0; b_ChannelCpt < 8;
931 if ((dw_ChannelMask >>
936 (0xFF - (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
940 outl(dw_Status, devpriv->iobase + 80);
943 /****************************************/
944 /* Test if set/rest any port 2 channels */
945 /****************************************/
947 if (dw_ChannelMask & 0xFF0000) {
948 dw_BitMask = dw_BitMask >> 16;
949 dw_ChannelMask = dw_ChannelMask >> 16;
951 /********************************************/
952 /* Read port 2 (second digital output port) */
953 /********************************************/
955 dw_Status = inl(devpriv->iobase + 112);
957 for (b_ChannelCpt = 0; b_ChannelCpt < 8;
959 if ((dw_ChannelMask >>
964 (0xFF - (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
968 outl(dw_Status, devpriv->iobase + 112);
972 /*******************************************/
973 /* Read port 0 (first digital output port) */
974 /*******************************************/
976 data[1] = inl(devpriv->iobase + 80);
978 /******************************************/
979 /* Read port 1 (first digital input port) */
980 /******************************************/
982 data[1] = data[1] | (inl(devpriv->iobase + 64) << 8);
984 /************************/
985 /* Test if port 2 input */
986 /************************/
988 if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF) == 0) {
990 data[1] | (inl(devpriv->iobase +
994 data[1] | (inl(devpriv->iobase +
998 /************************/
999 /* Config command error */
1000 /************************/
1002 printk("Channel mask error\n");
1006 /*******************/
1007 /* Data size error */
1008 /*******************/
1010 printk("Buffer size error\n");
1011 i_ReturnValue = -101;
1014 return i_ReturnValue;
1018 +----------------------------------------------------------------------------+
1019 | Function Name : int i_APCI3XXX_InsnReadTTLIO |
1020 | (struct comedi_device *dev, |
1021 | struct comedi_subdevice *s, |
1022 | struct comedi_insn *insn, |
1023 | unsigned int *data) |
1024 +----------------------------------------------------------------------------+
1025 | Task : Read the status from selected channel |
1026 +----------------------------------------------------------------------------+
1027 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
1028 +----------------------------------------------------------------------------+
1029 | Output Parameters : data[0] : Selected TTL channel state |
1030 +----------------------------------------------------------------------------+
1031 | Return Value : 0 : No error |
1032 | -3 : Channel selection error |
1033 | -101 : Data size error |
1034 +----------------------------------------------------------------------------+
1036 static int i_APCI3XXX_InsnReadTTLIO(struct comedi_device *dev,
1037 struct comedi_subdevice *s,
1038 struct comedi_insn *insn,
1041 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
1042 int i_ReturnValue = insn->n;
1043 unsigned int *pls_ReadData = data;
1045 /************************/
1046 /* Test the buffer size */
1047 /************************/
1050 /***********************/
1051 /* Test if read port 0 */
1052 /***********************/
1054 if (b_Channel < 8) {
1055 /*******************************************/
1056 /* Read port 0 (first digital output port) */
1057 /*******************************************/
1059 pls_ReadData[0] = inl(devpriv->iobase + 80);
1060 pls_ReadData[0] = (pls_ReadData[0] >> b_Channel) & 1;
1062 /***********************/
1063 /* Test if read port 1 */
1064 /***********************/
1066 if ((b_Channel > 7) && (b_Channel < 16)) {
1067 /******************************************/
1068 /* Read port 1 (first digital input port) */
1069 /******************************************/
1071 pls_ReadData[0] = inl(devpriv->iobase + 64);
1073 (pls_ReadData[0] >> (b_Channel -
1076 /***********************/
1077 /* Test if read port 2 */
1078 /***********************/
1080 if ((b_Channel > 15) && (b_Channel < 24)) {
1081 /************************/
1082 /* Test if port 2 input */
1083 /************************/
1085 if ((devpriv->ul_TTLPortConfiguration[0]
1088 inl(devpriv->iobase +
1092 (b_Channel - 16)) & 1;
1095 inl(devpriv->iobase +
1099 (b_Channel - 16)) & 1;
1102 /***************************/
1103 /* Channel selection error */
1104 /***************************/
1107 printk("Channel %d selection error\n",
1113 /*******************/
1114 /* Data size error */
1115 /*******************/
1117 printk("Buffer size error\n");
1118 i_ReturnValue = -101;
1121 return i_ReturnValue;
1125 +----------------------------------------------------------------------------+
1126 | TTL OUTPUT FUNCTIONS |
1127 +----------------------------------------------------------------------------+
1131 +----------------------------------------------------------------------------+
1132 | Function Name : int i_APCI3XXX_InsnWriteTTLIO |
1133 | (struct comedi_device *dev, |
1134 | struct comedi_subdevice *s, |
1135 | struct comedi_insn *insn, |
1136 | unsigned int *data) |
1137 +----------------------------------------------------------------------------+
1138 | Task : Set the state from TTL output channel |
1139 +----------------------------------------------------------------------------+
1140 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
1141 | b_State = data [0] |
1142 +----------------------------------------------------------------------------+
1143 | Output Parameters : - |
1144 +----------------------------------------------------------------------------+
1145 | Return Value : 0 : No error |
1146 | -3 : Channel selection error |
1147 | -101 : Data size error |
1148 +----------------------------------------------------------------------------+
1150 static int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device *dev,
1151 struct comedi_subdevice *s,
1152 struct comedi_insn *insn,
1155 int i_ReturnValue = insn->n;
1156 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
1157 unsigned char b_State = 0;
1158 unsigned int dw_Status = 0;
1160 /************************/
1161 /* Test the buffer size */
1162 /************************/
1165 b_State = (unsigned char) data[0];
1167 /***********************/
1168 /* Test if read port 0 */
1169 /***********************/
1171 if (b_Channel < 8) {
1172 /*****************************************************************************/
1173 /* Read port 0 (first digital output port) and set/reset the selected channel */
1174 /*****************************************************************************/
1176 dw_Status = inl(devpriv->iobase + 80);
1178 (dw_Status & (0xFF -
1179 (1 << b_Channel))) | ((b_State & 1) <<
1181 outl(dw_Status, devpriv->iobase + 80);
1183 /***********************/
1184 /* Test if read port 2 */
1185 /***********************/
1187 if ((b_Channel > 15) && (b_Channel < 24)) {
1188 /*************************/
1189 /* Test if port 2 output */
1190 /*************************/
1192 if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF)
1194 /*****************************************************************************/
1195 /* Read port 2 (first digital output port) and set/reset the selected channel */
1196 /*****************************************************************************/
1198 dw_Status = inl(devpriv->iobase + 112);
1200 (dw_Status & (0xFF -
1203 ((b_State & 1) << (b_Channel -
1205 outl(dw_Status, devpriv->iobase + 112);
1207 /***************************/
1208 /* Channel selection error */
1209 /***************************/
1212 printk("Channel %d selection error\n",
1216 /***************************/
1217 /* Channel selection error */
1218 /***************************/
1221 printk("Channel %d selection error\n",
1226 /*******************/
1227 /* Data size error */
1228 /*******************/
1230 printk("Buffer size error\n");
1231 i_ReturnValue = -101;
1234 return i_ReturnValue;
1238 +----------------------------------------------------------------------------+
1239 | DIGITAL INPUT SUBDEVICE |
1240 +----------------------------------------------------------------------------+
1244 +----------------------------------------------------------------------------+
1245 | Function name :int i_APCI3XXX_InsnReadDigitalInput |
1246 | (struct comedi_device *dev, |
1247 | struct comedi_subdevice *s, |
1248 | struct comedi_insn *insn, |
1249 | unsigned int *data) |
1250 +----------------------------------------------------------------------------+
1251 | Task : Reads the value of the specified Digital input channel |
1252 +----------------------------------------------------------------------------+
1253 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) (0 to 3) |
1254 +----------------------------------------------------------------------------+
1255 | Output Parameters : data[0] : Channel value |
1256 +----------------------------------------------------------------------------+
1257 | Return Value : 0 : No error |
1258 | -3 : Channel selection error |
1259 | -101 : Data size error |
1260 +----------------------------------------------------------------------------+
1263 static int i_APCI3XXX_InsnReadDigitalInput(struct comedi_device *dev,
1264 struct comedi_subdevice *s,
1265 struct comedi_insn *insn,
1268 int i_ReturnValue = insn->n;
1269 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
1270 unsigned int dw_Temp = 0;
1272 /***************************/
1273 /* Test the channel number */
1274 /***************************/
1276 if (b_Channel <= devpriv->ps_BoardInfo->i_NbrDiChannel) {
1277 /************************/
1278 /* Test the buffer size */
1279 /************************/
1282 dw_Temp = inl(devpriv->iobase + 32);
1283 *data = (dw_Temp >> b_Channel) & 1;
1285 /*******************/
1286 /* Data size error */
1287 /*******************/
1289 printk("Buffer size error\n");
1290 i_ReturnValue = -101;
1293 /***************************/
1294 /* Channel selection error */
1295 /***************************/
1297 printk("Channel selection error\n");
1301 return i_ReturnValue;
1305 +----------------------------------------------------------------------------+
1306 | Function name :int i_APCI3XXX_InsnBitsDigitalInput |
1307 | (struct comedi_device *dev, |
1308 | struct comedi_subdevice *s, |
1309 | struct comedi_insn *insn, |
1310 | unsigned int *data) |
1311 +----------------------------------------------------------------------------+
1312 | Task : Reads the value of the Digital input Port i.e.4channels|
1313 +----------------------------------------------------------------------------+
1314 | Input Parameters : - |
1315 +----------------------------------------------------------------------------+
1316 | Output Parameters : data[0] : Port value |
1317 +----------------------------------------------------------------------------+
1318 | Return Value :>0: No error |
1320 | -101 : Data size error |
1321 +----------------------------------------------------------------------------+
1323 static int i_APCI3XXX_InsnBitsDigitalInput(struct comedi_device *dev,
1324 struct comedi_subdevice *s,
1325 struct comedi_insn *insn,
1328 int i_ReturnValue = insn->n;
1329 unsigned int dw_Temp = 0;
1331 /************************/
1332 /* Test the buffer size */
1333 /************************/
1336 dw_Temp = inl(devpriv->iobase + 32);
1337 *data = dw_Temp & 0xf;
1339 /*******************/
1340 /* Data size error */
1341 /*******************/
1343 printk("Buffer size error\n");
1344 i_ReturnValue = -101;
1347 return i_ReturnValue;
1351 +----------------------------------------------------------------------------+
1352 | DIGITAL OUTPUT SUBDEVICE |
1353 +----------------------------------------------------------------------------+
1358 +----------------------------------------------------------------------------+
1359 | Function name :int i_APCI3XXX_InsnBitsDigitalOutput |
1360 | (struct comedi_device *dev, |
1361 | struct comedi_subdevice *s, |
1362 | struct comedi_insn *insn, |
1363 | unsigned int *data) |
1364 +----------------------------------------------------------------------------+
1365 | Task : Write the selected output mask and read the status from|
1366 | all digital output channles |
1367 +----------------------------------------------------------------------------+
1368 | Input Parameters : dw_ChannelMask = data [0]; |
1369 | dw_BitMask = data [1]; |
1370 +----------------------------------------------------------------------------+
1371 | Output Parameters : data[1] : All digital output channles states |
1372 +----------------------------------------------------------------------------+
1373 | Return Value : >0 : No error |
1374 | -4 : Channel mask error |
1375 | -101 : Data size error |
1376 +----------------------------------------------------------------------------+
1378 static int i_APCI3XXX_InsnBitsDigitalOutput(struct comedi_device *dev,
1379 struct comedi_subdevice *s,
1380 struct comedi_insn *insn,
1383 int i_ReturnValue = insn->n;
1384 unsigned char b_ChannelCpt = 0;
1385 unsigned int dw_ChannelMask = 0;
1386 unsigned int dw_BitMask = 0;
1387 unsigned int dw_Status = 0;
1389 /************************/
1390 /* Test the buffer size */
1391 /************************/
1394 /*******************************/
1395 /* Get the channe and bit mask */
1396 /*******************************/
1398 dw_ChannelMask = data[0];
1399 dw_BitMask = data[1];
1401 /*************************/
1402 /* Test the channel mask */
1403 /*************************/
1405 if ((dw_ChannelMask & 0XFFFFFFF0) == 0) {
1406 /*********************************/
1407 /* Test if set/reset any channel */
1408 /*********************************/
1410 if (dw_ChannelMask & 0xF) {
1411 /********************************/
1412 /* Read the digital output port */
1413 /********************************/
1415 dw_Status = inl(devpriv->iobase + 48);
1417 for (b_ChannelCpt = 0; b_ChannelCpt < 4;
1419 if ((dw_ChannelMask >> b_ChannelCpt) &
1423 (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
1427 outl(dw_Status, devpriv->iobase + 48);
1430 /********************************/
1431 /* Read the digital output port */
1432 /********************************/
1434 data[1] = inl(devpriv->iobase + 48);
1436 /************************/
1437 /* Config command error */
1438 /************************/
1440 printk("Channel mask error\n");
1444 /*******************/
1445 /* Data size error */
1446 /*******************/
1448 printk("Buffer size error\n");
1449 i_ReturnValue = -101;
1452 return i_ReturnValue;
1456 +----------------------------------------------------------------------------+
1457 | Function name :int i_APCI3XXX_InsnWriteDigitalOutput |
1458 | (struct comedi_device *dev, |
1459 | struct comedi_subdevice *s, |
1460 | struct comedi_insn *insn, |
1461 | unsigned int *data) |
1462 +----------------------------------------------------------------------------+
1463 | Task : Set the state from digital output channel |
1464 +----------------------------------------------------------------------------+
1465 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
1466 | b_State = data [0] |
1467 +----------------------------------------------------------------------------+
1468 | Output Parameters : - |
1469 +----------------------------------------------------------------------------+
1470 | Return Value : >0 : No error |
1471 | -3 : Channel selection error |
1472 | -101 : Data size error |
1473 +----------------------------------------------------------------------------+
1476 static int i_APCI3XXX_InsnWriteDigitalOutput(struct comedi_device *dev,
1477 struct comedi_subdevice *s,
1478 struct comedi_insn *insn,
1481 int i_ReturnValue = insn->n;
1482 unsigned char b_Channel = CR_CHAN(insn->chanspec);
1483 unsigned char b_State = 0;
1484 unsigned int dw_Status = 0;
1486 /************************/
1487 /* Test the buffer size */
1488 /************************/
1491 /***************************/
1492 /* Test the channel number */
1493 /***************************/
1495 if (b_Channel < devpriv->ps_BoardInfo->i_NbrDoChannel) {
1496 /*******************/
1497 /* Get the command */
1498 /*******************/
1500 b_State = (unsigned char) data[0];
1502 /********************************/
1503 /* Read the digital output port */
1504 /********************************/
1506 dw_Status = inl(devpriv->iobase + 48);
1510 (1 << b_Channel))) | ((b_State & 1) <<
1512 outl(dw_Status, devpriv->iobase + 48);
1514 /***************************/
1515 /* Channel selection error */
1516 /***************************/
1518 printk("Channel selection error\n");
1522 /*******************/
1523 /* Data size error */
1524 /*******************/
1526 printk("Buffer size error\n");
1527 i_ReturnValue = -101;
1530 return i_ReturnValue;
1534 +----------------------------------------------------------------------------+
1535 | Function name :int i_APCI3XXX_InsnReadDigitalOutput |
1536 | (struct comedi_device *dev, |
1537 | struct comedi_subdevice *s, |
1538 | struct comedi_insn *insn, |
1539 | unsigned int *data) |
1540 +----------------------------------------------------------------------------+
1541 | Task : Read the state from digital output channel |
1542 +----------------------------------------------------------------------------+
1543 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
1544 +----------------------------------------------------------------------------+
1545 | Output Parameters : b_State = data [0] |
1546 +----------------------------------------------------------------------------+
1547 | Return Value : >0 : No error |
1548 | -3 : Channel selection error |
1549 | -101 : Data size error |
1550 +----------------------------------------------------------------------------+
1553 static int i_APCI3XXX_InsnReadDigitalOutput(struct comedi_device *dev,
1554 struct comedi_subdevice *s,
1555 struct comedi_insn *insn,
1558 int i_ReturnValue = insn->n;
1559 unsigned char b_Channel = CR_CHAN(insn->chanspec);
1560 unsigned int dw_Status = 0;
1562 /************************/
1563 /* Test the buffer size */
1564 /************************/
1567 /***************************/
1568 /* Test the channel number */
1569 /***************************/
1571 if (b_Channel < devpriv->ps_BoardInfo->i_NbrDoChannel) {
1572 /********************************/
1573 /* Read the digital output port */
1574 /********************************/
1576 dw_Status = inl(devpriv->iobase + 48);
1578 dw_Status = (dw_Status >> b_Channel) & 1;
1581 /***************************/
1582 /* Channel selection error */
1583 /***************************/
1585 printk("Channel selection error\n");
1589 /*******************/
1590 /* Data size error */
1591 /*******************/
1593 printk("Buffer size error\n");
1594 i_ReturnValue = -101;
1597 return i_ReturnValue;
1601 +----------------------------------------------------------------------------+
1602 | Function Name : int i_APCI3XXX_Reset(struct comedi_device *dev) | +----------------------------------------------------------------------------+
1603 | Task :resets all the registers |
1604 +----------------------------------------------------------------------------+
1605 | Input Parameters : struct comedi_device *dev |
1606 +----------------------------------------------------------------------------+
1607 | Output Parameters : - |
1608 +----------------------------------------------------------------------------+
1609 | Return Value : - |
1610 +----------------------------------------------------------------------------+
1613 static int i_APCI3XXX_Reset(struct comedi_device *dev)
1615 unsigned char b_Cpt = 0;
1617 /*************************/
1618 /* Disable the interrupt */
1619 /*************************/
1621 disable_irq(dev->irq);
1623 /****************************/
1624 /* Reset the interrupt flag */
1625 /****************************/
1627 devpriv->b_EocEosInterrupt = 0;
1629 /***************************/
1630 /* Clear the start command */
1631 /***************************/
1633 writel(0, devpriv->dw_AiBase + 8);
1635 /*****************************/
1636 /* Reset the interrupt flags */
1637 /*****************************/
1639 writel(readl(devpriv->dw_AiBase + 16), devpriv->dw_AiBase + 16);
1645 readl(devpriv->dw_AiBase + 20);
1647 /******************/
1648 /* Clear the FIFO */
1649 /******************/
1651 for (b_Cpt = 0; b_Cpt < 16; b_Cpt++) {
1652 readl(devpriv->dw_AiBase + 28);
1655 /************************/
1656 /* Enable the interrupt */
1657 /************************/
1659 enable_irq(dev->irq);