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