addi_eeprom.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 Dieselstrasse 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 : ADDI DATA | Compiler : GCC | 33 | Modulname : addi_eeprom.c | Version : 2.96 | 34 +-------------------------------+---------------------------------------+ 35 | Project manager: Eric Stolz | Date : 02/12/2002 | 36 +-----------------------------------------------------------------------+ 37 | Description : ADDI EEPROM Module | 38 +-----------------------------------------------------------------------+ 39 | UPDATE'S | 40 +-----------------------------------------------------------------------+ 41 | Date | Author | Description of updates | 42 +----------+-----------+------------------------------------------------+ 43 | | | | 44 | | | | 45 +----------+-----------+------------------------------------------------+ 46*/ 47 48#define NVCMD_BEGIN_READ (0x7 << 5 ) // nvRam begin read command 49#define NVCMD_LOAD_LOW (0x4 << 5 ) // nvRam load low command 50#define NVCMD_LOAD_HIGH (0x5 << 5 ) // nvRam load high command 51#define EE76_CMD_LEN 13 // bits in instructions 52#define EE_READ 0x0180 // 01 1000 0000 read instruction 53 54#define EEPROM_DIGITALINPUT 0 55#define EEPROM_DIGITALOUTPUT 1 56#define EEPROM_ANALOGINPUT 2 57#define EEPROM_ANALOGOUTPUT 3 58#define EEPROM_TIMER 4 59#define EEPROM_WATCHDOG 5 60#define EEPROM_TIMER_WATCHDOG_COUNTER 10 61 62struct str_Functionality { 63 unsigned char b_Type; 64 unsigned short w_Address; 65}; 66 67typedef struct { 68 unsigned short w_HeaderSize; 69 unsigned char b_Nfunctions; 70 struct str_Functionality s_Functions[7]; 71} str_MainHeader; 72 73typedef struct { 74 unsigned short w_Nchannel; 75 unsigned char b_Interruptible; 76 unsigned short w_NinterruptLogic; 77} str_DigitalInputHeader; 78 79typedef struct { 80 unsigned short w_Nchannel; 81} str_DigitalOutputHeader; 82 83// used for timer as well as watchdog 84 85typedef struct { 86 unsigned short w_HeaderSize; 87 unsigned char b_Resolution; 88 unsigned char b_Mode; // in case of Watchdog it is functionality 89 unsigned short w_MinTiming; 90 unsigned char b_TimeBase; 91} str_TimerDetails; 92typedef struct { 93 94 unsigned short w_Ntimer; 95 str_TimerDetails s_TimerDetails[4]; // supports 4 timers 96} str_TimerMainHeader; 97 98typedef struct { 99 unsigned short w_Nchannel; 100 unsigned char b_Resolution; 101} str_AnalogOutputHeader; 102 103typedef struct { 104 unsigned short w_Nchannel; 105 unsigned short w_MinConvertTiming; 106 unsigned short w_MinDelayTiming; 107 unsigned char b_HasDma; 108 unsigned char b_Resolution; 109} str_AnalogInputHeader; 110 111 /*****************************************/ 112 /* Read Header Functions */ 113 /*****************************************/ 114 115int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, 116 char *pc_PCIChipInformation, struct comedi_device *dev); 117 118int i_EepromReadDigitalInputHeader(unsigned short w_PCIBoardEepromAddress, 119 char *pc_PCIChipInformation, unsigned short w_Address, 120 str_DigitalInputHeader * s_Header); 121 122int i_EepromReadDigitalOutputHeader(unsigned short w_PCIBoardEepromAddress, 123 char *pc_PCIChipInformation, unsigned short w_Address, 124 str_DigitalOutputHeader * s_Header); 125 126int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress, 127 char *pc_PCIChipInformation, unsigned short w_Address, 128 str_TimerMainHeader * s_Header); 129 130int i_EepromReadAnlogOutputHeader(unsigned short w_PCIBoardEepromAddress, 131 char *pc_PCIChipInformation, unsigned short w_Address, 132 str_AnalogOutputHeader * s_Header); 133 134int i_EepromReadAnlogInputHeader(unsigned short w_PCIBoardEepromAddress, 135 char *pc_PCIChipInformation, unsigned short w_Address, 136 str_AnalogInputHeader * s_Header); 137 138 /******************************************/ 139 /* Eeprom Specific Functions */ 140 /******************************************/ 141unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, 142 unsigned short w_EepromStartAddress); 143void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress); 144void v_EepromClock76(unsigned int dw_Address, unsigned int dw_RegisterValue); 145void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress); 146void v_EepromSendCommand76(unsigned int dw_Address, unsigned int dw_EepromCommand, 147 unsigned char b_DataLengthInBits); 148void v_EepromCs76Read(unsigned int dw_Address, unsigned short w_offset, unsigned short * pw_Value); 149 150/* 151+----------------------------------------------------------------------------+ 152| Function Name : unsigned short w_EepromReadWord | 153| (unsigned short w_PCIBoardEepromAddress, | 154| char * pc_PCIChipInformation, | 155| unsigned short w_EepromStartAddress) | 156+----------------------------------------------------------------------------+ 157| Task : Read from eepromn a word | 158+----------------------------------------------------------------------------+ 159| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | 160| | 161| char *pc_PCIChipInformation : PCI Chip Type. | 162| | 163| unsigned short w_EepromStartAddress : Selected eeprom address | 164+----------------------------------------------------------------------------+ 165| Output Parameters : - | 166+----------------------------------------------------------------------------+ 167| Return Value : Read word value from eeprom | 168+----------------------------------------------------------------------------+ 169*/ 170 171unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, 172 unsigned short w_EepromStartAddress) 173{ 174 175 unsigned char b_Counter = 0; 176 177 unsigned char b_ReadByte = 0; 178 179 unsigned char b_ReadLowByte = 0; 180 181 unsigned char b_ReadHighByte = 0; 182 183 unsigned char b_SelectedAddressLow = 0; 184 185 unsigned char b_SelectedAddressHigh = 0; 186 187 unsigned short w_ReadWord = 0; 188 189 /**************************/ 190 191 /* Test the PCI chip type */ 192 193 /**************************/ 194 195 if ((!strcmp(pc_PCIChipInformation, "S5920")) || 196 (!strcmp(pc_PCIChipInformation, "S5933"))) 197 { 198 199 for (b_Counter = 0; b_Counter < 2; b_Counter++) 200 { 201 202 b_SelectedAddressLow = (w_EepromStartAddress + b_Counter) % 256; //Read the low 8 bit part 203 204 b_SelectedAddressHigh = (w_EepromStartAddress + b_Counter) / 256; //Read the high 8 bit part 205 206 /************************************/ 207 208 /* Select the load low address mode */ 209 210 /************************************/ 211 212 outb(NVCMD_LOAD_LOW, w_PCIBoardEepromAddress + 0x3F); 213 214 /****************/ 215 216 /* Wait on busy */ 217 218 /****************/ 219 220 v_EepromWaitBusy(w_PCIBoardEepromAddress); 221 222 /************************/ 223 224 /* Load the low address */ 225 226 /************************/ 227 228 outb(b_SelectedAddressLow, 229 w_PCIBoardEepromAddress + 0x3E); 230 231 /****************/ 232 233 /* Wait on busy */ 234 235 /****************/ 236 237 v_EepromWaitBusy(w_PCIBoardEepromAddress); 238 239 /*************************************/ 240 241 /* Select the load high address mode */ 242 243 /*************************************/ 244 245 outb(NVCMD_LOAD_HIGH, w_PCIBoardEepromAddress + 0x3F); 246 247 /****************/ 248 249 /* Wait on busy */ 250 251 /****************/ 252 253 v_EepromWaitBusy(w_PCIBoardEepromAddress); 254 255 /*************************/ 256 257 /* Load the high address */ 258 259 /*************************/ 260 261 outb(b_SelectedAddressHigh, 262 w_PCIBoardEepromAddress + 0x3E); 263 264 /****************/ 265 266 /* Wait on busy */ 267 268 /****************/ 269 270 v_EepromWaitBusy(w_PCIBoardEepromAddress); 271 272 /************************/ 273 274 /* Select the READ mode */ 275 276 /************************/ 277 278 outb(NVCMD_BEGIN_READ, w_PCIBoardEepromAddress + 0x3F); 279 280 /****************/ 281 282 /* Wait on busy */ 283 284 /****************/ 285 286 v_EepromWaitBusy(w_PCIBoardEepromAddress); 287 288 /*****************************/ 289 290 /* Read data into the EEPROM */ 291 292 /*****************************/ 293 294 b_ReadByte = inb(w_PCIBoardEepromAddress + 0x3E); 295 296 /****************/ 297 298 /* Wait on busy */ 299 300 /****************/ 301 302 v_EepromWaitBusy(w_PCIBoardEepromAddress); 303 304 /*********************************/ 305 306 /* Select the upper address part */ 307 308 /*********************************/ 309 310 if (b_Counter == 0) 311 { 312 313 b_ReadLowByte = b_ReadByte; 314 315 } // if(b_Counter==0) 316 317 else 318 { 319 320 b_ReadHighByte = b_ReadByte; 321 322 } // if(b_Counter==0) 323 324 } // for (b_Counter=0; b_Counter<2; b_Counter++) 325 326 w_ReadWord = (b_ReadLowByte | (((unsigned short) b_ReadHighByte) * 256)); 327 328 } // end of if ((!strcmp(pc_PCIChipInformation, "S5920")) || (!strcmp(pc_PCIChipInformation, "S5933"))) 329 330 if (!strcmp(pc_PCIChipInformation, "93C76")) 331 { 332 333 /*************************************/ 334 335 /* Read 16 bit from the EEPROM 93C76 */ 336 337 /*************************************/ 338 339 v_EepromCs76Read(w_PCIBoardEepromAddress, w_EepromStartAddress, 340 &w_ReadWord); 341 342 } 343 344 return (w_ReadWord); 345 346} 347 348/* 349 350+----------------------------------------------------------------------------+ 351 352| Function Name : void v_EepromWaitBusy | 353 354| (unsigned short w_PCIBoardEepromAddress) | 355 356+----------------------------------------------------------------------------+ 357 358| Task : Wait the busy flag from PCI controller | 359 360+----------------------------------------------------------------------------+ 361 362| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom base address | 363 364+----------------------------------------------------------------------------+ 365 366| Output Parameters : - | 367 368+----------------------------------------------------------------------------+ 369 370| Return Value : - | 371 372+----------------------------------------------------------------------------+ 373 374*/ 375 376void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress) 377{ 378 379 unsigned char b_EepromBusy = 0; 380 381 do 382 { 383 384 /*************/ 385 386 /* IMPORTANT */ 387 388 /*************/ 389 390 /************************************************************************/ 391 392 /* An error has been written in the AMCC 5933 book at the page B-13 */ 393 394 /* Ex: if you read a byte and look for the busy statusEEPROM=0x80 and */ 395 396 /* the operator register is AMCC_OP_REG_MCSR+3 */ 397 398 /* unsigned short read EEPROM=0x8000 andAMCC_OP_REG_MCSR+2 */ 399 400 /* unsigned int read EEPROM=0x80000000 and AMCC_OP_REG_MCSR */ 401 402 /************************************************************************/ 403 404 b_EepromBusy = inb(w_PCIBoardEepromAddress + 0x3F); 405 b_EepromBusy = b_EepromBusy & 0x80; 406 407 } 408 while (b_EepromBusy == 0x80); 409 410} 411 412/* 413 414+---------------------------------------------------------------------------------+ 415 416| Function Name : void v_EepromClock76(unsigned int dw_Address, | 417 418| unsigned int dw_RegisterValue) | 419 420+---------------------------------------------------------------------------------+ 421 422| Task : This function sends the clocking sequence to the EEPROM. | 423 424+---------------------------------------------------------------------------------+ 425 426| Input Parameters : unsigned int dw_Address : PCI eeprom base address | 427 428| unsigned int dw_RegisterValue : PCI eeprom register value to write.| 429 430+---------------------------------------------------------------------------------+ 431 432| Output Parameters : - | 433 434+---------------------------------------------------------------------------------+ 435 436| Return Value : - | 437 438+---------------------------------------------------------------------------------+ 439 440*/ 441 442void v_EepromClock76(unsigned int dw_Address, unsigned int dw_RegisterValue) 443{ 444 445 /************************/ 446 447 /* Set EEPROM clock Low */ 448 449 /************************/ 450 451 outl(dw_RegisterValue & 0x6, dw_Address); 452 453 /***************/ 454 455 /* Wait 0.1 ms */ 456 457 /***************/ 458 459 udelay(100); 460 461 /*************************/ 462 463 /* Set EEPROM clock High */ 464 465 /*************************/ 466 467 outl(dw_RegisterValue | 0x1, dw_Address); 468 469 /***************/ 470 471 /* Wait 0.1 ms */ 472 473 /***************/ 474 475 udelay(100); 476 477} 478 479/* 480 481+---------------------------------------------------------------------------------+ 482 483| Function Name : void v_EepromSendCommand76(unsigned int dw_Address, | 484 485| unsigned int dw_EepromCommand, | 486 487| unsigned char b_DataLengthInBits) | 488 489+---------------------------------------------------------------------------------+ 490 491| Task : This function sends a Command to the EEPROM 93C76. | 492 493+---------------------------------------------------------------------------------+ 494 495| Input Parameters : unsigned int dw_Address : PCI eeprom base address | 496 497| unsigned int dw_EepromCommand : PCI eeprom command to write. | 498 499| unsigned char b_DataLengthInBits : PCI eeprom command data length. | 500 501+---------------------------------------------------------------------------------+ 502 503| Output Parameters : - | 504 505+---------------------------------------------------------------------------------+ 506 507| Return Value : - | 508 509+---------------------------------------------------------------------------------+ 510 511*/ 512 513void v_EepromSendCommand76(unsigned int dw_Address, unsigned int dw_EepromCommand, 514 unsigned char b_DataLengthInBits) 515{ 516 517 char c_BitPos = 0; 518 519 unsigned int dw_RegisterValue = 0; 520 521 /*****************************/ 522 523 /* Enable EEPROM Chip Select */ 524 525 /*****************************/ 526 527 dw_RegisterValue = 0x2; 528 529 /********************************************************************/ 530 531 /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */ 532 533 /********************************************************************/ 534 535 outl(dw_RegisterValue, dw_Address); 536 537 /***************/ 538 539 /* Wait 0.1 ms */ 540 541 /***************/ 542 543 udelay(100); 544 545 /*******************************************/ 546 547 /* Send EEPROM command - one bit at a time */ 548 549 /*******************************************/ 550 551 for (c_BitPos = (b_DataLengthInBits - 1); c_BitPos >= 0; c_BitPos--) 552 { 553 554 /**********************************/ 555 556 /* Check if current bit is 0 or 1 */ 557 558 /**********************************/ 559 560 if (dw_EepromCommand & (1 << c_BitPos)) 561 { 562 563 /***********/ 564 565 /* Write 1 */ 566 567 /***********/ 568 569 dw_RegisterValue = dw_RegisterValue | 0x4; 570 571 } 572 573 else 574 { 575 576 /***********/ 577 578 /* Write 0 */ 579 580 /***********/ 581 582 dw_RegisterValue = dw_RegisterValue & 0x3; 583 584 } 585 586 /*********************/ 587 588 /* Write the command */ 589 590 /*********************/ 591 592 outl(dw_RegisterValue, dw_Address); 593 594 /***************/ 595 596 /* Wait 0.1 ms */ 597 598 /***************/ 599 600 udelay(100); 601 602 /****************************/ 603 604 /* Trigger the EEPROM clock */ 605 606 /****************************/ 607 608 v_EepromClock76(dw_Address, dw_RegisterValue); 609 610 } 611 612} 613 614/* 615 616+---------------------------------------------------------------------------------+ 617 618| Function Name : void v_EepromCs76Read(unsigned int dw_Address, | 619 620| unsigned short w_offset, | 621 622| unsigned short * pw_Value) | 623 624+---------------------------------------------------------------------------------+ 625 626| Task : This function read a value from the EEPROM 93C76. | 627 628+---------------------------------------------------------------------------------+ 629 630| Input Parameters : unsigned int dw_Address : PCI eeprom base address | 631 632| unsigned short w_offset : Offset of the adress to read | 633 634| unsigned short * pw_Value : PCI eeprom 16 bit read value. | 635 636+---------------------------------------------------------------------------------+ 637 638| Output Parameters : - | 639 640+---------------------------------------------------------------------------------+ 641 642| Return Value : - | 643 644+---------------------------------------------------------------------------------+ 645 646*/ 647 648void v_EepromCs76Read(unsigned int dw_Address, unsigned short w_offset, unsigned short * pw_Value) 649{ 650 651 char c_BitPos = 0; 652 653 unsigned int dw_RegisterValue = 0; 654 655 unsigned int dw_RegisterValueRead = 0; 656 657 /*************************************************/ 658 659 /* Send EEPROM read command and offset to EEPROM */ 660 661 /*************************************************/ 662 663 v_EepromSendCommand76(dw_Address, (EE_READ << 4) | (w_offset / 2), 664 EE76_CMD_LEN); 665 666 /*******************************/ 667 668 /* Get the last register value */ 669 670 /*******************************/ 671 672 dw_RegisterValue = (((w_offset / 2) & 0x1) << 2) | 0x2; 673 674 /*****************************/ 675 676 /* Set the 16-bit value of 0 */ 677 678 /*****************************/ 679 680 *pw_Value = 0; 681 682 /************************/ 683 684 /* Get the 16-bit value */ 685 686 /************************/ 687 688 for (c_BitPos = 0; c_BitPos < 16; c_BitPos++) 689 { 690 691 /****************************/ 692 693 /* Trigger the EEPROM clock */ 694 695 /****************************/ 696 697 v_EepromClock76(dw_Address, dw_RegisterValue); 698 699 /**********************/ 700 701 /* Get the result bit */ 702 703 /**********************/ 704 705 dw_RegisterValueRead = inl(dw_Address); 706 707 /***************/ 708 709 /* Wait 0.1 ms */ 710 711 /***************/ 712 713 udelay(100); 714 715 /***************************************/ 716 717 /* Get bit value and shift into result */ 718 719 /***************************************/ 720 721 if (dw_RegisterValueRead & 0x8) 722 { 723 724 /**********/ 725 726 /* Read 1 */ 727 728 /**********/ 729 730 *pw_Value = (*pw_Value << 1) | 0x1; 731 732 } 733 734 else 735 { 736 737 /**********/ 738 739 /* Read 0 */ 740 741 /**********/ 742 743 *pw_Value = (*pw_Value << 1); 744 745 } 746 747 } 748 749 /*************************/ 750 751 /* Clear all EEPROM bits */ 752 753 /*************************/ 754 755 dw_RegisterValue = 0x0; 756 757 /********************************************************************/ 758 759 /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */ 760 761 /********************************************************************/ 762 763 outl(dw_RegisterValue, dw_Address); 764 765 /***************/ 766 767 /* Wait 0.1 ms */ 768 769 /***************/ 770 771 udelay(100); 772 773} 774 775 /******************************************/ 776 /* EEPROM HEADER READ FUNCTIONS */ 777 /******************************************/ 778 779/* 780+----------------------------------------------------------------------------+ 781| Function Name : int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, | 782| char * pc_PCIChipInformation,struct comedi_device *dev) | 783+----------------------------------------------------------------------------+ 784| Task : Read from eeprom Main Header | 785+----------------------------------------------------------------------------+ 786| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | 787| | 788| char *pc_PCIChipInformation : PCI Chip Type. | 789| | 790| struct comedi_device *dev : comedi device structure | 791| pointer | 792+----------------------------------------------------------------------------+ 793| Output Parameters : - | 794+----------------------------------------------------------------------------+ 795| Return Value : 0 | 796+----------------------------------------------------------------------------+ 797*/ 798 799int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, 800 char *pc_PCIChipInformation, struct comedi_device *dev) 801{ 802 unsigned short w_Temp, i, w_Count = 0; 803 unsigned int ui_Temp; 804 str_MainHeader s_MainHeader; 805 str_DigitalInputHeader s_DigitalInputHeader; 806 str_DigitalOutputHeader s_DigitalOutputHeader; 807 //str_TimerMainHeader s_TimerMainHeader,s_WatchdogMainHeader; 808 str_AnalogOutputHeader s_AnalogOutputHeader; 809 str_AnalogInputHeader s_AnalogInputHeader; 810 811 // Read size 812 s_MainHeader.w_HeaderSize = 813 w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 814 0x100 + 8); 815 816 // Read nbr of functionality 817 w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, 818 pc_PCIChipInformation, 0x100 + 10); 819 s_MainHeader.b_Nfunctions = (unsigned char) w_Temp & 0x00FF; 820 821 // Read functionality details 822 for (i = 0; i < s_MainHeader.b_Nfunctions; i++) { 823 // Read Type 824 w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, 825 pc_PCIChipInformation, 0x100 + 12 + w_Count); 826 s_MainHeader.s_Functions[i].b_Type = (unsigned char) w_Temp & 0x3F; 827 w_Count = w_Count + 2; 828 //Read Address 829 s_MainHeader.s_Functions[i].w_Address = 830 w_EepromReadWord(w_PCIBoardEepromAddress, 831 pc_PCIChipInformation, 0x100 + 12 + w_Count); 832 w_Count = w_Count + 2; 833 } 834 835 // Display main header info 836 for (i = 0; i < s_MainHeader.b_Nfunctions; i++) { 837 838 switch (s_MainHeader.s_Functions[i].b_Type) { 839 case EEPROM_DIGITALINPUT: 840 i_EepromReadDigitalInputHeader(w_PCIBoardEepromAddress, 841 pc_PCIChipInformation, 842 s_MainHeader.s_Functions[i].w_Address, 843 &s_DigitalInputHeader); 844 this_board->i_NbrDiChannel = 845 s_DigitalInputHeader.w_Nchannel; 846 break; 847 848 case EEPROM_DIGITALOUTPUT: 849 i_EepromReadDigitalOutputHeader(w_PCIBoardEepromAddress, 850 pc_PCIChipInformation, 851 s_MainHeader.s_Functions[i].w_Address, 852 &s_DigitalOutputHeader); 853 this_board->i_NbrDoChannel = 854 s_DigitalOutputHeader.w_Nchannel; 855 ui_Temp = 0xffffffff; 856 this_board->i_DoMaxdata = 857 ui_Temp >> (32 - this_board->i_NbrDoChannel); 858 break; 859 860 case EEPROM_ANALOGINPUT: 861 i_EepromReadAnlogInputHeader(w_PCIBoardEepromAddress, 862 pc_PCIChipInformation, 863 s_MainHeader.s_Functions[i].w_Address, 864 &s_AnalogInputHeader); 865 if (!(strcmp(this_board->pc_DriverName, "apci3200"))) 866 this_board->i_NbrAiChannel = 867 s_AnalogInputHeader.w_Nchannel * 4; 868 else 869 this_board->i_NbrAiChannel = 870 s_AnalogInputHeader.w_Nchannel; 871 this_board->i_Dma = s_AnalogInputHeader.b_HasDma; 872 this_board->ui_MinAcquisitiontimeNs = 873 (unsigned int) s_AnalogInputHeader.w_MinConvertTiming * 874 1000; 875 this_board->ui_MinDelaytimeNs = 876 (unsigned int) s_AnalogInputHeader.w_MinDelayTiming * 877 1000; 878 ui_Temp = 0xffff; 879 this_board->i_AiMaxdata = 880 ui_Temp >> (16 - 881 s_AnalogInputHeader.b_Resolution); 882 break; 883 884 case EEPROM_ANALOGOUTPUT: 885 i_EepromReadAnlogOutputHeader(w_PCIBoardEepromAddress, 886 pc_PCIChipInformation, 887 s_MainHeader.s_Functions[i].w_Address, 888 &s_AnalogOutputHeader); 889 this_board->i_NbrAoChannel = 890 s_AnalogOutputHeader.w_Nchannel; 891 ui_Temp = 0xffff; 892 this_board->i_AoMaxdata = 893 ui_Temp >> (16 - 894 s_AnalogOutputHeader.b_Resolution); 895 break; 896 897 case EEPROM_TIMER: 898 this_board->i_Timer = 1; //Timer subdevice present 899 break; 900 901 case EEPROM_WATCHDOG: 902 this_board->i_Timer = 1; //Timer subdevice present 903 break; 904 905 case EEPROM_TIMER_WATCHDOG_COUNTER: 906 this_board->i_Timer = 1; //Timer subdevice present 907 } 908 } 909 910 return 0; 911} 912 913/* 914+----------------------------------------------------------------------------+ 915| Function Name : int i_EepromReadDigitalInputHeader(unsigned short | 916| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, | 917| unsigned short w_Address,str_DigitalInputHeader *s_Header) | 918| | 919+----------------------------------------------------------------------------+ 920| Task : Read Digital Input Header | 921+----------------------------------------------------------------------------+ 922| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | 923| | 924| char *pc_PCIChipInformation : PCI Chip Type. | 925| | 926| str_DigitalInputHeader *s_Header: Digita Input Header | 927| Pointer | 928+----------------------------------------------------------------------------+ 929| Output Parameters : - | 930+----------------------------------------------------------------------------+ 931| Return Value : 0 | 932+----------------------------------------------------------------------------+ 933*/ 934int i_EepromReadDigitalInputHeader(unsigned short w_PCIBoardEepromAddress, 935 char *pc_PCIChipInformation, unsigned short w_Address, 936 str_DigitalInputHeader * s_Header) 937{ 938 unsigned short w_Temp; 939 940 // read nbr of channels 941 s_Header->w_Nchannel = 942 w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 943 0x100 + w_Address + 6); 944 945 // interruptible or not 946 w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, 947 pc_PCIChipInformation, 0x100 + w_Address + 8); 948 s_Header->b_Interruptible = (unsigned char) (w_Temp >> 7) & 0x01; 949 950// How many interruptible logic 951 s_Header->w_NinterruptLogic = 952 w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 953 0x100 + w_Address + 10); 954 955 return 0; 956} 957 958/* 959+----------------------------------------------------------------------------+ 960| Function Name : int i_EepromReadDigitalOutputHeader(unsigned short | 961| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, | 962| unsigned short w_Address,str_DigitalOutputHeader *s_Header) | 963| | 964+----------------------------------------------------------------------------+ 965| Task : Read Digital Output Header | 966+----------------------------------------------------------------------------+ 967| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | 968| | 969| char *pc_PCIChipInformation : PCI Chip Type. | 970| | 971| str_DigitalOutputHeader *s_Header: Digital Output Header| 972| Pointer | 973+----------------------------------------------------------------------------+ 974| Output Parameters : - | 975+----------------------------------------------------------------------------+ 976| Return Value : 0 | 977+----------------------------------------------------------------------------+ 978*/ 979int i_EepromReadDigitalOutputHeader(unsigned short w_PCIBoardEepromAddress, 980 char *pc_PCIChipInformation, unsigned short w_Address, 981 str_DigitalOutputHeader * s_Header) 982{ 983// Read Nbr channels 984 s_Header->w_Nchannel = 985 w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 986 0x100 + w_Address + 6); 987 return 0; 988} 989 990/* 991+----------------------------------------------------------------------------+ 992| Function Name : int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress, | 993| char *pc_PCIChipInformation,WORD w_Address, | 994| str_TimerMainHeader *s_Header) | 995+----------------------------------------------------------------------------+ 996| Task : Read Timer or Watchdog Header | 997+----------------------------------------------------------------------------+ 998| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | 999| | 1000| char *pc_PCIChipInformation : PCI Chip Type. | 1001| | 1002| str_TimerMainHeader *s_Header: Timer Header | 1003| Pointer | 1004+----------------------------------------------------------------------------+ 1005| Output Parameters : - | 1006+----------------------------------------------------------------------------+ 1007| Return Value : 0 | 1008+----------------------------------------------------------------------------+ 1009*/ 1010int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress, 1011 char *pc_PCIChipInformation, unsigned short w_Address, 1012 str_TimerMainHeader * s_Header) 1013{ 1014 1015 unsigned short i, w_Size = 0, w_Temp; 1016 1017//Read No of Timer 1018 s_Header->w_Ntimer = 1019 w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 1020 0x100 + w_Address + 6); 1021//Read header size 1022 1023 for (i = 0; i < s_Header->w_Ntimer; i++) { 1024 s_Header->s_TimerDetails[i].w_HeaderSize = 1025 w_EepromReadWord(w_PCIBoardEepromAddress, 1026 pc_PCIChipInformation, 1027 0x100 + w_Address + 8 + w_Size + 0); 1028 w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, 1029 pc_PCIChipInformation, 1030 0x100 + w_Address + 8 + w_Size + 2); 1031 1032 //Read Resolution 1033 s_Header->s_TimerDetails[i].b_Resolution = 1034 (unsigned char) (w_Temp >> 10) & 0x3F; 1035 1036 //Read Mode 1037 s_Header->s_TimerDetails[i].b_Mode = 1038 (unsigned char) (w_Temp >> 4) & 0x3F; 1039 1040 w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, 1041 pc_PCIChipInformation, 1042 0x100 + w_Address + 8 + w_Size + 4); 1043 1044 //Read MinTiming 1045 s_Header->s_TimerDetails[i].w_MinTiming = (w_Temp >> 6) & 0x3FF; 1046 1047 //Read Timebase 1048 s_Header->s_TimerDetails[i].b_TimeBase = (unsigned char) (w_Temp) & 0x3F; 1049 w_Size += s_Header->s_TimerDetails[i].w_HeaderSize; 1050 } 1051 1052 return 0; 1053} 1054 1055/* 1056+----------------------------------------------------------------------------+ 1057| Function Name : int i_EepromReadAnlogOutputHeader(unsigned short | 1058| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, | 1059| unsigned short w_Address,str_AnalogOutputHeader *s_Header) | 1060+----------------------------------------------------------------------------+ 1061| Task : Read Nalog Output Header | 1062+----------------------------------------------------------------------------+ 1063| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | 1064| | 1065| char *pc_PCIChipInformation : PCI Chip Type. | 1066| | 1067| str_AnalogOutputHeader *s_Header:Anlog Output Header | 1068| Pointer | 1069+----------------------------------------------------------------------------+ 1070| Output Parameters : - | 1071+----------------------------------------------------------------------------+ 1072| Return Value : 0 | 1073+----------------------------------------------------------------------------+ 1074*/ 1075 1076int i_EepromReadAnlogOutputHeader(unsigned short w_PCIBoardEepromAddress, 1077 char *pc_PCIChipInformation, unsigned short w_Address, 1078 str_AnalogOutputHeader * s_Header) 1079{ 1080 unsigned short w_Temp; 1081 // No of channels for 1st hard component 1082 w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, 1083 pc_PCIChipInformation, 0x100 + w_Address + 10); 1084 s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF; 1085 // Resolution for 1st hard component 1086 w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, 1087 pc_PCIChipInformation, 0x100 + w_Address + 16); 1088 s_Header->b_Resolution = (unsigned char) (w_Temp >> 8) & 0xFF; 1089 return 0; 1090} 1091 1092/* 1093+----------------------------------------------------------------------------+ 1094| Function Name : int i_EepromReadAnlogInputHeader(unsigned short | 1095| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, | 1096| unsigned short w_Address,str_AnalogInputHeader *s_Header) | 1097+----------------------------------------------------------------------------+ 1098| Task : Read Nalog Output Header | 1099+----------------------------------------------------------------------------+ 1100| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | 1101| | 1102| char *pc_PCIChipInformation : PCI Chip Type. | 1103| | 1104| str_AnalogInputHeader *s_Header:Anlog Input Header | 1105| Pointer | 1106+----------------------------------------------------------------------------+ 1107| Output Parameters : - | 1108+----------------------------------------------------------------------------+ 1109| Return Value : 0 | 1110+----------------------------------------------------------------------------+ 1111*/ 1112 1113// Reads only for ONE hardware component 1114int i_EepromReadAnlogInputHeader(unsigned short w_PCIBoardEepromAddress, 1115 char *pc_PCIChipInformation, unsigned short w_Address, 1116 str_AnalogInputHeader * s_Header) 1117{ 1118 unsigned short w_Temp, w_Offset; 1119 w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, 1120 pc_PCIChipInformation, 0x100 + w_Address + 10); 1121 s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF; 1122 s_Header->w_MinConvertTiming = 1123 w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 1124 0x100 + w_Address + 16); 1125 s_Header->w_MinDelayTiming = 1126 w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 1127 0x100 + w_Address + 30); 1128 w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, 1129 pc_PCIChipInformation, 0x100 + w_Address + 20); 1130 s_Header->b_HasDma = (w_Temp >> 13) & 0x01; // whether dma present or not 1131 1132 w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + w_Address + 72); // reading Y 1133 w_Temp = w_Temp & 0x00FF; 1134 if (w_Temp) //Y>0 1135 { 1136 w_Offset = 74 + (2 * w_Temp) + (10 * (1 + (w_Temp / 16))); // offset of first analog input single header 1137 w_Offset = w_Offset + 2; // resolution 1138 } else //Y=0 1139 { 1140 w_Offset = 74; 1141 w_Offset = w_Offset + 2; // resolution 1142 } 1143 1144// read Resolution 1145 w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, 1146 pc_PCIChipInformation, 0x100 + w_Address + w_Offset); 1147 s_Header->b_Resolution = w_Temp & 0x001F; // last 5 bits 1148 1149 return 0; 1150} 1151