APCI1710_Ssi.c revision 7aead6d77a8f4c3d05cce54fc2ab5babf2b8753f
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 : SSI.C | Version : 2.96 | 34 +-------------------------------+---------------------------------------+ 35 | Project manager: Eric Stolz | Date : 02/12/2002 | 36 +-----------------------------------------------------------------------+ 37 | Description : APCI-1710 SSI counter module | 38 +-----------------------------------------------------------------------+ 39 | several changes done by S. Weber in 1998 and C. Guinot in 2000 | 40 +-----------------------------------------------------------------------+ 41*/ 42 43/* 44+----------------------------------------------------------------------------+ 45| Included files | 46+----------------------------------------------------------------------------+ 47*/ 48 49#include "APCI1710_Ssi.h" 50 51/* 52+----------------------------------------------------------------------------+ 53| Function Name : _INT_ i_APCI1710_InitSSI | 54| (unsigned char_ b_BoardHandle, | 55| unsigned char_ b_ModulNbr, | 56| unsigned char_ b_SSIProfile, | 57| unsigned char_ b_PositionTurnLength, | 58| unsigned char_ b_TurnCptLength, | 59| unsigned char_ b_PCIInputClock, | 60| ULONG_ ul_SSIOutputClock, | 61| unsigned char_ b_SSICountingMode) | 62+----------------------------------------------------------------------------+ 63| Task : Configure the SSI operating mode from selected module | 64| (b_ModulNbr). You must calling this function be for you| 65| call any other function witch access of SSI. | 66+----------------------------------------------------------------------------+ 67| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710| 68| unsigned char_ b_ModulNbr : Module number to | 69| configure (0 to 3) | 70| unsigned char_ b_SSIProfile : Selection from SSI | 71| profile length (2 to 32).| 72| unsigned char_ b_PositionTurnLength : Selection from SSI | 73| position data length | 74| (1 to 31). | 75| unsigned char_ b_TurnCptLength : Selection from SSI turn | 76| counter data length | 77| (1 to 31). | 78| unsigned char b_PCIInputClock : Selection from PCI bus | 79| clock | 80| - APCI1710_30MHZ : | 81| The PC have a PCI bus | 82| clock from 30 MHz | 83| - APCI1710_33MHZ : | 84| The PC have a PCI bus | 85| clock from 33 MHz | 86| ULONG_ ul_SSIOutputClock : Selection from SSI output| 87| clock. | 88| From 229 to 5 000 000 Hz| 89| for 30 MHz selection. | 90| From 252 to 5 000 000 Hz| 91| for 33 MHz selection. | 92| unsigned char b_SSICountingMode : SSI counting mode | 93| selection | 94| - APCI1710_BINARY_MODE : | 95| Binary counting mode. | 96| - APCI1710_GRAY_MODE : | 97| Gray counting mode. 98 99 b_ModulNbr = CR_AREF(insn->chanspec); 100 b_SSIProfile = (unsigned char) data[0]; 101 b_PositionTurnLength= (unsigned char) data[1]; 102 b_TurnCptLength = (unsigned char) data[2]; 103 b_PCIInputClock = (unsigned char) data[3]; 104 ul_SSIOutputClock = (unsigned int) data[4]; 105 b_SSICountingMode = (unsigned char) data[5]; | 106+----------------------------------------------------------------------------+ 107| Output Parameters : - | 108+----------------------------------------------------------------------------+ 109| Return Value : 0: No error | 110| -1: The handle parameter of the board is wrong | 111| -2: The module parameter is wrong | 112| -3: The module is not a SSI module | 113| -4: The selected SSI profile length is wrong | 114| -5: The selected SSI position data length is wrong | 115| -6: The selected SSI turn counter data length is wrong | 116| -7: The selected PCI input clock is wrong | 117| -8: The selected SSI output clock is wrong | 118| -9: The selected SSI counting mode parameter is wrong | 119+----------------------------------------------------------------------------+ 120*/ 121 122int i_APCI1710_InsnConfigInitSSI(struct comedi_device *dev, struct comedi_subdevice *s, 123 struct comedi_insn *insn, unsigned int *data) 124{ 125 int i_ReturnValue = 0; 126 unsigned int ui_TimerValue; 127 unsigned char b_ModulNbr, b_SSIProfile, b_PositionTurnLength, b_TurnCptLength, 128 b_PCIInputClock, b_SSICountingMode; 129 unsigned int ul_SSIOutputClock; 130 131 b_ModulNbr = CR_AREF(insn->chanspec); 132 b_SSIProfile = (unsigned char) data[0]; 133 b_PositionTurnLength = (unsigned char) data[1]; 134 b_TurnCptLength = (unsigned char) data[2]; 135 b_PCIInputClock = (unsigned char) data[3]; 136 ul_SSIOutputClock = (unsigned int) data[4]; 137 b_SSICountingMode = (unsigned char) data[5]; 138 139 i_ReturnValue = insn->n; 140 /**************************/ 141 /* Test the module number */ 142 /**************************/ 143 144 if (b_ModulNbr < 4) { 145 /***********************/ 146 /* Test if SSI counter */ 147 /***********************/ 148 149 if ((devpriv->s_BoardInfos. 150 dw_MolduleConfiguration[b_ModulNbr] & 151 0xFFFF0000UL) == APCI1710_SSI_COUNTER) { 152 /*******************************/ 153 /* Test the SSI profile length */ 154 /*******************************/ 155 156 /* CG 22/03/00 b_SSIProfile >= 2 anstatt b_SSIProfile > 2 */ 157 if (b_SSIProfile >= 2 && b_SSIProfile < 33) { 158 /*************************************/ 159 /* Test the SSI position data length */ 160 /*************************************/ 161 162 if (b_PositionTurnLength > 0 163 && b_PositionTurnLength < 32) { 164 /*****************************************/ 165 /* Test the SSI turn counter data length */ 166 /*****************************************/ 167 168 if (b_TurnCptLength > 0 169 && b_TurnCptLength < 32) { 170 /***************************/ 171 /* Test the profile length */ 172 /***************************/ 173 174 if ((b_TurnCptLength + 175 b_PositionTurnLength) 176 <= b_SSIProfile) { 177 /****************************/ 178 /* Test the PCI input clock */ 179 /****************************/ 180 181 if (b_PCIInputClock == 182 APCI1710_30MHZ 183 || 184 b_PCIInputClock 185 == 186 APCI1710_33MHZ) 187 { 188 /*************************/ 189 /* Test the output clock */ 190 /*************************/ 191 192 if ((b_PCIInputClock == APCI1710_30MHZ && (ul_SSIOutputClock > 228 && ul_SSIOutputClock <= 5000000UL)) || (b_PCIInputClock == APCI1710_33MHZ && (ul_SSIOutputClock > 251 && ul_SSIOutputClock <= 5000000UL))) { 193 if (b_SSICountingMode == APCI1710_BINARY_MODE || b_SSICountingMode == APCI1710_GRAY_MODE) { 194 /**********************/ 195 /* Save configuration */ 196 /**********************/ 197 devpriv-> 198 s_ModuleInfo 199 [b_ModulNbr]. 200 s_SSICounterInfo. 201 b_SSIProfile 202 = 203 b_SSIProfile; 204 205 devpriv-> 206 s_ModuleInfo 207 [b_ModulNbr]. 208 s_SSICounterInfo. 209 b_PositionTurnLength 210 = 211 b_PositionTurnLength; 212 213 devpriv-> 214 s_ModuleInfo 215 [b_ModulNbr]. 216 s_SSICounterInfo. 217 b_TurnCptLength 218 = 219 b_TurnCptLength; 220 221 /*********************************/ 222 /* Initialise the profile length */ 223 /*********************************/ 224 225 if (b_SSICountingMode == APCI1710_BINARY_MODE) { 226 227 outl(b_SSIProfile + 1, devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr)); 228 } else { 229 230 outl(b_SSIProfile, devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr)); 231 } 232 233 /******************************/ 234 /* Calculate the output clock */ 235 /******************************/ 236 237 ui_TimerValue 238 = 239 (unsigned int) 240 ( 241 ((unsigned int) (b_PCIInputClock) * 500000UL) / ul_SSIOutputClock); 242 243 /************************/ 244 /* Initialise the timer */ 245 /************************/ 246 247 outl(ui_TimerValue, devpriv->s_BoardInfos.ui_Address + (64 * b_ModulNbr)); 248 249 /********************************/ 250 /* Initialise the counting mode */ 251 /********************************/ 252 253 outl(7 * b_SSICountingMode, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr)); 254 255 devpriv-> 256 s_ModuleInfo 257 [b_ModulNbr]. 258 s_SSICounterInfo. 259 b_SSIInit 260 = 261 1; 262 } else { 263 /*****************************************************/ 264 /* The selected SSI counting mode parameter is wrong */ 265 /*****************************************************/ 266 267 DPRINTK("The selected SSI counting mode parameter is wrong\n"); 268 i_ReturnValue 269 = 270 -9; 271 } 272 } else { 273 /******************************************/ 274 /* The selected SSI output clock is wrong */ 275 /******************************************/ 276 277 DPRINTK("The selected SSI output clock is wrong\n"); 278 i_ReturnValue 279 = 280 -8; 281 } 282 } else { 283 /*****************************************/ 284 /* The selected PCI input clock is wrong */ 285 /*****************************************/ 286 287 DPRINTK("The selected PCI input clock is wrong\n"); 288 i_ReturnValue = 289 -7; 290 } 291 } else { 292 /********************************************/ 293 /* The selected SSI profile length is wrong */ 294 /********************************************/ 295 296 DPRINTK("The selected SSI profile length is wrong\n"); 297 i_ReturnValue = -4; 298 } 299 } else { 300 /******************************************************/ 301 /* The selected SSI turn counter data length is wrong */ 302 /******************************************************/ 303 304 DPRINTK("The selected SSI turn counter data length is wrong\n"); 305 i_ReturnValue = -6; 306 } 307 } else { 308 /**************************************************/ 309 /* The selected SSI position data length is wrong */ 310 /**************************************************/ 311 312 DPRINTK("The selected SSI position data length is wrong\n"); 313 i_ReturnValue = -5; 314 } 315 } else { 316 /********************************************/ 317 /* The selected SSI profile length is wrong */ 318 /********************************************/ 319 320 DPRINTK("The selected SSI profile length is wrong\n"); 321 i_ReturnValue = -4; 322 } 323 } else { 324 /**********************************/ 325 /* The module is not a SSI module */ 326 /**********************************/ 327 328 DPRINTK("The module is not a SSI module\n"); 329 i_ReturnValue = -3; 330 } 331 } else { 332 /***********************/ 333 /* Module number error */ 334 /***********************/ 335 336 DPRINTK("Module number error\n"); 337 i_ReturnValue = -2; 338 } 339 340 return i_ReturnValue; 341} 342 343/* 344+----------------------------------------------------------------------------+ 345| Function Name : _INT_ i_APCI1710_Read1SSIValue | 346| (unsigned char_ b_BoardHandle, | 347| unsigned char_ b_ModulNbr, | 348| unsigned char_ b_SelectedSSI, | 349| PULONG_ pul_Position, | 350| PULONG_ pul_TurnCpt) 351 int i_APCI1710_ReadSSIValue(struct comedi_device *dev,struct comedi_subdevice *s, 352 struct comedi_insn *insn,unsigned int *data) | 353+----------------------------------------------------------------------------+ 354| Task : 355 356 357 Read the selected SSI counter (b_SelectedSSI) from | 358| selected module (b_ModulNbr). 359 or Read all SSI counter (b_SelectedSSI) from | 360| selected module (b_ModulNbr). | 361+----------------------------------------------------------------------------+ 362| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710| 363| unsigned char_ b_ModulNbr : Module number to | 364| configure (0 to 3) | 365| unsigned char_ b_SelectedSSI : Selection from SSI | 366| counter (0 to 2) 367 368 b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec); 369 b_SelectedSSI = (unsigned char) CR_CHAN(insn->chanspec); (in case of single ssi) 370 b_ReadType = (unsigned char) CR_RANGE(insn->chanspec); 371| 372+----------------------------------------------------------------------------+ 373| Output Parameters : PULONG_ pul_Position : SSI position in the turn | 374| PULONG_ pul_TurnCpt : Number of turns 375 376pul_Position = (unsigned int *) &data[0]; 377 pul_TurnCpt = (unsigned int *) &data[1]; | 378+----------------------------------------------------------------------------+ 379| Return Value : 0: No error | 380| -1: The handle parameter of the board is wrong | 381| -2: The module parameter is wrong | 382| -3: The module is not a SSI module | 383| -4: SSI not initialised see function | 384| "i_APCI1710_InitSSI" | 385| -5: The selected SSI is wrong | 386+----------------------------------------------------------------------------+ 387*/ 388 389int i_APCI1710_InsnReadSSIValue(struct comedi_device *dev, struct comedi_subdevice *s, 390 struct comedi_insn *insn, unsigned int *data) 391{ 392 int i_ReturnValue = 0; 393 unsigned char b_Cpt; 394 unsigned char b_Length; 395 unsigned char b_Schift; 396 unsigned char b_SSICpt; 397 unsigned int dw_And; 398 unsigned int dw_And1; 399 unsigned int dw_And2; 400 unsigned int dw_StatusReg; 401 unsigned int dw_CounterValue; 402 unsigned char b_ModulNbr; 403 unsigned char b_SelectedSSI; 404 unsigned char b_ReadType; 405 unsigned int *pul_Position; 406 unsigned int *pul_TurnCpt; 407 unsigned int *pul_Position1; 408 unsigned int *pul_TurnCpt1; 409 410 i_ReturnValue = insn->n; 411 pul_Position1 = (unsigned int *) &data[0]; 412/* For Read1 */ 413 pul_TurnCpt1 = (unsigned int *) &data[1]; 414/* For Read all */ 415 pul_Position = (unsigned int *) &data[0]; /* 0-2 */ 416 pul_TurnCpt = (unsigned int *) &data[3]; /* 3-5 */ 417 b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec); 418 b_SelectedSSI = (unsigned char) CR_CHAN(insn->chanspec); 419 b_ReadType = (unsigned char) CR_RANGE(insn->chanspec); 420 421 /**************************/ 422 /* Test the module number */ 423 /**************************/ 424 425 if (b_ModulNbr < 4) { 426 /***********************/ 427 /* Test if SSI counter */ 428 /***********************/ 429 430 if ((devpriv->s_BoardInfos. 431 dw_MolduleConfiguration[b_ModulNbr] & 432 0xFFFF0000UL) == APCI1710_SSI_COUNTER) { 433 /***************************/ 434 /* Test if SSI initialised */ 435 /***************************/ 436 437 if (devpriv->s_ModuleInfo[b_ModulNbr]. 438 s_SSICounterInfo.b_SSIInit == 1) { 439 440 switch (b_ReadType) { 441 442 case APCI1710_SSI_READ1VALUE: 443 /****************************************/ 444 /* Test the selected SSI counter number */ 445 /****************************************/ 446 447 if (b_SelectedSSI < 3) { 448 /************************/ 449 /* Start the conversion */ 450 /************************/ 451 452 outl(0, devpriv->s_BoardInfos. 453 ui_Address + 8 + 454 (64 * b_ModulNbr)); 455 456 do { 457 /*******************/ 458 /* Read the status */ 459 /*******************/ 460 461 dw_StatusReg = 462 inl(devpriv-> 463 s_BoardInfos. 464 ui_Address + 465 (64 * b_ModulNbr)); 466 } while ((dw_StatusReg & 0x1) 467 != 0); 468 469 /******************************/ 470 /* Read the SSI counter value */ 471 /******************************/ 472 473 dw_CounterValue = 474 inl(devpriv-> 475 s_BoardInfos. 476 ui_Address + 4 + 477 (b_SelectedSSI * 4) + 478 (64 * b_ModulNbr)); 479 480 b_Length = 481 devpriv-> 482 s_ModuleInfo 483 [b_ModulNbr]. 484 s_SSICounterInfo. 485 b_SSIProfile / 2; 486 487 if ((b_Length * 2) != 488 devpriv-> 489 s_ModuleInfo 490 [b_ModulNbr]. 491 s_SSICounterInfo. 492 b_SSIProfile) { 493 b_Length++; 494 } 495 496 b_Schift = 497 b_Length - 498 devpriv-> 499 s_ModuleInfo 500 [b_ModulNbr]. 501 s_SSICounterInfo. 502 b_PositionTurnLength; 503 504 *pul_Position1 = 505 dw_CounterValue >> 506 b_Schift; 507 508 dw_And = 1; 509 510 for (b_Cpt = 0; 511 b_Cpt < 512 devpriv-> 513 s_ModuleInfo 514 [b_ModulNbr]. 515 s_SSICounterInfo. 516 b_PositionTurnLength; 517 b_Cpt++) { 518 dw_And = dw_And * 2; 519 } 520 521 *pul_Position1 = 522 *pul_Position1 & 523 ((dw_And) - 1); 524 525 *pul_TurnCpt1 = 526 dw_CounterValue >> 527 b_Length; 528 529 dw_And = 1; 530 531 for (b_Cpt = 0; 532 b_Cpt < 533 devpriv-> 534 s_ModuleInfo 535 [b_ModulNbr]. 536 s_SSICounterInfo. 537 b_TurnCptLength; 538 b_Cpt++) { 539 dw_And = dw_And * 2; 540 } 541 542 *pul_TurnCpt1 = 543 *pul_TurnCpt1 & 544 ((dw_And) - 1); 545 } else { 546 /*****************************/ 547 /* The selected SSI is wrong */ 548 /*****************************/ 549 550 DPRINTK("The selected SSI is wrong\n"); 551 i_ReturnValue = -5; 552 } 553 break; 554 555 case APCI1710_SSI_READALLVALUE: 556 dw_And1 = 1; 557 558 for (b_Cpt = 0; 559 b_Cpt < 560 devpriv-> 561 s_ModuleInfo[b_ModulNbr]. 562 s_SSICounterInfo. 563 b_PositionTurnLength; b_Cpt++) { 564 dw_And1 = dw_And1 * 2; 565 } 566 567 dw_And2 = 1; 568 569 for (b_Cpt = 0; 570 b_Cpt < 571 devpriv-> 572 s_ModuleInfo[b_ModulNbr]. 573 s_SSICounterInfo. 574 b_TurnCptLength; b_Cpt++) { 575 dw_And2 = dw_And2 * 2; 576 } 577 578 /************************/ 579 /* Start the conversion */ 580 /************************/ 581 582 outl(0, devpriv->s_BoardInfos. 583 ui_Address + 8 + 584 (64 * b_ModulNbr)); 585 586 do { 587 /*******************/ 588 /* Read the status */ 589 /*******************/ 590 591 dw_StatusReg = 592 inl(devpriv-> 593 s_BoardInfos. 594 ui_Address + 595 (64 * b_ModulNbr)); 596 } while ((dw_StatusReg & 0x1) != 0); 597 598 for (b_SSICpt = 0; b_SSICpt < 3; 599 b_SSICpt++) { 600 /******************************/ 601 /* Read the SSI counter value */ 602 /******************************/ 603 604 dw_CounterValue = 605 inl(devpriv-> 606 s_BoardInfos. 607 ui_Address + 4 + 608 (b_SSICpt * 4) + 609 (64 * b_ModulNbr)); 610 611 b_Length = 612 devpriv-> 613 s_ModuleInfo 614 [b_ModulNbr]. 615 s_SSICounterInfo. 616 b_SSIProfile / 2; 617 618 if ((b_Length * 2) != 619 devpriv-> 620 s_ModuleInfo 621 [b_ModulNbr]. 622 s_SSICounterInfo. 623 b_SSIProfile) { 624 b_Length++; 625 } 626 627 b_Schift = 628 b_Length - 629 devpriv-> 630 s_ModuleInfo 631 [b_ModulNbr]. 632 s_SSICounterInfo. 633 b_PositionTurnLength; 634 635 pul_Position[b_SSICpt] = 636 dw_CounterValue >> 637 b_Schift; 638 pul_Position[b_SSICpt] = 639 pul_Position[b_SSICpt] & 640 ((dw_And1) - 1); 641 642 pul_TurnCpt[b_SSICpt] = 643 dw_CounterValue >> 644 b_Length; 645 pul_TurnCpt[b_SSICpt] = 646 pul_TurnCpt[b_SSICpt] & 647 ((dw_And2) - 1); 648 } 649 break; 650 651 default: 652 printk("Read Type Inputs Wrong\n"); 653 654 } /* switch ending */ 655 656 } else { 657 /***********************/ 658 /* SSI not initialised */ 659 /***********************/ 660 661 DPRINTK("SSI not initialised\n"); 662 i_ReturnValue = -4; 663 } 664 } else { 665 /**********************************/ 666 /* The module is not a SSI module */ 667 /**********************************/ 668 669 DPRINTK("The module is not a SSI module\n"); 670 i_ReturnValue = -3; 671 672 } 673 } else { 674 /***********************/ 675 /* Module number error */ 676 /***********************/ 677 678 DPRINTK("Module number error\n"); 679 i_ReturnValue = -2; 680 } 681 682 return i_ReturnValue; 683} 684 685/* 686+----------------------------------------------------------------------------+ 687| Function Name : _INT_ i_APCI1710_ReadSSI1DigitalInput | 688| (unsigned char_ b_BoardHandle, | 689| unsigned char_ b_ModulNbr, | 690| unsigned char_ b_InputChannel, | 691| unsigned char *_ pb_ChannelStatus) | 692+----------------------------------------------------------------------------+ 693| Task : 694 (0) Set the digital output from selected SSI moule | 695| (b_ModuleNbr) ON 696 (1) Set the digital output from selected SSI moule | 697| (b_ModuleNbr) OFF 698 (2)Read the status from selected SSI digital input | 699| (b_InputChannel) 700 (3)Read the status from all SSI digital inputs from | 701| selected SSI module (b_ModulNbr) | 702+----------------------------------------------------------------------------+ 703| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710| 704| unsigned char_ b_ModulNbr CR_AREF : Module number to | 705| configure (0 to 3) | 706| unsigned char_ b_InputChannel CR_CHAN : Selection from digital | 707| data[0] which IOTYPE input ( 0 to 2) | 708+----------------------------------------------------------------------------+ 709| Output Parameters : unsigned char *_ pb_ChannelStatus : Digital input channel | 710| data[0] status | 711| 0 : Channle is not active| 712| 1 : Channle is active | 713+----------------------------------------------------------------------------+ 714| Return Value : 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 SSI module | 718| -4: The selected SSI digital input is wrong | 719+----------------------------------------------------------------------------+ 720*/ 721 722int i_APCI1710_InsnBitsSSIDigitalIO(struct comedi_device *dev, struct comedi_subdevice *s, 723 struct comedi_insn *insn, unsigned int *data) 724{ 725 int i_ReturnValue = 0; 726 unsigned int dw_StatusReg; 727 unsigned char b_ModulNbr; 728 unsigned char b_InputChannel; 729 unsigned char *pb_ChannelStatus; 730 unsigned char *pb_InputStatus; 731 unsigned char b_IOType; 732 i_ReturnValue = insn->n; 733 b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec); 734 b_IOType = (unsigned char) data[0]; 735 736 /**************************/ 737 /* Test the module number */ 738 /**************************/ 739 740 if (b_ModulNbr < 4) { 741 /***********************/ 742 /* Test if SSI counter */ 743 /***********************/ 744 745 if ((devpriv->s_BoardInfos. 746 dw_MolduleConfiguration[b_ModulNbr] & 747 0xFFFF0000UL) == APCI1710_SSI_COUNTER) { 748 switch (b_IOType) { 749 case APCI1710_SSI_SET_CHANNELON: 750 /*****************************/ 751 /* Set the digital output ON */ 752 /*****************************/ 753 754 outl(1, devpriv->s_BoardInfos.ui_Address + 16 + 755 (64 * b_ModulNbr)); 756 break; 757 758 case APCI1710_SSI_SET_CHANNELOFF: 759 /******************************/ 760 /* Set the digital output OFF */ 761 /******************************/ 762 763 outl(0, devpriv->s_BoardInfos.ui_Address + 16 + 764 (64 * b_ModulNbr)); 765 break; 766 767 case APCI1710_SSI_READ_1CHANNEL: 768 /******************************************/ 769 /* Test the digital imnput channel number */ 770 /******************************************/ 771 772 b_InputChannel = (unsigned char) CR_CHAN(insn->chanspec); 773 pb_ChannelStatus = (unsigned char *) &data[0]; 774 775 if (b_InputChannel <= 2) { 776 /**************************/ 777 /* Read all digital input */ 778 /**************************/ 779 780 dw_StatusReg = 781 inl(devpriv->s_BoardInfos. 782 ui_Address + (64 * b_ModulNbr)); 783 *pb_ChannelStatus = 784 (unsigned char) (((~dw_StatusReg) >> (4 + 785 b_InputChannel)) 786 & 1); 787 } else { 788 /********************************/ 789 /* Selected digital input error */ 790 /********************************/ 791 792 DPRINTK("Selected digital input error\n"); 793 i_ReturnValue = -4; 794 } 795 break; 796 797 case APCI1710_SSI_READ_ALLCHANNEL: 798 /**************************/ 799 /* Read all digital input */ 800 /**************************/ 801 pb_InputStatus = (unsigned char *) &data[0]; 802 803 dw_StatusReg = 804 inl(devpriv->s_BoardInfos.ui_Address + 805 (64 * b_ModulNbr)); 806 *pb_InputStatus = 807 (unsigned char) (((~dw_StatusReg) >> 4) & 7); 808 break; 809 810 default: 811 printk("IO type wrong\n"); 812 813 } /* switch end */ 814 } else { 815 /**********************************/ 816 /* The module is not a SSI module */ 817 /**********************************/ 818 819 DPRINTK("The module is not a SSI module\n"); 820 i_ReturnValue = -3; 821 } 822 } else { 823 /***********************/ 824 /* Module number error */ 825 /***********************/ 826 827 DPRINTK("Module number error\n"); 828 i_ReturnValue = -2; 829 } 830 831 return i_ReturnValue; 832} 833