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 should 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 : API APCI1710 | Compiler : gcc | 33 | Module name : DIG_IO.C | Version : 2.96 | 34 +-------------------------------+---------------------------------------+ 35 | Project manager: Eric Stolz | Date : 02/12/2002 | 36 +-----------------------------------------------------------------------+ 37 | Description : APCI-1710 digital I/O module | 38 | | 39 | | 40 +-----------------------------------------------------------------------+ 41 | UPDATES | 42 +-----------------------------------------------------------------------+ 43 | Date | Author | Description of updates | 44 +----------+-----------+------------------------------------------------+ 45 | 16/06/98 | S. Weber | Digital input / output implementation | 46 |----------|-----------|------------------------------------------------| 47 | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 | 48 | | | available | 49 +-----------------------------------------------------------------------+ 50 | | | | 51 | | | | 52 +-----------------------------------------------------------------------+ 53*/ 54 55/* 56+----------------------------------------------------------------------------+ 57| Included files | 58+----------------------------------------------------------------------------+ 59*/ 60#include "APCI1710_Dig_io.h" 61 62/* 63+----------------------------------------------------------------------------+ 64| Function Name : int i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev, | 65| struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)| 66+----------------------------------------------------------------------------+ 67| Task : Configure the digital I/O operating mode from selected | 68| module (b_ModulNbr). You must calling this function be| 69| for you call any other function witch access of digital| 70| I/O. | 71+----------------------------------------------------------------------------+ 72| Input Parameters : | 73| unsigned char_ b_ModulNbr data[0]: Module number to | 74| configure (0 to 3) | 75| unsigned char_ b_ChannelAMode data[1] : Channel A mode selection | 76| 0 : Channel used for digital | 77| input | 78| 1 : Channel used for digital | 79| output | 80| unsigned char_ b_ChannelBMode data[2] : Channel B mode selection | 81| 0 : Channel used for digital | 82| input | 83| 1 : Channel used for digital | 84| output | 85 data[0] memory on/off 86Activates and deactivates the digital output memory. 87 After having | 88| called up this function with memory on,the output you have previously| 89| activated with the function are not reset 90+----------------------------------------------------------------------------+ 91| Output Parameters : - | 92+----------------------------------------------------------------------------+ 93| Return Value : 0: No error | 94| -1: The handle parameter of the board is wrong | 95| -2: The module parameter is wrong | 96| -3: The module is not a digital I/O module | 97| -4: Bi-directional channel A configuration error | 98| -5: Bi-directional channel B configuration error | 99+----------------------------------------------------------------------------+ 100*/ 101 102int i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev, struct comedi_subdevice *s, 103 struct comedi_insn *insn, unsigned int *data) 104{ 105 unsigned char b_ModulNbr, b_ChannelAMode, b_ChannelBMode; 106 unsigned char b_MemoryOnOff, b_ConfigType; 107 int i_ReturnValue = 0; 108 unsigned int dw_WriteConfig = 0; 109 110 b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec); 111 b_ConfigType = (unsigned char) data[0]; /* Memory or Init */ 112 b_ChannelAMode = (unsigned char) data[1]; 113 b_ChannelBMode = (unsigned char) data[2]; 114 b_MemoryOnOff = (unsigned char) data[1]; /* if memory operation */ 115 i_ReturnValue = insn->n; 116 117 /**************************/ 118 /* Test the module number */ 119 /**************************/ 120 121 if (b_ModulNbr >= 4) { 122 DPRINTK("Module Number invalid\n"); 123 i_ReturnValue = -2; 124 return i_ReturnValue; 125 } 126 switch (b_ConfigType) { 127 case APCI1710_DIGIO_MEMORYONOFF: 128 129 if (b_MemoryOnOff) /* If Memory ON */ 130 { 131 /****************************/ 132 /* Set the output memory on */ 133 /****************************/ 134 135 devpriv->s_ModuleInfo[b_ModulNbr]. 136 s_DigitalIOInfo.b_OutputMemoryEnabled = 1; 137 138 /***************************/ 139 /* Clear the output memory */ 140 /***************************/ 141 devpriv->s_ModuleInfo[b_ModulNbr]. 142 s_DigitalIOInfo.dw_OutputMemory = 0; 143 } else /* If memory off */ 144 { 145 /*****************************/ 146 /* Set the output memory off */ 147 /*****************************/ 148 149 devpriv->s_ModuleInfo[b_ModulNbr]. 150 s_DigitalIOInfo.b_OutputMemoryEnabled = 0; 151 } 152 break; 153 154 case APCI1710_DIGIO_INIT: 155 156 /*******************************/ 157 /* Test if digital I/O counter */ 158 /*******************************/ 159 160 if ((devpriv->s_BoardInfos. 161 dw_MolduleConfiguration[b_ModulNbr] & 162 0xFFFF0000UL) == APCI1710_DIGITAL_IO) { 163 164 /***************************************************/ 165 /* Test the bi-directional channel A configuration */ 166 /***************************************************/ 167 168 if ((b_ChannelAMode == 0) || (b_ChannelAMode == 1)) { 169 /***************************************************/ 170 /* Test the bi-directional channel B configuration */ 171 /***************************************************/ 172 173 if ((b_ChannelBMode == 0) 174 || (b_ChannelBMode == 1)) { 175 devpriv->s_ModuleInfo[b_ModulNbr]. 176 s_DigitalIOInfo.b_DigitalInit = 177 1; 178 179 /********************************/ 180 /* Save channel A configuration */ 181 /********************************/ 182 183 devpriv->s_ModuleInfo[b_ModulNbr]. 184 s_DigitalIOInfo. 185 b_ChannelAMode = b_ChannelAMode; 186 187 /********************************/ 188 /* Save channel B configuration */ 189 /********************************/ 190 191 devpriv->s_ModuleInfo[b_ModulNbr]. 192 s_DigitalIOInfo. 193 b_ChannelBMode = b_ChannelBMode; 194 195 /*****************************************/ 196 /* Set the channel A and B configuration */ 197 /*****************************************/ 198 199 dw_WriteConfig = 200 (unsigned int) (b_ChannelAMode | 201 (b_ChannelBMode * 2)); 202 203 /***************************/ 204 /* Write the configuration */ 205 /***************************/ 206 207 outl(dw_WriteConfig, 208 devpriv->s_BoardInfos. 209 ui_Address + 4 + 210 (64 * b_ModulNbr)); 211 212 } else { 213 /************************************************/ 214 /* Bi-directional channel B configuration error */ 215 /************************************************/ 216 DPRINTK("Bi-directional channel B configuration error\n"); 217 i_ReturnValue = -5; 218 } 219 220 } else { 221 /************************************************/ 222 /* Bi-directional channel A configuration error */ 223 /************************************************/ 224 DPRINTK("Bi-directional channel A configuration error\n"); 225 i_ReturnValue = -4; 226 227 } 228 229 } else { 230 /******************************************/ 231 /* The module is not a digital I/O module */ 232 /******************************************/ 233 DPRINTK("The module is not a digital I/O module\n"); 234 i_ReturnValue = -3; 235 } 236 } /* end of Switch */ 237 printk("Return Value %d\n", i_ReturnValue); 238 return i_ReturnValue; 239} 240 241/* 242+----------------------------------------------------------------------------+ 243| INPUT FUNCTIONS | 244+----------------------------------------------------------------------------+ 245*/ 246 247/* 248+----------------------------------------------------------------------------+ 249 250|INT i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev,comedi_subdevice 251*s, struct comedi_insn *insn,unsigned int *data) 252 253+----------------------------------------------------------------------------+ 254| Task : Read the status from selected digital I/O digital input| 255| (b_InputChannel) | 256+----------------------------------------------------------------------------| 257 258 259| 260| unsigned char_ b_ModulNbr CR_AREF(chanspec) : Selected module number | 261| (0 to 3) | 262| unsigned char_ b_InputChannel CR_CHAN(chanspec) : Selection from digital | 263| input ( 0 to 6) | 264| 0 : Channel C | 265| 1 : Channel D | 266| 2 : Channel E | 267| 3 : Channel F | 268| 4 : Channel G | 269| 5 : Channel A | 270| 6 : Channel B 271 272 273 | 274+----------------------------------------------------------------------------+ 275| Output Parameters : data[0] : Digital input channel | 276| status | 277| 0 : Channle is not active| 278| 1 : Channle is active | 279+----------------------------------------------------------------------------+ 280| Return Value : 0: No error | 281| -1: The handle parameter of the board is wrong | 282| -2: The module parameter is wrong | 283| -3: The module is not a digital I/O module | 284| -4: The selected digital I/O digital input is wrong | 285| -5: Digital I/O not initialised | 286| -6: The digital channel A is used for output | 287| -7: The digital channel B is used for output | 288+----------------------------------------------------------------------------+ 289*/ 290 291/* _INT_ i_APCI1710_ReadDigitalIOChlValue (unsigned char_ b_BoardHandle, */ 292/* 293* unsigned char_ b_ModulNbr, unsigned char_ b_InputChannel, 294* unsigned char *_ pb_ChannelStatus) 295*/ 296int i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev, 297 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 298{ 299 int i_ReturnValue = 0; 300 unsigned int dw_StatusReg; 301 unsigned char b_ModulNbr, b_InputChannel; 302 unsigned char *pb_ChannelStatus; 303 b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec); 304 b_InputChannel = (unsigned char) CR_CHAN(insn->chanspec); 305 data[0] = 0; 306 pb_ChannelStatus = (unsigned char *) &data[0]; 307 i_ReturnValue = insn->n; 308 309 /**************************/ 310 /* Test the module number */ 311 /**************************/ 312 313 if (b_ModulNbr < 4) { 314 /*******************************/ 315 /* Test if digital I/O counter */ 316 /*******************************/ 317 318 if ((devpriv->s_BoardInfos. 319 dw_MolduleConfiguration[b_ModulNbr] & 320 0xFFFF0000UL) == APCI1710_DIGITAL_IO) { 321 /******************************************/ 322 /* Test the digital imnput channel number */ 323 /******************************************/ 324 325 if (b_InputChannel <= 6) { 326 /**********************************************/ 327 /* Test if the digital I/O module initialised */ 328 /**********************************************/ 329 330 if (devpriv->s_ModuleInfo[b_ModulNbr]. 331 s_DigitalIOInfo.b_DigitalInit == 1) { 332 /**********************************/ 333 /* Test if channel A or channel B */ 334 /**********************************/ 335 336 if (b_InputChannel > 4) { 337 /*********************/ 338 /* Test if channel A */ 339 /*********************/ 340 341 if (b_InputChannel == 5) { 342 /***************************/ 343 /* Test the channel A mode */ 344 /***************************/ 345 346 if (devpriv-> 347 s_ModuleInfo 348 [b_ModulNbr]. 349 s_DigitalIOInfo. 350 b_ChannelAMode 351 != 0) { 352 /********************************************/ 353 /* The digital channel A is used for output */ 354 /********************************************/ 355 356 i_ReturnValue = 357 -6; 358 } 359 } /* if (b_InputChannel == 5) */ 360 else { 361 /***************************/ 362 /* Test the channel B mode */ 363 /***************************/ 364 365 if (devpriv-> 366 s_ModuleInfo 367 [b_ModulNbr]. 368 s_DigitalIOInfo. 369 b_ChannelBMode 370 != 0) { 371 /********************************************/ 372 /* The digital channel B is used for output */ 373 /********************************************/ 374 375 i_ReturnValue = 376 -7; 377 } 378 } /* if (b_InputChannel == 5) */ 379 } /* if (b_InputChannel > 4) */ 380 381 /***********************/ 382 /* Test if error occur */ 383 /***********************/ 384 385 if (i_ReturnValue >= 0) { 386 /**************************/ 387 /* Read all digital input */ 388 /**************************/ 389 390/* 391* INPDW (ps_APCI1710Variable-> s_Board [b_BoardHandle]. 392* s_BoardInfos. ui_Address + (64 * b_ModulNbr), &dw_StatusReg); 393*/ 394 395 dw_StatusReg = 396 inl(devpriv-> 397 s_BoardInfos. 398 ui_Address + 399 (64 * b_ModulNbr)); 400 401 *pb_ChannelStatus = 402 (unsigned char) ((dw_StatusReg ^ 403 0x1C) >> 404 b_InputChannel) & 1; 405 406 } /* if (i_ReturnValue == 0) */ 407 } else { 408 /*******************************/ 409 /* Digital I/O not initialised */ 410 /*******************************/ 411 DPRINTK("Digital I/O not initialised\n"); 412 i_ReturnValue = -5; 413 } 414 } else { 415 /********************************/ 416 /* Selected digital input error */ 417 /********************************/ 418 DPRINTK("Selected digital input error\n"); 419 i_ReturnValue = -4; 420 } 421 } else { 422 /******************************************/ 423 /* The module is not a digital I/O module */ 424 /******************************************/ 425 DPRINTK("The module is not a digital I/O module\n"); 426 i_ReturnValue = -3; 427 } 428 } else { 429 /***********************/ 430 /* Module number error */ 431 /***********************/ 432 DPRINTK("Module number error\n"); 433 i_ReturnValue = -2; 434 } 435 436 return i_ReturnValue; 437} 438 439/* 440+----------------------------------------------------------------------------+ 441| OUTPUT FUNCTIONS | 442+----------------------------------------------------------------------------+ 443*/ 444 445/* 446+----------------------------------------------------------------------------+ 447| Function Name : int i_APCI1710_InsnWriteDigitalIOChlOnOff(comedi_device 448|*dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) 449 450+----------------------------------------------------------------------------+ 451| Task : Sets or resets the output witch has been passed with the | 452| parameter b_Channel. Setting an output means setting | 453| an ouput high. | 454+----------------------------------------------------------------------------+ 455| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 | 456| unsigned char_ b_ModulNbr (aref ) : Selected module number (0 to 3)| 457| unsigned char_ b_OutputChannel (CR_CHAN) : Selection from digital output | 458| channel (0 to 2) | 459| 0 : Channel H | 460| 1 : Channel A | 461| 2 : Channel B | 462+----------------------------------------------------------------------------+ 463| Output Parameters : - | 464+----------------------------------------------------------------------------+ 465| Return Value : 0: No error | 466| -1: The handle parameter of the board is wrong | 467| -2: The module parameter is wrong | 468| -3: The module is not a digital I/O module | 469| -4: The selected digital output is wrong | 470| -5: digital I/O not initialised see function | 471| " i_APCI1710_InitDigitalIO" | 472| -6: The digital channel A is used for input | 473| -7: The digital channel B is used for input 474 -8: Digital Output Memory OFF. | 475| Use previously the function | 476| "i_APCI1710_SetDigitalIOMemoryOn". | 477+----------------------------------------------------------------------------+ 478*/ 479 480/* 481* _INT_ i_APCI1710_SetDigitalIOChlOn (unsigned char_ b_BoardHandle, 482* unsigned char_ b_ModulNbr, unsigned char_ b_OutputChannel) 483*/ 484int i_APCI1710_InsnWriteDigitalIOChlOnOff(struct comedi_device *dev, 485 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 486{ 487 int i_ReturnValue = 0; 488 unsigned int dw_WriteValue = 0; 489 unsigned char b_ModulNbr, b_OutputChannel; 490 i_ReturnValue = insn->n; 491 b_ModulNbr = CR_AREF(insn->chanspec); 492 b_OutputChannel = CR_CHAN(insn->chanspec); 493 494 /**************************/ 495 /* Test the module number */ 496 /**************************/ 497 498 if (b_ModulNbr < 4) { 499 /*******************************/ 500 /* Test if digital I/O counter */ 501 /*******************************/ 502 503 if ((devpriv->s_BoardInfos. 504 dw_MolduleConfiguration[b_ModulNbr] & 505 0xFFFF0000UL) == APCI1710_DIGITAL_IO) { 506 /**********************************************/ 507 /* Test if the digital I/O module initialised */ 508 /**********************************************/ 509 510 if (devpriv->s_ModuleInfo[b_ModulNbr]. 511 s_DigitalIOInfo.b_DigitalInit == 1) { 512 /******************************************/ 513 /* Test the digital output channel number */ 514 /******************************************/ 515 516 switch (b_OutputChannel) { 517 /*************/ 518 /* Channel H */ 519 /*************/ 520 521 case 0: 522 break; 523 524 /*************/ 525 /* Channel A */ 526 /*************/ 527 528 case 1: 529 if (devpriv->s_ModuleInfo[b_ModulNbr]. 530 s_DigitalIOInfo. 531 b_ChannelAMode != 1) { 532 /*******************************************/ 533 /* The digital channel A is used for input */ 534 /*******************************************/ 535 536 i_ReturnValue = -6; 537 } 538 break; 539 540 /*************/ 541 /* Channel B */ 542 /*************/ 543 544 case 2: 545 if (devpriv->s_ModuleInfo[b_ModulNbr]. 546 s_DigitalIOInfo. 547 b_ChannelBMode != 1) { 548 /*******************************************/ 549 /* The digital channel B is used for input */ 550 /*******************************************/ 551 552 i_ReturnValue = -7; 553 } 554 break; 555 556 default: 557 /****************************************/ 558 /* The selected digital output is wrong */ 559 /****************************************/ 560 561 i_ReturnValue = -4; 562 break; 563 } 564 565 /***********************/ 566 /* Test if error occur */ 567 /***********************/ 568 569 if (i_ReturnValue >= 0) { 570 571 /*********************************/ 572 /* Test if set channel ON */ 573 /*********************************/ 574 if (data[0]) { 575 /*********************************/ 576 /* Test if output memory enabled */ 577 /*********************************/ 578 579 if (devpriv-> 580 s_ModuleInfo 581 [b_ModulNbr]. 582 s_DigitalIOInfo. 583 b_OutputMemoryEnabled == 584 1) { 585 dw_WriteValue = 586 devpriv-> 587 s_ModuleInfo 588 [b_ModulNbr]. 589 s_DigitalIOInfo. 590 dw_OutputMemory 591 | (1 << 592 b_OutputChannel); 593 594 devpriv-> 595 s_ModuleInfo 596 [b_ModulNbr]. 597 s_DigitalIOInfo. 598 dw_OutputMemory 599 = dw_WriteValue; 600 } else { 601 dw_WriteValue = 602 1 << 603 b_OutputChannel; 604 } 605 } /* set channel off */ 606 else { 607 if (devpriv-> 608 s_ModuleInfo 609 [b_ModulNbr]. 610 s_DigitalIOInfo. 611 b_OutputMemoryEnabled == 612 1) { 613 dw_WriteValue = 614 devpriv-> 615 s_ModuleInfo 616 [b_ModulNbr]. 617 s_DigitalIOInfo. 618 dw_OutputMemory 619 & (0xFFFFFFFFUL 620 - 621 (1 << b_OutputChannel)); 622 623 devpriv-> 624 s_ModuleInfo 625 [b_ModulNbr]. 626 s_DigitalIOInfo. 627 dw_OutputMemory 628 = dw_WriteValue; 629 } else { 630 /*****************************/ 631 /* Digital Output Memory OFF */ 632 /*****************************/ 633 /* +Use previously the function "i_APCI1710_SetDigitalIOMemoryOn" */ 634 i_ReturnValue = -8; 635 } 636 637 } 638 /*******************/ 639 /* Write the value */ 640 /*******************/ 641 642 /* OUTPDW (ps_APCI1710Variable-> 643 * s_Board [b_BoardHandle]. 644 * s_BoardInfos. ui_Address + (64 * b_ModulNbr), 645 * dw_WriteValue); 646 */ 647*/ 648 outl(dw_WriteValue, 649 devpriv->s_BoardInfos. 650 ui_Address + (64 * b_ModulNbr)); 651 } 652 } else { 653 /*******************************/ 654 /* Digital I/O not initialised */ 655 /*******************************/ 656 657 i_ReturnValue = -5; 658 } 659 } else { 660 /******************************************/ 661 /* The module is not a digital I/O module */ 662 /******************************************/ 663 664 i_ReturnValue = -3; 665 } 666 } else { 667 /***********************/ 668 /* Module number error */ 669 /***********************/ 670 671 i_ReturnValue = -2; 672 } 673 674 return i_ReturnValue; 675} 676 677/* 678+----------------------------------------------------------------------------+ 679 680|INT i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device *dev,comedi_subdevice 681 *s, struct comedi_insn *insn,unsigned int *data) 682+----------------------------------------------------------------------------+ 683| Task : write: 684 Sets or resets one or several outputs from port. | 685| Setting an output means setting an output high. | 686| If you have switched OFF the digital output memory | 687| (OFF), all the other output are set to "0". 688 689| read: 690 Read the status from digital input port | 691| from selected digital I/O module (b_ModulNbr) 692+----------------------------------------------------------------------------+ 693| Input Parameters : 694 unsigned char_ b_BoardHandle : Handle of board APCI-1710 | 695| unsigned char_ b_ModulNbr CR_AREF(aref) : Selected module number (0 to 3)| 696| unsigned char_ b_PortValue CR_CHAN(chanspec) : Output Value ( 0 To 7 ) 697| data[0] read or write port 698| data[1] if write then indicate ON or OFF 699 700| if read : data[1] will return port status. 701+----------------------------------------------------------------------------+ 702| Output Parameters : - | 703+----------------------------------------------------------------------------+ 704| Return Value : 705 706| INPUT : 707 708 0: No error | 709| -1: The handle parameter of the board is wrong | 710| -2: The module parameter is wrong | 711| -3: The module is not a digital I/O module | 712| -4: Digital I/O not initialised 713 714 OUTPUT: 0: No error | 715| -1: The handle parameter of the board is wrong | 716| -2: The module parameter is wrong | 717| -3: The module is not a digital I/O module | 718| -4: Output value wrong | 719| -5: digital I/O not initialised see function | 720| " i_APCI1710_InitDigitalIO" | 721| -6: The digital channel A is used for input | 722| -7: The digital channel B is used for input 723 -8: Digital Output Memory OFF. | 724| Use previously the function | 725| "i_APCI1710_SetDigitalIOMemoryOn". | 726+----------------------------------------------------------------------------+ 727*/ 728 729/* 730 * _INT_ i_APCI1710_SetDigitalIOPortOn (unsigned char_ 731 * b_BoardHandle, unsigned char_ b_ModulNbr, unsigned char_ 732 * b_PortValue) 733*/ 734int i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device *dev, 735 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 736{ 737 int i_ReturnValue = 0; 738 unsigned int dw_WriteValue = 0; 739 unsigned int dw_StatusReg; 740 unsigned char b_ModulNbr, b_PortValue; 741 unsigned char b_PortOperation, b_PortOnOFF; 742 743 unsigned char *pb_PortValue; 744 745 b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec); 746 b_PortOperation = (unsigned char) data[0]; /* Input or output */ 747 b_PortOnOFF = (unsigned char) data[1]; /* if output then On or Off */ 748 b_PortValue = (unsigned char) data[2]; /* if out put then Value */ 749 i_ReturnValue = insn->n; 750 pb_PortValue = (unsigned char *) &data[0]; 751/* if input then read value */ 752 753 switch (b_PortOperation) { 754 case APCI1710_INPUT: 755 /**************************/ 756 /* Test the module number */ 757 /**************************/ 758 759 if (b_ModulNbr < 4) { 760 /*******************************/ 761 /* Test if digital I/O counter */ 762 /*******************************/ 763 764 if ((devpriv->s_BoardInfos. 765 dw_MolduleConfiguration[b_ModulNbr] & 766 0xFFFF0000UL) == APCI1710_DIGITAL_IO) { 767 /**********************************************/ 768 /* Test if the digital I/O module initialised */ 769 /**********************************************/ 770 771 if (devpriv->s_ModuleInfo[b_ModulNbr]. 772 s_DigitalIOInfo.b_DigitalInit == 1) { 773 /**************************/ 774 /* Read all digital input */ 775 /**************************/ 776 777 /* INPDW (ps_APCI1710Variable-> 778 * s_Board [b_BoardHandle]. 779 * s_BoardInfos. 780 * ui_Address + (64 * b_ModulNbr), 781 * &dw_StatusReg); 782 */ 783 784 dw_StatusReg = 785 inl(devpriv->s_BoardInfos. 786 ui_Address + (64 * b_ModulNbr)); 787 *pb_PortValue = 788 (unsigned char) (dw_StatusReg ^ 0x1C); 789 790 } else { 791 /*******************************/ 792 /* Digital I/O not initialised */ 793 /*******************************/ 794 795 i_ReturnValue = -4; 796 } 797 } else { 798 /******************************************/ 799 /* The module is not a digital I/O module */ 800 /******************************************/ 801 802 i_ReturnValue = -3; 803 } 804 } else { 805 /***********************/ 806 /* Module number error */ 807 /***********************/ 808 809 i_ReturnValue = -2; 810 } 811 812 break; 813 814 case APCI1710_OUTPUT: 815 /**************************/ 816 /* Test the module number */ 817 /**************************/ 818 819 if (b_ModulNbr < 4) { 820 /*******************************/ 821 /* Test if digital I/O counter */ 822 /*******************************/ 823 824 if ((devpriv->s_BoardInfos. 825 dw_MolduleConfiguration[b_ModulNbr] & 826 0xFFFF0000UL) == APCI1710_DIGITAL_IO) { 827 /**********************************************/ 828 /* Test if the digital I/O module initialised */ 829 /**********************************************/ 830 831 if (devpriv->s_ModuleInfo[b_ModulNbr]. 832 s_DigitalIOInfo.b_DigitalInit == 1) { 833 /***********************/ 834 /* Test the port value */ 835 /***********************/ 836 837 if (b_PortValue <= 7) { 838 /***********************************/ 839 /* Test the digital output channel */ 840 /***********************************/ 841 842 /**************************/ 843 /* Test if channel A used */ 844 /**************************/ 845 846 if ((b_PortValue & 2) == 2) { 847 if (devpriv-> 848 s_ModuleInfo 849 [b_ModulNbr]. 850 s_DigitalIOInfo. 851 b_ChannelAMode 852 != 1) { 853 /*******************************************/ 854 /* The digital channel A is used for input */ 855 /*******************************************/ 856 857 i_ReturnValue = 858 -6; 859 } 860 } /* if ((b_PortValue & 2) == 2) */ 861 862 /**************************/ 863 /* Test if channel B used */ 864 /**************************/ 865 866 if ((b_PortValue & 4) == 4) { 867 if (devpriv-> 868 s_ModuleInfo 869 [b_ModulNbr]. 870 s_DigitalIOInfo. 871 b_ChannelBMode 872 != 1) { 873 /*******************************************/ 874 /* The digital channel B is used for input */ 875 /*******************************************/ 876 877 i_ReturnValue = 878 -7; 879 } 880 } /* if ((b_PortValue & 4) == 4) */ 881 882 /***********************/ 883 /* Test if error occur */ 884 /***********************/ 885 886 if (i_ReturnValue >= 0) { 887 888 /* if(data[1]) { */ 889 890 switch (b_PortOnOFF) { 891 /*********************************/ 892 /* Test if set Port ON */ 893 /*********************************/ 894 895 case APCI1710_ON: 896 897 /*********************************/ 898 /* Test if output memory enabled */ 899 /*********************************/ 900 901 if (devpriv-> 902 s_ModuleInfo 903 [b_ModulNbr]. 904 s_DigitalIOInfo. 905 b_OutputMemoryEnabled 906 == 1) { 907 dw_WriteValue 908 = 909 devpriv-> 910 s_ModuleInfo 911 [b_ModulNbr]. 912 s_DigitalIOInfo. 913 dw_OutputMemory 914 | 915 b_PortValue; 916 917 devpriv-> 918 s_ModuleInfo 919 [b_ModulNbr]. 920 s_DigitalIOInfo. 921 dw_OutputMemory 922 = 923 dw_WriteValue; 924 } else { 925 dw_WriteValue 926 = 927 b_PortValue; 928 } 929 break; 930 931 /* If Set PORT OFF */ 932 case APCI1710_OFF: 933 934 /*********************************/ 935 /* Test if output memory enabled */ 936 /*********************************/ 937 938 if (devpriv-> 939 s_ModuleInfo 940 [b_ModulNbr]. 941 s_DigitalIOInfo. 942 b_OutputMemoryEnabled 943 == 1) { 944 dw_WriteValue 945 = 946 devpriv-> 947 s_ModuleInfo 948 [b_ModulNbr]. 949 s_DigitalIOInfo. 950 dw_OutputMemory 951 & 952 (0xFFFFFFFFUL 953 - 954 b_PortValue); 955 956 devpriv-> 957 s_ModuleInfo 958 [b_ModulNbr]. 959 s_DigitalIOInfo. 960 dw_OutputMemory 961 = 962 dw_WriteValue; 963 } else { 964 /*****************************/ 965 /* Digital Output Memory OFF */ 966 /*****************************/ 967 968 i_ReturnValue 969 = 970 -8; 971 } 972 } /* switch */ 973 974 /*******************/ 975 /* Write the value */ 976 /*******************/ 977 978 /* OUTPDW (ps_APCI1710Variable-> 979 * s_Board [b_BoardHandle]. 980 * s_BoardInfos. 981 * ui_Address + (64 * b_ModulNbr), 982 * dw_WriteValue); */ 983 984 outl(dw_WriteValue, 985 devpriv-> 986 s_BoardInfos. 987 ui_Address + 988 (64 * b_ModulNbr)); 989 } 990 } else { 991 /**********************/ 992 /* Output value wrong */ 993 /**********************/ 994 995 i_ReturnValue = -4; 996 } 997 } else { 998 /*******************************/ 999 /* Digital I/O not initialised */ 1000 /*******************************/ 1001 1002 i_ReturnValue = -5; 1003 } 1004 } else { 1005 /******************************************/ 1006 /* The module is not a digital I/O module */ 1007 /******************************************/ 1008 1009 i_ReturnValue = -3; 1010 } 1011 } else { 1012 /***********************/ 1013 /* Module number error */ 1014 /***********************/ 1015 1016 i_ReturnValue = -2; 1017 } 1018 break; 1019 1020 default: 1021 i_ReturnValue = -9; 1022 DPRINTK("NO INPUT/OUTPUT specified\n"); 1023 } /* switch INPUT / OUTPUT */ 1024 return i_ReturnValue; 1025} 1026