APCI1710_Chrono.c revision 756e9d7ca6292ba21a6a63bf35ed1abc5250b98d
1/** 2@verbatim 3 4Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. 5 6 ADDI-DATA GmbH 7 Dieselstrasse 3 8 D-77833 Ottersweier 9 Tel: +19(0)7223/9493-0 10 Fax: +49(0)7223/9493-92 11 http://www.addi-data-com 12 info@addi-data.com 13 14This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 15 16This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 17 18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 20You shoud also find the complete GPL in the COPYING file accompanying this source code. 21 22@endverbatim 23*/ 24/* 25 26 +-----------------------------------------------------------------------+ 27 | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier | 28 +-----------------------------------------------------------------------+ 29 | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com | 30 | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com | 31 +-----------------------------------------------------------------------+ 32 | Project : 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 wich | 128| this board | 129| -9: You can not used the 40MHz clock selection wich | 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 used the 40MHz clock selection wich this board */ 725 /**************************************************************/ 726 727 DPRINTK("You can not used the 40MHz clock selection wich 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 >= 0) 1390 && (ui_TimeOut <= 65535UL)) { 1391 1392 for (;;) { 1393 /*******************/ 1394 /* Read the status */ 1395 /*******************/ 1396 1397 dw_Status = 1398 inl(devpriv-> 1399 s_BoardInfos. 1400 ui_Address + 8 + 1401 (64 * b_ModulNbr)); 1402 1403 /********************/ 1404 /* Test if overflow */ 1405 /********************/ 1406 1407 if ((dw_Status & 8) == 8) { 1408 /******************/ 1409 /* Overflow occur */ 1410 /******************/ 1411 1412 *pb_ChronoStatus = 3; 1413 1414 /***************************/ 1415 /* Test if continuous mode */ 1416 /***************************/ 1417 1418 if (devpriv-> 1419 s_ModuleInfo 1420 [b_ModulNbr]. 1421 s_ChronoModuleInfo. 1422 b_CycleMode == 1423 APCI1710_CONTINUOUS) 1424 { 1425 /*************************/ 1426 /* Clear status register */ 1427 /*************************/ 1428 1429 outl(0, devpriv->s_BoardInfos.ui_Address + 36 + (64 * b_ModulNbr)); 1430 } 1431 1432 break; 1433 } // if ((dw_Status & 8) == 8) 1434 else { 1435 /*******************************/ 1436 /* Test if measurement stopped */ 1437 /*******************************/ 1438 1439 if ((dw_Status & 2) == 1440 2) { 1441 /***********************/ 1442 /* A stop signal occur */ 1443 /***********************/ 1444 1445 *pb_ChronoStatus 1446 = 2; 1447 1448 /***************************/ 1449 /* Test if continnous mode */ 1450 /***************************/ 1451 1452 if (devpriv-> 1453 s_ModuleInfo 1454 [b_ModulNbr]. 1455 s_ChronoModuleInfo. 1456 b_CycleMode 1457 == 1458 APCI1710_CONTINUOUS) 1459 { 1460 /*************************/ 1461 /* Clear status register */ 1462 /*************************/ 1463 1464 outl(0, devpriv->s_BoardInfos.ui_Address + 36 + (64 * b_ModulNbr)); 1465 } 1466 break; 1467 } // if ((dw_Status & 2) == 2) 1468 else { 1469 /*******************************/ 1470 /* Test if measurement started */ 1471 /*******************************/ 1472 1473 if ((dw_Status & 1) == 1) { 1474 /************************/ 1475 /* A start signal occur */ 1476 /************************/ 1477 1478 *pb_ChronoStatus 1479 = 1480 1; 1481 } // if ((dw_Status & 1) == 1) 1482 else { 1483 /***************************/ 1484 /* Measurement not started */ 1485 /***************************/ 1486 1487 *pb_ChronoStatus 1488 = 1489 0; 1490 } // if ((dw_Status & 1) == 1) 1491 } // if ((dw_Status & 2) == 2) 1492 } // if ((dw_Status & 8) == 8) 1493 1494 if (dw_TimeOut == ui_TimeOut) { 1495 /*****************/ 1496 /* Timeout occur */ 1497 /*****************/ 1498 1499 break; 1500 } else { 1501 /*************************/ 1502 /* Increment the timeout */ 1503 /*************************/ 1504 1505 dw_TimeOut = 1506 dw_TimeOut + 1; 1507 mdelay(1000); 1508 1509 } 1510 } // for (;;) 1511 1512 /*****************************/ 1513 /* Test if stop signal occur */ 1514 /*****************************/ 1515 1516 if (*pb_ChronoStatus == 2) { 1517 /**********************************/ 1518 /* Read the measured timing value */ 1519 /**********************************/ 1520 1521 *pul_ChronoValue = 1522 inl(devpriv-> 1523 s_BoardInfos. 1524 ui_Address + 4 + 1525 (64 * b_ModulNbr)); 1526 1527 if (*pul_ChronoValue != 0) { 1528 *pul_ChronoValue = 1529 *pul_ChronoValue 1530 - 1; 1531 } 1532 } else { 1533 /*************************/ 1534 /* Test if timeout occur */ 1535 /*************************/ 1536 1537 if ((*pb_ChronoStatus != 3) 1538 && (dw_TimeOut == 1539 ui_TimeOut) 1540 && (ui_TimeOut != 0)) { 1541 /*****************/ 1542 /* Timeout occur */ 1543 /*****************/ 1544 1545 *pb_ChronoStatus = 4; 1546 } 1547 } 1548 1549 } else { 1550 /******************************/ 1551 /* Timeout parameter is wrong */ 1552 /******************************/ 1553 DPRINTK("Timeout parameter is wrong\n"); 1554 i_ReturnValue = -5; 1555 } 1556 } else { 1557 /*******************************/ 1558 /* Chronometer not initialised */ 1559 /*******************************/ 1560 DPRINTK("Chronometer not initialised\n"); 1561 i_ReturnValue = -4; 1562 } 1563 } else { 1564 /******************************************/ 1565 /* The module is not a Chronometer module */ 1566 /******************************************/ 1567 DPRINTK("The module is not a Chronometer module\n"); 1568 i_ReturnValue = -3; 1569 } 1570 } else { 1571 /***********************/ 1572 /* Module number error */ 1573 /***********************/ 1574 DPRINTK("Module number error\n"); 1575 i_ReturnValue = -2; 1576 } 1577 1578 return (i_ReturnValue); 1579} 1580 1581/* 1582+----------------------------------------------------------------------------+ 1583| Function Name : _INT_ i_APCI1710_ConvertChronoValue | 1584| (unsigned char_ b_BoardHandle, | 1585| unsigned char_ b_ModulNbr, | 1586| ULONG_ ul_ChronoValue, | 1587| PULONG_ pul_Hour, | 1588| unsigned char *_ pb_Minute, | 1589| unsigned char *_ pb_Second, | 1590| unsigned int *_ pui_MilliSecond, | 1591| unsigned int *_ pui_MicroSecond, | 1592| unsigned int *_ pui_NanoSecond) | 1593+----------------------------------------------------------------------------+ 1594| Task : Convert the chronometer measured timing | 1595| (ul_ChronoValue) in to h, mn, s, ms, µs, ns. | 1596+----------------------------------------------------------------------------+ 1597| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 | 1598| unsigned char_ b_ModulNbr : Selected module number (0 to 3)| 1599| ULONG_ ul_ChronoValue : Measured chronometer timing | 1600| value. | 1601| See"i_APCI1710_ReadChronoValue"| 1602+----------------------------------------------------------------------------+ 1603| Output Parameters : PULONG_ pul_Hour : Chronometer timing hour | 1604| unsigned char *_ pb_Minute : Chronometer timing minute | 1605| unsigned char *_ pb_Second : Chronometer timing second | 1606| unsigned int *_ pui_MilliSecond : Chronometer timing mini | 1607| second | 1608| unsigned int *_ pui_MicroSecond : Chronometer timing micro | 1609| second | 1610| unsigned int *_ pui_NanoSecond : Chronometer timing nano | 1611| second | 1612+----------------------------------------------------------------------------+ 1613| Return Value : 0: No error | 1614| -1: The handle parameter of the board is wrong | 1615| -2: Module selection wrong | 1616| -3: The module is not a Chronometer module | 1617| -4: Chronometer not initialised see function | 1618| "i_APCI1710_InitChrono" | 1619+----------------------------------------------------------------------------+ 1620*/ 1621 1622int i_APCI1710_ConvertChronoValue(struct comedi_device * dev, 1623 unsigned char b_ModulNbr, 1624 unsigned int ul_ChronoValue, 1625 unsigned int * pul_Hour, 1626 unsigned char * pb_Minute, 1627 unsigned char * pb_Second, 1628 unsigned int * pui_MilliSecond, unsigned int * pui_MicroSecond, unsigned int * pui_NanoSecond) 1629{ 1630 int i_ReturnValue = 0; 1631 double d_Hour; 1632 double d_Minute; 1633 double d_Second; 1634 double d_MilliSecond; 1635 double d_MicroSecond; 1636 double d_NanoSecond; 1637 1638 /**************************/ 1639 /* Test the module number */ 1640 /**************************/ 1641 1642 if (b_ModulNbr < 4) { 1643 /***********************/ 1644 /* Test if chronometer */ 1645 /***********************/ 1646 1647 if ((devpriv->s_BoardInfos. 1648 dw_MolduleConfiguration[b_ModulNbr] & 1649 0xFFFF0000UL) == APCI1710_CHRONOMETER) { 1650 /***********************************/ 1651 /* Test if chronometer initialised */ 1652 /***********************************/ 1653 1654 if (devpriv-> 1655 s_ModuleInfo[b_ModulNbr]. 1656 s_ChronoModuleInfo.b_ChronoInit == 1) { 1657 fpu_begin(); 1658 1659 d_Hour = (double)ul_ChronoValue *(double) 1660 devpriv->s_ModuleInfo[b_ModulNbr]. 1661 s_ChronoModuleInfo.d_TimingInterval; 1662 1663 switch (devpriv-> 1664 s_ModuleInfo[b_ModulNbr]. 1665 s_ChronoModuleInfo.b_TimingUnit) { 1666 case 0: 1667 d_Hour = d_Hour / (double)1000.0; 1668 1669 case 1: 1670 d_Hour = d_Hour / (double)1000.0; 1671 1672 case 2: 1673 d_Hour = d_Hour / (double)1000.0; 1674 1675 case 3: 1676 d_Hour = d_Hour / (double)60.0; 1677 1678 case 4: 1679 /**********************/ 1680 /* Calculate the hour */ 1681 /**********************/ 1682 1683 d_Hour = d_Hour / (double)60.0; 1684 *pul_Hour = (unsigned int) d_Hour; 1685 1686 /************************/ 1687 /* Calculate the minute */ 1688 /************************/ 1689 1690 d_Minute = d_Hour - *pul_Hour; 1691 d_Minute = d_Minute * 60; 1692 *pb_Minute = (unsigned char) d_Minute; 1693 1694 /************************/ 1695 /* Calculate the second */ 1696 /************************/ 1697 1698 d_Second = d_Minute - *pb_Minute; 1699 d_Second = d_Second * 60; 1700 *pb_Second = (unsigned char) d_Second; 1701 1702 /*****************************/ 1703 /* Calculate the mini second */ 1704 /*****************************/ 1705 1706 d_MilliSecond = d_Second - *pb_Second; 1707 d_MilliSecond = d_MilliSecond * 1000; 1708 *pui_MilliSecond = (unsigned int) d_MilliSecond; 1709 1710 /******************************/ 1711 /* Calculate the micro second */ 1712 /******************************/ 1713 1714 d_MicroSecond = 1715 d_MilliSecond - 1716 *pui_MilliSecond; 1717 d_MicroSecond = d_MicroSecond * 1000; 1718 *pui_MicroSecond = (unsigned int) d_MicroSecond; 1719 1720 /******************************/ 1721 /* Calculate the micro second */ 1722 /******************************/ 1723 1724 d_NanoSecond = 1725 d_MicroSecond - 1726 *pui_MicroSecond; 1727 d_NanoSecond = d_NanoSecond * 1000; 1728 *pui_NanoSecond = (unsigned int) d_NanoSecond; 1729 break; 1730 } 1731 1732 fpu_end(); 1733 } else { 1734 /*******************************/ 1735 /* Chronometer not initialised */ 1736 /*******************************/ 1737 DPRINTK("Chronometer not initialised\n"); 1738 i_ReturnValue = -4; 1739 } 1740 } else { 1741 /******************************************/ 1742 /* The module is not a Chronometer module */ 1743 /******************************************/ 1744 DPRINTK("The module is not a Chronometer module\n"); 1745 i_ReturnValue = -3; 1746 } 1747 } else { 1748 /***********************/ 1749 /* Module number error */ 1750 /***********************/ 1751 DPRINTK("Module number error\n"); 1752 i_ReturnValue = -2; 1753 } 1754 1755 return (i_ReturnValue); 1756} 1757 1758/* 1759+----------------------------------------------------------------------------+ 1760| Function Name : int i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device *dev,struct comedi_subdevice *s, 1761 struct comedi_insn *insn,unsigned int *data) | 1762+----------------------------------------------------------------------------+ 1763| Task : Sets the output witch has been passed with the | 1764| parameter b_Channel. Setting an output means setting an| 1765| output high. | 1766+----------------------------------------------------------------------------+ 1767| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 | 1768| unsigned char_ b_ModulNbr : Selected module number (0 to 3)| 1769| unsigned char_ b_OutputChannel : Selection from digital output | 1770| CR_CHAN() channel (0 to 2) | 1771| 0 : Channel H | 1772| 1 : Channel A | 1773| 2 : Channel B | 1774+----------------------------------------------------------------------------+ 1775| Output Parameters : - | 1776+----------------------------------------------------------------------------+ 1777| Return Value : 0: No error | 1778| -1: The handle parameter of the board is wrong | 1779| -2: Module selection wrong | 1780| -3: The module is not a Chronometer module | 1781| -4: The selected digital output is wrong | 1782| -5: Chronometer not initialised see function | 1783| "i_APCI1710_InitChrono" | 1784+----------------------------------------------------------------------------+ 1785*/ 1786 1787/* 1788+----------------------------------------------------------------------------+ 1789| Function Name : _INT_ i_APCI1710_SetChronoChlOff | 1790| (unsigned char_ b_BoardHandle, | 1791| unsigned char_ b_ModulNbr, | 1792| unsigned char_ b_OutputChannel) | 1793+----------------------------------------------------------------------------+ 1794| Task : Resets the output witch has been passed with the | 1795| parameter b_Channel. Resetting an output means setting | 1796| an output low. | 1797+----------------------------------------------------------------------------+ 1798| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 1799 data[0] : Chl ON, Chl OFF , Chl Read , Port Read 1800 1801| unsigned char_ b_ModulNbr CR_AREF : Selected module number (0 to 3)| 1802| unsigned char_ b_OutputChannel CR_CHAN : Selection from digital output | 1803| channel (0 to 2) | 1804| 0 : Channel H | 1805| 1 : Channel A | 1806| 2 : Channel B | 1807+----------------------------------------------------------------------------+ 1808| Output Parameters : - | 1809+----------------------------------------------------------------------------+ 1810| Return Value : 0: No error | 1811| -1: The handle parameter of the board is wrong | 1812| -2: Module selection wrong | 1813| -3: The module is not a Chronometer module | 1814| -4: The selected digital output is wrong | 1815| -5: Chronometer not initialised see function | 1816| "i_APCI1710_InitChrono" | 1817+----------------------------------------------------------------------------+ 1818*/ 1819 1820/* 1821+----------------------------------------------------------------------------+ 1822| Function Name : _INT_ i_APCI1710_ReadChronoChlValue | 1823| (unsigned char_ b_BoardHandle, | 1824| unsigned char_ b_ModulNbr, | 1825| unsigned char_ b_InputChannel, | 1826| unsigned char *_ pb_ChannelStatus) | 1827+----------------------------------------------------------------------------+ 1828| Task : Return the status from selected digital input | 1829| (b_InputChannel) from selected chronometer | 1830| module (b_ModulNbr). | 1831+----------------------------------------------------------------------------+ 1832| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 | 1833| unsigned char_ b_ModulNbr : Selected module number (0 to 3)| 1834| unsigned char_ b_InputChannel : Selection from digital input | 1835| channel (0 to 2) | 1836| CR_CHAN() 0 : Channel E | 1837| 1 : Channel F | 1838| 2 : Channel G | 1839+----------------------------------------------------------------------------+ 1840| Output Parameters : unsigned char *_ pb_ChannelStatus : Digital input channel status.| 1841| data[0] 0 : Channel is not active | 1842| 1 : Channel is active | 1843+----------------------------------------------------------------------------+ 1844| Return Value : 0: No error | 1845| -1: The handle parameter of the board is wrong | 1846| -2: Module selection wrong | 1847| -3: The module is not a Chronometer module | 1848| -4: The selected digital input is wrong | 1849| -5: Chronometer not initialised see function | 1850| "i_APCI1710_InitChrono" | 1851+----------------------------------------------------------------------------+ 1852*/ 1853 1854/* 1855+----------------------------------------------------------------------------+ 1856| Function Name : _INT_ i_APCI1710_ReadChronoPortValue | 1857| (unsigned char_ b_BoardHandle, | 1858| unsigned char_ b_ModulNbr, | 1859| unsigned char *_ pb_PortValue) | 1860+----------------------------------------------------------------------------+ 1861| Task : Return the status from digital inputs port from | 1862| selected (b_ModulNbr) chronometer module. | 1863+----------------------------------------------------------------------------+ 1864| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 | 1865| unsigned char_ b_ModulNbr : Selected module number (0 to 3)| 1866+----------------------------------------------------------------------------+ 1867| Output Parameters : unsigned char *_ pb_PortValue : Digital inputs port status. 1868| data[0] 1869+----------------------------------------------------------------------------+ 1870| Return Value : 0: No error | 1871| -1: The handle parameter of the board is wrong | 1872| -2: Module selection wrong | 1873| -3: The module is not a Chronometer module | 1874| -4: Chronometer not initialised see function | 1875| "i_APCI1710_InitChrono" | 1876+----------------------------------------------------------------------------+ 1877*/ 1878 1879int i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device * dev, 1880 struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data) 1881{ 1882 int i_ReturnValue = 0; 1883 unsigned char b_ModulNbr, b_OutputChannel, b_InputChannel, b_IOType; 1884 unsigned int dw_Status; 1885 unsigned char * pb_ChannelStatus; 1886 unsigned char * pb_PortValue; 1887 1888 b_ModulNbr = CR_AREF(insn->chanspec); 1889 i_ReturnValue = insn->n; 1890 b_IOType = (unsigned char) data[0]; 1891 1892 /**************************/ 1893 /* Test the module number */ 1894 /**************************/ 1895 1896 if (b_ModulNbr < 4) { 1897 /***********************/ 1898 /* Test if chronometer */ 1899 /***********************/ 1900 1901 if ((devpriv->s_BoardInfos. 1902 dw_MolduleConfiguration[b_ModulNbr] & 1903 0xFFFF0000UL) == APCI1710_CHRONOMETER) { 1904 /***********************************/ 1905 /* Test if chronometer initialised */ 1906 /***********************************/ 1907 1908 if (devpriv->s_ModuleInfo[b_ModulNbr]. 1909 s_ChronoModuleInfo.b_ChronoInit == 1) { 1910 /***********************************/ 1911 /* Test the digital output channel */ 1912 /***********************************/ 1913 switch (b_IOType) { 1914 1915 case APCI1710_CHRONO_SET_CHANNELOFF: 1916 1917 b_OutputChannel = 1918 (unsigned char) CR_CHAN(insn->chanspec); 1919 if (b_OutputChannel <= 2) { 1920 1921 outl(0, devpriv->s_BoardInfos. 1922 ui_Address + 20 + 1923 (b_OutputChannel * 4) + 1924 (64 * b_ModulNbr)); 1925 } // if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2)) 1926 else { 1927 /****************************************/ 1928 /* The selected digital output is wrong */ 1929 /****************************************/ 1930 1931 DPRINTK("The selected digital output is wrong\n"); 1932 i_ReturnValue = -4; 1933 1934 } // if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2)) 1935 1936 break; 1937 1938 case APCI1710_CHRONO_SET_CHANNELON: 1939 1940 b_OutputChannel = 1941 (unsigned char) CR_CHAN(insn->chanspec); 1942 if (b_OutputChannel <= 2) { 1943 1944 outl(1, devpriv->s_BoardInfos. 1945 ui_Address + 20 + 1946 (b_OutputChannel * 4) + 1947 (64 * b_ModulNbr)); 1948 } // if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2)) 1949 else { 1950 /****************************************/ 1951 /* The selected digital output is wrong */ 1952 /****************************************/ 1953 1954 DPRINTK("The selected digital output is wrong\n"); 1955 i_ReturnValue = -4; 1956 1957 } // if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2)) 1958 1959 break; 1960 1961 case APCI1710_CHRONO_READ_CHANNEL: 1962 /**********************************/ 1963 /* Test the digital input channel */ 1964 /**********************************/ 1965 pb_ChannelStatus = (unsigned char *) & data[0]; 1966 b_InputChannel = 1967 (unsigned char) CR_CHAN(insn->chanspec); 1968 1969 if (b_InputChannel <= 2) { 1970 1971 dw_Status = 1972 inl(devpriv-> 1973 s_BoardInfos. 1974 ui_Address + 12 + 1975 (64 * b_ModulNbr)); 1976 1977 *pb_ChannelStatus = 1978 (unsigned char) (((dw_Status >> 1979 b_InputChannel) 1980 & 1) ^ 1); 1981 } // if ((b_InputChannel >= 0) && (b_InputChannel <= 2)) 1982 else { 1983 /***************************************/ 1984 /* The selected digital input is wrong */ 1985 /***************************************/ 1986 1987 DPRINTK("The selected digital input is wrong\n"); 1988 i_ReturnValue = -4; 1989 } // if ((b_InputChannel >= 0) && (b_InputChannel <= 2)) 1990 1991 break; 1992 1993 case APCI1710_CHRONO_READ_PORT: 1994 1995 pb_PortValue = (unsigned char *) & data[0]; 1996 1997 dw_Status = 1998 inl(devpriv->s_BoardInfos. 1999 ui_Address + 12 + 2000 (64 * b_ModulNbr)); 2001 2002 *pb_PortValue = 2003 (unsigned char) ((dw_Status & 0x7) ^ 7); 2004 break; 2005 } 2006 } else { 2007 /*******************************/ 2008 /* Chronometer not initialised */ 2009 /*******************************/ 2010 2011 DPRINTK("Chronometer not initialised\n"); 2012 i_ReturnValue = -5; 2013 } 2014 } else { 2015 /******************************************/ 2016 /* The module is not a Chronometer module */ 2017 /******************************************/ 2018 2019 DPRINTK("The module is not a Chronometer module\n"); 2020 i_ReturnValue = -3; 2021 } 2022 } else { 2023 /***********************/ 2024 /* Module number error */ 2025 /***********************/ 2026 2027 DPRINTK("Module number error\n"); 2028 i_ReturnValue = -2; 2029 } 2030 2031 return (i_ReturnValue); 2032} 2033