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 : Inp_CPT.C | Version : 2.96 | 34 +-------------------------------+---------------------------------------+ 35 | Project manager: Eric Stolz | Date : 02/12/2002 | 36 +-----------------------------------------------------------------------+ 37 | Description : APCI-1710 pulse encoder module | 38 | | 39 | | 40 +-----------------------------------------------------------------------+ 41 | UPDATES | 42 +-----------------------------------------------------------------------+ 43 | Date | Author | Description of updates | 44 +----------+-----------+------------------------------------------------+ 45 | | | | 46 |----------|-----------|------------------------------------------------| 47 | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 | 48 | | | available | 49 +-----------------------------------------------------------------------+ 50*/ 51 52/* 53+----------------------------------------------------------------------------+ 54| Included files | 55+----------------------------------------------------------------------------+ 56*/ 57 58#include "APCI1710_Inp_cpt.h" 59 60/* 61+----------------------------------------------------------------------------+ 62| Function Name : _INT_ i_APCI1710_InitPulseEncoder | 63| (unsigned char_ b_BoardHandle, | 64| unsigned char_ b_ModulNbr, | 65| unsigned char_ b_PulseEncoderNbr, | 66| unsigned char_ b_InputLevelSelection, | 67| unsigned char_ b_TriggerOutputAction, | 68| ULONG_ ul_StartValue) | 69+----------------------------------------------------------------------------+ 70| Task : Configure the pulse encoder operating mode selected via| 71| b_ModulNbr and b_PulseEncoderNbr. The pulse encoder | 72| after each pulse decrement the counter value from 1. | 73| | 74| You must calling this function be for you call any | 75| other function witch access of pulse encoders. | 76+----------------------------------------------------------------------------+ 77| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710| 78| unsigned char_ b_ModulNbr : Module number to | 79| configure (0 to 3) | 80| unsigned char_ b_PulseEncoderNbr : Pulse encoder selection | 81| (0 to 3) | 82| unsigned char_ b_InputLevelSelection : Input level selection | 83| (0 or 1) | 84| 0 : Set pulse encoder| 85| count the the low| 86| level pulse. | 87| 1 : Set pulse encoder| 88| count the the | 89| high level pulse.| 90| unsigned char_ b_TriggerOutputAction : Digital TRIGGER output | 91| action | 92| 0 : No action | 93| 1 : Set the trigger | 94| output to "1" | 95| (high) after the | 96| passage from 1 to| 97| 0 from pulse | 98| encoder. | 99| 2 : Set the trigger | 100| output to "0" | 101| (low) after the | 102| passage from 1 to| 103| 0 from pulse | 104| encoder | 105| ULONG_ ul_StartValue : Pulse encoder start value| 106| (1 to 4294967295) 107 b_ModulNbr =(unsigned char) CR_AREF(insn->chanspec); 108 b_PulseEncoderNbr =(unsigned char) data[0]; 109 b_InputLevelSelection =(unsigned char) data[1]; 110 b_TriggerOutputAction =(unsigned char) data[2]; 111 ul_StartValue =(unsigned int) data[3]; 112 | 113+----------------------------------------------------------------------------+ 114| Output Parameters : - | 115+----------------------------------------------------------------------------+ 116| Return Value : 0: No error | 117| -1: The handle parameter of the board is wrong | 118| -2: The module is not a pulse encoder module | 119| -3: Pulse encoder selection is wrong | 120| -4: Input level selection is wrong | 121| -5: Digital TRIGGER output action selection is wrong | 122| -6: Pulse encoder start value is wrong | 123+----------------------------------------------------------------------------+ 124*/ 125 126int i_APCI1710_InsnConfigInitPulseEncoder(struct comedi_device *dev, 127 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 128{ 129 int i_ReturnValue = 0; 130 unsigned int dw_IntRegister; 131 132 unsigned char b_ModulNbr; 133 unsigned char b_PulseEncoderNbr; 134 unsigned char b_InputLevelSelection; 135 unsigned char b_TriggerOutputAction; 136 unsigned int ul_StartValue; 137 138 b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec); 139 b_PulseEncoderNbr = (unsigned char) data[0]; 140 b_InputLevelSelection = (unsigned char) data[1]; 141 b_TriggerOutputAction = (unsigned char) data[2]; 142 ul_StartValue = (unsigned int) data[3]; 143 144 i_ReturnValue = insn->n; 145 146 /***********************************/ 147 /* Test the selected module number */ 148 /***********************************/ 149 150 if (b_ModulNbr <= 3) { 151 /*************************/ 152 /* Test if pulse encoder */ 153 /*************************/ 154 155 if ((devpriv->s_BoardInfos. 156 dw_MolduleConfiguration[b_ModulNbr] & 157 APCI1710_PULSE_ENCODER) == 158 APCI1710_PULSE_ENCODER) { 159 /******************************************/ 160 /* Test the selected pulse encoder number */ 161 /******************************************/ 162 163 if (b_PulseEncoderNbr <= 3) { 164 /************************/ 165 /* Test the input level */ 166 /************************/ 167 168 if ((b_InputLevelSelection == 0) 169 || (b_InputLevelSelection == 1)) { 170 /*******************************************/ 171 /* Test the ouput TRIGGER action selection */ 172 /*******************************************/ 173 174 if ((b_TriggerOutputAction <= 2) 175 || (b_PulseEncoderNbr > 0)) { 176 if (ul_StartValue > 1) { 177 178 dw_IntRegister = 179 inl(devpriv-> 180 s_BoardInfos. 181 ui_Address + 182 20 + 183 (64 * b_ModulNbr)); 184 185 /***********************/ 186 /* Set the start value */ 187 /***********************/ 188 189 outl(ul_StartValue, 190 devpriv-> 191 s_BoardInfos. 192 ui_Address + 193 (b_PulseEncoderNbr 194 * 4) + 195 (64 * b_ModulNbr)); 196 197 /***********************/ 198 /* Set the input level */ 199 /***********************/ 200 devpriv-> 201 s_ModuleInfo 202 [b_ModulNbr]. 203 s_PulseEncoderModuleInfo. 204 dw_SetRegister = 205 (devpriv-> 206 s_ModuleInfo 207 [b_ModulNbr]. 208 s_PulseEncoderModuleInfo. 209 dw_SetRegister & 210 (0xFFFFFFFFUL - 211 (1UL << (8 + b_PulseEncoderNbr)))) | ((1UL & (~b_InputLevelSelection)) << (8 + b_PulseEncoderNbr)); 212 213 /*******************************/ 214 /* Test if output trigger used */ 215 /*******************************/ 216 217 if ((b_TriggerOutputAction > 0) && (b_PulseEncoderNbr > 1)) { 218 /****************************/ 219 /* Enable the output action */ 220 /****************************/ 221 222 devpriv-> 223 s_ModuleInfo 224 [b_ModulNbr]. 225 s_PulseEncoderModuleInfo. 226 dw_SetRegister 227 = 228 devpriv-> 229 s_ModuleInfo 230 [b_ModulNbr]. 231 s_PulseEncoderModuleInfo. 232 dw_SetRegister 233 | (1UL 234 << (4 + b_PulseEncoderNbr)); 235 236 /*********************************/ 237 /* Set the output TRIGGER action */ 238 /*********************************/ 239 240 devpriv-> 241 s_ModuleInfo 242 [b_ModulNbr]. 243 s_PulseEncoderModuleInfo. 244 dw_SetRegister 245 = 246 (devpriv-> 247 s_ModuleInfo 248 [b_ModulNbr]. 249 s_PulseEncoderModuleInfo. 250 dw_SetRegister 251 & 252 (0xFFFFFFFFUL 253 - 254 (1UL << (12 + b_PulseEncoderNbr)))) | ((1UL & (b_TriggerOutputAction - 1)) << (12 + b_PulseEncoderNbr)); 255 } else { 256 /*****************************/ 257 /* Disable the output action */ 258 /*****************************/ 259 260 devpriv-> 261 s_ModuleInfo 262 [b_ModulNbr]. 263 s_PulseEncoderModuleInfo. 264 dw_SetRegister 265 = 266 devpriv-> 267 s_ModuleInfo 268 [b_ModulNbr]. 269 s_PulseEncoderModuleInfo. 270 dw_SetRegister 271 & 272 (0xFFFFFFFFUL 273 - 274 (1UL << (4 + b_PulseEncoderNbr))); 275 } 276 277 /*************************/ 278 /* Set the configuration */ 279 /*************************/ 280 281 outl(devpriv-> 282 s_ModuleInfo 283 [b_ModulNbr]. 284 s_PulseEncoderModuleInfo. 285 dw_SetRegister, 286 devpriv-> 287 s_BoardInfos. 288 ui_Address + 289 20 + 290 (64 * b_ModulNbr)); 291 292 devpriv-> 293 s_ModuleInfo 294 [b_ModulNbr]. 295 s_PulseEncoderModuleInfo. 296 s_PulseEncoderInfo 297 [b_PulseEncoderNbr]. 298 b_PulseEncoderInit 299 = 1; 300 } else { 301 /**************************************/ 302 /* Pulse encoder start value is wrong */ 303 /**************************************/ 304 305 DPRINTK("Pulse encoder start value is wrong\n"); 306 i_ReturnValue = -6; 307 } 308 } else { 309 /****************************************************/ 310 /* Digital TRIGGER output action selection is wrong */ 311 /****************************************************/ 312 313 DPRINTK("Digital TRIGGER output action selection is wrong\n"); 314 i_ReturnValue = -5; 315 } 316 } else { 317 /**********************************/ 318 /* Input level selection is wrong */ 319 /**********************************/ 320 321 DPRINTK("Input level selection is wrong\n"); 322 i_ReturnValue = -4; 323 } 324 } else { 325 /************************************/ 326 /* Pulse encoder selection is wrong */ 327 /************************************/ 328 329 DPRINTK("Pulse encoder selection is wrong\n"); 330 i_ReturnValue = -3; 331 } 332 } else { 333 /********************************************/ 334 /* The module is not a pulse encoder module */ 335 /********************************************/ 336 337 DPRINTK("The module is not a pulse encoder module\n"); 338 i_ReturnValue = -2; 339 } 340 } else { 341 /********************************************/ 342 /* The module is not a pulse encoder module */ 343 /********************************************/ 344 345 DPRINTK("The module is not a pulse encoder module\n"); 346 i_ReturnValue = -2; 347 } 348 349 return i_ReturnValue; 350} 351 352/* 353+----------------------------------------------------------------------------+ 354| Function Name : _INT_ i_APCI1710_EnablePulseEncoder | 355| (unsigned char_ b_BoardHandle, | 356| unsigned char_ b_ModulNbr, | 357| unsigned char_ b_PulseEncoderNbr, | 358| unsigned char_ b_CycleSelection, | 359| unsigned char_ b_InterruptHandling) | 360+----------------------------------------------------------------------------+ 361| Task : Enableor disable the selected pulse encoder (b_PulseEncoderNbr) | 362| from selected module (b_ModulNbr). Each input pulse | 363| decrement the pulse encoder counter value from 1. | 364| If you enabled the interrupt (b_InterruptHandling), a | 365| interrupt is generated when the pulse encoder has run | 366| down. | 367+----------------------------------------------------------------------------+ 368| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710| 369| unsigned char_ b_ModulNbr : Module number to | 370| configure (0 to 3) | 371| unsigned char_ b_PulseEncoderNbr : Pulse encoder selection | 372| (0 to 3) | 373| unsigned char_ b_CycleSelection : APCI1710_CONTINUOUS: | 374| Each time the | 375| counting value is set| 376| on "0", the pulse | 377| encoder load the | 378| start value after | 379| the next pulse. | 380| APCI1710_SINGLE: | 381| If the counter is set| 382| on "0", the pulse | 383| encoder is stopped. | 384| unsigned char_ b_InterruptHandling : Interrupts can be | 385| generated, when the pulse| 386| encoder has run down. | 387| With this parameter the | 388| user decides if | 389| interrupts are used or | 390| not. | 391| APCI1710_ENABLE: | 392| Interrupts are enabled | 393| APCI1710_DISABLE: | 394| Interrupts are disabled 395 396 b_ModulNbr =(unsigned char) CR_AREF(insn->chanspec); 397 b_Action =(unsigned char) data[0]; 398 b_PulseEncoderNbr =(unsigned char) data[1]; 399 b_CycleSelection =(unsigned char) data[2]; 400 b_InterruptHandling =(unsigned char) data[3];| 401+----------------------------------------------------------------------------+ 402| Output Parameters : - | 403+----------------------------------------------------------------------------+ 404| Return Value : 0: No error | 405| -1: The handle parameter of the board is wrong | 406| -2: Module selection is wrong | 407| -3: Pulse encoder selection is wrong | 408| -4: Pulse encoder not initialised. | 409| See function "i_APCI1710_InitPulseEncoder" | 410| -5: Cycle selection mode is wrong | 411| -6: Interrupt handling mode is wrong | 412| -7: Interrupt routine not installed. | 413| See function "i_APCI1710_SetBoardIntRoutineX" | 414+----------------------------------------------------------------------------+ 415*/ 416 417int i_APCI1710_InsnWriteEnableDisablePulseEncoder(struct comedi_device *dev, 418 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 419{ 420 int i_ReturnValue = 0; 421 unsigned char b_ModulNbr; 422 unsigned char b_PulseEncoderNbr; 423 unsigned char b_CycleSelection; 424 unsigned char b_InterruptHandling; 425 unsigned char b_Action; 426 427 i_ReturnValue = insn->n; 428 b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec); 429 b_Action = (unsigned char) data[0]; 430 b_PulseEncoderNbr = (unsigned char) data[1]; 431 b_CycleSelection = (unsigned char) data[2]; 432 b_InterruptHandling = (unsigned char) data[3]; 433 434 /***********************************/ 435 /* Test the selected module number */ 436 /***********************************/ 437 438 if (b_ModulNbr <= 3) { 439 /******************************************/ 440 /* Test the selected pulse encoder number */ 441 /******************************************/ 442 443 if (b_PulseEncoderNbr <= 3) { 444 /*************************************/ 445 /* Test if pulse encoder initialised */ 446 /*************************************/ 447 448 if (devpriv->s_ModuleInfo[b_ModulNbr]. 449 s_PulseEncoderModuleInfo. 450 s_PulseEncoderInfo[b_PulseEncoderNbr]. 451 b_PulseEncoderInit == 1) { 452 switch (b_Action) { 453 454 case APCI1710_ENABLE: 455 /****************************/ 456 /* Test the cycle selection */ 457 /****************************/ 458 459 if (b_CycleSelection == 460 APCI1710_CONTINUOUS 461 || b_CycleSelection == 462 APCI1710_SINGLE) { 463 /*******************************/ 464 /* Test the interrupt handling */ 465 /*******************************/ 466 467 if (b_InterruptHandling == 468 APCI1710_ENABLE 469 || b_InterruptHandling 470 == APCI1710_DISABLE) { 471 /******************************/ 472 /* Test if interrupt not used */ 473 /******************************/ 474 475 if (b_InterruptHandling 476 == 477 APCI1710_DISABLE) 478 { 479 /*************************/ 480 /* Disable the interrupt */ 481 /*************************/ 482 483 devpriv-> 484 s_ModuleInfo 485 [b_ModulNbr]. 486 s_PulseEncoderModuleInfo. 487 dw_SetRegister 488 = 489 devpriv-> 490 s_ModuleInfo 491 [b_ModulNbr]. 492 s_PulseEncoderModuleInfo. 493 dw_SetRegister 494 & 495 (0xFFFFFFFFUL 496 - 497 (1UL << b_PulseEncoderNbr)); 498 } else { 499 500 /************************/ 501 /* Enable the interrupt */ 502 /************************/ 503 504 devpriv-> 505 s_ModuleInfo 506 [b_ModulNbr]. 507 s_PulseEncoderModuleInfo. 508 dw_SetRegister 509 = 510 devpriv-> 511 s_ModuleInfo 512 [b_ModulNbr]. 513 s_PulseEncoderModuleInfo. 514 dw_SetRegister 515 | (1UL 516 << 517 b_PulseEncoderNbr); 518 devpriv->tsk_Current = current; /* Save the current process task structure */ 519 520 } 521 522 if (i_ReturnValue >= 0) { 523 /***********************************/ 524 /* Enable or disable the interrupt */ 525 /***********************************/ 526 527 outl(devpriv-> 528 s_ModuleInfo 529 [b_ModulNbr]. 530 s_PulseEncoderModuleInfo. 531 dw_SetRegister, 532 devpriv-> 533 s_BoardInfos. 534 ui_Address 535 + 20 + 536 (64 * b_ModulNbr)); 537 538 /****************************/ 539 /* Enable the pulse encoder */ 540 /****************************/ 541 devpriv-> 542 s_ModuleInfo 543 [b_ModulNbr]. 544 s_PulseEncoderModuleInfo. 545 dw_ControlRegister 546 = 547 devpriv-> 548 s_ModuleInfo 549 [b_ModulNbr]. 550 s_PulseEncoderModuleInfo. 551 dw_ControlRegister 552 | (1UL 553 << 554 b_PulseEncoderNbr); 555 556 /**********************/ 557 /* Set the cycle mode */ 558 /**********************/ 559 560 devpriv-> 561 s_ModuleInfo 562 [b_ModulNbr]. 563 s_PulseEncoderModuleInfo. 564 dw_ControlRegister 565 = 566 (devpriv-> 567 s_ModuleInfo 568 [b_ModulNbr]. 569 s_PulseEncoderModuleInfo. 570 dw_ControlRegister 571 & 572 (0xFFFFFFFFUL 573 - 574 (1 << (b_PulseEncoderNbr + 4)))) | ((b_CycleSelection & 1UL) << (4 + b_PulseEncoderNbr)); 575 576 /****************************/ 577 /* Enable the pulse encoder */ 578 /****************************/ 579 580 outl(devpriv-> 581 s_ModuleInfo 582 [b_ModulNbr]. 583 s_PulseEncoderModuleInfo. 584 dw_ControlRegister, 585 devpriv-> 586 s_BoardInfos. 587 ui_Address 588 + 16 + 589 (64 * b_ModulNbr)); 590 } 591 } else { 592 /************************************/ 593 /* Interrupt handling mode is wrong */ 594 /************************************/ 595 596 DPRINTK("Interrupt handling mode is wrong\n"); 597 i_ReturnValue = -6; 598 } 599 } else { 600 /*********************************/ 601 /* Cycle selection mode is wrong */ 602 /*********************************/ 603 604 DPRINTK("Cycle selection mode is wrong\n"); 605 i_ReturnValue = -5; 606 } 607 break; 608 609 case APCI1710_DISABLE: 610 devpriv->s_ModuleInfo[b_ModulNbr]. 611 s_PulseEncoderModuleInfo. 612 dw_ControlRegister = 613 devpriv-> 614 s_ModuleInfo[b_ModulNbr]. 615 s_PulseEncoderModuleInfo. 616 dw_ControlRegister & 617 (0xFFFFFFFFUL - 618 (1UL << b_PulseEncoderNbr)); 619 620 /*****************************/ 621 /* Disable the pulse encoder */ 622 /*****************************/ 623 624 outl(devpriv->s_ModuleInfo[b_ModulNbr]. 625 s_PulseEncoderModuleInfo. 626 dw_ControlRegister, 627 devpriv->s_BoardInfos. 628 ui_Address + 16 + 629 (64 * b_ModulNbr)); 630 631 break; 632 } /* switch End */ 633 634 } else { 635 /*********************************/ 636 /* Pulse encoder not initialised */ 637 /*********************************/ 638 639 DPRINTK("Pulse encoder not initialised\n"); 640 i_ReturnValue = -4; 641 } 642 } else { 643 /************************************/ 644 /* Pulse encoder selection is wrong */ 645 /************************************/ 646 647 DPRINTK("Pulse encoder selection is wrong\n"); 648 i_ReturnValue = -3; 649 } 650 } else { 651 /*****************************/ 652 /* Module selection is wrong */ 653 /*****************************/ 654 655 DPRINTK("Module selection is wrong\n"); 656 i_ReturnValue = -2; 657 } 658 659 return i_ReturnValue; 660} 661 662/* 663+----------------------------------------------------------------------------+ 664| Function Name : _INT_ i_APCI1710_ReadPulseEncoderStatus | 665| (unsigned char_ b_BoardHandle, | 666| unsigned char_ b_ModulNbr, | 667| unsigned char_ b_PulseEncoderNbr, | 668| unsigned char *_ pb_Status) | 669+----------------------------------------------------------------------------+ 670| Task APCI1710_PULSEENCODER_READ : Reads the pulse encoder status 671 and valuefrom selected pulse | 672| encoder (b_PulseEncoderNbr) from selected module | 673| (b_ModulNbr). | 674+----------------------------------------------------------------------------+ 675 unsigned char b_Type; data[0] 676 APCI1710_PULSEENCODER_WRITE 677 Writes a 32-bit value (ul_WriteValue) into the selected| 678| pulse encoder (b_PulseEncoderNbr) from selected module | 679| (b_ModulNbr). This operation set the new start pulse | 680| encoder value. 681 APCI1710_PULSEENCODER_READ 682| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710| 683| CRAREF() unsigned char_ b_ModulNbr : Module number to | 684| configure (0 to 3) | 685| data[1] unsigned char_ b_PulseEncoderNbr : Pulse encoder selection | 686| (0 to 3) 687 APCI1710_PULSEENCODER_WRITE 688 data[2] ULONG_ ul_WriteValue : 32-bit value to be | 689| written | 690+----------------------------------------------------------------------------+ 691| Output Parameters : unsigned char *_ pb_Status : Pulse encoder status. | 692| 0 : No overflow occur| 693| 1 : Overflow occur 694 PULONG_ pul_ReadValue : Pulse encoder value | | 695+----------------------------------------------------------------------------+ 696| Return Value : 0: No error | 697| -1: The handle parameter of the board is wrong | 698| -2: Module selection is wrong | 699| -3: Pulse encoder selection is wrong | 700| -4: Pulse encoder not initialised. | 701| See function "i_APCI1710_InitPulseEncoder" | 702+----------------------------------------------------------------------------+ 703*/ 704 705/*_INT_ i_APCI1710_ReadPulseEncoderStatus (unsigned char_ b_BoardHandle, 706 unsigned char_ b_ModulNbr, 707 unsigned char_ b_PulseEncoderNbr, 708 709 unsigned char *_ pb_Status) 710 */ 711int i_APCI1710_InsnBitsReadWritePulseEncoder(struct comedi_device *dev, 712 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 713{ 714 int i_ReturnValue = 0; 715 unsigned int dw_StatusRegister; 716 unsigned char b_ModulNbr; 717 unsigned char b_PulseEncoderNbr; 718 unsigned char *pb_Status; 719 unsigned char b_Type; 720 unsigned int *pul_ReadValue; 721 unsigned int ul_WriteValue; 722 723 i_ReturnValue = insn->n; 724 b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec); 725 b_Type = (unsigned char) data[0]; 726 b_PulseEncoderNbr = (unsigned char) data[1]; 727 pb_Status = (unsigned char *) &data[0]; 728 pul_ReadValue = (unsigned int *) &data[1]; 729 730 /***********************************/ 731 /* Test the selected module number */ 732 /***********************************/ 733 734 if (b_ModulNbr <= 3) { 735 /******************************************/ 736 /* Test the selected pulse encoder number */ 737 /******************************************/ 738 739 if (b_PulseEncoderNbr <= 3) { 740 /*************************************/ 741 /* Test if pulse encoder initialised */ 742 /*************************************/ 743 744 if (devpriv->s_ModuleInfo[b_ModulNbr]. 745 s_PulseEncoderModuleInfo. 746 s_PulseEncoderInfo[b_PulseEncoderNbr]. 747 b_PulseEncoderInit == 1) { 748 749 switch (b_Type) { 750 case APCI1710_PULSEENCODER_READ: 751 /****************************/ 752 /* Read the status register */ 753 /****************************/ 754 755 dw_StatusRegister = 756 inl(devpriv->s_BoardInfos. 757 ui_Address + 16 + 758 (64 * b_ModulNbr)); 759 760 devpriv->s_ModuleInfo[b_ModulNbr]. 761 s_PulseEncoderModuleInfo. 762 dw_StatusRegister = devpriv-> 763 s_ModuleInfo[b_ModulNbr]. 764 s_PulseEncoderModuleInfo. 765 dw_StatusRegister | 766 dw_StatusRegister; 767 768 *pb_Status = 769 (unsigned char) (devpriv-> 770 s_ModuleInfo[b_ModulNbr]. 771 s_PulseEncoderModuleInfo. 772 dw_StatusRegister >> (1 + 773 b_PulseEncoderNbr)) & 1; 774 775 devpriv->s_ModuleInfo[b_ModulNbr]. 776 s_PulseEncoderModuleInfo. 777 dw_StatusRegister = 778 devpriv-> 779 s_ModuleInfo[b_ModulNbr]. 780 s_PulseEncoderModuleInfo. 781 dw_StatusRegister & 782 (0xFFFFFFFFUL - (1 << (1 + 783 b_PulseEncoderNbr))); 784 785 /******************/ 786 /* Read the value */ 787 /******************/ 788 789 *pul_ReadValue = 790 inl(devpriv->s_BoardInfos. 791 ui_Address + 792 (4 * b_PulseEncoderNbr) + 793 (64 * b_ModulNbr)); 794 break; 795 796 case APCI1710_PULSEENCODER_WRITE: 797 ul_WriteValue = (unsigned int) data[2]; 798 /*******************/ 799 /* Write the value */ 800 /*******************/ 801 802 outl(ul_WriteValue, 803 devpriv->s_BoardInfos. 804 ui_Address + 805 (4 * b_PulseEncoderNbr) + 806 (64 * b_ModulNbr)); 807 808 } /* end of switch */ 809 } else { 810 /*********************************/ 811 /* Pulse encoder not initialised */ 812 /*********************************/ 813 814 DPRINTK("Pulse encoder not initialised\n"); 815 i_ReturnValue = -4; 816 } 817 } else { 818 /************************************/ 819 /* Pulse encoder selection is wrong */ 820 /************************************/ 821 822 DPRINTK("Pulse encoder selection is wrong\n"); 823 i_ReturnValue = -3; 824 } 825 } else { 826 /*****************************/ 827 /* Module selection is wrong */ 828 /*****************************/ 829 830 DPRINTK("Module selection is wrong\n"); 831 i_ReturnValue = -2; 832 } 833 834 return i_ReturnValue; 835} 836 837int i_APCI1710_InsnReadInterruptPulseEncoder(struct comedi_device *dev, 838 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 839{ 840 841 data[0] = devpriv->s_InterruptParameters. 842 s_FIFOInterruptParameters[devpriv-> 843 s_InterruptParameters.ui_Read].b_OldModuleMask; 844 data[1] = devpriv->s_InterruptParameters. 845 s_FIFOInterruptParameters[devpriv-> 846 s_InterruptParameters.ui_Read].ul_OldInterruptMask; 847 data[2] = devpriv->s_InterruptParameters. 848 s_FIFOInterruptParameters[devpriv-> 849 s_InterruptParameters.ui_Read].ul_OldCounterLatchValue; 850 851 /***************************/ 852 /* Increment the read FIFO */ 853 /***************************/ 854 855 devpriv->s_InterruptParameters. 856 ui_Read = (devpriv-> 857 s_InterruptParameters.ui_Read + 1) % APCI1710_SAVE_INTERRUPT; 858 859 return insn->n; 860 861} 862