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 #ifndef COMEDI_SUBD_TTLIO
48 #define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */
51 #define APCI3XXX_SINGLE 0
52 #define APCI3XXX_DIFF 1
53 #define APCI3XXX_CONFIGURATION 0
55 #define APCI3XXX_TTL_INIT_DIRECTION_PORT2 0
57 static const struct comedi_lrange range_apci3XXX_ai = {
70 static const struct comedi_lrange range_apci3XXX_ao = {
78 +----------------------------------------------------------------------------+
79 | ANALOG INPUT FUNCTIONS |
80 +----------------------------------------------------------------------------+
84 +----------------------------------------------------------------------------+
85 | Function Name : int i_APCI3XXX_TestConversionStarted |
86 | (struct comedi_device *dev) |
87 +----------------------------------------------------------------------------+
88 | Task Test if any conversion started |
89 +----------------------------------------------------------------------------+
90 | Input Parameters : - |
91 +----------------------------------------------------------------------------+
92 | Output Parameters : - |
93 +----------------------------------------------------------------------------+
94 | Return Value : 0 : Conversion not started |
95 | 1 : Conversion started |
96 +----------------------------------------------------------------------------+
98 static int i_APCI3XXX_TestConversionStarted(struct comedi_device *dev)
100 struct addi_private *devpriv = dev->private;
102 if ((readl(devpriv->dw_AiBase + 8) & 0x80000UL) == 0x80000UL)
110 +----------------------------------------------------------------------------+
111 | Function Name : int i_APCI3XXX_AnalogInputConfigOperatingMode |
112 | (struct comedi_device *dev, |
113 | struct comedi_subdevice *s, |
114 | struct comedi_insn *insn, |
115 | unsigned int *data) |
116 +----------------------------------------------------------------------------+
117 | Task Converting mode and convert time selection |
118 +----------------------------------------------------------------------------+
119 | Input Parameters : b_SingleDiff = (unsigned char) data[1]; |
120 | b_TimeBase = (unsigned char) data[2]; (0: ns, 1:micros 2:ms)|
121 | dw_ReloadValue = (unsigned int) data[3]; |
123 +----------------------------------------------------------------------------+
124 | Output Parameters : - |
125 +----------------------------------------------------------------------------+
126 | Return Value :>0 : No error |
127 | -1 : Single/Diff selection error |
128 | -2 : Convert time base unity selection error |
129 | -3 : Convert time value selection error |
130 | -10: Any conversion started |
132 | -100 : Config command error |
133 | -101 : Data size error |
134 +----------------------------------------------------------------------------+
136 static int i_APCI3XXX_AnalogInputConfigOperatingMode(struct comedi_device *dev,
137 struct comedi_subdevice *s,
138 struct comedi_insn *insn,
141 const struct addi_board *this_board = comedi_board(dev);
142 struct addi_private *devpriv = dev->private;
143 int i_ReturnValue = insn->n;
144 unsigned char b_TimeBase = 0;
145 unsigned char b_SingleDiff = 0;
146 unsigned int dw_ReloadValue = 0;
147 unsigned int dw_TestReloadValue = 0;
149 /************************/
150 /* Test the buffer size */
151 /************************/
154 /****************************/
155 /* Get the Singel/Diff flag */
156 /****************************/
158 b_SingleDiff = (unsigned char) data[1];
160 /****************************/
161 /* Get the time base unitiy */
162 /****************************/
164 b_TimeBase = (unsigned char) data[2];
166 /*************************************/
167 /* Get the convert time reload value */
168 /*************************************/
170 dw_ReloadValue = (unsigned int) data[3];
172 /**********************/
173 /* Test the time base */
174 /**********************/
176 if ((this_board->b_AvailableConvertUnit & (1 << b_TimeBase)) !=
178 /*******************************/
179 /* Test the convert time value */
180 /*******************************/
182 if (dw_ReloadValue <= 65535) {
183 dw_TestReloadValue = dw_ReloadValue;
185 if (b_TimeBase == 1) {
187 dw_TestReloadValue * 1000UL;
189 if (b_TimeBase == 2) {
191 dw_TestReloadValue * 1000000UL;
194 /*******************************/
195 /* Test the convert time value */
196 /*******************************/
198 if (dw_TestReloadValue >=
199 devpriv->s_EeParameters.
200 ui_MinAcquisitiontimeNs) {
201 if ((b_SingleDiff == APCI3XXX_SINGLE)
204 if (((b_SingleDiff == APCI3XXX_SINGLE)
205 && (devpriv->s_EeParameters.i_NbrAiChannel == 0))
206 || ((b_SingleDiff == APCI3XXX_DIFF)
207 && (this_board->i_NbrAiChannelDiff == 0))
209 /*******************************/
210 /* Single/Diff selection error */
211 /*******************************/
213 printk("Single/Diff selection error\n");
216 /**********************************/
217 /* Test if conversion not started */
218 /**********************************/
220 if (i_APCI3XXX_TestConversionStarted(dev) == 0) {
222 ui_EocEosConversionTime
227 b_EocEosConversionTimeBase
238 /*******************************/
239 /* Set the convert timing unit */
240 /*******************************/
242 writel((unsigned int)b_TimeBase,
243 devpriv->dw_AiBase + 36);
245 /**************************/
246 /* Set the convert timing */
247 /*************************/
249 writel(dw_ReloadValue, devpriv->dw_AiBase + 32);
251 /**************************/
252 /* Any conversion started */
253 /**************************/
255 printk("Any conversion started\n");
261 /*******************************/
262 /* Single/Diff selection error */
263 /*******************************/
265 printk("Single/Diff selection error\n");
269 /************************/
270 /* Time selection error */
271 /************************/
273 printk("Convert time value selection error\n");
277 /************************/
278 /* Time selection error */
279 /************************/
281 printk("Convert time value selection error\n");
285 /*****************************/
286 /* Time base selection error */
287 /*****************************/
289 printk("Convert time base unity selection error\n");
293 /*******************/
294 /* Data size error */
295 /*******************/
297 printk("Buffer size error\n");
298 i_ReturnValue = -101;
301 return i_ReturnValue;
305 +----------------------------------------------------------------------------+
306 | Function Name : int i_APCI3XXX_InsnConfigAnalogInput |
307 | (struct comedi_device *dev, |
308 | struct comedi_subdevice *s, |
309 | struct comedi_insn *insn, |
310 | unsigned int *data) |
311 +----------------------------------------------------------------------------+
312 | Task Converting mode and convert time selection |
313 +----------------------------------------------------------------------------+
314 | Input Parameters : b_ConvertMode = (unsigned char) data[0]; |
315 | b_TimeBase = (unsigned char) data[1]; (0: ns, 1:micros 2:ms)|
316 | dw_ReloadValue = (unsigned int) data[2]; |
318 +----------------------------------------------------------------------------+
319 | Output Parameters : - |
320 +----------------------------------------------------------------------------+
321 | Return Value :>0: No error |
323 | -100 : Config command error |
324 | -101 : Data size error |
325 +----------------------------------------------------------------------------+
327 static int i_APCI3XXX_InsnConfigAnalogInput(struct comedi_device *dev,
328 struct comedi_subdevice *s,
329 struct comedi_insn *insn,
332 int i_ReturnValue = insn->n;
334 /************************/
335 /* Test the buffer size */
336 /************************/
339 switch ((unsigned char) data[0]) {
340 case APCI3XXX_CONFIGURATION:
342 i_APCI3XXX_AnalogInputConfigOperatingMode(dev,
347 i_ReturnValue = -100;
348 printk("Config command error %d\n", data[0]);
352 /*******************/
353 /* Data size error */
354 /*******************/
356 printk("Buffer size error\n");
357 i_ReturnValue = -101;
360 return i_ReturnValue;
364 +----------------------------------------------------------------------------+
365 | Function Name : int i_APCI3XXX_InsnReadAnalogInput |
366 | (struct comedi_device *dev, |
367 | struct comedi_subdevice *s, |
368 | struct comedi_insn *insn, |
369 | unsigned int *data) |
370 +----------------------------------------------------------------------------+
371 | Task Read 1 analog input |
372 +----------------------------------------------------------------------------+
373 | Input Parameters : b_Range = CR_RANGE(insn->chanspec); |
374 | b_Channel = CR_CHAN(insn->chanspec); |
375 | dw_NbrOfAcquisition = insn->n; |
376 +----------------------------------------------------------------------------+
377 | Output Parameters : - |
378 +----------------------------------------------------------------------------+
379 | Return Value :>0: No error |
380 | -3 : Channel selection error |
381 | -4 : Configuration selelection error |
382 | -10: Any conversion started |
384 | -100 : Config command error |
385 | -101 : Data size error |
386 +----------------------------------------------------------------------------+
388 static int i_APCI3XXX_InsnReadAnalogInput(struct comedi_device *dev,
389 struct comedi_subdevice *s,
390 struct comedi_insn *insn,
393 const struct addi_board *this_board = comedi_board(dev);
394 struct addi_private *devpriv = dev->private;
395 int i_ReturnValue = insn->n;
396 unsigned char b_Configuration = (unsigned char) CR_RANGE(insn->chanspec);
397 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
398 unsigned int dw_Temp = 0;
399 unsigned int dw_Configuration = 0;
400 unsigned int dw_AcquisitionCpt = 0;
401 unsigned char b_Interrupt = 0;
403 /*************************************/
404 /* Test if operating mode configured */
405 /*************************************/
407 if (devpriv->b_AiInitialisation) {
408 /***************************/
409 /* Test the channel number */
410 /***************************/
412 if (((b_Channel < devpriv->s_EeParameters.i_NbrAiChannel)
413 && (devpriv->b_SingelDiff == APCI3XXX_SINGLE))
414 || ((b_Channel < this_board->i_NbrAiChannelDiff)
415 && (devpriv->b_SingelDiff == APCI3XXX_DIFF))) {
416 /**********************************/
417 /* Test the channel configuration */
418 /**********************************/
420 if (b_Configuration > 7) {
421 /***************************/
422 /* Channel not initialised */
423 /***************************/
426 printk("Channel %d range %d selection error\n",
427 b_Channel, b_Configuration);
430 /***************************/
431 /* Channel selection error */
432 /***************************/
435 printk("Channel %d selection error\n", b_Channel);
438 /**************************/
439 /* Test if no error occur */
440 /**************************/
442 if (i_ReturnValue >= 0) {
443 /************************/
444 /* Test the buffer size */
445 /************************/
447 if ((b_Interrupt != 0) || ((b_Interrupt == 0)
448 && (insn->n >= 1))) {
449 /**********************************/
450 /* Test if conversion not started */
451 /**********************************/
453 if (i_APCI3XXX_TestConversionStarted(dev) == 0) {
458 writel(0x10000UL, devpriv->dw_AiBase + 12);
460 /*******************************/
461 /* Get and save the delay mode */
462 /*******************************/
464 dw_Temp = readl(devpriv->dw_AiBase + 4);
465 dw_Temp = dw_Temp & 0xFFFFFEF0UL;
467 /***********************************/
468 /* Channel configuration selection */
469 /***********************************/
471 writel(dw_Temp, devpriv->dw_AiBase + 4);
473 /**************************/
474 /* Make the configuration */
475 /**************************/
478 (b_Configuration & 3) |
479 ((unsigned int) (b_Configuration >> 2)
480 << 6) | ((unsigned int) devpriv->
483 /***************************/
484 /* Write the configuration */
485 /***************************/
487 writel(dw_Configuration,
488 devpriv->dw_AiBase + 0);
490 /*********************/
491 /* Channel selection */
492 /*********************/
494 writel(dw_Temp | 0x100UL,
495 devpriv->dw_AiBase + 4);
496 writel((unsigned int) b_Channel,
497 devpriv->dw_AiBase + 0);
499 /***********************/
500 /* Restaure delay mode */
501 /***********************/
503 writel(dw_Temp, devpriv->dw_AiBase + 4);
505 /***********************************/
506 /* Set the number of sequence to 1 */
507 /***********************************/
509 writel(1, devpriv->dw_AiBase + 48);
511 /***************************/
512 /* Save the interrupt flag */
513 /***************************/
515 devpriv->b_EocEosInterrupt =
518 /*******************************/
519 /* Save the number of channels */
520 /*******************************/
522 devpriv->ui_AiNbrofChannels = 1;
524 /******************************/
525 /* Test if interrupt not used */
526 /******************************/
528 if (b_Interrupt == 0) {
529 for (dw_AcquisitionCpt = 0;
532 dw_AcquisitionCpt++) {
533 /************************/
534 /* Start the conversion */
535 /************************/
537 writel(0x80000UL, devpriv->dw_AiBase + 8);
544 dw_Temp = readl(devpriv->dw_AiBase + 20);
545 dw_Temp = dw_Temp & 1;
546 } while (dw_Temp != 1);
548 /*************************/
549 /* Read the analog value */
550 /*************************/
552 data[dw_AcquisitionCpt] = (unsigned int)readl(devpriv->dw_AiBase + 28);
555 /************************/
556 /* Start the conversion */
557 /************************/
559 writel(0x180000UL, devpriv->dw_AiBase + 8);
562 /**************************/
563 /* Any conversion started */
564 /**************************/
566 printk("Any conversion started\n");
570 /*******************/
571 /* Data size error */
572 /*******************/
574 printk("Buffer size error\n");
575 i_ReturnValue = -101;
579 /***************************/
580 /* Channel selection error */
581 /***************************/
583 printk("Operating mode not configured\n");
586 return i_ReturnValue;
590 +----------------------------------------------------------------------------+
591 | Function name : void v_APCI3XXX_Interrupt (int irq, |
593 +----------------------------------------------------------------------------+
594 | Task :Interrupt handler for APCI3XXX |
595 | When interrupt occurs this gets called. |
596 | First it finds which interrupt has been generated and |
597 | handles corresponding interrupt |
598 +----------------------------------------------------------------------------+
599 | Input Parameters : - |
600 +----------------------------------------------------------------------------+
602 +----------------------------------------------------------------------------+
605 static void v_APCI3XXX_Interrupt(int irq, void *d)
607 struct comedi_device *dev = d;
608 struct addi_private *devpriv = dev->private;
609 unsigned char b_CopyCpt = 0;
610 unsigned int dw_Status = 0;
612 /***************************/
613 /* Test if interrupt occur */
614 /***************************/
616 dw_Status = readl(devpriv->dw_AiBase + 16);
617 if ( (dw_Status & 0x2UL) == 0x2UL) {
618 /***********************/
619 /* Reset the interrupt */
620 /***********************/
622 writel(dw_Status, 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(devpriv->dw_AiBase + 28);
640 /**************************/
641 /* Set the interrupt flag */
642 /**************************/
644 devpriv->b_EocEosInterrupt = 2;
646 /**********************************************/
647 /* Send a signal to from kernel to user space */
648 /**********************************************/
650 send_sig(SIGIO, devpriv->tsk_Current, 0);
656 +----------------------------------------------------------------------------+
657 | ANALOG OUTPUT SUBDEVICE |
658 +----------------------------------------------------------------------------+
662 +----------------------------------------------------------------------------+
663 | Function Name : int i_APCI3XXX_InsnWriteAnalogOutput |
664 | (struct comedi_device *dev, |
665 | struct comedi_subdevice *s, |
666 | struct comedi_insn *insn, |
667 | unsigned int *data) |
668 +----------------------------------------------------------------------------+
669 | Task Read 1 analog input |
670 +----------------------------------------------------------------------------+
671 | Input Parameters : b_Range = CR_RANGE(insn->chanspec); |
672 | b_Channel = CR_CHAN(insn->chanspec); |
673 | data[0] = analog value; |
674 +----------------------------------------------------------------------------+
675 | Output Parameters : - |
676 +----------------------------------------------------------------------------+
677 | Return Value :>0: No error |
678 | -3 : Channel selection error |
679 | -4 : Configuration selelection error |
681 | -101 : Data size error |
682 +----------------------------------------------------------------------------+
684 static int i_APCI3XXX_InsnWriteAnalogOutput(struct comedi_device *dev,
685 struct comedi_subdevice *s,
686 struct comedi_insn *insn,
689 struct addi_private *devpriv = dev->private;
690 unsigned char b_Range = (unsigned char) CR_RANGE(insn->chanspec);
691 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
692 unsigned int dw_Status = 0;
693 int i_ReturnValue = insn->n;
695 /************************/
696 /* Test the buffer size */
697 /************************/
700 /***************************/
701 /* Test the channel number */
702 /***************************/
704 if (b_Channel < devpriv->s_EeParameters.i_NbrAoChannel) {
705 /**********************************/
706 /* Test the channel configuration */
707 /**********************************/
710 /***************************/
711 /* Set the range selection */
712 /***************************/
714 writel(b_Range, devpriv->dw_AiBase + 96);
716 /**************************************************/
717 /* Write the analog value to the selected channel */
718 /**************************************************/
720 writel((data[0] << 8) | b_Channel,
721 devpriv->dw_AiBase + 100);
723 /****************************/
724 /* Wait the end of transfer */
725 /****************************/
728 dw_Status = readl(devpriv->dw_AiBase + 96);
729 } while ((dw_Status & 0x100) != 0x100);
731 /***************************/
732 /* Channel not initialised */
733 /***************************/
736 printk("Channel %d range %d selection error\n",
740 /***************************/
741 /* Channel selection error */
742 /***************************/
745 printk("Channel %d selection error\n", b_Channel);
748 /*******************/
749 /* Data size error */
750 /*******************/
752 printk("Buffer size error\n");
753 i_ReturnValue = -101;
756 return i_ReturnValue;
760 +----------------------------------------------------------------------------+
762 +----------------------------------------------------------------------------+
766 +----------------------------------------------------------------------------+
767 | Function Name : int i_APCI3XXX_InsnConfigInitTTLIO |
768 | (struct comedi_device *dev, |
769 | struct comedi_subdevice *s, |
770 | struct comedi_insn *insn, |
771 | unsigned int *data) |
772 +----------------------------------------------------------------------------+
773 | Task You must calling this function be |
774 | for you call any other function witch access of TTL. |
775 | APCI3XXX_TTL_INIT_DIRECTION_PORT2(user inputs for direction)|
776 +----------------------------------------------------------------------------+
777 | Input Parameters : b_InitType = (unsigned char) data[0]; |
778 | b_Port2Mode = (unsigned char) data[1]; |
779 +----------------------------------------------------------------------------+
780 | Output Parameters : - |
781 +----------------------------------------------------------------------------+
782 | Return Value :>0: No error |
783 | -1: Port 2 mode selection is wrong |
785 | -100 : Config command error |
786 | -101 : Data size error |
787 +----------------------------------------------------------------------------+
789 static int i_APCI3XXX_InsnConfigInitTTLIO(struct comedi_device *dev,
790 struct comedi_subdevice *s,
791 struct comedi_insn *insn,
794 struct addi_private *devpriv = dev->private;
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 +----------------------------------------------------------------------------+
919 static int i_APCI3XXX_InsnBitsTTLIO(struct comedi_device *dev,
920 struct comedi_subdevice *s,
921 struct comedi_insn *insn,
924 struct addi_private *devpriv = dev->private;
925 int i_ReturnValue = insn->n;
926 unsigned char b_ChannelCpt = 0;
927 unsigned int dw_ChannelMask = 0;
928 unsigned int dw_BitMask = 0;
929 unsigned int dw_Status = 0;
931 /************************/
932 /* Test the buffer size */
933 /************************/
936 /*******************************/
937 /* Get the channe and bit mask */
938 /*******************************/
940 dw_ChannelMask = data[0];
941 dw_BitMask = data[1];
943 /*************************/
944 /* Test the channel mask */
945 /*************************/
947 if (((dw_ChannelMask & 0XFF00FF00) == 0) &&
948 (((devpriv->ul_TTLPortConfiguration[0] & 0xFF) == 0xFF)
949 || (((devpriv->ul_TTLPortConfiguration[0] &
951 && ((dw_ChannelMask & 0XFF0000) ==
953 /*********************************/
954 /* Test if set/reset any channel */
955 /*********************************/
957 if (dw_ChannelMask) {
958 /****************************************/
959 /* Test if set/rest any port 0 channels */
960 /****************************************/
962 if (dw_ChannelMask & 0xFF) {
963 /*******************************************/
964 /* Read port 0 (first digital output port) */
965 /*******************************************/
967 dw_Status = inl(devpriv->iobase + 80);
969 for (b_ChannelCpt = 0; b_ChannelCpt < 8;
971 if ((dw_ChannelMask >>
976 (0xFF - (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
980 outl(dw_Status, devpriv->iobase + 80);
983 /****************************************/
984 /* Test if set/rest any port 2 channels */
985 /****************************************/
987 if (dw_ChannelMask & 0xFF0000) {
988 dw_BitMask = dw_BitMask >> 16;
989 dw_ChannelMask = dw_ChannelMask >> 16;
991 /********************************************/
992 /* Read port 2 (second digital output port) */
993 /********************************************/
995 dw_Status = inl(devpriv->iobase + 112);
997 for (b_ChannelCpt = 0; b_ChannelCpt < 8;
999 if ((dw_ChannelMask >>
1004 (0xFF - (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
1008 outl(dw_Status, devpriv->iobase + 112);
1012 /*******************************************/
1013 /* Read port 0 (first digital output port) */
1014 /*******************************************/
1016 data[1] = inl(devpriv->iobase + 80);
1018 /******************************************/
1019 /* Read port 1 (first digital input port) */
1020 /******************************************/
1022 data[1] = data[1] | (inl(devpriv->iobase + 64) << 8);
1024 /************************/
1025 /* Test if port 2 input */
1026 /************************/
1028 if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF) == 0) {
1030 data[1] | (inl(devpriv->iobase +
1034 data[1] | (inl(devpriv->iobase +
1038 /************************/
1039 /* Config command error */
1040 /************************/
1042 printk("Channel mask error\n");
1046 /*******************/
1047 /* Data size error */
1048 /*******************/
1050 printk("Buffer size error\n");
1051 i_ReturnValue = -101;
1054 return i_ReturnValue;
1058 +----------------------------------------------------------------------------+
1059 | Function Name : int i_APCI3XXX_InsnReadTTLIO |
1060 | (struct comedi_device *dev, |
1061 | struct comedi_subdevice *s, |
1062 | struct comedi_insn *insn, |
1063 | unsigned int *data) |
1064 +----------------------------------------------------------------------------+
1065 | Task : Read the status from selected channel |
1066 +----------------------------------------------------------------------------+
1067 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
1068 +----------------------------------------------------------------------------+
1069 | Output Parameters : data[0] : Selected TTL channel state |
1070 +----------------------------------------------------------------------------+
1071 | Return Value : 0 : No error |
1072 | -3 : Channel selection error |
1073 | -101 : Data size error |
1074 +----------------------------------------------------------------------------+
1076 static int i_APCI3XXX_InsnReadTTLIO(struct comedi_device *dev,
1077 struct comedi_subdevice *s,
1078 struct comedi_insn *insn,
1081 struct addi_private *devpriv = dev->private;
1082 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
1083 int i_ReturnValue = insn->n;
1084 unsigned int *pls_ReadData = data;
1086 /************************/
1087 /* Test the buffer size */
1088 /************************/
1091 /***********************/
1092 /* Test if read port 0 */
1093 /***********************/
1095 if (b_Channel < 8) {
1096 /*******************************************/
1097 /* Read port 0 (first digital output port) */
1098 /*******************************************/
1100 pls_ReadData[0] = inl(devpriv->iobase + 80);
1101 pls_ReadData[0] = (pls_ReadData[0] >> b_Channel) & 1;
1103 /***********************/
1104 /* Test if read port 1 */
1105 /***********************/
1107 if ((b_Channel > 7) && (b_Channel < 16)) {
1108 /******************************************/
1109 /* Read port 1 (first digital input port) */
1110 /******************************************/
1112 pls_ReadData[0] = inl(devpriv->iobase + 64);
1114 (pls_ReadData[0] >> (b_Channel -
1117 /***********************/
1118 /* Test if read port 2 */
1119 /***********************/
1121 if ((b_Channel > 15) && (b_Channel < 24)) {
1122 /************************/
1123 /* Test if port 2 input */
1124 /************************/
1126 if ((devpriv->ul_TTLPortConfiguration[0]
1129 inl(devpriv->iobase +
1133 (b_Channel - 16)) & 1;
1136 inl(devpriv->iobase +
1140 (b_Channel - 16)) & 1;
1143 /***************************/
1144 /* Channel selection error */
1145 /***************************/
1148 printk("Channel %d selection error\n",
1154 /*******************/
1155 /* Data size error */
1156 /*******************/
1158 printk("Buffer size error\n");
1159 i_ReturnValue = -101;
1162 return i_ReturnValue;
1166 +----------------------------------------------------------------------------+
1167 | TTL OUTPUT FUNCTIONS |
1168 +----------------------------------------------------------------------------+
1172 +----------------------------------------------------------------------------+
1173 | Function Name : int i_APCI3XXX_InsnWriteTTLIO |
1174 | (struct comedi_device *dev, |
1175 | struct comedi_subdevice *s, |
1176 | struct comedi_insn *insn, |
1177 | unsigned int *data) |
1178 +----------------------------------------------------------------------------+
1179 | Task : Set the state from TTL output channel |
1180 +----------------------------------------------------------------------------+
1181 | Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
1182 | b_State = data [0] |
1183 +----------------------------------------------------------------------------+
1184 | Output Parameters : - |
1185 +----------------------------------------------------------------------------+
1186 | Return Value : 0 : No error |
1187 | -3 : Channel selection error |
1188 | -101 : Data size error |
1189 +----------------------------------------------------------------------------+
1191 static int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device *dev,
1192 struct comedi_subdevice *s,
1193 struct comedi_insn *insn,
1196 struct addi_private *devpriv = dev->private;
1197 int i_ReturnValue = insn->n;
1198 unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
1199 unsigned char b_State = 0;
1200 unsigned int dw_Status = 0;
1202 /************************/
1203 /* Test the buffer size */
1204 /************************/
1207 b_State = (unsigned char) data[0];
1209 /***********************/
1210 /* Test if read port 0 */
1211 /***********************/
1213 if (b_Channel < 8) {
1214 /*****************************************************************************/
1215 /* Read port 0 (first digital output port) and set/reset the selected channel */
1216 /*****************************************************************************/
1218 dw_Status = inl(devpriv->iobase + 80);
1220 (dw_Status & (0xFF -
1221 (1 << b_Channel))) | ((b_State & 1) <<
1223 outl(dw_Status, devpriv->iobase + 80);
1225 /***********************/
1226 /* Test if read port 2 */
1227 /***********************/
1229 if ((b_Channel > 15) && (b_Channel < 24)) {
1230 /*************************/
1231 /* Test if port 2 output */
1232 /*************************/
1234 if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF)
1236 /*****************************************************************************/
1237 /* Read port 2 (first digital output port) and set/reset the selected channel */
1238 /*****************************************************************************/
1240 dw_Status = inl(devpriv->iobase + 112);
1242 (dw_Status & (0xFF -
1245 ((b_State & 1) << (b_Channel -
1247 outl(dw_Status, devpriv->iobase + 112);
1249 /***************************/
1250 /* Channel selection error */
1251 /***************************/
1254 printk("Channel %d selection error\n",
1258 /***************************/
1259 /* Channel selection error */
1260 /***************************/
1263 printk("Channel %d selection error\n",
1268 /*******************/
1269 /* Data size error */
1270 /*******************/
1272 printk("Buffer size error\n");
1273 i_ReturnValue = -101;
1276 return i_ReturnValue;
1279 static int apci3xxx_di_insn_bits(struct comedi_device *dev,
1280 struct comedi_subdevice *s,
1281 struct comedi_insn *insn,
1284 struct addi_private *devpriv = dev->private;
1286 data[1] = inl(devpriv->iobase + 32) & 0xf;
1291 static int apci3xxx_do_insn_bits(struct comedi_device *dev,
1292 struct comedi_subdevice *s,
1293 struct comedi_insn *insn,
1296 struct addi_private *devpriv = dev->private;
1297 unsigned int mask = data[0];
1298 unsigned int bits = data[1];
1300 s->state = inl(devpriv->iobase + 48) & 0xf;
1303 s->state |= (bits & mask);
1305 outl(s->state, devpriv->iobase + 48);
1314 +----------------------------------------------------------------------------+
1315 | Function Name : int i_APCI3XXX_Reset(struct comedi_device *dev) | +----------------------------------------------------------------------------+
1316 | Task :resets all the registers |
1317 +----------------------------------------------------------------------------+
1318 | Input Parameters : struct comedi_device *dev |
1319 +----------------------------------------------------------------------------+
1320 | Output Parameters : - |
1321 +----------------------------------------------------------------------------+
1322 | Return Value : - |
1323 +----------------------------------------------------------------------------+
1326 static int i_APCI3XXX_Reset(struct comedi_device *dev)
1328 struct addi_private *devpriv = dev->private;
1329 unsigned char b_Cpt = 0;
1331 /*************************/
1332 /* Disable the interrupt */
1333 /*************************/
1335 disable_irq(dev->irq);
1337 /****************************/
1338 /* Reset the interrupt flag */
1339 /****************************/
1341 devpriv->b_EocEosInterrupt = 0;
1343 /***************************/
1344 /* Clear the start command */
1345 /***************************/
1347 writel(0, devpriv->dw_AiBase + 8);
1349 /*****************************/
1350 /* Reset the interrupt flags */
1351 /*****************************/
1353 writel(readl(devpriv->dw_AiBase + 16), devpriv->dw_AiBase + 16);
1359 readl(devpriv->dw_AiBase + 20);
1361 /******************/
1362 /* Clear the FIFO */
1363 /******************/
1365 for (b_Cpt = 0; b_Cpt < 16; b_Cpt++) {
1366 readl(devpriv->dw_AiBase + 28);
1369 /************************/
1370 /* Enable the interrupt */
1371 /************************/
1373 enable_irq(dev->irq);