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