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