hwdrv_apci035.c revision 90035c0886b256d75bced13b3b3cea5234aff136
1/** 2@verbatim 3 4Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. 5 6 ADDI-DATA GmbH 7 Dieselstrasse 3 8 D-77833 Ottersweier 9 Tel: +19(0)7223/9493-0 10 Fax: +49(0)7223/9493-92 11 http://www.addi-data-com 12 info@addi-data.com 13 14This 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. 15 16This 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. 17 18You 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 19 20You shoud also find the complete GPL in the COPYING file accompanying this source code. 21 22@endverbatim 23*/ 24/* 25 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 +-----------------------------------------------------------------------+ 39 | UPDATES | 40 +----------+-----------+------------------------------------------------+ 41 | Date | Author | Description of updates | 42 +----------+-----------+------------------------------------------------+ 43 | | | | 44 | | | | 45 | | | | 46 +----------+-----------+------------------------------------------------+ 47*/ 48 49/* 50+----------------------------------------------------------------------------+ 51| Included files | 52+----------------------------------------------------------------------------+ 53*/ 54#include "hwdrv_apci035.h" 55INT i_WatchdogNbr = 0; 56INT i_Temp = 0; 57INT i_Flag = 1; 58/* 59+----------------------------------------------------------------------------+ 60| Function Name : int i_APCI035_ConfigTimerWatchdog | 61| (struct comedi_device *dev,struct comedi_subdevice *s, | 62| struct 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 | 69| | 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 | 76 1:Enable 77 0:Disable 78 data[5] :External Trigger Level 79 00 Trigger Disabled 80 01 Trigger Enabled (Low level) 81 10 Trigger Enabled (High Level) 82 11 Trigger Enabled (High/Low level) 83 data[6] : External Gate | 84 1:Enable 85 0:Disable 86 data[7] : External Gate level 87 00 Gate Disabled 88 01 Gate Enabled (Low level) 89 10 Gate Enabled (High Level) 90 data[8] :Warning Relay 91 1: ENABLE 92 0: DISABLE 93 data[9] :Warning Delay available 94 data[10] :Warning Relay Time unit 95 data[11] :Warning Relay Time Reload value 96 data[12] :Reset Relay 97 1 : ENABLE 98 0 : DISABLE 99 data[13] :Interrupt 100 1 : ENABLE 101 0 : DISABLE 102 103| 104+----------------------------------------------------------------------------+ 105| Output Parameters : -- | 106+----------------------------------------------------------------------------+ 107| Return Value : TRUE : No error occur | 108| : FALSE : Error occur. Return the error | 109| | 110+----------------------------------------------------------------------------+ 111*/ 112INT i_APCI035_ConfigTimerWatchdog(struct comedi_device * dev, struct comedi_subdevice * s, 113 struct comedi_insn * insn, unsigned int * data) 114{ 115 UINT ui_Status = 0; 116 UINT ui_Command = 0; 117 UINT ui_Mode = 0; 118 i_Temp = 0; 119 devpriv->tsk_Current = current; 120 devpriv->b_TimerSelectMode = data[0]; 121 i_WatchdogNbr = data[1]; 122 if (data[0] == 0) { 123 ui_Mode = 2; 124 } else { 125 ui_Mode = 0; 126 } 127//ui_Command = inl(devpriv->iobase+((i_WatchdogNbr-1)*32)+12); 128 ui_Command = 0; 129//ui_Command = ui_Command & 0xFFFFF9FEUL; 130 outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); 131 ui_Command = 0; 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) { 142 143 /******************************/ 144 /* Set the mode : */ 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 /******************************/ 152 153 ui_Command = 154 (ui_Command & 0xFFF719E2UL) | ui_Mode << 13UL | 0x10UL; 155 156 } //if (data[0] == ADDIDATA_TIMER) 157 else { 158 if (data[0] == ADDIDATA_WATCHDOG) { 159 160 /******************************/ 161 /* Set the mode : */ 162 /* - Disable the hardware */ 163 /* - Disable the counter mode */ 164 /* - Disable the warning */ 165 /* - Disable the reset */ 166 /* - Disable the timer mode */ 167 /******************************/ 168 169 ui_Command = ui_Command & 0xFFF819E2UL; 170 171 } else { 172 printk("\n The parameter for Timer/watchdog selection is in error\n"); 173 return -EINVAL; 174 } 175 } 176 outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); 177 ui_Command = 0; 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); 188 } 189 outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); 190 ui_Command = 0; 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); 201 } 202 outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); 203 ui_Command = 0; 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 /************************/ 218 outl(data[11], 219 devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 24); 220 /**********************/ 221 /* Set the time unite */ 222 /**********************/ 223 outl(data[10], 224 devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 28); 225 } 226 227 ui_Command = 0; 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 /*************************************/ 241 ui_Command = 0; 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); 247 248 ui_Command = (ui_Command & 0xFFFFF9FDUL) | (data[13] << 1); 249 outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); 250 251 return insn->n; 252} 253 254/* 255+----------------------------------------------------------------------------+ 256| Function Name : int i_APCI035_StartStopWriteTimerWatchdog | 257| (struct comedi_device *dev,struct comedi_subdevice *s, | 258| struct 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 | 265| | 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 | 272| | 273+----------------------------------------------------------------------------+ 274| Output Parameters : -- | 275+----------------------------------------------------------------------------+ 276| Return Value : TRUE : No error occur | 277| : FALSE : Error occur. Return the error | 278| | 279+----------------------------------------------------------------------------+ 280*/ 281INT i_APCI035_StartStopWriteTimerWatchdog(struct comedi_device * dev, 282 struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data) 283{ 284 UINT ui_Command = 0; 285 INT i_Count = 0; 286 if (data[0] == 1) { 287 ui_Command = 288 inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); 289 /**********************/ 290 /* Start the hardware */ 291 /**********************/ 292 ui_Command = (ui_Command & 0xFFFFF9FFUL) | 0x1UL; 293 outl(ui_Command, 294 devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); 295 } // if (data[0]==1) 296 if (data[0] == 2) { 297 ui_Command = 298 inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); 299 /***************************/ 300 /* Set the trigger command */ 301 /***************************/ 302 ui_Command = (ui_Command & 0xFFFFF9FFUL) | 0x200UL; 303 outl(ui_Command, 304 devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); 305 } 306 307 if (data[0] == 0) //Stop The Watchdog 308 { 309 //Stop The Watchdog 310 ui_Command = 0; 311 //ui_Command = inl(devpriv->iobase+((i_WatchdogNbr-1)*32)+12); 312 //ui_Command = ui_Command & 0xFFFFF9FEUL; 313 outl(ui_Command, 314 devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); 315 } // if (data[1]==0) 316 if (data[0] == 3) //stop all Watchdogs 317 { 318 ui_Command = 0; 319 for (i_Count = 1; i_Count <= 4; i_Count++) { 320 if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) { 321 ui_Command = 0x2UL; 322 } else { 323 ui_Command = 0x10UL; 324 } 325 i_WatchdogNbr = i_Count; 326 outl(ui_Command, 327 devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 328 0); 329 } 330 331 } 332 if (data[0] == 4) //start all Watchdogs 333 { 334 ui_Command = 0; 335 for (i_Count = 1; i_Count <= 4; i_Count++) { 336 if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) { 337 ui_Command = 0x1UL; 338 } else { 339 ui_Command = 0x8UL; 340 } 341 i_WatchdogNbr = i_Count; 342 outl(ui_Command, 343 devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 344 0); 345 } 346 } 347 if (data[0] == 5) //trigger all Watchdogs 348 { 349 ui_Command = 0; 350 for (i_Count = 1; i_Count <= 4; i_Count++) { 351 if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) { 352 ui_Command = 0x4UL; 353 } else { 354 ui_Command = 0x20UL; 355 } 356 357 i_WatchdogNbr = i_Count; 358 outl(ui_Command, 359 devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 360 0); 361 } 362 i_Temp = 1; 363 } 364 return insn->n; 365} 366 367/* 368+----------------------------------------------------------------------------+ 369| Function Name : int i_APCI035_ReadTimerWatchdog | 370| (struct comedi_device *dev,struct comedi_subdevice *s, | 371| struct 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 | 378| | 379| | 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 386 387 388+----------------------------------------------------------------------------+ 389| Return Value : TRUE : No error occur | 390| : FALSE : Error occur. Return the error | 391| | 392+----------------------------------------------------------------------------+ 393*/ 394INT i_APCI035_ReadTimerWatchdog(struct comedi_device * dev, struct comedi_subdevice * s, 395 struct comedi_insn * insn, unsigned int * data) 396{ 397 UINT ui_Status = 0; // Status register 398 i_WatchdogNbr = insn->unused[0]; 399 /******************/ 400 /* Get the status */ 401 /******************/ 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); 421 422 } // if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER) 423 424 return insn->n; 425} 426 427/* 428+----------------------------------------------------------------------------+ 429| Function Name : INT i_APCI035_ConfigAnalogInput | 430| (struct comedi_device *dev,struct comedi_subdevice *s, | 431| struct 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| struct comedi_insn *insn : Insn Structure Pointer | 438| unsigned int *data : Data Pointer contains | 439| configuration parameters as below | 440| data[0] : Warning delay value 441| | 442+----------------------------------------------------------------------------+ 443| Output Parameters : -- | 444+----------------------------------------------------------------------------+ 445| Return Value : TRUE : No error occur | 446| : FALSE : Error occur. Return the error | 447| | 448+----------------------------------------------------------------------------+ 449*/ 450INT i_APCI035_ConfigAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s, 451 struct comedi_insn * insn, unsigned int * data) 452{ 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); 462 463 return insn->n; 464} 465 466/* 467+----------------------------------------------------------------------------+ 468| Function Name : int i_APCI035_ReadAnalogInput | 469| (struct comedi_device *dev,struct comedi_subdevice *s, | 470| struct 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 | 480| | 481+----------------------------------------------------------------------------+ 482| Return Value : TRUE : No error occur | 483| : FALSE : Error occur. Return the error | 484| | 485+----------------------------------------------------------------------------+ 486*/ 487INT i_APCI035_ReadAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s, 488 struct comedi_insn * insn, unsigned int * data) 489{ 490 UINT ui_CommandRegister = 0; 491/******************/ 492/* Set the start */ 493/******************/ 494 ui_CommandRegister = 0x80000; 495 /******************************/ 496 /* Write the command register */ 497 /******************************/ 498 outl(ui_CommandRegister, devpriv->iobase + 128 + 8); 499 500/***************************************/ 501/* Read the digital value of the input */ 502/***************************************/ 503 data[0] = inl(devpriv->iobase + 128 + 28); 504 return insn->n; 505} 506 507/* 508+----------------------------------------------------------------------------+ 509| Function Name : int i_APCI035_Reset(struct comedi_device *dev) | 510| | 511+----------------------------------------------------------------------------+ 512| Task :Resets the registers of the card | 513+----------------------------------------------------------------------------+ 514| Input Parameters : | 515+----------------------------------------------------------------------------+ 516| Output Parameters : -- | 517+----------------------------------------------------------------------------+ 518| Return Value : | 519| | 520+----------------------------------------------------------------------------+ 521*/ 522INT i_APCI035_Reset(struct comedi_device * dev) 523{ 524 INT i_Count = 0; 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 528 } 529 outl(0x0, devpriv->iobase + 128 + 12); //Disable the warning delay 530 531 return 0; 532} 533 534/* 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 | 548| | 549+----------------------------------------------------------------------------+ 550*/ 551static void v_APCI035_Interrupt(int irq, void *d) 552{ 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; 559 if (i_Temp == 1) { 560 i_WatchdogNbr = i_Flag; 561 i_Flag = i_Flag + 1; 562 } 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 /**************************************/ 570 571 ui_StatusRegister2 = 572 inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 20); 573 574 if ((((ui_StatusRegister1) & 0x8) == 0x8)) //Test if warning relay interrupt 575 { 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)) 592 593 else { 594 if ((ui_StatusRegister2 & 0x1) == 0x1) { 595 send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample 596 } 597 } //else if (((ui_StatusRegister1 & 0x8) == 0x8)) 598 599 return; 600} 601