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