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-035 | Compiler : GCC |
33 | Module name : hwdrv_apci035.c | Version : 2.96 |
34 +-------------------------------+---------------------------------------+
35 | Project manager: Eric Stolz | Date : 02/12/2002 |
36 +-------------------------------+---------------------------------------+
37 | Description : Hardware Layer Acces For APCI-035 |
38 +-----------------------------------------------------------------------+
40 +----------+-----------+------------------------------------------------+
41 | Date | Author | Description of updates |
42 +----------+-----------+------------------------------------------------+
46 +----------+-----------+------------------------------------------------+
50 +----------------------------------------------------------------------------+
52 +----------------------------------------------------------------------------+
54 #include "hwdrv_apci035.h"
55 INT i_WatchdogNbr
= 0;
59 +----------------------------------------------------------------------------+
60 | Function Name : int i_APCI035_ConfigTimerWatchdog |
61 | (struct comedi_device *dev,struct comedi_subdevice *s, |
62 | comedi_insn *insn,unsigned int *data) |
63 +----------------------------------------------------------------------------+
64 | Task : Configures The Timer , Counter or Watchdog |
65 +----------------------------------------------------------------------------+
66 | Input Parameters : struct comedi_device *dev : Driver handle |
67 | UINT *data : Data Pointer contains |
68 | configuration parameters as below |
70 | data[0] : 0 Configure As Timer |
71 | 1 Configure As Watchdog |
72 data[1] : Watchdog number
73 | data[2] : Time base Unit |
74 | data[3] : Reload Value |
75 data[4] : External Trigger |
78 data[5] :External Trigger Level
80 01 Trigger Enabled (Low level)
81 10 Trigger Enabled (High Level)
82 11 Trigger Enabled (High/Low level)
83 data[6] : External Gate |
86 data[7] : External Gate level
88 01 Gate Enabled (Low level)
89 10 Gate Enabled (High Level)
90 data[8] :Warning Relay
93 data[9] :Warning Delay available
94 data[10] :Warning Relay Time unit
95 data[11] :Warning Relay Time Reload value
104 +----------------------------------------------------------------------------+
105 | Output Parameters : -- |
106 +----------------------------------------------------------------------------+
107 | Return Value : TRUE : No error occur |
108 | : FALSE : Error occur. Return the error |
110 +----------------------------------------------------------------------------+
112 INT
i_APCI035_ConfigTimerWatchdog(struct comedi_device
* dev
, struct comedi_subdevice
* s
,
113 comedi_insn
* insn
, unsigned int * data
)
119 devpriv
->tsk_Current
= current
;
120 devpriv
->b_TimerSelectMode
= data
[0];
121 i_WatchdogNbr
= data
[1];
127 //ui_Command = inl(devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
129 //ui_Command = ui_Command & 0xFFFFF9FEUL;
130 outl(ui_Command
, devpriv
->iobase
+ ((i_WatchdogNbr
- 1) * 32) + 12);
132 ui_Command
= inl(devpriv
->iobase
+ ((i_WatchdogNbr
- 1) * 32) + 12);
133 /************************/
134 /* Set the reload value */
135 /************************/
136 outl(data
[3], devpriv
->iobase
+ ((i_WatchdogNbr
- 1) * 32) + 4);
137 /*********************/
138 /* Set the time unit */
139 /*********************/
140 outl(data
[2], devpriv
->iobase
+ ((i_WatchdogNbr
- 1) * 32) + 8);
141 if (data
[0] == ADDIDATA_TIMER
) {
143 /******************************/
145 /* - Disable the hardware */
146 /* - Disable the counter mode */
147 /* - Disable the warning */
148 /* - Disable the reset */
149 /* - Enable the timer mode */
150 /* - Set the timer mode */
151 /******************************/
154 (ui_Command
& 0xFFF719E2UL
) | ui_Mode
<< 13UL | 0x10UL
;
156 } //if (data[0] == ADDIDATA_TIMER)
158 if (data
[0] == ADDIDATA_WATCHDOG
) {
160 /******************************/
162 /* - Disable the hardware */
163 /* - Disable the counter mode */
164 /* - Disable the warning */
165 /* - Disable the reset */
166 /* - Disable the timer mode */
167 /******************************/
169 ui_Command
= ui_Command
& 0xFFF819E2UL
;
172 printk("\n The parameter for Timer/watchdog selection is in error\n");
176 outl(ui_Command
, devpriv
->iobase
+ ((i_WatchdogNbr
- 1) * 32) + 12);
178 ui_Command
= inl(devpriv
->iobase
+ ((i_WatchdogNbr
- 1) * 32) + 12);
179 /********************************/
180 /* Disable the hardware trigger */
181 /********************************/
182 ui_Command
= ui_Command
& 0xFFFFF89FUL
;
183 if (data
[4] == ADDIDATA_ENABLE
) {
184 /**********************************/
185 /* Set the hardware trigger level */
186 /**********************************/
187 ui_Command
= ui_Command
| (data
[5] << 5);
189 outl(ui_Command
, devpriv
->iobase
+ ((i_WatchdogNbr
- 1) * 32) + 12);
191 ui_Command
= inl(devpriv
->iobase
+ ((i_WatchdogNbr
- 1) * 32) + 12);
192 /*****************************/
193 /* Disable the hardware gate */
194 /*****************************/
195 ui_Command
= ui_Command
& 0xFFFFF87FUL
;
196 if (data
[6] == ADDIDATA_ENABLE
) {
197 /*******************************/
198 /* Set the hardware gate level */
199 /*******************************/
200 ui_Command
= ui_Command
| (data
[7] << 7);
202 outl(ui_Command
, devpriv
->iobase
+ ((i_WatchdogNbr
- 1) * 32) + 12);
204 ui_Command
= inl(devpriv
->iobase
+ ((i_WatchdogNbr
- 1) * 32) + 12);
205 /*******************************/
206 /* Disable the hardware output */
207 /*******************************/
208 ui_Command
= ui_Command
& 0xFFFFF9FBUL
;
209 /*********************************/
210 /* Set the hardware output level */
211 /*********************************/
212 ui_Command
= ui_Command
| (data
[8] << 2);
213 outl(ui_Command
, devpriv
->iobase
+ ((i_WatchdogNbr
- 1) * 32) + 12);
214 if (data
[9] == ADDIDATA_ENABLE
) {
215 /************************/
216 /* Set the reload value */
217 /************************/
219 devpriv
->iobase
+ ((i_WatchdogNbr
- 1) * 32) + 24);
220 /**********************/
221 /* Set the time unite */
222 /**********************/
224 devpriv
->iobase
+ ((i_WatchdogNbr
- 1) * 32) + 28);
228 ui_Command
= inl(devpriv
->iobase
+ ((i_WatchdogNbr
- 1) * 32) + 12);
229 /*******************************/
230 /* Disable the hardware output */
231 /*******************************/
232 ui_Command
= ui_Command
& 0xFFFFF9F7UL
;
233 /*********************************/
234 /* Set the hardware output level */
235 /*********************************/
236 ui_Command
= ui_Command
| (data
[12] << 3);
237 outl(ui_Command
, devpriv
->iobase
+ ((i_WatchdogNbr
- 1) * 32) + 12);
238 /*************************************/
239 /** Enable the watchdog interrupt **/
240 /*************************************/
242 ui_Command
= inl(devpriv
->iobase
+ ((i_WatchdogNbr
- 1) * 32) + 12);
243 /*******************************/
244 /* Set the interrupt selection */
245 /*******************************/
246 ui_Status
= inl(devpriv
->iobase
+ ((i_WatchdogNbr
- 1) * 32) + 16);
248 ui_Command
= (ui_Command
& 0xFFFFF9FDUL
) | (data
[13] << 1);
249 outl(ui_Command
, devpriv
->iobase
+ ((i_WatchdogNbr
- 1) * 32) + 12);
255 +----------------------------------------------------------------------------+
256 | Function Name : int i_APCI035_StartStopWriteTimerWatchdog |
257 | (struct comedi_device *dev,struct comedi_subdevice *s, |
258 | comedi_insn *insn,unsigned int *data) |
259 +----------------------------------------------------------------------------+
260 | Task : Start / Stop The Selected Timer , or Watchdog |
261 +----------------------------------------------------------------------------+
262 | Input Parameters : struct comedi_device *dev : Driver handle |
263 | UINT *data : Data Pointer contains |
264 | configuration parameters as below |
266 | data[0] : 0 - Stop Selected Timer/Watchdog |
267 | 1 - Start Selected Timer/Watchdog |
268 | 2 - Trigger Selected Timer/Watchdog |
269 | 3 - Stop All Timer/Watchdog |
270 | 4 - Start All Timer/Watchdog |
271 | 5 - Trigger All Timer/Watchdog |
273 +----------------------------------------------------------------------------+
274 | Output Parameters : -- |
275 +----------------------------------------------------------------------------+
276 | Return Value : TRUE : No error occur |
277 | : FALSE : Error occur. Return the error |
279 +----------------------------------------------------------------------------+
281 INT
i_APCI035_StartStopWriteTimerWatchdog(struct comedi_device
* dev
,
282 struct comedi_subdevice
* s
, comedi_insn
* insn
, unsigned int * data
)
288 inl(devpriv
->iobase
+ ((i_WatchdogNbr
- 1) * 32) + 12);
289 /**********************/
290 /* Start the hardware */
291 /**********************/
292 ui_Command
= (ui_Command
& 0xFFFFF9FFUL
) | 0x1UL
;
294 devpriv
->iobase
+ ((i_WatchdogNbr
- 1) * 32) + 12);
298 inl(devpriv
->iobase
+ ((i_WatchdogNbr
- 1) * 32) + 12);
299 /***************************/
300 /* Set the trigger command */
301 /***************************/
302 ui_Command
= (ui_Command
& 0xFFFFF9FFUL
) | 0x200UL
;
304 devpriv
->iobase
+ ((i_WatchdogNbr
- 1) * 32) + 12);
307 if (data
[0] == 0) //Stop The Watchdog
311 //ui_Command = inl(devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
312 //ui_Command = ui_Command & 0xFFFFF9FEUL;
314 devpriv
->iobase
+ ((i_WatchdogNbr
- 1) * 32) + 12);
316 if (data
[0] == 3) //stop all Watchdogs
319 for (i_Count
= 1; i_Count
<= 4; i_Count
++) {
320 if (devpriv
->b_TimerSelectMode
== ADDIDATA_WATCHDOG
) {
325 i_WatchdogNbr
= i_Count
;
327 devpriv
->iobase
+ ((i_WatchdogNbr
- 1) * 32) +
332 if (data
[0] == 4) //start all Watchdogs
335 for (i_Count
= 1; i_Count
<= 4; i_Count
++) {
336 if (devpriv
->b_TimerSelectMode
== ADDIDATA_WATCHDOG
) {
341 i_WatchdogNbr
= i_Count
;
343 devpriv
->iobase
+ ((i_WatchdogNbr
- 1) * 32) +
347 if (data
[0] == 5) //trigger all Watchdogs
350 for (i_Count
= 1; i_Count
<= 4; i_Count
++) {
351 if (devpriv
->b_TimerSelectMode
== ADDIDATA_WATCHDOG
) {
357 i_WatchdogNbr
= i_Count
;
359 devpriv
->iobase
+ ((i_WatchdogNbr
- 1) * 32) +
368 +----------------------------------------------------------------------------+
369 | Function Name : int i_APCI035_ReadTimerWatchdog |
370 | (struct comedi_device *dev,struct comedi_subdevice *s, |
371 | comedi_insn *insn,unsigned int *data) |
372 +----------------------------------------------------------------------------+
373 | Task : Read The Selected Timer , Counter or Watchdog |
374 +----------------------------------------------------------------------------+
375 | Input Parameters : struct comedi_device *dev : Driver handle |
376 | UINT *data : Data Pointer contains |
377 | configuration parameters as below |
380 +----------------------------------------------------------------------------+
381 | Output Parameters : data[0] : software trigger status
382 data[1] : hardware trigger status
383 | data[2] : Software clear status
384 data[3] : Overflow status
385 data[4] : Timer actual value
388 +----------------------------------------------------------------------------+
389 | Return Value : TRUE : No error occur |
390 | : FALSE : Error occur. Return the error |
392 +----------------------------------------------------------------------------+
394 INT
i_APCI035_ReadTimerWatchdog(struct comedi_device
* dev
, struct comedi_subdevice
* s
,
395 comedi_insn
* insn
, unsigned int * data
)
397 UINT ui_Status
= 0; // Status register
398 i_WatchdogNbr
= insn
->unused
[0];
402 ui_Status
= inl(devpriv
->iobase
+ ((i_WatchdogNbr
- 1) * 32) + 16);
403 /***********************************/
404 /* Get the software trigger status */
405 /***********************************/
406 data
[0] = ((ui_Status
>> 1) & 1);
407 /***********************************/
408 /* Get the hardware trigger status */
409 /***********************************/
410 data
[1] = ((ui_Status
>> 2) & 1);
411 /*********************************/
412 /* Get the software clear status */
413 /*********************************/
414 data
[2] = ((ui_Status
>> 3) & 1);
415 /***************************/
416 /* Get the overflow status */
417 /***************************/
418 data
[3] = ((ui_Status
>> 0) & 1);
419 if (devpriv
->b_TimerSelectMode
== ADDIDATA_TIMER
) {
420 data
[4] = inl(devpriv
->iobase
+ ((i_WatchdogNbr
- 1) * 32) + 0);
422 } // if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
428 +----------------------------------------------------------------------------+
429 | Function Name : INT i_APCI035_ConfigAnalogInput |
430 | (struct comedi_device *dev,struct comedi_subdevice *s, |
431 | comedi_insn *insn,unsigned int *data) |
432 +----------------------------------------------------------------------------+
433 | Task : Configures The Analog Input Subdevice |
434 +----------------------------------------------------------------------------+
435 | Input Parameters : struct comedi_device *dev : Driver handle |
436 | struct comedi_subdevice *s : Subdevice Pointer |
437 | comedi_insn *insn : Insn Structure Pointer |
438 | unsigned int *data : Data Pointer contains |
439 | configuration parameters as below |
440 | data[0] : Warning delay value
442 +----------------------------------------------------------------------------+
443 | Output Parameters : -- |
444 +----------------------------------------------------------------------------+
445 | Return Value : TRUE : No error occur |
446 | : FALSE : Error occur. Return the error |
448 +----------------------------------------------------------------------------+
450 INT
i_APCI035_ConfigAnalogInput(struct comedi_device
* dev
, struct comedi_subdevice
* s
,
451 comedi_insn
* insn
, unsigned int * data
)
453 devpriv
->tsk_Current
= current
;
454 outl(0x200 | 0, devpriv
->iobase
+ 128 + 0x4);
455 outl(0, devpriv
->iobase
+ 128 + 0);
456 /********************************/
457 /* Initialise the warning value */
458 /********************************/
459 outl(0x300 | 0, devpriv
->iobase
+ 128 + 0x4);
460 outl((data
[0] << 8), devpriv
->iobase
+ 128 + 0);
461 outl(0x200000UL
, devpriv
->iobase
+ 128 + 12);
467 +----------------------------------------------------------------------------+
468 | Function Name : int i_APCI035_ReadAnalogInput |
469 | (struct comedi_device *dev,struct comedi_subdevice *s, |
470 | comedi_insn *insn,unsigned int *data) |
471 +----------------------------------------------------------------------------+
472 | Task : Read value of the selected channel |
473 +----------------------------------------------------------------------------+
474 | Input Parameters : struct comedi_device *dev : Driver handle |
475 | UINT ui_NoOfChannels : No Of Channels To read |
476 | UINT *data : Data Pointer to read status |
477 +----------------------------------------------------------------------------+
478 | Output Parameters : -- |
479 | data[0] : Digital Value Of Input |
481 +----------------------------------------------------------------------------+
482 | Return Value : TRUE : No error occur |
483 | : FALSE : Error occur. Return the error |
485 +----------------------------------------------------------------------------+
487 INT
i_APCI035_ReadAnalogInput(struct comedi_device
* dev
, struct comedi_subdevice
* s
,
488 comedi_insn
* insn
, unsigned int * data
)
490 UINT ui_CommandRegister
= 0;
494 ui_CommandRegister
= 0x80000;
495 /******************************/
496 /* Write the command register */
497 /******************************/
498 outl(ui_CommandRegister
, devpriv
->iobase
+ 128 + 8);
500 /***************************************/
501 /* Read the digital value of the input */
502 /***************************************/
503 data
[0] = inl(devpriv
->iobase
+ 128 + 28);
508 +----------------------------------------------------------------------------+
509 | Function Name : int i_APCI035_Reset(struct comedi_device *dev) |
511 +----------------------------------------------------------------------------+
512 | Task :Resets the registers of the card |
513 +----------------------------------------------------------------------------+
514 | Input Parameters : |
515 +----------------------------------------------------------------------------+
516 | Output Parameters : -- |
517 +----------------------------------------------------------------------------+
520 +----------------------------------------------------------------------------+
522 INT
i_APCI035_Reset(struct comedi_device
* dev
)
525 for (i_Count
= 1; i_Count
<= 4; i_Count
++) {
526 i_WatchdogNbr
= i_Count
;
527 outl(0x0, devpriv
->iobase
+ ((i_WatchdogNbr
- 1) * 32) + 0); //stop all timers
529 outl(0x0, devpriv
->iobase
+ 128 + 12); //Disable the warning delay
535 +----------------------------------------------------------------------------+
536 | Function Name : static void v_APCI035_Interrupt |
537 | (int irq , void *d) |
538 +----------------------------------------------------------------------------+
539 | Task : Interrupt processing Routine |
540 +----------------------------------------------------------------------------+
541 | Input Parameters : int irq : irq number |
542 | void *d : void pointer |
543 +----------------------------------------------------------------------------+
544 | Output Parameters : -- |
545 +----------------------------------------------------------------------------+
546 | Return Value : TRUE : No error occur |
547 | : FALSE : Error occur. Return the error |
549 +----------------------------------------------------------------------------+
551 static void v_APCI035_Interrupt(int irq
, void *d
)
553 struct comedi_device
*dev
= d
;
554 UINT ui_StatusRegister1
= 0;
555 UINT ui_StatusRegister2
= 0;
556 UINT ui_ReadCommand
= 0;
557 UINT ui_ChannelNumber
= 0;
558 UINT ui_DigitalTemperature
= 0;
560 i_WatchdogNbr
= i_Flag
;
563 /**************************************/
564 /* Read the interrupt status register of temperature Warning */
565 /**************************************/
566 ui_StatusRegister1
= inl(devpriv
->iobase
+ 128 + 16);
567 /**************************************/
568 /* Read the interrupt status register for Watchdog/timer */
569 /**************************************/
572 inl(devpriv
->iobase
+ ((i_WatchdogNbr
- 1) * 32) + 20);
574 if ((((ui_StatusRegister1
) & 0x8) == 0x8)) //Test if warning relay interrupt
576 /**********************************/
577 /* Disable the temperature warning */
578 /**********************************/
579 ui_ReadCommand
= inl(devpriv
->iobase
+ 128 + 12);
580 ui_ReadCommand
= ui_ReadCommand
& 0xFFDF0000UL
;
581 outl(ui_ReadCommand
, devpriv
->iobase
+ 128 + 12);
582 /***************************/
583 /* Read the channel number */
584 /***************************/
585 ui_ChannelNumber
= inl(devpriv
->iobase
+ 128 + 60);
586 /**************************************/
587 /* Read the digital temperature value */
588 /**************************************/
589 ui_DigitalTemperature
= inl(devpriv
->iobase
+ 128 + 60);
590 send_sig(SIGIO
, devpriv
->tsk_Current
, 0); // send signal to the sample
591 } //if (((ui_StatusRegister1 & 0x8) == 0x8))
594 if ((ui_StatusRegister2
& 0x1) == 0x1) {
595 send_sig(SIGIO
, devpriv
->tsk_Current
, 0); // send signal to the sample
597 } //else if (((ui_StatusRegister1 & 0x8) == 0x8))