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 : CHRONO.C | Version : 2.96 | 34 +-------------------------------+---------------------------------------+ 35 | Project manager: Eric Stolz | Date : 02/12/2002 | 36 +-----------------------------------------------------------------------+ 37 | Description : APCI-1710 chronometer module | 38 | | 39 | | 40 +-----------------------------------------------------------------------+ 41 | UPDATES | 42 +-----------------------------------------------------------------------+ 43 | Date | Author | Description of updates | 44 +----------+-----------+------------------------------------------------+ 45 | 29/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_Chrono.h" 61 62/* 63+----------------------------------------------------------------------------+ 64| Function Name : _INT_ i_APCI1710_InitChrono | 65| (unsigned char_ b_BoardHandle, | 66| unsigned char_ b_ModulNbr, | 67| unsigned char_ b_ChronoMode, | 68| unsigned char_ b_PCIInputClock, | 69| unsigned char_ b_TimingUnit, | 70| ULONG_ ul_TimingInterval, | 71| PULONG_ pul_RealTimingInterval) 72 73+----------------------------------------------------------------------------+ 74| Task : Configure the chronometer operating mode (b_ChronoMode)| 75| from selected module (b_ModulNbr). | 76| The ul_TimingInterval and ul_TimingUnit determine the | 77| timing base for the measurement. | 78| The pul_RealTimingInterval return the real timing | 79| value. You must calling this function be for you call | 80| any other function witch access of the chronometer. | 81| | 82| Witch this functionality from the APCI-1710 you have | 83| the possibility to measure the timing witch two event. | 84| | 85| The mode 0 and 1 is appropriate for period measurement.| 86| The mode 2 and 3 is appropriate for frequent | 87| measurement. | 88| The mode 4 to 7 is appropriate for measuring the timing| 89| between two event. | 90+----------------------------------------------------------------------------+ 91| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 | 92| unsigned char_ b_ModulNbr CR_AREF(insn->chanspec) : Module number to configure | 93| (0 to 3) | 94| unsigned char_ b_ChronoMode data[0] : Chronometer action mode | 95| (0 to 7). | 96| unsigned char_ b_PCIInputClock data[1] : Selection from PCI bus clock| 97| - APCI1710_30MHZ : | 98| The PC have a PCI bus | 99| clock from 30 MHz | 100| - APCI1710_33MHZ : | 101| The PC have a PCI bus | 102| clock from 33 MHz | 103| - APCI1710_40MHZ | 104| The APCI-1710 have a | 105| integrated 40Mhz | 106| quartz. | 107| unsigned char_ b_TimingUnit data[2] : Base timing unity (0 to 4) | 108| 0 : ns | 109| 1 : µs | 110| 2 : ms | 111| 3 : s | 112| 4 : mn | 113| ULONG_ ul_TimingInterval : data[3] Base timing value. | 114+----------------------------------------------------------------------------+ 115| Output Parameters : PULONG_ pul_RealTimingInterval : Real base timing | 116| value. 117| data[0] 118+----------------------------------------------------------------------------+ 119| Return Value : 0: No error | 120| -1: The handle parameter of the board is wrong | 121| -2: Module selection wrong | 122| -3: The module is not a Chronometer module | 123| -4: Chronometer mode selection is wrong | 124| -5: The selected PCI input clock is wrong | 125| -6: Timing unity selection is wrong | 126| -7: Base timing selection is wrong | 127| -8: You can not used the 40MHz clock selection with | 128| this board | 129| -9: You can not used the 40MHz clock selection with | 130| this CHRONOS version | 131+----------------------------------------------------------------------------+ 132*/ 133 134int i_APCI1710_InsnConfigInitChrono(struct comedi_device *dev, struct comedi_subdevice *s, 135 struct comedi_insn *insn, unsigned int *data) 136{ 137 int i_ReturnValue = 0; 138 unsigned int ul_TimerValue = 0; 139 unsigned int ul_TimingInterval = 0; 140 unsigned int ul_RealTimingInterval = 0; 141 double d_RealTimingInterval = 0; 142 unsigned int dw_ModeArray[8] = 143 { 0x01, 0x05, 0x00, 0x04, 0x02, 0x0E, 0x0A, 0x06 }; 144 unsigned char b_ModulNbr, b_ChronoMode, b_PCIInputClock, b_TimingUnit; 145 146 b_ModulNbr = CR_AREF(insn->chanspec); 147 b_ChronoMode = (unsigned char) data[0]; 148 b_PCIInputClock = (unsigned char) data[1]; 149 b_TimingUnit = (unsigned char) data[2]; 150 ul_TimingInterval = (unsigned int) data[3]; 151 i_ReturnValue = insn->n; 152 153 /**************************/ 154 /* Test the module number */ 155 /**************************/ 156 157 if (b_ModulNbr < 4) { 158 /***********************/ 159 /* Test if chronometer */ 160 /***********************/ 161 162 if ((devpriv->s_BoardInfos. 163 dw_MolduleConfiguration[b_ModulNbr] & 164 0xFFFF0000UL) == APCI1710_CHRONOMETER) { 165 /*****************************/ 166 /* Test the chronometer mode */ 167 /*****************************/ 168 169 if (b_ChronoMode <= 7) { 170 /**************************/ 171 /* Test the PCI bus clock */ 172 /**************************/ 173 174 if ((b_PCIInputClock == APCI1710_30MHZ) || 175 (b_PCIInputClock == APCI1710_33MHZ) || 176 (b_PCIInputClock == APCI1710_40MHZ)) { 177 /*************************/ 178 /* Test the timing unity */ 179 /*************************/ 180 181 if (b_TimingUnit <= 4) { 182 /**********************************/ 183 /* Test the base timing selection */ 184 /**********************************/ 185 186 if (((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 66) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 143165576UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 143165UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 143UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 2UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 60) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 130150240UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 130150UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 130UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 2UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 50) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 107374182UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 107374UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 107UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 1UL))) { 187 /**************************/ 188 /* Test the board version */ 189 /**************************/ 190 191 if (((b_PCIInputClock == APCI1710_40MHZ) && (devpriv->s_BoardInfos.b_BoardVersion > 0)) || (b_PCIInputClock != APCI1710_40MHZ)) { 192 /************************/ 193 /* Test the TOR version */ 194 /************************/ 195 196 if (((b_PCIInputClock == APCI1710_40MHZ) && ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) >= 0x3131)) || (b_PCIInputClock != APCI1710_40MHZ)) { 197 fpu_begin 198 (); 199 200 /****************************************/ 201 /* Calculate the timer 0 division fator */ 202 /****************************************/ 203 204 switch (b_TimingUnit) { 205 /******/ 206 /* ns */ 207 /******/ 208 209 case 0: 210 211 /******************/ 212 /* Timer 0 factor */ 213 /******************/ 214 215 ul_TimerValue 216 = 217 (unsigned int) 218 (ul_TimingInterval 219 * 220 (0.001 * b_PCIInputClock)); 221 222 /*******************/ 223 /* Round the value */ 224 /*******************/ 225 226 if ((double)((double)ul_TimingInterval * (0.001 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) { 227 ul_TimerValue 228 = 229 ul_TimerValue 230 + 231 1; 232 } 233 234 /*****************************/ 235 /* Calculate the real timing */ 236 /*****************************/ 237 238 ul_RealTimingInterval 239 = 240 (unsigned int) 241 (ul_TimerValue 242 / 243 (0.001 * (double)b_PCIInputClock)); 244 d_RealTimingInterval 245 = 246 (double) 247 ul_TimerValue 248 / 249 (0.001 250 * 251 (double) 252 b_PCIInputClock); 253 254 if ((double)((double)ul_TimerValue / (0.001 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) { 255 ul_RealTimingInterval 256 = 257 ul_RealTimingInterval 258 + 259 1; 260 } 261 262 ul_TimingInterval 263 = 264 ul_TimingInterval 265 - 266 1; 267 ul_TimerValue 268 = 269 ul_TimerValue 270 - 271 2; 272 if (b_PCIInputClock != APCI1710_40MHZ) { 273 ul_TimerValue 274 = 275 (unsigned int) 276 ( 277 (double) 278 (ul_TimerValue) 279 * 280 0.99392); 281 } 282 283 break; 284 285 /******/ 286 /* æs */ 287 /******/ 288 289 case 1: 290 291 /******************/ 292 /* Timer 0 factor */ 293 /******************/ 294 295 ul_TimerValue 296 = 297 (unsigned int) 298 (ul_TimingInterval 299 * 300 (1.0 * b_PCIInputClock)); 301 302 /*******************/ 303 /* Round the value */ 304 /*******************/ 305 306 if ((double)((double)ul_TimingInterval * (1.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) { 307 ul_TimerValue 308 = 309 ul_TimerValue 310 + 311 1; 312 } 313 314 /*****************************/ 315 /* Calculate the real timing */ 316 /*****************************/ 317 318 ul_RealTimingInterval 319 = 320 (unsigned int) 321 (ul_TimerValue 322 / 323 (1.0 * (double)b_PCIInputClock)); 324 d_RealTimingInterval 325 = 326 (double) 327 ul_TimerValue 328 / 329 ( 330 (double) 331 1.0 332 * 333 (double) 334 b_PCIInputClock); 335 336 if ((double)((double)ul_TimerValue / (1.0 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) { 337 ul_RealTimingInterval 338 = 339 ul_RealTimingInterval 340 + 341 1; 342 } 343 344 ul_TimingInterval 345 = 346 ul_TimingInterval 347 - 348 1; 349 ul_TimerValue 350 = 351 ul_TimerValue 352 - 353 2; 354 if (b_PCIInputClock != APCI1710_40MHZ) { 355 ul_TimerValue 356 = 357 (unsigned int) 358 ( 359 (double) 360 (ul_TimerValue) 361 * 362 0.99392); 363 } 364 365 break; 366 367 /******/ 368 /* ms */ 369 /******/ 370 371 case 2: 372 373 /******************/ 374 /* Timer 0 factor */ 375 /******************/ 376 377 ul_TimerValue 378 = 379 ul_TimingInterval 380 * 381 (1000 382 * 383 b_PCIInputClock); 384 385 /*******************/ 386 /* Round the value */ 387 /*******************/ 388 389 if ((double)((double)ul_TimingInterval * (1000.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) { 390 ul_TimerValue 391 = 392 ul_TimerValue 393 + 394 1; 395 } 396 397 /*****************************/ 398 /* Calculate the real timing */ 399 /*****************************/ 400 401 ul_RealTimingInterval 402 = 403 (unsigned int) 404 (ul_TimerValue 405 / 406 (1000.0 * (double)b_PCIInputClock)); 407 d_RealTimingInterval 408 = 409 (double) 410 ul_TimerValue 411 / 412 (1000.0 413 * 414 (double) 415 b_PCIInputClock); 416 417 if ((double)((double)ul_TimerValue / (1000.0 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) { 418 ul_RealTimingInterval 419 = 420 ul_RealTimingInterval 421 + 422 1; 423 } 424 425 ul_TimingInterval 426 = 427 ul_TimingInterval 428 - 429 1; 430 ul_TimerValue 431 = 432 ul_TimerValue 433 - 434 2; 435 if (b_PCIInputClock != APCI1710_40MHZ) { 436 ul_TimerValue 437 = 438 (unsigned int) 439 ( 440 (double) 441 (ul_TimerValue) 442 * 443 0.99392); 444 } 445 446 break; 447 448 /*****/ 449 /* s */ 450 /*****/ 451 452 case 3: 453 454 /******************/ 455 /* Timer 0 factor */ 456 /******************/ 457 458 ul_TimerValue 459 = 460 (unsigned int) 461 (ul_TimingInterval 462 * 463 (1000000.0 464 * 465 b_PCIInputClock)); 466 467 /*******************/ 468 /* Round the value */ 469 /*******************/ 470 471 if ((double)((double)ul_TimingInterval * (1000000.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) { 472 ul_TimerValue 473 = 474 ul_TimerValue 475 + 476 1; 477 } 478 479 /*****************************/ 480 /* Calculate the real timing */ 481 /*****************************/ 482 483 ul_RealTimingInterval 484 = 485 (unsigned int) 486 (ul_TimerValue 487 / 488 (1000000.0 489 * 490 (double) 491 b_PCIInputClock)); 492 d_RealTimingInterval 493 = 494 (double) 495 ul_TimerValue 496 / 497 (1000000.0 498 * 499 (double) 500 b_PCIInputClock); 501 502 if ((double)((double)ul_TimerValue / (1000000.0 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) { 503 ul_RealTimingInterval 504 = 505 ul_RealTimingInterval 506 + 507 1; 508 } 509 510 ul_TimingInterval 511 = 512 ul_TimingInterval 513 - 514 1; 515 ul_TimerValue 516 = 517 ul_TimerValue 518 - 519 2; 520 if (b_PCIInputClock != APCI1710_40MHZ) { 521 ul_TimerValue 522 = 523 (unsigned int) 524 ( 525 (double) 526 (ul_TimerValue) 527 * 528 0.99392); 529 } 530 531 break; 532 533 /******/ 534 /* mn */ 535 /******/ 536 537 case 4: 538 539 /******************/ 540 /* Timer 0 factor */ 541 /******************/ 542 543 ul_TimerValue 544 = 545 (unsigned int) 546 ( 547 (ul_TimingInterval 548 * 549 60) 550 * 551 (1000000.0 552 * 553 b_PCIInputClock)); 554 555 /*******************/ 556 /* Round the value */ 557 /*******************/ 558 559 if ((double)((double)(ul_TimingInterval * 60.0) * (1000000.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) { 560 ul_TimerValue 561 = 562 ul_TimerValue 563 + 564 1; 565 } 566 567 /*****************************/ 568 /* Calculate the real timing */ 569 /*****************************/ 570 571 ul_RealTimingInterval 572 = 573 (unsigned int) 574 (ul_TimerValue 575 / 576 (1000000.0 577 * 578 (double) 579 b_PCIInputClock)) 580 / 581 60; 582 d_RealTimingInterval 583 = 584 ( 585 (double) 586 ul_TimerValue 587 / 588 (0.001 * (double)b_PCIInputClock)) / 60.0; 589 590 if ((double)(((double)ul_TimerValue / (1000000.0 * (double)b_PCIInputClock)) / 60.0) >= (double)((double)ul_RealTimingInterval + 0.5)) { 591 ul_RealTimingInterval 592 = 593 ul_RealTimingInterval 594 + 595 1; 596 } 597 598 ul_TimingInterval 599 = 600 ul_TimingInterval 601 - 602 1; 603 ul_TimerValue 604 = 605 ul_TimerValue 606 - 607 2; 608 if (b_PCIInputClock != APCI1710_40MHZ) { 609 ul_TimerValue 610 = 611 (unsigned int) 612 ( 613 (double) 614 (ul_TimerValue) 615 * 616 0.99392); 617 } 618 619 break; 620 } 621 622 fpu_end(); 623 624 /****************************/ 625 /* Save the PCI input clock */ 626 /****************************/ 627 628 devpriv-> 629 s_ModuleInfo 630 [b_ModulNbr]. 631 s_ChronoModuleInfo. 632 b_PCIInputClock 633 = 634 b_PCIInputClock; 635 636 /*************************/ 637 /* Save the timing unity */ 638 /*************************/ 639 640 devpriv-> 641 s_ModuleInfo 642 [b_ModulNbr]. 643 s_ChronoModuleInfo. 644 b_TimingUnit 645 = 646 b_TimingUnit; 647 648 /************************/ 649 /* Save the base timing */ 650 /************************/ 651 652 devpriv-> 653 s_ModuleInfo 654 [b_ModulNbr]. 655 s_ChronoModuleInfo. 656 d_TimingInterval 657 = 658 d_RealTimingInterval; 659 660 /****************************/ 661 /* Set the chronometer mode */ 662 /****************************/ 663 664 devpriv-> 665 s_ModuleInfo 666 [b_ModulNbr]. 667 s_ChronoModuleInfo. 668 dw_ConfigReg 669 = 670 dw_ModeArray 671 [b_ChronoMode]; 672 673 /***********************/ 674 /* Test if 40 MHz used */ 675 /***********************/ 676 677 if (b_PCIInputClock == APCI1710_40MHZ) { 678 devpriv-> 679 s_ModuleInfo 680 [b_ModulNbr]. 681 s_ChronoModuleInfo. 682 dw_ConfigReg 683 = 684 devpriv-> 685 s_ModuleInfo 686 [b_ModulNbr]. 687 s_ChronoModuleInfo. 688 dw_ConfigReg 689 | 690 0x80; 691 } 692 693 outl(devpriv->s_ModuleInfo[b_ModulNbr].s_ChronoModuleInfo.dw_ConfigReg, devpriv->s_BoardInfos.ui_Address + 16 + (64 * b_ModulNbr)); 694 695 /***********************/ 696 /* Write timer 0 value */ 697 /***********************/ 698 699 outl(ul_TimerValue, devpriv->s_BoardInfos.ui_Address + (64 * b_ModulNbr)); 700 701 /*********************/ 702 /* Chronometer init. */ 703 /*********************/ 704 705 devpriv-> 706 s_ModuleInfo 707 [b_ModulNbr]. 708 s_ChronoModuleInfo. 709 b_ChronoInit 710 = 711 1; 712 } else { 713 /***********************************************/ 714 /* TOR version error for 40MHz clock selection */ 715 /***********************************************/ 716 717 DPRINTK("TOR version error for 40MHz clock selection\n"); 718 i_ReturnValue 719 = 720 -9; 721 } 722 } else { 723 /**************************************************************/ 724 /* You can not use the 40MHz clock selection with this board */ 725 /**************************************************************/ 726 727 DPRINTK("You can not used the 40MHz clock selection with this board\n"); 728 i_ReturnValue = 729 -8; 730 } 731 } else { 732 /**********************************/ 733 /* Base timing selection is wrong */ 734 /**********************************/ 735 736 DPRINTK("Base timing selection is wrong\n"); 737 i_ReturnValue = -7; 738 } 739 } /* if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4)) */ 740 else { 741 /***********************************/ 742 /* Timing unity selection is wrong */ 743 /***********************************/ 744 745 DPRINTK("Timing unity selection is wrong\n"); 746 i_ReturnValue = -6; 747 } /* if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4)) */ 748 } /* if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ)) */ 749 else { 750 /*****************************************/ 751 /* The selected PCI input clock is wrong */ 752 /*****************************************/ 753 754 DPRINTK("The selected PCI input clock is wrong\n"); 755 i_ReturnValue = -5; 756 } /* if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ)) */ 757 } /* if (b_ChronoMode >= 0 && b_ChronoMode <= 7) */ 758 else { 759 /***************************************/ 760 /* Chronometer mode selection is wrong */ 761 /***************************************/ 762 763 DPRINTK("Chronometer mode selection is wrong\n"); 764 i_ReturnValue = -4; 765 } /* if (b_ChronoMode >= 0 && b_ChronoMode <= 7) */ 766 } else { 767 /******************************************/ 768 /* The module is not a Chronometer module */ 769 /******************************************/ 770 771 DPRINTK("The module is not a Chronometer module\n"); 772 i_ReturnValue = -3; 773 } 774 } else { 775 /***********************/ 776 /* Module number error */ 777 /***********************/ 778 779 DPRINTK("Module number error\n"); 780 i_ReturnValue = -2; 781 } 782 data[0] = ul_RealTimingInterval; 783 return i_ReturnValue; 784} 785 786/* 787+----------------------------------------------------------------------------+ 788| Function Name : _INT_ i_APCI1710_EnableChrono | 789| (unsigned char_ b_BoardHandle, | 790| unsigned char_ b_ModulNbr, | 791| unsigned char_ b_CycleMode, | 792| unsigned char_ b_InterruptEnable) 793int i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device *dev, 794struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) | 795+----------------------------------------------------------------------------+ 796| Task : Enable the chronometer from selected module | 797| (b_ModulNbr). You must calling the | 798| "i_APCI1710_InitChrono" function be for you call this | 799| function. | 800| If you enable the chronometer interrupt, the | 801| chronometer generate a interrupt after the stop signal.| 802| See function "i_APCI1710_SetBoardIntRoutineX" and the | 803| Interrupt mask description chapter from this manual. | 804| The b_CycleMode parameter determine if you will | 805| measured a single or more cycle. 806 807| Disable the chronometer from selected module | 808| (b_ModulNbr). If you disable the chronometer after a | 809| start signal occur and you restart the chronometer | 810| witch the " i_APCI1710_EnableChrono" function, if no | 811| stop signal occur this start signal is ignored. 812+----------------------------------------------------------------------------+ 813| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 | 814| unsigned char_ b_ModulNbr CR_AREF(chanspec) : Selected module number (0 to 3) | 815 data[0] ENABle/Disable chrono 816| unsigned char_ b_CycleMode : Selected the chronometer | 817| data[1] acquisition mode | 818| unsigned char_ b_InterruptEnable : Enable or disable the | 819| data[2] chronometer interrupt. | 820| APCI1710_ENABLE: | 821| Enable the chronometer | 822| interrupt | 823| APCI1710_DISABLE: | 824| Disable the chronometer | 825| interrupt | 826+----------------------------------------------------------------------------+ 827| Output Parameters : - | 828+----------------------------------------------------------------------------+ 829| Return Value : 0: No error | 830| -1: The handle parameter of the board is wrong | 831| -2: Module selection wrong | 832| -3: The module is not a Chronometer module | 833| -4: Chronometer not initialised see function | 834| "i_APCI1710_InitChrono" | 835| -5: Chronometer acquisition mode cycle is wrong | 836| -6: Interrupt parameter is wrong | 837| -7: Interrupt function not initialised. | 838| See function "i_APCI1710_SetBoardIntRoutineX" 839 -8: data[0] wrong input | 840+----------------------------------------------------------------------------+ 841*/ 842 843int i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device *dev, 844 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 845{ 846 int i_ReturnValue = 0; 847 unsigned char b_ModulNbr, b_CycleMode, b_InterruptEnable, b_Action; 848 b_ModulNbr = CR_AREF(insn->chanspec); 849 b_Action = (unsigned char) data[0]; 850 b_CycleMode = (unsigned char) data[1]; 851 b_InterruptEnable = (unsigned char) data[2]; 852 i_ReturnValue = insn->n; 853 854 /**************************/ 855 /* Test the module number */ 856 /**************************/ 857 858 if (b_ModulNbr < 4) { 859 /***********************/ 860 /* Test if chronometer */ 861 /***********************/ 862 863 if ((devpriv->s_BoardInfos. 864 dw_MolduleConfiguration[b_ModulNbr] & 865 0xFFFF0000UL) == APCI1710_CHRONOMETER) { 866 /***********************************/ 867 /* Test if chronometer initialised */ 868 /***********************************/ 869 870 if (devpriv->s_ModuleInfo[b_ModulNbr]. 871 s_ChronoModuleInfo.b_ChronoInit == 1) { 872 873 switch (b_Action) { 874 875 case APCI1710_ENABLE: 876 877 /*********************************/ 878 /* Test the cycle mode parameter */ 879 /*********************************/ 880 881 if ((b_CycleMode == APCI1710_SINGLE) 882 || (b_CycleMode == 883 APCI1710_CONTINUOUS)) { 884 /***************************/ 885 /* Test the interrupt flag */ 886 /***************************/ 887 888 if ((b_InterruptEnable == 889 APCI1710_ENABLE) 890 || (b_InterruptEnable == 891 APCI1710_DISABLE)) 892 { 893 894 /***************************/ 895 /* Save the interrupt flag */ 896 /***************************/ 897 898 devpriv-> 899 s_ModuleInfo 900 [b_ModulNbr]. 901 s_ChronoModuleInfo. 902 b_InterruptMask 903 = 904 b_InterruptEnable; 905 906 /***********************/ 907 /* Save the cycle mode */ 908 /***********************/ 909 910 devpriv-> 911 s_ModuleInfo 912 [b_ModulNbr]. 913 s_ChronoModuleInfo. 914 b_CycleMode = 915 b_CycleMode; 916 917 devpriv-> 918 s_ModuleInfo 919 [b_ModulNbr]. 920 s_ChronoModuleInfo. 921 dw_ConfigReg = 922 (devpriv-> 923 s_ModuleInfo 924 [b_ModulNbr]. 925 s_ChronoModuleInfo. 926 dw_ConfigReg & 927 0x8F) | ((1 & 928 b_InterruptEnable) 929 << 5) | ((1 & 930 b_CycleMode) 931 << 6) | 0x10; 932 933 /*****************************/ 934 /* Test if interrupt enabled */ 935 /*****************************/ 936 937 if (b_InterruptEnable == 938 APCI1710_ENABLE) 939 { 940 /****************************/ 941 /* Clear the interrupt flag */ 942 /****************************/ 943 944 outl(devpriv-> 945 s_ModuleInfo 946 [b_ModulNbr]. 947 s_ChronoModuleInfo. 948 dw_ConfigReg, 949 devpriv-> 950 s_BoardInfos. 951 ui_Address 952 + 32 + 953 (64 * b_ModulNbr)); 954 devpriv->tsk_Current = current; /* Save the current process task structure */ 955 } 956 957 /***********************************/ 958 /* Enable or disable the interrupt */ 959 /* Enable the chronometer */ 960 /***********************************/ 961 962 outl(devpriv-> 963 s_ModuleInfo 964 [b_ModulNbr]. 965 s_ChronoModuleInfo. 966 dw_ConfigReg, 967 devpriv-> 968 s_BoardInfos. 969 ui_Address + 970 16 + 971 (64 * b_ModulNbr)); 972 973 /*************************/ 974 /* Clear status register */ 975 /*************************/ 976 977 outl(0, devpriv-> 978 s_BoardInfos. 979 ui_Address + 980 36 + 981 (64 * b_ModulNbr)); 982 983 } /* if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE)) */ 984 else { 985 /********************************/ 986 /* Interrupt parameter is wrong */ 987 /********************************/ 988 989 DPRINTK("Interrupt parameter is wrong\n"); 990 i_ReturnValue = -6; 991 } /* if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE)) */ 992 } /* if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS)) */ 993 else { 994 /***********************************************/ 995 /* Chronometer acquisition mode cycle is wrong */ 996 /***********************************************/ 997 998 DPRINTK("Chronometer acquisition mode cycle is wrong\n"); 999 i_ReturnValue = -5; 1000 } /* if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS)) */ 1001 break; 1002 1003 case APCI1710_DISABLE: 1004 1005 devpriv->s_ModuleInfo[b_ModulNbr]. 1006 s_ChronoModuleInfo. 1007 b_InterruptMask = 0; 1008 1009 devpriv->s_ModuleInfo[b_ModulNbr]. 1010 s_ChronoModuleInfo. 1011 dw_ConfigReg = 1012 devpriv-> 1013 s_ModuleInfo[b_ModulNbr]. 1014 s_ChronoModuleInfo. 1015 dw_ConfigReg & 0x2F; 1016 1017 /***************************/ 1018 /* Disable the interrupt */ 1019 /* Disable the chronometer */ 1020 /***************************/ 1021 1022 outl(devpriv->s_ModuleInfo[b_ModulNbr]. 1023 s_ChronoModuleInfo.dw_ConfigReg, 1024 devpriv->s_BoardInfos. 1025 ui_Address + 16 + 1026 (64 * b_ModulNbr)); 1027 1028 /***************************/ 1029 /* Test if continuous mode */ 1030 /***************************/ 1031 1032 if (devpriv->s_ModuleInfo[b_ModulNbr]. 1033 s_ChronoModuleInfo. 1034 b_CycleMode == 1035 APCI1710_CONTINUOUS) { 1036 /*************************/ 1037 /* Clear status register */ 1038 /*************************/ 1039 1040 outl(0, devpriv->s_BoardInfos. 1041 ui_Address + 36 + 1042 (64 * b_ModulNbr)); 1043 } 1044 break; 1045 1046 default: 1047 DPRINTK("Inputs wrong! Enable or Disable chrono\n"); 1048 i_ReturnValue = -8; 1049 } /* switch ENABLE/DISABLE */ 1050 } else { 1051 /*******************************/ 1052 /* Chronometer not initialised */ 1053 /*******************************/ 1054 1055 DPRINTK("Chronometer not initialised\n"); 1056 i_ReturnValue = -4; 1057 } 1058 } else { 1059 /******************************************/ 1060 /* The module is not a Chronometer module */ 1061 /******************************************/ 1062 1063 DPRINTK("The module is not a Chronometer module\n"); 1064 i_ReturnValue = -3; 1065 } 1066 } else { 1067 /***********************/ 1068 /* Module number error */ 1069 /***********************/ 1070 1071 DPRINTK("Module number error\n"); 1072 i_ReturnValue = -2; 1073 } 1074 1075 return i_ReturnValue; 1076} 1077 1078/* 1079+----------------------------------------------------------------------------+ 1080| Function Name :INT i_APCI1710_InsnReadChrono(struct comedi_device *dev,struct comedi_subdevice *s, 1081struct comedi_insn *insn,unsigned int *data) | 1082+----------------------------------------------------------------------------+ 1083| Task : Read functions for Timer | 1084+----------------------------------------------------------------------------+ 1085| Input Parameters : 1086+----------------------------------------------------------------------------+ 1087| Output Parameters : - | 1088+----------------------------------------------------------------------------+ 1089| Return Value : 1090+----------------------------------------------------------------------------+ 1091*/ 1092 1093int i_APCI1710_InsnReadChrono(struct comedi_device *dev, struct comedi_subdevice *s, 1094 struct comedi_insn *insn, unsigned int *data) 1095{ 1096 unsigned char b_ReadType; 1097 int i_ReturnValue = insn->n; 1098 1099 b_ReadType = CR_CHAN(insn->chanspec); 1100 1101 switch (b_ReadType) { 1102 case APCI1710_CHRONO_PROGRESS_STATUS: 1103 i_ReturnValue = i_APCI1710_GetChronoProgressStatus(dev, 1104 (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]); 1105 break; 1106 1107 case APCI1710_CHRONO_READVALUE: 1108 i_ReturnValue = i_APCI1710_ReadChronoValue(dev, 1109 (unsigned char) CR_AREF(insn->chanspec), 1110 (unsigned int) insn->unused[0], 1111 (unsigned char *) &data[0], (unsigned int *) &data[1]); 1112 break; 1113 1114 case APCI1710_CHRONO_CONVERTVALUE: 1115 i_ReturnValue = i_APCI1710_ConvertChronoValue(dev, 1116 (unsigned char) CR_AREF(insn->chanspec), 1117 (unsigned int) insn->unused[0], 1118 (unsigned int *) &data[0], 1119 (unsigned char *) &data[1], 1120 (unsigned char *) &data[2], 1121 (unsigned int *) &data[3], 1122 (unsigned int *) &data[4], (unsigned int *) &data[5]); 1123 break; 1124 1125 case APCI1710_CHRONO_READINTERRUPT: 1126 printk("In Chrono Read Interrupt\n"); 1127 1128 data[0] = devpriv->s_InterruptParameters. 1129 s_FIFOInterruptParameters[devpriv-> 1130 s_InterruptParameters.ui_Read].b_OldModuleMask; 1131 data[1] = devpriv->s_InterruptParameters. 1132 s_FIFOInterruptParameters[devpriv-> 1133 s_InterruptParameters.ui_Read].ul_OldInterruptMask; 1134 data[2] = devpriv->s_InterruptParameters. 1135 s_FIFOInterruptParameters[devpriv-> 1136 s_InterruptParameters.ui_Read].ul_OldCounterLatchValue; 1137 1138 /**************************/ 1139 /* Increment the read FIFO */ 1140 /***************************/ 1141 1142 devpriv-> 1143 s_InterruptParameters. 1144 ui_Read = (devpriv-> 1145 s_InterruptParameters. 1146 ui_Read + 1) % APCI1710_SAVE_INTERRUPT; 1147 break; 1148 1149 default: 1150 printk("ReadType Parameter wrong\n"); 1151 } 1152 1153 if (i_ReturnValue >= 0) 1154 i_ReturnValue = insn->n; 1155 return i_ReturnValue; 1156 1157} 1158 1159/* 1160+----------------------------------------------------------------------------+ 1161| Function Name : _INT_ i_APCI1710_GetChronoProgressStatus | 1162| (unsigned char_ b_BoardHandle, | 1163| unsigned char_ b_ModulNbr, | 1164| unsigned char *_ pb_ChronoStatus) | 1165+----------------------------------------------------------------------------+ 1166| Task : Return the chronometer status (pb_ChronoStatus) from | 1167| selected chronometer module (b_ModulNbr). | 1168+----------------------------------------------------------------------------+ 1169| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 | 1170| unsigned char_ b_ModulNbr : Selected module number (0 to 3) | 1171+----------------------------------------------------------------------------+ 1172| Output Parameters : PULONG_ pb_ChronoStatus : Return the chronometer | 1173| status. | 1174| 0 : Measurement not started.| 1175| No start signal occur. | 1176| 1 : Measurement started. | 1177| A start signal occur. | 1178| 2 : Measurement stopped. | 1179| A stop signal occur. | 1180| The measurement is | 1181| terminate. | 1182| 3: A overflow occur. You | 1183| must change the base | 1184| timing witch the | 1185| function | 1186| "i_APCI1710_InitChrono" | 1187+----------------------------------------------------------------------------+ 1188| Return Value : 0: No error | 1189| -1: The handle parameter of the board is wrong | 1190| -2: Module selection wrong | 1191| -3: The module is not a Chronometer module | 1192| -4: Chronometer not initialised see function | 1193| "i_APCI1710_InitChrono" | 1194+----------------------------------------------------------------------------+ 1195*/ 1196 1197int i_APCI1710_GetChronoProgressStatus(struct comedi_device *dev, 1198 unsigned char b_ModulNbr, unsigned char *pb_ChronoStatus) 1199{ 1200 int i_ReturnValue = 0; 1201 unsigned int dw_Status; 1202 1203 /**************************/ 1204 /* Test the module number */ 1205 /**************************/ 1206 1207 if (b_ModulNbr < 4) { 1208 /***********************/ 1209 /* Test if chronometer */ 1210 /***********************/ 1211 1212 if ((devpriv->s_BoardInfos. 1213 dw_MolduleConfiguration[b_ModulNbr] & 1214 0xFFFF0000UL) == APCI1710_CHRONOMETER) { 1215 /***********************************/ 1216 /* Test if chronometer initialised */ 1217 /***********************************/ 1218 1219 if (devpriv-> 1220 s_ModuleInfo[b_ModulNbr]. 1221 s_ChronoModuleInfo.b_ChronoInit == 1) { 1222 1223 dw_Status = inl(devpriv->s_BoardInfos. 1224 ui_Address + 8 + (64 * b_ModulNbr)); 1225 1226 /********************/ 1227 /* Test if overflow */ 1228 /********************/ 1229 1230 if ((dw_Status & 8) == 8) { 1231 /******************/ 1232 /* Overflow occur */ 1233 /******************/ 1234 1235 *pb_ChronoStatus = 3; 1236 } /* if ((dw_Status & 8) == 8) */ 1237 else { 1238 /*******************************/ 1239 /* Test if measurement stopped */ 1240 /*******************************/ 1241 1242 if ((dw_Status & 2) == 2) { 1243 /***********************/ 1244 /* A stop signal occur */ 1245 /***********************/ 1246 1247 *pb_ChronoStatus = 2; 1248 } /* if ((dw_Status & 2) == 2) */ 1249 else { 1250 /*******************************/ 1251 /* Test if measurement started */ 1252 /*******************************/ 1253 1254 if ((dw_Status & 1) == 1) { 1255 /************************/ 1256 /* A start signal occur */ 1257 /************************/ 1258 1259 *pb_ChronoStatus = 1; 1260 } /* if ((dw_Status & 1) == 1) */ 1261 else { 1262 /***************************/ 1263 /* Measurement not started */ 1264 /***************************/ 1265 1266 *pb_ChronoStatus = 0; 1267 } /* if ((dw_Status & 1) == 1) */ 1268 } /* if ((dw_Status & 2) == 2) */ 1269 } /* if ((dw_Status & 8) == 8) */ 1270 } else { 1271 /*******************************/ 1272 /* Chronometer not initialised */ 1273 /*******************************/ 1274 DPRINTK("Chronometer not initialised\n"); 1275 i_ReturnValue = -4; 1276 } 1277 } else { 1278 /******************************************/ 1279 /* The module is not a Chronometer module */ 1280 /******************************************/ 1281 DPRINTK("The module is not a Chronometer module\n"); 1282 i_ReturnValue = -3; 1283 } 1284 } else { 1285 /***********************/ 1286 /* Module number error */ 1287 /***********************/ 1288 DPRINTK("Module number error\n"); 1289 i_ReturnValue = -2; 1290 } 1291 1292 return i_ReturnValue; 1293} 1294 1295/* 1296+----------------------------------------------------------------------------+ 1297| Function Name : _INT_ i_APCI1710_ReadChronoValue | 1298| (unsigned char_ b_BoardHandle, | 1299| unsigned char_ b_ModulNbr, | 1300| unsigned int_ ui_TimeOut, | 1301| unsigned char *_ pb_ChronoStatus, | 1302| PULONG_ pul_ChronoValue) | 1303+----------------------------------------------------------------------------+ 1304| Task : Return the chronometer status (pb_ChronoStatus) and the| 1305| timing value (pul_ChronoValue) after a stop signal | 1306| occur from selected chronometer module (b_ModulNbr). | 1307| This function are only avaible if you have disabled | 1308| the interrupt functionality. See function | 1309| "i_APCI1710_EnableChrono" and the Interrupt mask | 1310| description chapter. | 1311| You can test the chronometer status witch the | 1312| "i_APCI1710_GetChronoProgressStatus" function. | 1313| | 1314| The returned value from pul_ChronoValue parameter is | 1315| not real measured timing. | 1316| You must used the "i_APCI1710_ConvertChronoValue" | 1317| function or make this operation for calculate the | 1318| timing: | 1319| | 1320| Timing = pul_ChronoValue * pul_RealTimingInterval. | 1321| | 1322| pul_RealTimingInterval is the returned parameter from | 1323| "i_APCI1710_InitChrono" function and the time unity is | 1324| the b_TimingUnit from "i_APCI1710_InitChrono" function| 1325+----------------------------------------------------------------------------+ 1326| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 | 1327| unsigned char_ b_ModulNbr : Selected module number (0 to 3) | 1328+----------------------------------------------------------------------------+ 1329| Output Parameters : PULONG_ pb_ChronoStatus : Return the chronometer | 1330| status. | 1331| 0 : Measurement not started.| 1332| No start signal occur. | 1333| 1 : Measurement started. | 1334| A start signal occur. | 1335| 2 : Measurement stopped. | 1336| A stop signal occur. | 1337| The measurement is | 1338| terminate. | 1339| 3: A overflow occur. You | 1340| must change the base | 1341| timing witch the | 1342| function | 1343| "i_APCI1710_InitChrono" | 1344| unsigned int * pul_ChronoValue : Chronometer timing value. | 1345+----------------------------------------------------------------------------+ 1346| Return Value : 0: No error | 1347| -1: The handle parameter of the board is wrong | 1348| -2: Module selection wrong | 1349| -3: The module is not a Chronometer module | 1350| -4: Chronometer not initialised see function | 1351| "i_APCI1710_InitChrono" | 1352| -5: Timeout parameter is wrong (0 to 65535) | 1353| -6: Interrupt routine installed. You can not read | 1354| directly the chronometer measured timing. | 1355+----------------------------------------------------------------------------+ 1356*/ 1357 1358int i_APCI1710_ReadChronoValue(struct comedi_device *dev, 1359 unsigned char b_ModulNbr, 1360 unsigned int ui_TimeOut, unsigned char *pb_ChronoStatus, unsigned int *pul_ChronoValue) 1361{ 1362 int i_ReturnValue = 0; 1363 unsigned int dw_Status; 1364 unsigned int dw_TimeOut = 0; 1365 1366 /**************************/ 1367 /* Test the module number */ 1368 /**************************/ 1369 1370 if (b_ModulNbr < 4) { 1371 /***********************/ 1372 /* Test if chronometer */ 1373 /***********************/ 1374 1375 if ((devpriv->s_BoardInfos. 1376 dw_MolduleConfiguration[b_ModulNbr] & 1377 0xFFFF0000UL) == APCI1710_CHRONOMETER) { 1378 /***********************************/ 1379 /* Test if chronometer initialised */ 1380 /***********************************/ 1381 1382 if (devpriv-> 1383 s_ModuleInfo[b_ModulNbr]. 1384 s_ChronoModuleInfo.b_ChronoInit == 1) { 1385 /*****************************/ 1386 /* Test the timout parameter */ 1387 /*****************************/ 1388 1389 if (ui_TimeOut <= 65535UL) { 1390 1391 for (;;) { 1392 /*******************/ 1393 /* Read the status */ 1394 /*******************/ 1395 1396 dw_Status = 1397 inl(devpriv-> 1398 s_BoardInfos. 1399 ui_Address + 8 + 1400 (64 * b_ModulNbr)); 1401 1402 /********************/ 1403 /* Test if overflow */ 1404 /********************/ 1405 1406 if ((dw_Status & 8) == 8) { 1407 /******************/ 1408 /* Overflow occur */ 1409 /******************/ 1410 1411 *pb_ChronoStatus = 3; 1412 1413 /***************************/ 1414 /* Test if continuous mode */ 1415 /***************************/ 1416 1417 if (devpriv-> 1418 s_ModuleInfo 1419 [b_ModulNbr]. 1420 s_ChronoModuleInfo. 1421 b_CycleMode == 1422 APCI1710_CONTINUOUS) 1423 { 1424 /*************************/ 1425 /* Clear status register */ 1426 /*************************/ 1427 1428 outl(0, devpriv->s_BoardInfos.ui_Address + 36 + (64 * b_ModulNbr)); 1429 } 1430 1431 break; 1432 } /* if ((dw_Status & 8) == 8) */ 1433 else { 1434 /*******************************/ 1435 /* Test if measurement stopped */ 1436 /*******************************/ 1437 1438 if ((dw_Status & 2) == 1439 2) { 1440 /***********************/ 1441 /* A stop signal occur */ 1442 /***********************/ 1443 1444 *pb_ChronoStatus 1445 = 2; 1446 1447 /***************************/ 1448 /* Test if continnous mode */ 1449 /***************************/ 1450 1451 if (devpriv-> 1452 s_ModuleInfo 1453 [b_ModulNbr]. 1454 s_ChronoModuleInfo. 1455 b_CycleMode 1456 == 1457 APCI1710_CONTINUOUS) 1458 { 1459 /*************************/ 1460 /* Clear status register */ 1461 /*************************/ 1462 1463 outl(0, devpriv->s_BoardInfos.ui_Address + 36 + (64 * b_ModulNbr)); 1464 } 1465 break; 1466 } /* if ((dw_Status & 2) == 2) */ 1467 else { 1468 /*******************************/ 1469 /* Test if measurement started */ 1470 /*******************************/ 1471 1472 if ((dw_Status & 1) == 1) { 1473 /************************/ 1474 /* A start signal occur */ 1475 /************************/ 1476 1477 *pb_ChronoStatus 1478 = 1479 1; 1480 } /* if ((dw_Status & 1) == 1) */ 1481 else { 1482 /***************************/ 1483 /* Measurement not started */ 1484 /***************************/ 1485 1486 *pb_ChronoStatus 1487 = 1488 0; 1489 } /* if ((dw_Status & 1) == 1) */ 1490 } /* if ((dw_Status & 2) == 2) */ 1491 } /* if ((dw_Status & 8) == 8) */ 1492 1493 if (dw_TimeOut == ui_TimeOut) { 1494 /*****************/ 1495 /* Timeout occur */ 1496 /*****************/ 1497 1498 break; 1499 } else { 1500 /*************************/ 1501 /* Increment the timeout */ 1502 /*************************/ 1503 1504 dw_TimeOut = 1505 dw_TimeOut + 1; 1506 mdelay(1000); 1507 1508 } 1509 } /* for (;;) */ 1510 1511 /*****************************/ 1512 /* Test if stop signal occur */ 1513 /*****************************/ 1514 1515 if (*pb_ChronoStatus == 2) { 1516 /**********************************/ 1517 /* Read the measured timing value */ 1518 /**********************************/ 1519 1520 *pul_ChronoValue = 1521 inl(devpriv-> 1522 s_BoardInfos. 1523 ui_Address + 4 + 1524 (64 * b_ModulNbr)); 1525 1526 if (*pul_ChronoValue != 0) { 1527 *pul_ChronoValue = 1528 *pul_ChronoValue 1529 - 1; 1530 } 1531 } else { 1532 /*************************/ 1533 /* Test if timeout occur */ 1534 /*************************/ 1535 1536 if ((*pb_ChronoStatus != 3) 1537 && (dw_TimeOut == 1538 ui_TimeOut) 1539 && (ui_TimeOut != 0)) { 1540 /*****************/ 1541 /* Timeout occur */ 1542 /*****************/ 1543 1544 *pb_ChronoStatus = 4; 1545 } 1546 } 1547 1548 } else { 1549 /******************************/ 1550 /* Timeout parameter is wrong */ 1551 /******************************/ 1552 DPRINTK("Timeout parameter is wrong\n"); 1553 i_ReturnValue = -5; 1554 } 1555 } else { 1556 /*******************************/ 1557 /* Chronometer not initialised */ 1558 /*******************************/ 1559 DPRINTK("Chronometer not initialised\n"); 1560 i_ReturnValue = -4; 1561 } 1562 } else { 1563 /******************************************/ 1564 /* The module is not a Chronometer module */ 1565 /******************************************/ 1566 DPRINTK("The module is not a Chronometer module\n"); 1567 i_ReturnValue = -3; 1568 } 1569 } else { 1570 /***********************/ 1571 /* Module number error */ 1572 /***********************/ 1573 DPRINTK("Module number error\n"); 1574 i_ReturnValue = -2; 1575 } 1576 1577 return i_ReturnValue; 1578} 1579 1580/* 1581+----------------------------------------------------------------------------+ 1582| Function Name : _INT_ i_APCI1710_ConvertChronoValue | 1583| (unsigned char_ b_BoardHandle, | 1584| unsigned char_ b_ModulNbr, | 1585| ULONG_ ul_ChronoValue, | 1586| PULONG_ pul_Hour, | 1587| unsigned char *_ pb_Minute, | 1588| unsigned char *_ pb_Second, | 1589| unsigned int *_ pui_MilliSecond, | 1590| unsigned int *_ pui_MicroSecond, | 1591| unsigned int *_ pui_NanoSecond) | 1592+----------------------------------------------------------------------------+ 1593| Task : Convert the chronometer measured timing | 1594| (ul_ChronoValue) in to h, mn, s, ms, µs, ns. | 1595+----------------------------------------------------------------------------+ 1596| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 | 1597| unsigned char_ b_ModulNbr : Selected module number (0 to 3)| 1598| ULONG_ ul_ChronoValue : Measured chronometer timing | 1599| value. | 1600| See"i_APCI1710_ReadChronoValue"| 1601+----------------------------------------------------------------------------+ 1602| Output Parameters : PULONG_ pul_Hour : Chronometer timing hour | 1603| unsigned char *_ pb_Minute : Chronometer timing minute | 1604| unsigned char *_ pb_Second : Chronometer timing second | 1605| unsigned int *_ pui_MilliSecond : Chronometer timing mini | 1606| second | 1607| unsigned int *_ pui_MicroSecond : Chronometer timing micro | 1608| second | 1609| unsigned int *_ pui_NanoSecond : Chronometer timing nano | 1610| second | 1611+----------------------------------------------------------------------------+ 1612| Return Value : 0: No error | 1613| -1: The handle parameter of the board is wrong | 1614| -2: Module selection wrong | 1615| -3: The module is not a Chronometer module | 1616| -4: Chronometer not initialised see function | 1617| "i_APCI1710_InitChrono" | 1618+----------------------------------------------------------------------------+ 1619*/ 1620 1621int i_APCI1710_ConvertChronoValue(struct comedi_device *dev, 1622 unsigned char b_ModulNbr, 1623 unsigned int ul_ChronoValue, 1624 unsigned int *pul_Hour, 1625 unsigned char *pb_Minute, 1626 unsigned char *pb_Second, 1627 unsigned int *pui_MilliSecond, unsigned int *pui_MicroSecond, unsigned int *pui_NanoSecond) 1628{ 1629 int i_ReturnValue = 0; 1630 double d_Hour; 1631 double d_Minute; 1632 double d_Second; 1633 double d_MilliSecond; 1634 double d_MicroSecond; 1635 double d_NanoSecond; 1636 1637 /**************************/ 1638 /* Test the module number */ 1639 /**************************/ 1640 1641 if (b_ModulNbr < 4) { 1642 /***********************/ 1643 /* Test if chronometer */ 1644 /***********************/ 1645 1646 if ((devpriv->s_BoardInfos. 1647 dw_MolduleConfiguration[b_ModulNbr] & 1648 0xFFFF0000UL) == APCI1710_CHRONOMETER) { 1649 /***********************************/ 1650 /* Test if chronometer initialised */ 1651 /***********************************/ 1652 1653 if (devpriv-> 1654 s_ModuleInfo[b_ModulNbr]. 1655 s_ChronoModuleInfo.b_ChronoInit == 1) { 1656 fpu_begin(); 1657 1658 d_Hour = (double)ul_ChronoValue *(double) 1659 devpriv->s_ModuleInfo[b_ModulNbr]. 1660 s_ChronoModuleInfo.d_TimingInterval; 1661 1662 switch (devpriv-> 1663 s_ModuleInfo[b_ModulNbr]. 1664 s_ChronoModuleInfo.b_TimingUnit) { 1665 case 0: 1666 d_Hour = d_Hour / (double)1000.0; 1667 1668 case 1: 1669 d_Hour = d_Hour / (double)1000.0; 1670 1671 case 2: 1672 d_Hour = d_Hour / (double)1000.0; 1673 1674 case 3: 1675 d_Hour = d_Hour / (double)60.0; 1676 1677 case 4: 1678 /**********************/ 1679 /* Calculate the hour */ 1680 /**********************/ 1681 1682 d_Hour = d_Hour / (double)60.0; 1683 *pul_Hour = (unsigned int) d_Hour; 1684 1685 /************************/ 1686 /* Calculate the minute */ 1687 /************************/ 1688 1689 d_Minute = d_Hour - *pul_Hour; 1690 d_Minute = d_Minute * 60; 1691 *pb_Minute = (unsigned char) d_Minute; 1692 1693 /************************/ 1694 /* Calculate the second */ 1695 /************************/ 1696 1697 d_Second = d_Minute - *pb_Minute; 1698 d_Second = d_Second * 60; 1699 *pb_Second = (unsigned char) d_Second; 1700 1701 /*****************************/ 1702 /* Calculate the mini second */ 1703 /*****************************/ 1704 1705 d_MilliSecond = d_Second - *pb_Second; 1706 d_MilliSecond = d_MilliSecond * 1000; 1707 *pui_MilliSecond = (unsigned int) d_MilliSecond; 1708 1709 /******************************/ 1710 /* Calculate the micro second */ 1711 /******************************/ 1712 1713 d_MicroSecond = 1714 d_MilliSecond - 1715 *pui_MilliSecond; 1716 d_MicroSecond = d_MicroSecond * 1000; 1717 *pui_MicroSecond = (unsigned int) d_MicroSecond; 1718 1719 /******************************/ 1720 /* Calculate the micro second */ 1721 /******************************/ 1722 1723 d_NanoSecond = 1724 d_MicroSecond - 1725 *pui_MicroSecond; 1726 d_NanoSecond = d_NanoSecond * 1000; 1727 *pui_NanoSecond = (unsigned int) d_NanoSecond; 1728 break; 1729 } 1730 1731 fpu_end(); 1732 } else { 1733 /*******************************/ 1734 /* Chronometer not initialised */ 1735 /*******************************/ 1736 DPRINTK("Chronometer not initialised\n"); 1737 i_ReturnValue = -4; 1738 } 1739 } else { 1740 /******************************************/ 1741 /* The module is not a Chronometer module */ 1742 /******************************************/ 1743 DPRINTK("The module is not a Chronometer module\n"); 1744 i_ReturnValue = -3; 1745 } 1746 } else { 1747 /***********************/ 1748 /* Module number error */ 1749 /***********************/ 1750 DPRINTK("Module number error\n"); 1751 i_ReturnValue = -2; 1752 } 1753 1754 return i_ReturnValue; 1755} 1756 1757/* 1758+----------------------------------------------------------------------------+ 1759| Function Name : int i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device *dev,struct comedi_subdevice *s, 1760 struct comedi_insn *insn,unsigned int *data) | 1761+----------------------------------------------------------------------------+ 1762| Task : Sets the output witch has been passed with the | 1763| parameter b_Channel. Setting an output means setting an| 1764| output high. | 1765+----------------------------------------------------------------------------+ 1766| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 | 1767| unsigned char_ b_ModulNbr : Selected module number (0 to 3)| 1768| unsigned char_ b_OutputChannel : Selection from digital output | 1769| CR_CHAN() channel (0 to 2) | 1770| 0 : Channel H | 1771| 1 : Channel A | 1772| 2 : Channel B | 1773+----------------------------------------------------------------------------+ 1774| Output Parameters : - | 1775+----------------------------------------------------------------------------+ 1776| Return Value : 0: No error | 1777| -1: The handle parameter of the board is wrong | 1778| -2: Module selection wrong | 1779| -3: The module is not a Chronometer module | 1780| -4: The selected digital output is wrong | 1781| -5: Chronometer not initialised see function | 1782| "i_APCI1710_InitChrono" | 1783+----------------------------------------------------------------------------+ 1784*/ 1785 1786/* 1787+----------------------------------------------------------------------------+ 1788| Function Name : _INT_ i_APCI1710_SetChronoChlOff | 1789| (unsigned char_ b_BoardHandle, | 1790| unsigned char_ b_ModulNbr, | 1791| unsigned char_ b_OutputChannel) | 1792+----------------------------------------------------------------------------+ 1793| Task : Resets the output witch has been passed with the | 1794| parameter b_Channel. Resetting an output means setting | 1795| an output low. | 1796+----------------------------------------------------------------------------+ 1797| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 1798 data[0] : Chl ON, Chl OFF , Chl Read , Port Read 1799 1800| unsigned char_ b_ModulNbr CR_AREF : Selected module number (0 to 3)| 1801| unsigned char_ b_OutputChannel CR_CHAN : Selection from digital output | 1802| channel (0 to 2) | 1803| 0 : Channel H | 1804| 1 : Channel A | 1805| 2 : Channel B | 1806+----------------------------------------------------------------------------+ 1807| Output Parameters : - | 1808+----------------------------------------------------------------------------+ 1809| Return Value : 0: No error | 1810| -1: The handle parameter of the board is wrong | 1811| -2: Module selection wrong | 1812| -3: The module is not a Chronometer module | 1813| -4: The selected digital output is wrong | 1814| -5: Chronometer not initialised see function | 1815| "i_APCI1710_InitChrono" | 1816+----------------------------------------------------------------------------+ 1817*/ 1818 1819/* 1820+----------------------------------------------------------------------------+ 1821| Function Name : _INT_ i_APCI1710_ReadChronoChlValue | 1822| (unsigned char_ b_BoardHandle, | 1823| unsigned char_ b_ModulNbr, | 1824| unsigned char_ b_InputChannel, | 1825| unsigned char *_ pb_ChannelStatus) | 1826+----------------------------------------------------------------------------+ 1827| Task : Return the status from selected digital input | 1828| (b_InputChannel) from selected chronometer | 1829| module (b_ModulNbr). | 1830+----------------------------------------------------------------------------+ 1831| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 | 1832| unsigned char_ b_ModulNbr : Selected module number (0 to 3)| 1833| unsigned char_ b_InputChannel : Selection from digital input | 1834| channel (0 to 2) | 1835| CR_CHAN() 0 : Channel E | 1836| 1 : Channel F | 1837| 2 : Channel G | 1838+----------------------------------------------------------------------------+ 1839| Output Parameters : unsigned char *_ pb_ChannelStatus : Digital input channel status.| 1840| data[0] 0 : Channel is not active | 1841| 1 : Channel is active | 1842+----------------------------------------------------------------------------+ 1843| Return Value : 0: No error | 1844| -1: The handle parameter of the board is wrong | 1845| -2: Module selection wrong | 1846| -3: The module is not a Chronometer module | 1847| -4: The selected digital input is wrong | 1848| -5: Chronometer not initialised see function | 1849| "i_APCI1710_InitChrono" | 1850+----------------------------------------------------------------------------+ 1851*/ 1852 1853/* 1854+----------------------------------------------------------------------------+ 1855| Function Name : _INT_ i_APCI1710_ReadChronoPortValue | 1856| (unsigned char_ b_BoardHandle, | 1857| unsigned char_ b_ModulNbr, | 1858| unsigned char *_ pb_PortValue) | 1859+----------------------------------------------------------------------------+ 1860| Task : Return the status from digital inputs port from | 1861| selected (b_ModulNbr) chronometer module. | 1862+----------------------------------------------------------------------------+ 1863| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 | 1864| unsigned char_ b_ModulNbr : Selected module number (0 to 3)| 1865+----------------------------------------------------------------------------+ 1866| Output Parameters : unsigned char *_ pb_PortValue : Digital inputs port status. 1867| data[0] 1868+----------------------------------------------------------------------------+ 1869| Return Value : 0: No error | 1870| -1: The handle parameter of the board is wrong | 1871| -2: Module selection wrong | 1872| -3: The module is not a Chronometer module | 1873| -4: Chronometer not initialised see function | 1874| "i_APCI1710_InitChrono" | 1875+----------------------------------------------------------------------------+ 1876*/ 1877 1878int i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device *dev, 1879 struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) 1880{ 1881 int i_ReturnValue = 0; 1882 unsigned char b_ModulNbr, b_OutputChannel, b_InputChannel, b_IOType; 1883 unsigned int dw_Status; 1884 unsigned char *pb_ChannelStatus; 1885 unsigned char *pb_PortValue; 1886 1887 b_ModulNbr = CR_AREF(insn->chanspec); 1888 i_ReturnValue = insn->n; 1889 b_IOType = (unsigned char) data[0]; 1890 1891 /**************************/ 1892 /* Test the module number */ 1893 /**************************/ 1894 1895 if (b_ModulNbr < 4) { 1896 /***********************/ 1897 /* Test if chronometer */ 1898 /***********************/ 1899 1900 if ((devpriv->s_BoardInfos. 1901 dw_MolduleConfiguration[b_ModulNbr] & 1902 0xFFFF0000UL) == APCI1710_CHRONOMETER) { 1903 /***********************************/ 1904 /* Test if chronometer initialised */ 1905 /***********************************/ 1906 1907 if (devpriv->s_ModuleInfo[b_ModulNbr]. 1908 s_ChronoModuleInfo.b_ChronoInit == 1) { 1909 /***********************************/ 1910 /* Test the digital output channel */ 1911 /***********************************/ 1912 switch (b_IOType) { 1913 1914 case APCI1710_CHRONO_SET_CHANNELOFF: 1915 1916 b_OutputChannel = 1917 (unsigned char) CR_CHAN(insn->chanspec); 1918 if (b_OutputChannel <= 2) { 1919 1920 outl(0, devpriv->s_BoardInfos. 1921 ui_Address + 20 + 1922 (b_OutputChannel * 4) + 1923 (64 * b_ModulNbr)); 1924 } /* if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2)) */ 1925 else { 1926 /****************************************/ 1927 /* The selected digital output is wrong */ 1928 /****************************************/ 1929 1930 DPRINTK("The selected digital output is wrong\n"); 1931 i_ReturnValue = -4; 1932 1933 } /* if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2)) */ 1934 1935 break; 1936 1937 case APCI1710_CHRONO_SET_CHANNELON: 1938 1939 b_OutputChannel = 1940 (unsigned char) CR_CHAN(insn->chanspec); 1941 if (b_OutputChannel <= 2) { 1942 1943 outl(1, devpriv->s_BoardInfos. 1944 ui_Address + 20 + 1945 (b_OutputChannel * 4) + 1946 (64 * b_ModulNbr)); 1947 } /* if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2)) */ 1948 else { 1949 /****************************************/ 1950 /* The selected digital output is wrong */ 1951 /****************************************/ 1952 1953 DPRINTK("The selected digital output is wrong\n"); 1954 i_ReturnValue = -4; 1955 1956 } /* if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2)) */ 1957 1958 break; 1959 1960 case APCI1710_CHRONO_READ_CHANNEL: 1961 /**********************************/ 1962 /* Test the digital input channel */ 1963 /**********************************/ 1964 pb_ChannelStatus = (unsigned char *) &data[0]; 1965 b_InputChannel = 1966 (unsigned char) CR_CHAN(insn->chanspec); 1967 1968 if (b_InputChannel <= 2) { 1969 1970 dw_Status = 1971 inl(devpriv-> 1972 s_BoardInfos. 1973 ui_Address + 12 + 1974 (64 * b_ModulNbr)); 1975 1976 *pb_ChannelStatus = 1977 (unsigned char) (((dw_Status >> 1978 b_InputChannel) 1979 & 1) ^ 1); 1980 } /* if ((b_InputChannel >= 0) && (b_InputChannel <= 2)) */ 1981 else { 1982 /***************************************/ 1983 /* The selected digital input is wrong */ 1984 /***************************************/ 1985 1986 DPRINTK("The selected digital input is wrong\n"); 1987 i_ReturnValue = -4; 1988 } /* if ((b_InputChannel >= 0) && (b_InputChannel <= 2)) */ 1989 1990 break; 1991 1992 case APCI1710_CHRONO_READ_PORT: 1993 1994 pb_PortValue = (unsigned char *) &data[0]; 1995 1996 dw_Status = 1997 inl(devpriv->s_BoardInfos. 1998 ui_Address + 12 + 1999 (64 * b_ModulNbr)); 2000 2001 *pb_PortValue = 2002 (unsigned char) ((dw_Status & 0x7) ^ 7); 2003 break; 2004 } 2005 } else { 2006 /*******************************/ 2007 /* Chronometer not initialised */ 2008 /*******************************/ 2009 2010 DPRINTK("Chronometer not initialised\n"); 2011 i_ReturnValue = -5; 2012 } 2013 } else { 2014 /******************************************/ 2015 /* The module is not a Chronometer module */ 2016 /******************************************/ 2017 2018 DPRINTK("The module is not a Chronometer module\n"); 2019 i_ReturnValue = -3; 2020 } 2021 } else { 2022 /***********************/ 2023 /* Module number error */ 2024 /***********************/ 2025 2026 DPRINTK("Module number error\n"); 2027 i_ReturnValue = -2; 2028 } 2029 2030 return i_ReturnValue; 2031} 2032