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.
26 +-----------------------------------------------------------------------+
27 | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
28 +-----------------------------------------------------------------------+
29 | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
30 | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
31 +-------------------------------+---------------------------------------+
32 | Project : APCI-3501 | Compiler : GCC |
33 | Module name : hwdrv_apci3501.c| Version : 2.96 |
34 +-------------------------------+---------------------------------------+
35 | Project manager: Eric Stolz | Date : 02/12/2002 |
36 +-------------------------------+---------------------------------------+
37 | Description : Hardware Layer Acces For APCI-3501 |
38 +-----------------------------------------------------------------------+
40 +----------+-----------+------------------------------------------------+
41 | Date | Author | Description of updates |
42 +----------+-----------+------------------------------------------------+
46 +----------+-----------+------------------------------------------------+
50 +----------------------------------------------------------------------------+
52 +----------------------------------------------------------------------------+
54 #include "hwdrv_apci3501.h"
57 +----------------------------------------------------------------------------+
58 | Function Name : int i_APCI3501_ReadDigitalInput |
59 | (struct comedi_device *dev,struct comedi_subdevice *s, |
60 | struct comedi_insn *insn,unsigned int *data) |
61 +----------------------------------------------------------------------------+
62 | Task : Read value of the selected channel or port |
63 +----------------------------------------------------------------------------+
64 | Input Parameters : struct comedi_device *dev : Driver handle |
65 | unsigned int ui_NoOfChannels : No Of Channels To read |
66 | unsigned int *data : Data Pointer to read status |
67 +----------------------------------------------------------------------------+
68 | Output Parameters : -- |
69 +----------------------------------------------------------------------------+
70 | Return Value : TRUE : No error occur |
71 | : FALSE : Error occur. Return the error |
73 +----------------------------------------------------------------------------+
76 int i_APCI3501_ReadDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
77 struct comedi_insn * insn, unsigned int * data)
80 unsigned int ui_NoOfChannel;
81 ui_NoOfChannel = CR_CHAN(insn->chanspec);
83 *data = inl(devpriv->iobase + APCI3501_DIGITAL_IP);
85 *data = (*data >> ui_NoOfChannel) & 0x1;
93 printk("\nSpecified channel not supported \n");
94 } //elseif (ui_Temp==1)
95 } //elseif (ui_Temp==0)
100 +----------------------------------------------------------------------------+
101 | Function Name : int i_APCI3501_ConfigDigitalOutput |
102 | (struct comedi_device *dev,struct comedi_subdevice *s, |
103 | struct comedi_insn *insn,unsigned int *data) |
104 +----------------------------------------------------------------------------+
105 | Task : Configures The Digital Output Subdevice. |
106 +----------------------------------------------------------------------------+
107 | Input Parameters : struct comedi_device *dev : Driver handle |
108 | unsigned int *data : Data Pointer contains |
109 | configuration parameters as below |
111 | data[1] : 1 Enable VCC Interrupt |
112 | 0 Disable VCC Interrupt |
113 | data[2] : 1 Enable CC Interrupt |
114 | 0 Disable CC Interrupt |
116 +----------------------------------------------------------------------------+
117 | Output Parameters : -- |
118 +----------------------------------------------------------------------------+
119 | Return Value : TRUE : No error occur |
120 | : FALSE : Error occur. Return the error |
122 +----------------------------------------------------------------------------+
124 int i_APCI3501_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
125 struct comedi_insn * insn, unsigned int * data)
128 if ((data[0] != 0) && (data[0] != 1)) {
130 "Not a valid Data !!! ,Data should be 1 or 0\n");
132 } //if ( (data[0]!=0) && (data[0]!=1) )
134 devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
137 devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
138 } //else if (data[0])
143 +----------------------------------------------------------------------------+
144 | Function Name : int i_APCI3501_WriteDigitalOutput |
145 | (struct comedi_device *dev,struct comedi_subdevice *s, |
146 | struct comedi_insn *insn,unsigned int *data) |
147 +----------------------------------------------------------------------------+
148 | Task : writes To the digital Output Subdevice |
149 +----------------------------------------------------------------------------+
150 | Input Parameters : struct comedi_device *dev : Driver handle |
151 | struct comedi_subdevice *s : Subdevice Pointer |
152 | struct comedi_insn *insn : Insn Structure Pointer |
153 | unsigned int *data : Data Pointer contains |
154 | configuration parameters as below |
156 +----------------------------------------------------------------------------+
157 | Output Parameters : -- |
158 +----------------------------------------------------------------------------+
159 | Return Value : TRUE : No error occur |
160 | : FALSE : Error occur. Return the error |
162 +----------------------------------------------------------------------------+
164 int i_APCI3501_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
165 struct comedi_insn * insn, unsigned int * data)
167 unsigned int ui_Temp, ui_Temp1;
168 unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
169 if (devpriv->b_OutputMemoryStatus) {
170 ui_Temp = inl(devpriv->iobase + APCI3501_DIGITAL_OP);
171 } //if(devpriv->b_OutputMemoryStatus )
174 } //if(devpriv->b_OutputMemoryStatus )
177 data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
178 outl(data[0], devpriv->iobase + APCI3501_DIGITAL_OP);
182 data[0] = (data[0] << (2 * data[2])) | ui_Temp;
184 devpriv->iobase + APCI3501_DIGITAL_OP);
187 printk("\nSpecified channel not supported\n");
188 } //else if(data[1]==1)
189 } //elseif(data[1]==0)
194 data[0] = ~data[0] & 0x1;
196 ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
197 ui_Temp = ui_Temp | ui_Temp1;
199 (data[0] << ui_NoOfChannel) ^
201 data[0] = data[0] & ui_Temp;
203 devpriv->iobase + APCI3501_DIGITAL_OP);
207 data[0] = ~data[0] & 0x3;
209 ui_Temp1 = ui_Temp1 << 2 * data[2];
210 ui_Temp = ui_Temp | ui_Temp1;
214 0xffffffff) & ui_Temp;
217 APCI3501_DIGITAL_OP);
220 printk("\nSpecified channel not supported\n");
221 } //else if(data[1]==1)
222 } //elseif(data[1]==0)
225 printk("\nSpecified functionality does not exist\n");
227 } //if else data[3]==1)
228 } //if else data[3]==0)
233 +----------------------------------------------------------------------------+
234 | Function Name : int i_APCI3501_ReadDigitalOutput |
235 | (struct comedi_device *dev,struct comedi_subdevice *s, |
236 | struct comedi_insn *insn,unsigned int *data) |
237 +----------------------------------------------------------------------------+
238 | Task : Read value of the selected channel or port |
239 +----------------------------------------------------------------------------+
240 | Input Parameters : struct comedi_device *dev : Driver handle |
241 | unsigned int ui_NoOfChannels : No Of Channels To read |
242 | unsigned int *data : Data Pointer to read status |
243 +----------------------------------------------------------------------------+
244 | Output Parameters : -- |
245 +----------------------------------------------------------------------------+
246 | Return Value : TRUE : No error occur |
247 | : FALSE : Error occur. Return the error |
249 +----------------------------------------------------------------------------+
251 int i_APCI3501_ReadDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
252 struct comedi_insn * insn, unsigned int * data)
254 unsigned int ui_Temp;
255 unsigned int ui_NoOfChannel;
257 ui_NoOfChannel = CR_CHAN(insn->chanspec);
259 *data = inl(devpriv->iobase + APCI3501_DIGITAL_OP);
261 *data = (*data >> ui_NoOfChannel) & 0x1;
269 printk("\nSpecified channel not supported \n");
270 } // else if (ui_Temp==1)
271 } // else if (ui_Temp==0)
276 +----------------------------------------------------------------------------+
277 | Function Name : int i_APCI3501_ConfigAnalogOutput |
278 | (struct comedi_device *dev,struct comedi_subdevice *s, |
279 | struct comedi_insn *insn,unsigned int *data) |
280 +----------------------------------------------------------------------------+
281 | Task : Configures The Analog Output Subdevice |
282 +----------------------------------------------------------------------------+
283 | Input Parameters : struct comedi_device *dev : Driver handle |
284 | struct comedi_subdevice *s : Subdevice Pointer |
285 | struct comedi_insn *insn : Insn Structure Pointer |
286 | unsigned int *data : Data Pointer contains |
287 | configuration parameters as below |
289 | data[0] : Voltage Mode |
293 +----------------------------------------------------------------------------+
294 | Output Parameters : -- |
295 +----------------------------------------------------------------------------+
296 | Return Value : TRUE : No error occur |
297 | : FALSE : Error occur. Return the error |
299 +----------------------------------------------------------------------------+
301 int i_APCI3501_ConfigAnalogOutput(struct comedi_device * dev, struct comedi_subdevice * s,
302 struct comedi_insn * insn, unsigned int * data)
305 devpriv->iobase + APCI3501_ANALOG_OUTPUT +
306 APCI3501_AO_VOLT_MODE);
309 devpriv->b_InterruptMode = MODE1;
311 devpriv->b_InterruptMode = MODE0;
317 +----------------------------------------------------------------------------+
318 | Function Name : int i_APCI3501_WriteAnalogOutput |
319 | (struct comedi_device *dev,struct comedi_subdevice *s, |
320 | struct comedi_insn *insn,unsigned int *data) |
321 +----------------------------------------------------------------------------+
322 | Task : Writes To the Selected Anlog Output Channel |
323 +----------------------------------------------------------------------------+
324 | Input Parameters : struct comedi_device *dev : Driver handle |
325 | struct comedi_subdevice *s : Subdevice Pointer |
326 | struct comedi_insn *insn : Insn Structure Pointer |
327 | unsigned int *data : Data Pointer contains |
328 | configuration parameters as below |
331 +----------------------------------------------------------------------------+
332 | Output Parameters : -- |
333 +----------------------------------------------------------------------------+
334 | Return Value : TRUE : No error occur |
335 | : FALSE : Error occur. Return the error |
337 +----------------------------------------------------------------------------+
339 int i_APCI3501_WriteAnalogOutput(struct comedi_device * dev, struct comedi_subdevice * s,
340 struct comedi_insn * insn, unsigned int * data)
342 ULONG ul_Command1 = 0, ul_Channel_no, ul_Polarity, ul_DAC_Ready = 0;;
344 ul_Channel_no = CR_CHAN(insn->chanspec);
346 if (devpriv->b_InterruptMode == MODE1) {
347 ul_Polarity = 0x80000000;
348 if ((*data < 0) || (*data > 16384)) {
349 printk("\nIn WriteAnalogOutput :: Not Valid Data\n");
352 } // end if(devpriv->b_InterruptMode==MODE1)
355 if ((*data < 0) || (*data > 8192)) {
356 printk("\nIn WriteAnalogOutput :: Not Valid Data\n");
361 if ((ul_Channel_no < 0) || (ul_Channel_no > 7)) {
362 printk("\nIn WriteAnalogOutput :: Not Valid Channel\n");
363 } // end if((ul_Channel_no<0)||(ul_Channel_no>7))
365 ul_DAC_Ready = inl(devpriv->iobase + APCI3501_ANALOG_OUTPUT);
367 while (ul_DAC_Ready == 0) {
368 ul_DAC_Ready = inl(devpriv->iobase + APCI3501_ANALOG_OUTPUT);
369 ul_DAC_Ready = (ul_DAC_Ready >> 8) & 1;
373 // Output the Value on the output channels.
375 (ULONG) ((ULONG) (ul_Channel_no & 0xFF) |
376 (ULONG) ((*data << 0x8) & 0x7FFFFF00L) |
377 (ULONG) (ul_Polarity));
379 devpriv->iobase + APCI3501_ANALOG_OUTPUT +
387 +----------------------------------------------------------------------------+
388 | Function Name : int i_APCI3501_ConfigTimerCounterWatchdog |
389 | (struct comedi_device *dev,struct comedi_subdevice *s, |
390 | struct comedi_insn *insn,unsigned int *data) |
391 +----------------------------------------------------------------------------+
392 | Task : Configures The Timer , Counter or Watchdog |
393 +----------------------------------------------------------------------------+
394 | Input Parameters : struct comedi_device *dev : Driver handle |
395 | unsigned int *data : Data Pointer contains |
396 | configuration parameters as below |
398 | data[0] : 0 Configure As Timer |
399 | 1 Configure As Counter |
400 | 2 Configure As Watchdog |
401 | data[1] : 1 Enable Interrupt |
402 | 0 Disable Interrupt |
403 | data[2] : Time Unit |
404 | data[3] : Reload Value |
405 +----------------------------------------------------------------------------+
406 | Output Parameters : -- |
407 +----------------------------------------------------------------------------+
408 | Return Value : TRUE : No error occur |
409 | : FALSE : Error occur. Return the error |
411 +----------------------------------------------------------------------------+
413 int i_APCI3501_ConfigTimerCounterWatchdog(struct comedi_device * dev,
414 struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
416 ULONG ul_Command1 = 0;
417 devpriv->tsk_Current = current;
418 if (data[0] == ADDIDATA_WATCHDOG) {
420 devpriv->b_TimerSelectMode = ADDIDATA_WATCHDOG;
421 //Disable the watchdog
422 outl(0x0, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); //disable Wa
425 //Enable TIMER int & DISABLE ALL THE OTHER int SOURCES
427 devpriv->iobase + APCI3501_WATCHDOG +
430 outl(0x0, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); //disable Timer interrupt
433 //Loading the Timebase value
435 devpriv->iobase + APCI3501_WATCHDOG +
436 APCI3501_TCW_TIMEBASE);
438 //Loading the Reload value
440 devpriv->iobase + APCI3501_WATCHDOG +
441 APCI3501_TCW_RELOAD_VALUE);
443 ul_Command1 = inl(devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG) | 0xFFF819E0UL; //e2->e0
445 devpriv->iobase + APCI3501_WATCHDOG +
447 } //end if(data[0]==ADDIDATA_WATCHDOG)
449 else if (data[0] == ADDIDATA_TIMER) {
450 //First Stop The Timer
452 inl(devpriv->iobase + APCI3501_WATCHDOG +
454 ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
455 outl(ul_Command1, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); //Stop The Timer
456 devpriv->b_TimerSelectMode = ADDIDATA_TIMER;
458 //Enable TIMER int & DISABLE ALL THE OTHER int SOURCES
460 devpriv->iobase + APCI3501_WATCHDOG +
463 outl(0x0, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); //disable Timer interrupt
468 devpriv->iobase + APCI3501_WATCHDOG +
469 APCI3501_TCW_TIMEBASE);
471 //Loading the Reload value
473 devpriv->iobase + APCI3501_WATCHDOG +
474 APCI3501_TCW_RELOAD_VALUE);
476 // printk ("\nTimer Address :: %x\n", (devpriv->iobase+APCI3501_WATCHDOG));
478 inl(devpriv->iobase + APCI3501_WATCHDOG +
481 (ul_Command1 & 0xFFF719E2UL) | 2UL << 13UL | 0x10UL;
482 outl(ul_Command1, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); //mode 2
484 } //end if(data[0]==ADDIDATA_TIMER)
490 +----------------------------------------------------------------------------+
491 | Function Name : int i_APCI3501_StartStopWriteTimerCounterWatchdog |
492 | (struct comedi_device *dev,struct comedi_subdevice *s, |
493 | struct comedi_insn *insn,unsigned int *data) |
494 +----------------------------------------------------------------------------+
495 | Task : Start / Stop The Selected Timer , Counter or Watchdog |
496 +----------------------------------------------------------------------------+
497 | Input Parameters : struct comedi_device *dev : Driver handle |
498 | unsigned int *data : Data Pointer contains |
499 | configuration parameters as below |
501 | data[0] : 0 Timer |
503 | 2 Watchdog | | data[1] : 1 Start |
504 | 0 Stop | 2 Trigger |
505 +----------------------------------------------------------------------------+
506 | Output Parameters : -- |
507 +----------------------------------------------------------------------------+
508 | Return Value : TRUE : No error occur |
509 | : FALSE : Error occur. Return the error |
511 +----------------------------------------------------------------------------+
514 int i_APCI3501_StartStopWriteTimerCounterWatchdog(struct comedi_device * dev,
515 struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
517 ULONG ul_Command1 = 0;
519 if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
523 inl(devpriv->iobase + APCI3501_WATCHDOG +
525 ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
526 //Enable the Watchdog
528 devpriv->iobase + APCI3501_WATCHDOG +
532 else if (data[1] == 0) //Stop The Watchdog
536 inl(devpriv->iobase + APCI3501_WATCHDOG +
538 ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
540 devpriv->iobase + APCI3501_WATCHDOG +
542 } else if (data[1] == 2) {
544 inl(devpriv->iobase + APCI3501_WATCHDOG +
546 ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x200UL;
548 devpriv->iobase + APCI3501_WATCHDOG +
551 } // end if (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
553 if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
557 inl(devpriv->iobase + APCI3501_WATCHDOG +
559 ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
562 devpriv->iobase + APCI3501_WATCHDOG +
564 } else if (data[1] == 0) {
567 inl(devpriv->iobase + APCI3501_WATCHDOG +
569 ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
571 devpriv->iobase + APCI3501_WATCHDOG +
575 else if (data[1] == 2) {
578 inl(devpriv->iobase + APCI3501_WATCHDOG +
580 ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x200UL;
582 devpriv->iobase + APCI3501_WATCHDOG +
586 } // end if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
587 i_Temp = inl(devpriv->iobase + APCI3501_WATCHDOG +
588 APCI3501_TCW_TRIG_STATUS) & 0x1;
593 +----------------------------------------------------------------------------+
594 | Function Name : int i_APCI3501_ReadTimerCounterWatchdog |
595 | (struct comedi_device *dev,struct comedi_subdevice *s, |
596 | struct comedi_insn *insn,unsigned int *data) |
597 +----------------------------------------------------------------------------+
598 | Task : Read The Selected Timer , Counter or Watchdog |
599 +----------------------------------------------------------------------------+
600 | Input Parameters : struct comedi_device *dev : Driver handle |
601 | unsigned int *data : Data Pointer contains |
602 | configuration parameters as below |
604 | data[0] : 0 Timer |
606 | 2 Watchdog | | data[1] : Timer Counter Watchdog Number |
607 +----------------------------------------------------------------------------+
608 | Output Parameters : -- |
609 +----------------------------------------------------------------------------+
610 | Return Value : TRUE : No error occur |
611 | : FALSE : Error occur. Return the error |
613 +----------------------------------------------------------------------------+
616 int i_APCI3501_ReadTimerCounterWatchdog(struct comedi_device * dev,
617 struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
620 if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
622 inl(devpriv->iobase + APCI3501_WATCHDOG +
623 APCI3501_TCW_TRIG_STATUS) & 0x1;
624 data[1] = inl(devpriv->iobase + APCI3501_WATCHDOG);
625 } // end if (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
627 else if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
629 inl(devpriv->iobase + APCI3501_WATCHDOG +
630 APCI3501_TCW_TRIG_STATUS) & 0x1;
631 data[1] = inl(devpriv->iobase + APCI3501_WATCHDOG);
632 } // end if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
634 else if ((devpriv->b_TimerSelectMode != ADDIDATA_TIMER)
635 && (devpriv->b_TimerSelectMode != ADDIDATA_WATCHDOG)) {
636 printk("\nIn ReadTimerCounterWatchdog :: Invalid Subdevice \n");
642 +----------------------------------------------------------------------------+
643 | Function Name : int i_APCI3501_Reset(struct comedi_device *dev) |
645 +----------------------------------------------------------------------------+
646 | Task :Resets the registers of the card |
647 +----------------------------------------------------------------------------+
648 | Input Parameters : |
649 +----------------------------------------------------------------------------+
650 | Output Parameters : -- |
651 +----------------------------------------------------------------------------+
654 +----------------------------------------------------------------------------+
657 int i_APCI3501_Reset(struct comedi_device * dev)
659 int i_Count = 0, i_temp = 0;
660 ULONG ul_Command1 = 0, ul_Polarity, ul_DAC_Ready = 0;
661 outl(0x0, devpriv->iobase + APCI3501_DIGITAL_OP);
662 outl(1, devpriv->iobase + APCI3501_ANALOG_OUTPUT +
663 APCI3501_AO_VOLT_MODE);
665 ul_Polarity = 0x80000000;
667 for (i_Count = 0; i_Count <= 7; i_Count++) {
668 ul_DAC_Ready = inl(devpriv->iobase + APCI3501_ANALOG_OUTPUT);
670 while (ul_DAC_Ready == 0) {
672 inl(devpriv->iobase + APCI3501_ANALOG_OUTPUT);
673 ul_DAC_Ready = (ul_DAC_Ready >> 8) & 1;
677 // Output the Value on the output channels.
679 (ULONG) ((ULONG) (i_Count & 0xFF) |
680 (ULONG) ((i_temp << 0x8) & 0x7FFFFF00L) |
681 (ULONG) (ul_Polarity));
683 devpriv->iobase + APCI3501_ANALOG_OUTPUT +
692 +----------------------------------------------------------------------------+
693 | Function Name : static void v_APCI3501_Interrupt |
694 | (int irq , void *d) |
695 +----------------------------------------------------------------------------+
696 | Task : Interrupt processing Routine |
697 +----------------------------------------------------------------------------+
698 | Input Parameters : int irq : irq number |
699 | void *d : void pointer |
700 +----------------------------------------------------------------------------+
701 | Output Parameters : -- |
702 +----------------------------------------------------------------------------+
703 | Return Value : TRUE : No error occur |
704 | : FALSE : Error occur. Return the error |
706 +----------------------------------------------------------------------------+
708 void v_APCI3501_Interrupt(int irq, void *d)
711 struct comedi_device *dev = d;
712 unsigned int ui_Timer_AOWatchdog;
713 unsigned long ul_Command1;
716 inl(devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG);
718 ul_Command1 = (ul_Command1 & 0xFFFFF9FDul);
720 devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG);
722 ui_Timer_AOWatchdog =
723 inl(devpriv->iobase + APCI3501_WATCHDOG +
724 APCI3501_TCW_IRQ) & 0x1;
726 if ((!ui_Timer_AOWatchdog)) {
727 comedi_error(dev, "IRQ from unknow source");
732 //Send a signal to from kernel to user space
733 send_sig(SIGIO, devpriv->tsk_Current, 0);
735 inl(devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG);
736 ul_Command1 = ((ul_Command1 & 0xFFFFF9FDul) | 1 << 1);
738 devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG);
739 i_temp = inl(devpriv->iobase + APCI3501_WATCHDOG +
740 APCI3501_TCW_TRIG_STATUS) & 0x1;