/** @verbatim Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. ADDI-DATA GmbH Dieselstrasse 3 D-77833 Ottersweier Tel: +19(0)7223/9493-0 Fax: +49(0)7223/9493-92 http://www.addi-data-com info@addi-data.com This 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. This 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. You 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 You shoud also find the complete GPL in the COPYING file accompanying this source code. @endverbatim */ /* +-----------------------------------------------------------------------+ | (C) ADDI-DATA GmbH Dieselstrasse 3 D-77833 Ottersweier | +-----------------------------------------------------------------------+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com | | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com | +-----------------------------------------------------------------------+ | Project : ADDI DATA | Compiler : GCC | | Modulname : addi_eeprom.c | Version : 2.96 | +-------------------------------+---------------------------------------+ | Project manager: Eric Stolz | Date : 02/12/2002 | +-----------------------------------------------------------------------+ | Description : ADDI EEPROM Module | +-----------------------------------------------------------------------+ | UPDATE'S | +-----------------------------------------------------------------------+ | Date | Author | Description of updates | +----------+-----------+------------------------------------------------+ | | | | | | | | +----------+-----------+------------------------------------------------+ */ #define NVCMD_BEGIN_READ (0x7 << 5) /* nvRam begin read command */ #define NVCMD_LOAD_LOW (0x4 << 5) /* nvRam load low command */ #define NVCMD_LOAD_HIGH (0x5 << 5) /* nvRam load high command */ #define EE76_CMD_LEN 13 /* bits in instructions */ #define EE_READ 0x0180 /* 01 1000 0000 read instruction */ #define EEPROM_DIGITALINPUT 0 #define EEPROM_DIGITALOUTPUT 1 #define EEPROM_ANALOGINPUT 2 #define EEPROM_ANALOGOUTPUT 3 #define EEPROM_TIMER 4 #define EEPROM_WATCHDOG 5 #define EEPROM_TIMER_WATCHDOG_COUNTER 10 struct str_Functionality { unsigned char b_Type; unsigned short w_Address; }; struct str_MainHeader { unsigned short w_HeaderSize; unsigned char b_Nfunctions; struct str_Functionality s_Functions[7]; }; struct str_DigitalInputHeader { unsigned short w_Nchannel; unsigned char b_Interruptible; unsigned short w_NinterruptLogic; }; struct str_DigitalOutputHeader { unsigned short w_Nchannel; }; /* used for timer as well as watchdog */ struct str_TimerDetails { unsigned short w_HeaderSize; unsigned char b_Resolution; unsigned char b_Mode; /* in case of Watchdog it is functionality */ unsigned short w_MinTiming; unsigned char b_TimeBase; }; struct str_TimerMainHeader { unsigned short w_Ntimer; struct str_TimerDetails s_TimerDetails[4]; /* supports 4 timers */ }; typedef struct { unsigned short w_Nchannel; unsigned char b_Resolution; } str_AnalogOutputHeader; struct str_AnalogInputHeader { unsigned short w_Nchannel; unsigned short w_MinConvertTiming; unsigned short w_MinDelayTiming; unsigned char b_HasDma; unsigned char b_Resolution; }; /*****************************************/ /* Read Header Functions */ /*****************************************/ int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, struct comedi_device *dev); int i_EepromReadDigitalInputHeader(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, unsigned short w_Address, struct str_DigitalInputHeader *s_Header); int i_EepromReadDigitalOutputHeader(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, unsigned short w_Address, struct str_DigitalOutputHeader *s_Header); int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, unsigned short w_Address, struct str_TimerMainHeader *s_Header); int i_EepromReadAnlogOutputHeader(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, unsigned short w_Address, str_AnalogOutputHeader *s_Header); int i_EepromReadAnlogInputHeader(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, unsigned short w_Address, struct str_AnalogInputHeader *s_Header); /******************************************/ /* Eeprom Specific Functions */ /******************************************/ unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, unsigned short w_EepromStartAddress); void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress); void v_EepromClock76(unsigned int dw_Address, unsigned int dw_RegisterValue); void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress); void v_EepromSendCommand76(unsigned int dw_Address, unsigned int dw_EepromCommand, unsigned char b_DataLengthInBits); void v_EepromCs76Read(unsigned int dw_Address, unsigned short w_offset, unsigned short *pw_Value); /* +----------------------------------------------------------------------------+ | Function Name : unsigned short w_EepromReadWord | | (unsigned short w_PCIBoardEepromAddress, | | char * pc_PCIChipInformation, | | unsigned short w_EepromStartAddress) | +----------------------------------------------------------------------------+ | Task : Read from eepromn a word | +----------------------------------------------------------------------------+ | Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | | | | char *pc_PCIChipInformation : PCI Chip Type. | | | | unsigned short w_EepromStartAddress : Selected eeprom address | +----------------------------------------------------------------------------+ | Output Parameters : - | +----------------------------------------------------------------------------+ | Return Value : Read word value from eeprom | +----------------------------------------------------------------------------+ */ unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, unsigned short w_EepromStartAddress) { unsigned char b_Counter = 0; unsigned char b_ReadByte = 0; unsigned char b_ReadLowByte = 0; unsigned char b_ReadHighByte = 0; unsigned char b_SelectedAddressLow = 0; unsigned char b_SelectedAddressHigh = 0; unsigned short w_ReadWord = 0; /**************************/ /* Test the PCI chip type */ /**************************/ if ((!strcmp(pc_PCIChipInformation, "S5920")) || (!strcmp(pc_PCIChipInformation, "S5933"))) { for (b_Counter = 0; b_Counter < 2; b_Counter++) { b_SelectedAddressLow = (w_EepromStartAddress + b_Counter) % 256; /* Read the low 8 bit part */ b_SelectedAddressHigh = (w_EepromStartAddress + b_Counter) / 256; /* Read the high 8 bit part */ /************************************/ /* Select the load low address mode */ /************************************/ outb(NVCMD_LOAD_LOW, w_PCIBoardEepromAddress + 0x3F); /****************/ /* Wait on busy */ /****************/ v_EepromWaitBusy(w_PCIBoardEepromAddress); /************************/ /* Load the low address */ /************************/ outb(b_SelectedAddressLow, w_PCIBoardEepromAddress + 0x3E); /****************/ /* Wait on busy */ /****************/ v_EepromWaitBusy(w_PCIBoardEepromAddress); /*************************************/ /* Select the load high address mode */ /*************************************/ outb(NVCMD_LOAD_HIGH, w_PCIBoardEepromAddress + 0x3F); /****************/ /* Wait on busy */ /****************/ v_EepromWaitBusy(w_PCIBoardEepromAddress); /*************************/ /* Load the high address */ /*************************/ outb(b_SelectedAddressHigh, w_PCIBoardEepromAddress + 0x3E); /****************/ /* Wait on busy */ /****************/ v_EepromWaitBusy(w_PCIBoardEepromAddress); /************************/ /* Select the READ mode */ /************************/ outb(NVCMD_BEGIN_READ, w_PCIBoardEepromAddress + 0x3F); /****************/ /* Wait on busy */ /****************/ v_EepromWaitBusy(w_PCIBoardEepromAddress); /*****************************/ /* Read data into the EEPROM */ /*****************************/ b_ReadByte = inb(w_PCIBoardEepromAddress + 0x3E); /****************/ /* Wait on busy */ /****************/ v_EepromWaitBusy(w_PCIBoardEepromAddress); /*********************************/ /* Select the upper address part */ /*********************************/ if (b_Counter == 0) { b_ReadLowByte = b_ReadByte; } /* if(b_Counter==0) */ else { b_ReadHighByte = b_ReadByte; } /* if(b_Counter==0) */ } /* for (b_Counter=0; b_Counter<2; b_Counter++) */ w_ReadWord = (b_ReadLowByte | (((unsigned short) b_ReadHighByte) * 256)); } /* end of if ((!strcmp(pc_PCIChipInformation, "S5920")) || (!strcmp(pc_PCIChipInformation, "S5933"))) */ if (!strcmp(pc_PCIChipInformation, "93C76")) { /*************************************/ /* Read 16 bit from the EEPROM 93C76 */ /*************************************/ v_EepromCs76Read(w_PCIBoardEepromAddress, w_EepromStartAddress, &w_ReadWord); } return w_ReadWord; } /* +----------------------------------------------------------------------------+ | Function Name : void v_EepromWaitBusy | | (unsigned short w_PCIBoardEepromAddress) | +----------------------------------------------------------------------------+ | Task : Wait the busy flag from PCI controller | +----------------------------------------------------------------------------+ | Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom base address | +----------------------------------------------------------------------------+ | Output Parameters : - | +----------------------------------------------------------------------------+ | Return Value : - | +----------------------------------------------------------------------------+ */ void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress) { unsigned char b_EepromBusy = 0; do { /*************/ /* IMPORTANT */ /*************/ /************************************************************************/ /* An error has been written in the AMCC 5933 book at the page B-13 */ /* Ex: if you read a byte and look for the busy statusEEPROM=0x80 and */ /* the operator register is AMCC_OP_REG_MCSR+3 */ /* unsigned short read EEPROM=0x8000 andAMCC_OP_REG_MCSR+2 */ /* unsigned int read EEPROM=0x80000000 and AMCC_OP_REG_MCSR */ /************************************************************************/ b_EepromBusy = inb(w_PCIBoardEepromAddress + 0x3F); b_EepromBusy = b_EepromBusy & 0x80; } while (b_EepromBusy == 0x80); } /* +---------------------------------------------------------------------------------+ | Function Name : void v_EepromClock76(unsigned int dw_Address, | | unsigned int dw_RegisterValue) | +---------------------------------------------------------------------------------+ | Task : This function sends the clocking sequence to the EEPROM. | +---------------------------------------------------------------------------------+ | Input Parameters : unsigned int dw_Address : PCI eeprom base address | | unsigned int dw_RegisterValue : PCI eeprom register value to write.| +---------------------------------------------------------------------------------+ | Output Parameters : - | +---------------------------------------------------------------------------------+ | Return Value : - | +---------------------------------------------------------------------------------+ */ void v_EepromClock76(unsigned int dw_Address, unsigned int dw_RegisterValue) { /************************/ /* Set EEPROM clock Low */ /************************/ outl(dw_RegisterValue & 0x6, dw_Address); /***************/ /* Wait 0.1 ms */ /***************/ udelay(100); /*************************/ /* Set EEPROM clock High */ /*************************/ outl(dw_RegisterValue | 0x1, dw_Address); /***************/ /* Wait 0.1 ms */ /***************/ udelay(100); } /* +---------------------------------------------------------------------------------+ | Function Name : void v_EepromSendCommand76(unsigned int dw_Address, | | unsigned int dw_EepromCommand, | | unsigned char b_DataLengthInBits) | +---------------------------------------------------------------------------------+ | Task : This function sends a Command to the EEPROM 93C76. | +---------------------------------------------------------------------------------+ | Input Parameters : unsigned int dw_Address : PCI eeprom base address | | unsigned int dw_EepromCommand : PCI eeprom command to write. | | unsigned char b_DataLengthInBits : PCI eeprom command data length. | +---------------------------------------------------------------------------------+ | Output Parameters : - | +---------------------------------------------------------------------------------+ | Return Value : - | +---------------------------------------------------------------------------------+ */ void v_EepromSendCommand76(unsigned int dw_Address, unsigned int dw_EepromCommand, unsigned char b_DataLengthInBits) { char c_BitPos = 0; unsigned int dw_RegisterValue = 0; /*****************************/ /* Enable EEPROM Chip Select */ /*****************************/ dw_RegisterValue = 0x2; /********************************************************************/ /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */ /********************************************************************/ outl(dw_RegisterValue, dw_Address); /***************/ /* Wait 0.1 ms */ /***************/ udelay(100); /*******************************************/ /* Send EEPROM command - one bit at a time */ /*******************************************/ for (c_BitPos = (b_DataLengthInBits - 1); c_BitPos >= 0; c_BitPos--) { /**********************************/ /* Check if current bit is 0 or 1 */ /**********************************/ if (dw_EepromCommand & (1 << c_BitPos)) { /***********/ /* Write 1 */ /***********/ dw_RegisterValue = dw_RegisterValue | 0x4; } else { /***********/ /* Write 0 */ /***********/ dw_RegisterValue = dw_RegisterValue & 0x3; } /*********************/ /* Write the command */ /*********************/ outl(dw_RegisterValue, dw_Address); /***************/ /* Wait 0.1 ms */ /***************/ udelay(100); /****************************/ /* Trigger the EEPROM clock */ /****************************/ v_EepromClock76(dw_Address, dw_RegisterValue); } } /* +---------------------------------------------------------------------------------+ | Function Name : void v_EepromCs76Read(unsigned int dw_Address, | | unsigned short w_offset, | | unsigned short * pw_Value) | +---------------------------------------------------------------------------------+ | Task : This function read a value from the EEPROM 93C76. | +---------------------------------------------------------------------------------+ | Input Parameters : unsigned int dw_Address : PCI eeprom base address | | unsigned short w_offset : Offset of the adress to read | | unsigned short * pw_Value : PCI eeprom 16 bit read value. | +---------------------------------------------------------------------------------+ | Output Parameters : - | +---------------------------------------------------------------------------------+ | Return Value : - | +---------------------------------------------------------------------------------+ */ void v_EepromCs76Read(unsigned int dw_Address, unsigned short w_offset, unsigned short *pw_Value) { char c_BitPos = 0; unsigned int dw_RegisterValue = 0; unsigned int dw_RegisterValueRead = 0; /*************************************************/ /* Send EEPROM read command and offset to EEPROM */ /*************************************************/ v_EepromSendCommand76(dw_Address, (EE_READ << 4) | (w_offset / 2), EE76_CMD_LEN); /*******************************/ /* Get the last register value */ /*******************************/ dw_RegisterValue = (((w_offset / 2) & 0x1) << 2) | 0x2; /*****************************/ /* Set the 16-bit value of 0 */ /*****************************/ *pw_Value = 0; /************************/ /* Get the 16-bit value */ /************************/ for (c_BitPos = 0; c_BitPos < 16; c_BitPos++) { /****************************/ /* Trigger the EEPROM clock */ /****************************/ v_EepromClock76(dw_Address, dw_RegisterValue); /**********************/ /* Get the result bit */ /**********************/ dw_RegisterValueRead = inl(dw_Address); /***************/ /* Wait 0.1 ms */ /***************/ udelay(100); /***************************************/ /* Get bit value and shift into result */ /***************************************/ if (dw_RegisterValueRead & 0x8) { /**********/ /* Read 1 */ /**********/ *pw_Value = (*pw_Value << 1) | 0x1; } else { /**********/ /* Read 0 */ /**********/ *pw_Value = (*pw_Value << 1); } } /*************************/ /* Clear all EEPROM bits */ /*************************/ dw_RegisterValue = 0x0; /********************************************************************/ /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */ /********************************************************************/ outl(dw_RegisterValue, dw_Address); /***************/ /* Wait 0.1 ms */ /***************/ udelay(100); } /******************************************/ /* EEPROM HEADER READ FUNCTIONS */ /******************************************/ /* +----------------------------------------------------------------------------+ | Function Name : int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, | | char * pc_PCIChipInformation,struct comedi_device *dev) | +----------------------------------------------------------------------------+ | Task : Read from eeprom Main Header | +----------------------------------------------------------------------------+ | Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | | | | char *pc_PCIChipInformation : PCI Chip Type. | | | | struct comedi_device *dev : comedi device structure | | pointer | +----------------------------------------------------------------------------+ | Output Parameters : - | +----------------------------------------------------------------------------+ | Return Value : 0 | +----------------------------------------------------------------------------+ */ int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, struct comedi_device *dev) { unsigned short w_Temp, i, w_Count = 0; unsigned int ui_Temp; struct str_MainHeader s_MainHeader; struct str_DigitalInputHeader s_DigitalInputHeader; struct str_DigitalOutputHeader s_DigitalOutputHeader; /* struct str_TimerMainHeader s_TimerMainHeader,s_WatchdogMainHeader; */ str_AnalogOutputHeader s_AnalogOutputHeader; struct str_AnalogInputHeader s_AnalogInputHeader; /* Read size */ s_MainHeader.w_HeaderSize = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + 8); /* Read nbr of functionality */ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + 10); s_MainHeader.b_Nfunctions = (unsigned char) w_Temp & 0x00FF; /* Read functionality details */ for (i = 0; i < s_MainHeader.b_Nfunctions; i++) { /* Read Type */ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + 12 + w_Count); s_MainHeader.s_Functions[i].b_Type = (unsigned char) w_Temp & 0x3F; w_Count = w_Count + 2; /* Read Address */ s_MainHeader.s_Functions[i].w_Address = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + 12 + w_Count); w_Count = w_Count + 2; } /* Display main header info */ for (i = 0; i < s_MainHeader.b_Nfunctions; i++) { switch (s_MainHeader.s_Functions[i].b_Type) { case EEPROM_DIGITALINPUT: i_EepromReadDigitalInputHeader(w_PCIBoardEepromAddress, pc_PCIChipInformation, s_MainHeader.s_Functions[i].w_Address, &s_DigitalInputHeader); this_board->i_NbrDiChannel = s_DigitalInputHeader.w_Nchannel; break; case EEPROM_DIGITALOUTPUT: i_EepromReadDigitalOutputHeader(w_PCIBoardEepromAddress, pc_PCIChipInformation, s_MainHeader.s_Functions[i].w_Address, &s_DigitalOutputHeader); this_board->i_NbrDoChannel = s_DigitalOutputHeader.w_Nchannel; ui_Temp = 0xffffffff; this_board->i_DoMaxdata = ui_Temp >> (32 - this_board->i_NbrDoChannel); break; case EEPROM_ANALOGINPUT: i_EepromReadAnlogInputHeader(w_PCIBoardEepromAddress, pc_PCIChipInformation, s_MainHeader.s_Functions[i].w_Address, &s_AnalogInputHeader); if (!(strcmp(this_board->pc_DriverName, "apci3200"))) this_board->i_NbrAiChannel = s_AnalogInputHeader.w_Nchannel * 4; else this_board->i_NbrAiChannel = s_AnalogInputHeader.w_Nchannel; this_board->i_Dma = s_AnalogInputHeader.b_HasDma; this_board->ui_MinAcquisitiontimeNs = (unsigned int) s_AnalogInputHeader.w_MinConvertTiming * 1000; this_board->ui_MinDelaytimeNs = (unsigned int) s_AnalogInputHeader.w_MinDelayTiming * 1000; ui_Temp = 0xffff; this_board->i_AiMaxdata = ui_Temp >> (16 - s_AnalogInputHeader.b_Resolution); break; case EEPROM_ANALOGOUTPUT: i_EepromReadAnlogOutputHeader(w_PCIBoardEepromAddress, pc_PCIChipInformation, s_MainHeader.s_Functions[i].w_Address, &s_AnalogOutputHeader); this_board->i_NbrAoChannel = s_AnalogOutputHeader.w_Nchannel; ui_Temp = 0xffff; this_board->i_AoMaxdata = ui_Temp >> (16 - s_AnalogOutputHeader.b_Resolution); break; case EEPROM_TIMER: this_board->i_Timer = 1; /* Timer subdevice present */ break; case EEPROM_WATCHDOG: this_board->i_Timer = 1; /* Timer subdevice present */ break; case EEPROM_TIMER_WATCHDOG_COUNTER: this_board->i_Timer = 1; /* Timer subdevice present */ } } return 0; } /* +----------------------------------------------------------------------------+ | Function Name : int i_EepromReadDigitalInputHeader(unsigned short | | w_PCIBoardEepromAddress,char *pc_PCIChipInformation, | | unsigned short w_Address,struct str_DigitalInputHeader *s_Header) | | | +----------------------------------------------------------------------------+ | Task : Read Digital Input Header | +----------------------------------------------------------------------------+ | Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | | | | char *pc_PCIChipInformation : PCI Chip Type. | | | | struct str_DigitalInputHeader *s_Header: Digita Input Header | | Pointer | +----------------------------------------------------------------------------+ | Output Parameters : - | +----------------------------------------------------------------------------+ | Return Value : 0 | +----------------------------------------------------------------------------+ */ int i_EepromReadDigitalInputHeader(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, unsigned short w_Address, struct str_DigitalInputHeader *s_Header) { unsigned short w_Temp; /* read nbr of channels */ s_Header->w_Nchannel = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + w_Address + 6); /* interruptible or not */ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + w_Address + 8); s_Header->b_Interruptible = (unsigned char) (w_Temp >> 7) & 0x01; /* How many interruptible logic */ s_Header->w_NinterruptLogic = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + w_Address + 10); return 0; } /* +----------------------------------------------------------------------------+ | Function Name : int i_EepromReadDigitalOutputHeader(unsigned short | | w_PCIBoardEepromAddress,char *pc_PCIChipInformation, | | unsigned short w_Address,struct str_DigitalOutputHeader *s_Header) | | | +----------------------------------------------------------------------------+ | Task : Read Digital Output Header | +----------------------------------------------------------------------------+ | Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | | | | char *pc_PCIChipInformation : PCI Chip Type. | | | | struct str_DigitalOutputHeader *s_Header: Digital Output Header| | Pointer | +----------------------------------------------------------------------------+ | Output Parameters : - | +----------------------------------------------------------------------------+ | Return Value : 0 | +----------------------------------------------------------------------------+ */ int i_EepromReadDigitalOutputHeader(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, unsigned short w_Address, struct str_DigitalOutputHeader *s_Header) { /* Read Nbr channels */ s_Header->w_Nchannel = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + w_Address + 6); return 0; } /* +----------------------------------------------------------------------------+ | Function Name : int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress, | | char *pc_PCIChipInformation,WORD w_Address, | | struct str_TimerMainHeader *s_Header) | +----------------------------------------------------------------------------+ | Task : Read Timer or Watchdog Header | +----------------------------------------------------------------------------+ | Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | | | | char *pc_PCIChipInformation : PCI Chip Type. | | | | struct str_TimerMainHeader *s_Header: Timer Header | | Pointer | +----------------------------------------------------------------------------+ | Output Parameters : - | +----------------------------------------------------------------------------+ | Return Value : 0 | +----------------------------------------------------------------------------+ */ int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, unsigned short w_Address, struct str_TimerMainHeader *s_Header) { unsigned short i, w_Size = 0, w_Temp; /* Read No of Timer */ s_Header->w_Ntimer = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + w_Address + 6); /* Read header size */ for (i = 0; i < s_Header->w_Ntimer; i++) { s_Header->s_TimerDetails[i].w_HeaderSize = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + w_Address + 8 + w_Size + 0); w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + w_Address + 8 + w_Size + 2); /* Read Resolution */ s_Header->s_TimerDetails[i].b_Resolution = (unsigned char) (w_Temp >> 10) & 0x3F; /* Read Mode */ s_Header->s_TimerDetails[i].b_Mode = (unsigned char) (w_Temp >> 4) & 0x3F; w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + w_Address + 8 + w_Size + 4); /* Read MinTiming */ s_Header->s_TimerDetails[i].w_MinTiming = (w_Temp >> 6) & 0x3FF; /* Read Timebase */ s_Header->s_TimerDetails[i].b_TimeBase = (unsigned char) (w_Temp) & 0x3F; w_Size += s_Header->s_TimerDetails[i].w_HeaderSize; } return 0; } /* +----------------------------------------------------------------------------+ | Function Name : int i_EepromReadAnlogOutputHeader(unsigned short | | w_PCIBoardEepromAddress,char *pc_PCIChipInformation, | | unsigned short w_Address,str_AnalogOutputHeader *s_Header) | +----------------------------------------------------------------------------+ | Task : Read Nalog Output Header | +----------------------------------------------------------------------------+ | Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | | | | char *pc_PCIChipInformation : PCI Chip Type. | | | | str_AnalogOutputHeader *s_Header:Anlog Output Header | | Pointer | +----------------------------------------------------------------------------+ | Output Parameters : - | +----------------------------------------------------------------------------+ | Return Value : 0 | +----------------------------------------------------------------------------+ */ int i_EepromReadAnlogOutputHeader(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, unsigned short w_Address, str_AnalogOutputHeader *s_Header) { unsigned short w_Temp; /* No of channels for 1st hard component */ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + w_Address + 10); s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF; /* Resolution for 1st hard component */ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + w_Address + 16); s_Header->b_Resolution = (unsigned char) (w_Temp >> 8) & 0xFF; return 0; } /* +----------------------------------------------------------------------------+ | Function Name : int i_EepromReadAnlogInputHeader(unsigned short | | w_PCIBoardEepromAddress,char *pc_PCIChipInformation, | | unsigned short w_Address,struct str_AnalogInputHeader *s_Header) | +----------------------------------------------------------------------------+ | Task : Read Nalog Output Header | +----------------------------------------------------------------------------+ | Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | | | | char *pc_PCIChipInformation : PCI Chip Type. | | | | struct str_AnalogInputHeader *s_Header:Anlog Input Header | | Pointer | +----------------------------------------------------------------------------+ | Output Parameters : - | +----------------------------------------------------------------------------+ | Return Value : 0 | +----------------------------------------------------------------------------+ */ /* Reads only for ONE hardware component */ int i_EepromReadAnlogInputHeader(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, unsigned short w_Address, struct str_AnalogInputHeader *s_Header) { unsigned short w_Temp, w_Offset; w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + w_Address + 10); s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF; s_Header->w_MinConvertTiming = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + w_Address + 16); s_Header->w_MinDelayTiming = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + w_Address + 30); w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + w_Address + 20); s_Header->b_HasDma = (w_Temp >> 13) & 0x01; /* whether dma present or not */ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + w_Address + 72); /* reading Y */ w_Temp = w_Temp & 0x00FF; if (w_Temp) /* Y>0 */ { w_Offset = 74 + (2 * w_Temp) + (10 * (1 + (w_Temp / 16))); /* offset of first analog input single header */ w_Offset = w_Offset + 2; /* resolution */ } else /* Y=0 */ { w_Offset = 74; w_Offset = w_Offset + 2; /* resolution */ } /* read Resolution */ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + w_Address + w_Offset); s_Header->b_Resolution = w_Temp & 0x001F; /* last 5 bits */ return 0; }