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 shoud 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 +----------------------------------------------------------------------------+
71 int i_APCI3XXX_TestConversionStarted(struct comedi_device *dev)
73 if ((readl((void *)(devpriv->dw_AiBase + 8)) & 0x80000UL) == 0x80000UL)
81 +----------------------------------------------------------------------------+
82 | Function Name : int i_APCI3XXX_AnalogInputConfigOperatingMode |
83 | (struct comedi_device *dev, |
84 | struct comedi_subdevice *s, |
85 | struct comedi_insn *insn, |
86 | unsigned int *data) |
87 +----------------------------------------------------------------------------+
88 | Task Converting mode and convert time selection |
89 +----------------------------------------------------------------------------+
90 | Input Parameters : b_SingleDiff = (unsigned char) data[1]; |
91 | b_TimeBase = (unsigned char) data[2]; (0: ns, 1:micros 2:ms)|
92 | dw_ReloadValue = (unsigned int) data[3]; |
94 +----------------------------------------------------------------------------+
95 | Output Parameters : - |
96 +----------------------------------------------------------------------------+
97 | Return Value :>0 : No error |
98 | -1 : Single/Diff selection error |
99 | -2 : Convert time base unity selection error |
100 | -3 : Convert time value selection error |
101 | -10: Any conversion started |
103 | -100 : Config command error |
104 | -101 : Data size error |
105 +----------------------------------------------------------------------------+
108 int i_APCI3XXX_AnalogInputConfigOperatingMode(struct comedi_device *dev,
109 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
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 >= 0) && (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)
215 /**************************/
216 /* Set the convert timing */
217 /*************************/
219 writel(dw_ReloadValue, (void *)(devpriv->dw_AiBase + 32));
221 /**************************/
222 /* Any conversion started */
223 /**************************/
225 printk("Any conversion started\n");
231 /*******************************/
232 /* Single/Diff selection error */
233 /*******************************/
235 printk("Single/Diff selection error\n");
239 /************************/
240 /* Time selection error */
241 /************************/
243 printk("Convert time value selection error\n");
247 /************************/
248 /* Time selection error */
249 /************************/
251 printk("Convert time value selection error\n");
255 /*****************************/
256 /* Time base selection error */
257 /*****************************/
259 printk("Convert time base unity selection error\n");
263 /*******************/
264 /* Data size error */
265 /*******************/
267 printk("Buffer size error\n");
268 i_ReturnValue = -101;
271 return i_ReturnValue;
275 +----------------------------------------------------------------------------+
276 | Function Name : int i_APCI3XXX_InsnConfigAnalogInput |
277 | (struct comedi_device *dev, |
278 | struct comedi_subdevice *s, |
279 | struct comedi_insn *insn, |
280 | unsigned int *data) |
281 +----------------------------------------------------------------------------+
282 | Task Converting mode and convert time selection |
283 +----------------------------------------------------------------------------+
284 | Input Parameters : b_ConvertMode = (unsigned char) data[0]; |
285 | b_TimeBase = (unsigned char) data[1]; (0: ns, 1:micros 2:ms)|
286 | dw_ReloadValue = (unsigned int) data[2]; |
288 +----------------------------------------------------------------------------+
289 | Output Parameters : - |
290 +----------------------------------------------------------------------------+
291 | Return Value :>0: No error |
293 | -100 : Config command error |
294 | -101 : Data size error |
295 +----------------------------------------------------------------------------+
298 int i_APCI3XXX_InsnConfigAnalogInput(struct comedi_device *dev,
299 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
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 +----------------------------------------------------------------------------+
358 int i_APCI3XXX_InsnReadAnalogInput(struct comedi_device *dev,
359 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
361 int i_ReturnValue = insn->n;
362 unsigned char b_Configuration = (unsigned char) CR_RANGE(insn->chanspec);
363 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
364 unsigned int dw_Temp = 0;
365 unsigned int dw_Configuration = 0;
366 unsigned int dw_AcquisitionCpt = 0;
367 unsigned char b_Interrupt = 0;
369 /*************************************/
370 /* Test if operating mode configured */
371 /*************************************/
373 if (devpriv->b_AiInitialisation) {
374 /***************************/
375 /* Test the channel number */
376 /***************************/
378 if (((b_Channel < devpriv->ps_BoardInfo->i_NbrAiChannel)
379 && (devpriv->b_SingelDiff == APCI3XXX_SINGLE))
380 || ((b_Channel < devpriv->ps_BoardInfo->
382 && (devpriv->b_SingelDiff == APCI3XXX_DIFF))) {
383 /**********************************/
384 /* Test the channel configuration */
385 /**********************************/
387 if (b_Configuration > 7) {
388 /***************************/
389 /* Channel not initialised */
390 /***************************/
393 printk("Channel %d range %d selection error\n",
394 b_Channel, b_Configuration);
397 /***************************/
398 /* Channel selection error */
399 /***************************/
402 printk("Channel %d selection error\n", b_Channel);
405 /**************************/
406 /* Test if no error occur */
407 /**************************/
409 if (i_ReturnValue >= 0) {
410 /************************/
411 /* Test the buffer size */
412 /************************/
414 if ((b_Interrupt != 0) || ((b_Interrupt == 0)
415 && (insn->n >= 1))) {
416 /**********************************/
417 /* Test if conversion not started */
418 /**********************************/
420 if (i_APCI3XXX_TestConversionStarted(dev) == 0) {
426 (void *)(devpriv->dw_AiBase +
429 /*******************************/
430 /* Get and save the delay mode */
431 /*******************************/
434 readl((void *)(devpriv->
436 dw_Temp = dw_Temp & 0xFFFFFEF0UL;
438 /***********************************/
439 /* Channel configuration selection */
440 /***********************************/
443 (void *)(devpriv->dw_AiBase +
446 /**************************/
447 /* Make the configuration */
448 /**************************/
451 (b_Configuration & 3) |
452 ((unsigned int) (b_Configuration >> 2)
453 << 6) | ((unsigned int) devpriv->
456 /***************************/
457 /* Write the configuration */
458 /***************************/
460 writel(dw_Configuration,
461 (void *)(devpriv->dw_AiBase +
464 /*********************/
465 /* Channel selection */
466 /*********************/
468 writel(dw_Temp | 0x100UL,
469 (void *)(devpriv->dw_AiBase +
471 writel((unsigned int) b_Channel,
472 (void *)(devpriv->dw_AiBase +
475 /***********************/
476 /* Restaure delay mode */
477 /***********************/
480 (void *)(devpriv->dw_AiBase +
483 /***********************************/
484 /* Set the number of sequence to 1 */
485 /***********************************/
488 (void *)(devpriv->dw_AiBase +
491 /***************************/
492 /* Save the interrupt flag */
493 /***************************/
495 devpriv->b_EocEosInterrupt =
498 /*******************************/
499 /* Save the number of channels */
500 /*******************************/
502 devpriv->ui_AiNbrofChannels = 1;
504 /******************************/
505 /* Test if interrupt not used */
506 /******************************/
508 if (b_Interrupt == 0) {
509 for (dw_AcquisitionCpt = 0;
512 dw_AcquisitionCpt++) {
513 /************************/
514 /* Start the conversion */
515 /************************/
538 } while (dw_Temp != 1);
540 /*************************/
541 /* Read the analog value */
542 /*************************/
544 data[dw_AcquisitionCpt]
554 /************************/
555 /* Start the conversion */
556 /************************/
563 /**************************/
564 /* Any conversion started */
565 /**************************/
567 printk("Any conversion started\n");
571 /*******************/
572 /* Data size error */
573 /*******************/
575 printk("Buffer size error\n");
576 i_ReturnValue = -101;
580 /***************************/
581 /* Channel selection error */
582 /***************************/
584 printk("Operating mode not configured\n");
587 return i_ReturnValue;
591 +----------------------------------------------------------------------------+
592 | Function name : void v_APCI3XXX_Interrupt (int irq, |
594 +----------------------------------------------------------------------------+
595 | Task :Interrupt handler for APCI3XXX |
596 | When interrupt occurs this gets called. |
597 | First it finds which interrupt has been generated and |
598 | handles corresponding interrupt |
599 +----------------------------------------------------------------------------+
600 | Input Parameters : - |
601 +----------------------------------------------------------------------------+
603 +----------------------------------------------------------------------------+
606 void v_APCI3XXX_Interrupt(int irq, void *d)
608 struct comedi_device *dev = d;
609 unsigned char b_CopyCpt = 0;
610 unsigned int dw_Status = 0;
612 /***************************/
613 /* Test if interrupt occur */
614 /***************************/
616 dw_Status = readl((void *)(devpriv->dw_AiBase + 16));
617 if ( (dw_Status & 0x2UL) == 0x2UL) {
618 /***********************/
619 /* Reset the interrupt */
620 /***********************/
622 writel(dw_Status, (void *)(devpriv->dw_AiBase + 16));
624 /*****************************/
625 /* Test if interrupt enabled */
626 /*****************************/
628 if (devpriv->b_EocEosInterrupt == 1) {
629 /********************************/
630 /* Read all analog inputs value */
631 /********************************/
634 b_CopyCpt < devpriv->ui_AiNbrofChannels;
636 devpriv->ui_AiReadData[b_CopyCpt] =
637 (unsigned int) readl((void *)(devpriv->
641 /**************************/
642 /* Set the interrupt flag */
643 /**************************/
645 devpriv->b_EocEosInterrupt = 2;
647 /**********************************************/
648 /* Send a signal to from kernel to user space */
649 /**********************************************/
651 send_sig(SIGIO, devpriv->tsk_Current, 0);
657 +----------------------------------------------------------------------------+
658 | ANALOG OUTPUT SUBDEVICE |
659 +----------------------------------------------------------------------------+
663 +----------------------------------------------------------------------------+
664 | Function Name : int i_APCI3XXX_InsnWriteAnalogOutput |
665 | (struct comedi_device *dev, |
666 | struct comedi_subdevice *s, |
667 | struct comedi_insn *insn, |
668 | unsigned int *data) |
669 +----------------------------------------------------------------------------+
670 | Task Read 1 analog input |
671 +----------------------------------------------------------------------------+
672 | Input Parameters : b_Range = CR_RANGE(insn->chanspec); |
673 | b_Channel = CR_CHAN(insn->chanspec); |
674 | data[0] = analog value; |
675 +----------------------------------------------------------------------------+
676 | Output Parameters : - |
677 +----------------------------------------------------------------------------+
678 | Return Value :>0: No error |
679 | -3 : Channel selection error |
680 | -4 : Configuration selelection error |
682 | -101 : Data size error |
683 +----------------------------------------------------------------------------+
686 int i_APCI3XXX_InsnWriteAnalogOutput(struct comedi_device *dev,
687 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
689 unsigned char b_Range = (unsigned char) CR_RANGE(insn->chanspec);
690 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
691 unsigned int dw_Status = 0;
692 int i_ReturnValue = insn->n;
694 /************************/
695 /* Test the buffer size */
696 /************************/
699 /***************************/
700 /* Test the channel number */
701 /***************************/
703 if (b_Channel < devpriv->ps_BoardInfo->i_NbrAoChannel) {
704 /**********************************/
705 /* Test the channel configuration */
706 /**********************************/
709 /***************************/
710 /* Set the range selection */
711 /***************************/
714 (void *)(devpriv->dw_AiBase + 96));
716 /**************************************************/
717 /* Write the analog value to the selected channel */
718 /**************************************************/
720 writel((data[0] << 8) | b_Channel,
721 (void *)(devpriv->dw_AiBase + 100));
723 /****************************/
724 /* Wait the end of transfer */
725 /****************************/
729 readl((void *)(devpriv->
731 } while ((dw_Status & 0x100) != 0x100);
733 /***************************/
734 /* Channel not initialised */
735 /***************************/
738 printk("Channel %d range %d selection error\n",
742 /***************************/
743 /* Channel selection error */
744 /***************************/
747 printk("Channel %d selection error\n", b_Channel);
750 /*******************/
751 /* Data size error */
752 /*******************/
754 printk("Buffer size error\n");
755 i_ReturnValue = -101;
758 return i_ReturnValue;
762 +----------------------------------------------------------------------------+
764 +----------------------------------------------------------------------------+
768 +----------------------------------------------------------------------------+
769 | Function Name : int i_APCI3XXX_InsnConfigInitTTLIO |
770 | (struct comedi_device *dev, |
771 | struct comedi_subdevice *s, |
772 | struct comedi_insn *insn, |
773 | unsigned int *data) |
774 +----------------------------------------------------------------------------+
775 | Task You must calling this function be |
776 | for you call any other function witch access of TTL. |
777 | APCI3XXX_TTL_INIT_DIRECTION_PORT2(user inputs for direction)|
778 +----------------------------------------------------------------------------+
779 | Input Parameters : b_InitType = (unsigned char) data[0]; |
780 | b_Port2Mode = (unsigned char) data[1]; |
781 +----------------------------------------------------------------------------+
782 | Output Parameters : - |
783 +----------------------------------------------------------------------------+
784 | Return Value :>0: No error |
785 | -1: Port 2 mode selection is wrong |
787 | -100 : Config command error |
788 | -101 : Data size error |
789 +----------------------------------------------------------------------------+
792 int i_APCI3XXX_InsnConfigInitTTLIO(struct comedi_device *dev,
793 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
795 int i_ReturnValue = insn->n;
796 unsigned char b_Command = 0;
798 /************************/
799 /* Test the buffer size */
800 /************************/
803 /*******************/
804 /* Get the command */
805 /* **************** */
807 b_Command = (unsigned char) data[0];
809 /********************/
810 /* Test the command */
811 /********************/
813 if (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2) {
814 /***************************************/
815 /* Test the initialisation buffer size */
816 /***************************************/
818 if ((b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2)
820 /*******************/
821 /* Data size error */
822 /*******************/
824 printk("Buffer size error\n");
825 i_ReturnValue = -101;
828 /************************/
829 /* Config command error */
830 /************************/
832 printk("Command selection error\n");
833 i_ReturnValue = -100;
836 /*******************/
837 /* Data size error */
838 /*******************/
840 printk("Buffer size error\n");
841 i_ReturnValue = -101;
844 /*********************************************************************************/
845 /* Test if no error occur and APCI3XXX_TTL_INIT_DIRECTION_PORT2 command selected */
846 /*********************************************************************************/
848 if ((i_ReturnValue >= 0)
849 && (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2)) {
850 /**********************/
851 /* Test the direction */
852 /**********************/
854 if ((data[1] == 0) || (data[1] == 0xFF)) {
855 /**************************/
856 /* Save the configuration */
857 /**************************/
859 devpriv->ul_TTLPortConfiguration[0] =
860 devpriv->ul_TTLPortConfiguration[0] | data[1];
862 /************************/
863 /* Port direction error */
864 /************************/
866 printk("Port 2 direction selection error\n");
871 /**************************/
872 /* Test if no error occur */
873 /**************************/
875 if (i_ReturnValue >= 0) {
876 /***********************************/
877 /* Test if TTL port initilaisation */
878 /***********************************/
880 if (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2) {
881 /*************************/
882 /* Set the configuration */
883 /*************************/
885 outl(data[1], devpriv->iobase + 224);
889 return i_ReturnValue;
893 +----------------------------------------------------------------------------+
894 | TTL INPUT FUNCTIONS |
895 +----------------------------------------------------------------------------+
899 +----------------------------------------------------------------------------+
900 | Function Name : int i_APCI3XXX_InsnBitsTTLIO |
901 | (struct comedi_device *dev, |
902 | struct comedi_subdevice *s, |
903 | struct comedi_insn *insn, |
904 | unsigned int *data) |
905 +----------------------------------------------------------------------------+
906 | Task : Write the selected output mask and read the status from|
908 +----------------------------------------------------------------------------+
909 | Input Parameters : dw_ChannelMask = data [0]; |
910 | dw_BitMask = data [1]; |
911 +----------------------------------------------------------------------------+
912 | Output Parameters : data[1] : All TTL channles states |
913 +----------------------------------------------------------------------------+
914 | Return Value : >0 : No error |
915 | -4 : Channel mask error |
916 | -101 : Data size error |
917 +----------------------------------------------------------------------------+
920 int i_APCI3XXX_InsnBitsTTLIO(struct comedi_device *dev,
921 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
923 int i_ReturnValue = insn->n;
924 unsigned char b_ChannelCpt = 0;
925 unsigned int dw_ChannelMask = 0;
926 unsigned int dw_BitMask = 0;
927 unsigned int dw_Status = 0;
929 /************************/
930 /* Test the buffer size */
931 /************************/
934 /*******************************/
935 /* Get the channe and bit mask */
936 /*******************************/
938 dw_ChannelMask = data[0];
939 dw_BitMask = data[1];
941 /*************************/
942 /* Test the channel mask */
943 /*************************/
945 if (((dw_ChannelMask & 0XFF00FF00) == 0) &&
946 (((devpriv->ul_TTLPortConfiguration[0] & 0xFF) == 0xFF)
947 || (((devpriv->ul_TTLPortConfiguration[0] &
949 && ((dw_ChannelMask & 0XFF0000) ==
951 /*********************************/
952 /* Test if set/reset any channel */
953 /*********************************/
955 if (dw_ChannelMask) {
956 /****************************************/
957 /* Test if set/rest any port 0 channels */
958 /****************************************/
960 if (dw_ChannelMask & 0xFF) {
961 /*******************************************/
962 /* Read port 0 (first digital output port) */
963 /*******************************************/
965 dw_Status = inl(devpriv->iobase + 80);
967 for (b_ChannelCpt = 0; b_ChannelCpt < 8;
969 if ((dw_ChannelMask >>
974 (0xFF - (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
978 outl(dw_Status, devpriv->iobase + 80);
981 /****************************************/
982 /* Test if set/rest any port 2 channels */
983 /****************************************/
985 if (dw_ChannelMask & 0xFF0000) {
986 dw_BitMask = dw_BitMask >> 16;
987 dw_ChannelMask = dw_ChannelMask >> 16;
989 /********************************************/
990 /* Read port 2 (second digital output port) */
991 /********************************************/
993 dw_Status = inl(devpriv->iobase + 112);
995 for (b_ChannelCpt = 0; b_ChannelCpt < 8;
997 if ((dw_ChannelMask >>
1002 (0xFF - (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
1006 outl(dw_Status, devpriv->iobase + 112);
1010 /*******************************************/
1011 /* Read port 0 (first digital output port) */
1012 /*******************************************/
1014 data[1] = inl(devpriv->iobase + 80);
1016 /******************************************/
1017 /* Read port 1 (first digital input port) */
1018 /******************************************/
1020 data[1] = data[1] | (inl(devpriv->iobase + 64) << 8);
1022 /************************/
1023 /* Test if port 2 input */
1024 /************************/
1026 if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF) == 0) {
1028 data[1] | (inl(devpriv->iobase +
1032 data[1] | (inl(devpriv->iobase +
1036 /************************/
1037 /* Config command error */
1038 /************************/
1040 printk("Channel mask error\n");
1044 /*******************/
1045 /* Data size error */
1046 /*******************/
1048 printk("Buffer size error\n");
1049 i_ReturnValue = -101;
1052 return i_ReturnValue;
1056 +----------------------------------------------------------------------------+
1057 | Function Name : int i_APCI3XXX_InsnReadTTLIO |
1058 | (struct comedi_device *dev, |
1059 | struct comedi_subdevice *s, |
1060 | struct comedi_insn *insn, |
1061 | unsigned int *data) |
1062 +----------------------------------------------------------------------------+
1063 | Task : Read the status from selected channel |
1064 +----------------------------------------------------------------------------+
1065 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
1066 +----------------------------------------------------------------------------+
1067 | Output Parameters : data[0] : Selected TTL channel state |
1068 +----------------------------------------------------------------------------+
1069 | Return Value : 0 : No error |
1070 | -3 : Channel selection error |
1071 | -101 : Data size error |
1072 +----------------------------------------------------------------------------+
1075 int i_APCI3XXX_InsnReadTTLIO(struct comedi_device *dev,
1076 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
1078 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
1079 int i_ReturnValue = insn->n;
1080 unsigned int *pls_ReadData = data;
1082 /************************/
1083 /* Test the buffer size */
1084 /************************/
1087 /***********************/
1088 /* Test if read port 0 */
1089 /***********************/
1091 if (b_Channel < 8) {
1092 /*******************************************/
1093 /* Read port 0 (first digital output port) */
1094 /*******************************************/
1096 pls_ReadData[0] = inl(devpriv->iobase + 80);
1097 pls_ReadData[0] = (pls_ReadData[0] >> b_Channel) & 1;
1099 /***********************/
1100 /* Test if read port 1 */
1101 /***********************/
1103 if ((b_Channel > 7) && (b_Channel < 16)) {
1104 /******************************************/
1105 /* Read port 1 (first digital input port) */
1106 /******************************************/
1108 pls_ReadData[0] = inl(devpriv->iobase + 64);
1110 (pls_ReadData[0] >> (b_Channel -
1113 /***********************/
1114 /* Test if read port 2 */
1115 /***********************/
1117 if ((b_Channel > 15) && (b_Channel < 24)) {
1118 /************************/
1119 /* Test if port 2 input */
1120 /************************/
1122 if ((devpriv->ul_TTLPortConfiguration[0]
1125 inl(devpriv->iobase +
1129 (b_Channel - 16)) & 1;
1132 inl(devpriv->iobase +
1136 (b_Channel - 16)) & 1;
1139 /***************************/
1140 /* Channel selection error */
1141 /***************************/
1144 printk("Channel %d selection error\n",
1150 /*******************/
1151 /* Data size error */
1152 /*******************/
1154 printk("Buffer size error\n");
1155 i_ReturnValue = -101;
1158 return i_ReturnValue;
1162 +----------------------------------------------------------------------------+
1163 | TTL OUTPUT FUNCTIONS |
1164 +----------------------------------------------------------------------------+
1168 +----------------------------------------------------------------------------+
1169 | Function Name : int i_APCI3XXX_InsnWriteTTLIO |
1170 | (struct comedi_device *dev, |
1171 | struct comedi_subdevice *s, |
1172 | struct comedi_insn *insn, |
1173 | unsigned int *data) |
1174 +----------------------------------------------------------------------------+
1175 | Task : Set the state from TTL output channel |
1176 +----------------------------------------------------------------------------+
1177 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
1178 | b_State = data [0] |
1179 +----------------------------------------------------------------------------+
1180 | Output Parameters : - |
1181 +----------------------------------------------------------------------------+
1182 | Return Value : 0 : No error |
1183 | -3 : Channel selection error |
1184 | -101 : Data size error |
1185 +----------------------------------------------------------------------------+
1188 int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device *dev,
1189 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
1191 int i_ReturnValue = insn->n;
1192 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
1193 unsigned char b_State = 0;
1194 unsigned int dw_Status = 0;
1196 /************************/
1197 /* Test the buffer size */
1198 /************************/
1201 b_State = (unsigned char) data[0];
1203 /***********************/
1204 /* Test if read port 0 */
1205 /***********************/
1207 if (b_Channel < 8) {
1208 /*****************************************************************************/
1209 /* Read port 0 (first digital output port) and set/reset the selcted channel */
1210 /*****************************************************************************/
1212 dw_Status = inl(devpriv->iobase + 80);
1214 (dw_Status & (0xFF -
1215 (1 << b_Channel))) | ((b_State & 1) <<
1217 outl(dw_Status, devpriv->iobase + 80);
1219 /***********************/
1220 /* Test if read port 2 */
1221 /***********************/
1223 if ((b_Channel > 15) && (b_Channel < 24)) {
1224 /*************************/
1225 /* Test if port 2 output */
1226 /*************************/
1228 if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF)
1230 /*****************************************************************************/
1231 /* Read port 2 (first digital output port) and set/reset the selcted channel */
1232 /*****************************************************************************/
1234 dw_Status = inl(devpriv->iobase + 112);
1236 (dw_Status & (0xFF -
1239 ((b_State & 1) << (b_Channel -
1241 outl(dw_Status, devpriv->iobase + 112);
1243 /***************************/
1244 /* Channel selection error */
1245 /***************************/
1248 printk("Channel %d selection error\n",
1252 /***************************/
1253 /* Channel selection error */
1254 /***************************/
1257 printk("Channel %d selection error\n",
1262 /*******************/
1263 /* Data size error */
1264 /*******************/
1266 printk("Buffer size error\n");
1267 i_ReturnValue = -101;
1270 return i_ReturnValue;
1274 +----------------------------------------------------------------------------+
1275 | DIGITAL INPUT SUBDEVICE |
1276 +----------------------------------------------------------------------------+
1280 +----------------------------------------------------------------------------+
1281 | Function name :int i_APCI3XXX_InsnReadDigitalInput |
1282 | (struct comedi_device *dev, |
1283 | struct comedi_subdevice *s, |
1284 | struct comedi_insn *insn, |
1285 | unsigned int *data) |
1286 +----------------------------------------------------------------------------+
1287 | Task : Reads the value of the specified Digital input channel |
1288 +----------------------------------------------------------------------------+
1289 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) (0 to 3) |
1290 +----------------------------------------------------------------------------+
1291 | Output Parameters : data[0] : Channel value |
1292 +----------------------------------------------------------------------------+
1293 | Return Value : 0 : No error |
1294 | -3 : Channel selection error |
1295 | -101 : Data size error |
1296 +----------------------------------------------------------------------------+
1299 int i_APCI3XXX_InsnReadDigitalInput(struct comedi_device *dev,
1300 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
1302 int i_ReturnValue = insn->n;
1303 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
1304 unsigned int dw_Temp = 0;
1306 /***************************/
1307 /* Test the channel number */
1308 /***************************/
1310 if (b_Channel <= devpriv->ps_BoardInfo->i_NbrDiChannel) {
1311 /************************/
1312 /* Test the buffer size */
1313 /************************/
1316 dw_Temp = inl(devpriv->iobase + 32);
1317 *data = (dw_Temp >> b_Channel) & 1;
1319 /*******************/
1320 /* Data size error */
1321 /*******************/
1323 printk("Buffer size error\n");
1324 i_ReturnValue = -101;
1327 /***************************/
1328 /* Channel selection error */
1329 /***************************/
1331 printk("Channel selection error\n");
1335 return i_ReturnValue;
1339 +----------------------------------------------------------------------------+
1340 | Function name :int i_APCI3XXX_InsnBitsDigitalInput |
1341 | (struct comedi_device *dev, |
1342 | struct comedi_subdevice *s, |
1343 | struct comedi_insn *insn, |
1344 | unsigned int *data) |
1345 +----------------------------------------------------------------------------+
1346 | Task : Reads the value of the Digital input Port i.e.4channels|
1347 +----------------------------------------------------------------------------+
1348 | Input Parameters : - |
1349 +----------------------------------------------------------------------------+
1350 | Output Parameters : data[0] : Port value |
1351 +----------------------------------------------------------------------------+
1352 | Return Value :>0: No error |
1354 | -101 : Data size error |
1355 +----------------------------------------------------------------------------+
1357 int i_APCI3XXX_InsnBitsDigitalInput(struct comedi_device *dev,
1358 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
1360 int i_ReturnValue = insn->n;
1361 unsigned int dw_Temp = 0;
1363 /************************/
1364 /* Test the buffer size */
1365 /************************/
1368 dw_Temp = inl(devpriv->iobase + 32);
1369 *data = dw_Temp & 0xf;
1371 /*******************/
1372 /* Data size error */
1373 /*******************/
1375 printk("Buffer size error\n");
1376 i_ReturnValue = -101;
1379 return i_ReturnValue;
1383 +----------------------------------------------------------------------------+
1384 | DIGITAL OUTPUT SUBDEVICE |
1385 +----------------------------------------------------------------------------+
1390 +----------------------------------------------------------------------------+
1391 | Function name :int i_APCI3XXX_InsnBitsDigitalOutput |
1392 | (struct comedi_device *dev, |
1393 | struct comedi_subdevice *s, |
1394 | struct comedi_insn *insn, |
1395 | unsigned int *data) |
1396 +----------------------------------------------------------------------------+
1397 | Task : Write the selected output mask and read the status from|
1398 | all digital output channles |
1399 +----------------------------------------------------------------------------+
1400 | Input Parameters : dw_ChannelMask = data [0]; |
1401 | dw_BitMask = data [1]; |
1402 +----------------------------------------------------------------------------+
1403 | Output Parameters : data[1] : All digital output channles states |
1404 +----------------------------------------------------------------------------+
1405 | Return Value : >0 : No error |
1406 | -4 : Channel mask error |
1407 | -101 : Data size error |
1408 +----------------------------------------------------------------------------+
1410 int i_APCI3XXX_InsnBitsDigitalOutput(struct comedi_device *dev,
1411 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
1413 int i_ReturnValue = insn->n;
1414 unsigned char b_ChannelCpt = 0;
1415 unsigned int dw_ChannelMask = 0;
1416 unsigned int dw_BitMask = 0;
1417 unsigned int dw_Status = 0;
1419 /************************/
1420 /* Test the buffer size */
1421 /************************/
1424 /*******************************/
1425 /* Get the channe and bit mask */
1426 /*******************************/
1428 dw_ChannelMask = data[0];
1429 dw_BitMask = data[1];
1431 /*************************/
1432 /* Test the channel mask */
1433 /*************************/
1435 if ((dw_ChannelMask & 0XFFFFFFF0) == 0) {
1436 /*********************************/
1437 /* Test if set/reset any channel */
1438 /*********************************/
1440 if (dw_ChannelMask & 0xF) {
1441 /********************************/
1442 /* Read the digital output port */
1443 /********************************/
1445 dw_Status = inl(devpriv->iobase + 48);
1447 for (b_ChannelCpt = 0; b_ChannelCpt < 4;
1449 if ((dw_ChannelMask >> b_ChannelCpt) &
1453 (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
1457 outl(dw_Status, devpriv->iobase + 48);
1460 /********************************/
1461 /* Read the digital output port */
1462 /********************************/
1464 data[1] = inl(devpriv->iobase + 48);
1466 /************************/
1467 /* Config command error */
1468 /************************/
1470 printk("Channel mask error\n");
1474 /*******************/
1475 /* Data size error */
1476 /*******************/
1478 printk("Buffer size error\n");
1479 i_ReturnValue = -101;
1482 return i_ReturnValue;
1486 +----------------------------------------------------------------------------+
1487 | Function name :int i_APCI3XXX_InsnWriteDigitalOutput |
1488 | (struct comedi_device *dev, |
1489 | struct comedi_subdevice *s, |
1490 | struct comedi_insn *insn, |
1491 | unsigned int *data) |
1492 +----------------------------------------------------------------------------+
1493 | Task : Set the state from digital output channel |
1494 +----------------------------------------------------------------------------+
1495 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
1496 | b_State = data [0] |
1497 +----------------------------------------------------------------------------+
1498 | Output Parameters : - |
1499 +----------------------------------------------------------------------------+
1500 | Return Value : >0 : No error |
1501 | -3 : Channel selection error |
1502 | -101 : Data size error |
1503 +----------------------------------------------------------------------------+
1506 int i_APCI3XXX_InsnWriteDigitalOutput(struct comedi_device *dev,
1507 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
1509 int i_ReturnValue = insn->n;
1510 unsigned char b_Channel = CR_CHAN(insn->chanspec);
1511 unsigned char b_State = 0;
1512 unsigned int dw_Status = 0;
1514 /************************/
1515 /* Test the buffer size */
1516 /************************/
1519 /***************************/
1520 /* Test the channel number */
1521 /***************************/
1523 if (b_Channel < devpriv->ps_BoardInfo->i_NbrDoChannel) {
1524 /*******************/
1525 /* Get the command */
1526 /*******************/
1528 b_State = (unsigned char) data[0];
1530 /********************************/
1531 /* Read the digital output port */
1532 /********************************/
1534 dw_Status = inl(devpriv->iobase + 48);
1538 (1 << b_Channel))) | ((b_State & 1) <<
1540 outl(dw_Status, devpriv->iobase + 48);
1542 /***************************/
1543 /* Channel selection error */
1544 /***************************/
1546 printk("Channel selection error\n");
1550 /*******************/
1551 /* Data size error */
1552 /*******************/
1554 printk("Buffer size error\n");
1555 i_ReturnValue = -101;
1558 return i_ReturnValue;
1562 +----------------------------------------------------------------------------+
1563 | Function name :int i_APCI3XXX_InsnReadDigitalOutput |
1564 | (struct comedi_device *dev, |
1565 | struct comedi_subdevice *s, |
1566 | struct comedi_insn *insn, |
1567 | unsigned int *data) |
1568 +----------------------------------------------------------------------------+
1569 | Task : Read the state from digital output channel |
1570 +----------------------------------------------------------------------------+
1571 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
1572 +----------------------------------------------------------------------------+
1573 | Output Parameters : b_State = data [0] |
1574 +----------------------------------------------------------------------------+
1575 | Return Value : >0 : No error |
1576 | -3 : Channel selection error |
1577 | -101 : Data size error |
1578 +----------------------------------------------------------------------------+
1581 int i_APCI3XXX_InsnReadDigitalOutput(struct comedi_device *dev,
1582 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
1584 int i_ReturnValue = insn->n;
1585 unsigned char b_Channel = CR_CHAN(insn->chanspec);
1586 unsigned int dw_Status = 0;
1588 /************************/
1589 /* Test the buffer size */
1590 /************************/
1593 /***************************/
1594 /* Test the channel number */
1595 /***************************/
1597 if (b_Channel < devpriv->ps_BoardInfo->i_NbrDoChannel) {
1598 /********************************/
1599 /* Read the digital output port */
1600 /********************************/
1602 dw_Status = inl(devpriv->iobase + 48);
1604 dw_Status = (dw_Status >> b_Channel) & 1;
1607 /***************************/
1608 /* Channel selection error */
1609 /***************************/
1611 printk("Channel selection error\n");
1615 /*******************/
1616 /* Data size error */
1617 /*******************/
1619 printk("Buffer size error\n");
1620 i_ReturnValue = -101;
1623 return i_ReturnValue;
1627 +----------------------------------------------------------------------------+
1628 | Function Name : int i_APCI3XXX_Reset(struct comedi_device *dev) | +----------------------------------------------------------------------------+
1629 | Task :resets all the registers |
1630 +----------------------------------------------------------------------------+
1631 | Input Parameters : struct comedi_device *dev |
1632 +----------------------------------------------------------------------------+
1633 | Output Parameters : - |
1634 +----------------------------------------------------------------------------+
1635 | Return Value : - |
1636 +----------------------------------------------------------------------------+
1639 int i_APCI3XXX_Reset(struct comedi_device *dev)
1641 unsigned char b_Cpt = 0;
1643 /*************************/
1644 /* Disable the interrupt */
1645 /*************************/
1647 disable_irq(dev->irq);
1649 /****************************/
1650 /* Reset the interrupt flag */
1651 /****************************/
1653 devpriv->b_EocEosInterrupt = 0;
1655 /***************************/
1656 /* Clear the start command */
1657 /***************************/
1659 writel(0, (void *)(devpriv->dw_AiBase + 8));
1661 /*****************************/
1662 /* Reset the interrupt flags */
1663 /*****************************/
1665 writel(readl((void *)(devpriv->dw_AiBase + 16)),
1666 (void *)(devpriv->dw_AiBase + 16));
1672 readl((void *)(devpriv->dw_AiBase + 20));
1674 /******************/
1675 /* Clear the FIFO */
1676 /******************/
1678 for (b_Cpt = 0; b_Cpt < 16; b_Cpt++) {
1679 readl((void *)(devpriv->dw_AiBase + 28));
1682 /************************/
1683 /* Enable the interrupt */
1684 /************************/
1686 enable_irq(dev->irq);